From db2da43fc178a5a9e1bb2c2a13681d5be919533e Mon Sep 17 00:00:00 2001 From: dongheng Date: Wed, 14 Sep 2016 19:39:24 +0800 Subject: [PATCH 001/343] components/openssl: add API header for openssl compatibility layer --- components/openssl/include/openssl/ssl.h | 1651 ++++++++++++++++++++++ 1 file changed, 1651 insertions(+) create mode 100644 components/openssl/include/openssl/ssl.h diff --git a/components/openssl/include/openssl/ssl.h b/components/openssl/include/openssl/ssl.h new file mode 100644 index 0000000000..b7b784fe71 --- /dev/null +++ b/components/openssl/include/openssl/ssl.h @@ -0,0 +1,1651 @@ +#ifndef HEADER_SSL_H +#define HEADER_SSL_H + +#include "ssl_types.h" + +/* +{ +*/ + +/* + * SSL_CTX_new - create a SSL context + * + * @param method - the SSL context method point + * + * @return the context point, if create failed return NULL + */ +SSL_CTX* SSL_CTX_new(const SSL_METHOD *method); + +/* + * SSL_CTX_free - free a SSL context + * + * @param method - the SSL context point + * + * @return none + */ +void SSL_CTX_free(SSL_CTX *ctx); + +/* + * SSL_new - create a SSL + * + * @param ctx - the SSL context point + * + * @return the SSL point or NULL if failed + */ +SSL* SSL_new(SSL_CTX *ctx); + +/* + * SSL_free - free the SSL + * + * @param ssl - the SSL point + * + * @return none + */ +void SSL_free(SSL *ssl); + +/* + * SSL_connect - connect to the remote SSL server + * + * @param ssl - the SSL point + * + * @return + * 1 : OK + * -1 : failed + */ +int SSL_connect(SSL *ssl); + +/* + * SSL_accept - accept the remote connection + * + * @param ssl - the SSL point + * + * @return + * 1 : OK + * -1 : failed + */ +int SSL_accept(SSL *ssl); + +/* + * SSL_read - read data from to remote + * + * @param ssl - the SSL point which has been connected + * @param buffer - the received data buffer point + * @param len - the received data length + * + * @return + * > 0 : OK, and return received data bytes + * = 0 : connection is closed + * < 0 : an error catch + */ +int SSL_read(SSL *ssl, void *buffer, int len); + +/* + * SSL_write - send the data to remote + * + * @param ssl - the SSL point which has been connected + * @param buffer - the send data buffer point + * @param len - the send data length + * + * @return + * > 0 : OK, and return sent data bytes + * = 0 : connection is closed + * < 0 : an error catch + */ +int SSL_write(SSL *ssl, const void *buffer, int len); + +/* + * SSL_get_verify_result - get the verifying result of the SSL certification + * + * @param ssl - the SSL point + * + * @return the result of verifying + */ +long SSL_get_verify_result(const SSL *ssl); + +/* + * SSL_shutdown - shutdown the connection + * + * @param ssl - the SSL point + * + * @return + * 1 : OK + * 0 : shutdown is not finished + * -1 : an error catch + */ +int SSL_shutdown(SSL *ssl); + +/* + * SSL_set_fd - bind the socket file description into the SSL + * + * @param ssl - the SSL point + * @param fd - socket handle + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_set_fd(SSL *ssl, int fd); + +/* + * SSL_CTX_use_PrivateKey - These functions load the private key into the SSL_CTX or SSL object + * + * @param ctx - the SSL context point + * @param pkey - private key object point + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey); + +/* + * SSL_CTX_use_PrivateKey - These functions load the certification into the SSL_CTX or SSL object + * + * @param ctx - the SSL context point + * @param pkey - certification object point + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x); + +/* + * SSLv23_client_method - create the target SSL context client method + * + * @param none + * + * @return the SSLV2.3 version SSL context client method + */ +const SSL_METHOD* SSLv23_client_method(void); + +/* + * TLSv1_client_method - create the target SSL context client method + * + * @param none + * + * @return the TLSV1.0 version SSL context client method + */ +const SSL_METHOD* TLSv1_client_method(void); + +/* + * SSLv3_client_method - create the target SSL context client method + * + * @param none + * + * @return the SSLV1.0 version SSL context client method + */ +const SSL_METHOD* SSLv3_client_method(void); + +/* + * TLSv1_1_client_method - create the target SSL context client method + * + * @param none + * + * @return the TLSV1.1 version SSL context client method + */ +const SSL_METHOD* TLSv1_1_client_method(void); + + +/* + * SSLv23_server_method - create the target SSL context server method + * + * @param none + * + * @return the SSLV2.3 version SSL context server method + */ +const SSL_METHOD* SSLv23_server_method(void); + +/* + * TLSv1_1_server_method - create the target SSL context server method + * + * @param none + * + * @return the TLSV1.1 version SSL context server method + */ +const SSL_METHOD* TLSv1_1_server_method(void); + +/* + * TLSv1_server_method - create the target SSL context server method + * + * @param none + * + * @return the TLSV1.0 version SSL context server method + */ +const SSL_METHOD* TLSv1_server_method(void); + +/* + * SSLv3_server_method - create the target SSL context server method + * + * @param none + * + * @return the SSLV3.0 version SSL context server method + */ +const SSL_METHOD* SSLv3_server_method(void); + +/* + * SSL_CTX_set_alpn_select_cb - set the SSL context ALPN select callback function + * + * @param ctx - SSL context point + * @param cb - ALPN select callback function + * @param arg - ALPN select callback function entry private data point + * + * @return none + */ +void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx, + int (*cb) (SSL *ssl, + const unsigned char **out, + unsigned char *outlen, + const unsigned char *in, + unsigned int inlen, + void *arg), + void *arg); + + +/* + * SSL_CTX_set_alpn_protos - set the SSL context ALPN select protocol + * + * @param ctx - SSL context point + * @param protos - ALPN protocol name + * @param protos_len - ALPN protocol name bytes + * + * @return + * 0 : OK + * 1 : failed + */ +int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos, unsigned int protos_len); + +/* + * SSL_CTX_set_next_proto_select_cb - set the SSL context next ALPN select callback function + * + * @param ctx - SSL context point + * @param cb - ALPN select callback function + * @param arg - ALPN select callback function entry private data point + * + * @return none + */ +void SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx, + int (*cb) (SSL *ssl, + unsigned char **out, + unsigned char *outlen, + const unsigned char *in, + unsigned int inlen, + void *arg), + void *arg); + +/* + * SSL_get_error - get SSL error code + * + * @param ssl - SSL point + * @param ret_code - SSL return code + * + * @return SSL error number + */ +int SSL_get_error(const SSL *ssl, int ret_code); + +/* + * ERR_clear_error - clear the SSL error code + * + * @param none + * + * @return none + */ +void ERR_clear_error(void); + +/* + * ERR_get_error - get the current SSL error code + * + * @param none + * + * @return current SSL error number + */ +int ERR_get_error(void); + +/* + * ERR_load_SSL_strings - register the SSL error strings + * + * @param none + * + * @return none + */ +void ERR_load_SSL_strings(void); + +/* + * SSL_library_init - initialize the SSL library + * + * @param none + * + * @return none + */ +void SSL_library_init(void); + +/* + * ERR_error_string - generates a human-readable string representing the error code e + * and store it into the "ret" point memory + * + * @param e - error code + * @param ret - memory point to store the string + * + * @return the result string point + */ +char *ERR_error_string(unsigned long e, char *ret); + +/* + * SSL_CTX_set_options - add the SSL context option + * + * @param ctx - SSL context point + * @param opt - new SSL context option + * + * @return the SSL context option + */ +unsigned long SSL_CTX_set_options(SSL_CTX *ctx, unsigned long opt); + +/* + * SSL_CTX_set_options - add the SSL context mode + * + * @param ctx - SSL context point + * @param mod - new SSL context mod + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_CTX_set_mode(SSL_CTX *ctx, int mod); + +/* +} +*/ + +/* + * SSL_do_handshake - perform the SSL handshake + * + * @param ssl - SSL point + * + * @return + * 1 : OK + * 0 : failed + * -1 : a error catch + */ +int SSL_do_handshake(SSL *ssl); + +/* + * SSL_get_version - get the SSL current version + * + * @param ssl - SSL point + * + * @return the version string + */ +const char *SSL_get_version(const SSL *ssl); + +/* + * SSL_CTX_set_ssl_version - set the SSL context version + * + * @param ctx - SSL context point + * @param meth - SSL method point + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth); + +/* + * SSL_CTX_get_ssl_method - get the SSL context current method + * + * @param ctx - SSL context point + * + * @return the SSL context current method + */ +const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx); + +/* + * SSL_CTX_get_ssl_method - get the SSL current method + * + * @param ssl - SSL point + * + * @return the SSL current method + */ +const SSL_METHOD *SSL_get_ssl_method(SSL *ssl); + +/* + * SSL_set_ssl_method - set the SSL method + * + * @param ssl - SSL point + * @param meth - SSL method point + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_set_ssl_method(SSL *ssl, const SSL_METHOD *method); + +/* + * SSL_add_client_CA - add CA client certification into the SSL + * + * @param ssl - SSL point + * @param x - CA certification point + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_add_client_CA(SSL *ssl, X509 *x); + +/* + * SSL_add_client_CA - add CA client certification into the SSL context + * + * @param ctx - SSL context point + * @param x - CA certification point + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x); + +/* + * SSL_set_client_CA_list - set the SSL CA certification list + * + * @param ssl - SSL point + * @param name_list - CA certification list + * + * @return none + */ +void SSL_set_client_CA_list(SSL *ssl, STACK_OF(X509_NAME) *name_list); + +/* + * SSL_CTX_set_client_CA_list - set the SSL context CA certification list + * + * @param ctx - SSL context point + * @param name_list - CA certification list + * + * @return none + */ +void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list); + +/* + * SSL_get_client_CA_list - get the SSL CA certification list + * + * @param ssl - SSL point + * + * @return CA certification list + */ +STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *ssl); + +/* + * SSL_CTX_get_client_CA_list - get the SSL context CA certification list + * + * @param ctx - SSL context point + * + * @return CA certification list + */ +STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx); + +/* + * SSL_get_certificate - get the SSL certification point + * + * @param ssl - SSL point + * + * @return SSL certification point + */ +X509 *SSL_get_certificate(const SSL *ssl); + +/* + * SSL_get_privatekey - get the SSL private key point + * + * @param ssl - SSL point + * + * @return SSL private key point + */ +EVP_PKEY *SSL_get_privatekey(const SSL *ssl); + +/* + * SSL_set_info_callback - set the SSL information callback function + * + * @param ssl - SSL point + * @param cb - information callback function + * + * @return none + */ +void SSL_set_info_callback(SSL *ssl, void (*cb) (const SSL *ssl, int type, int val)); + +/* + * SSL_get_state - get the SSL state + * + * @param ssl - SSL point + * + * @return SSL state + */ +OSSL_HANDSHAKE_STATE SSL_get_state(const SSL *ssl); + +/* + * SSL_CTX_set_default_read_buffer_len - set the SSL context read buffer length + * + * @param ctx - SSL context point + * @param len - read buffer length + * + * @return none + */ +void SSL_CTX_set_default_read_buffer_len(SSL_CTX *ctx, size_t len); + +/* + * SSL_set_default_read_buffer_len - set the SSL read buffer length + * + * @param ssl - SSL point + * @param len - read buffer length + * + * @return none + */ +void SSL_set_default_read_buffer_len(SSL *ssl, size_t len); + +/* + * SSL_set_security_level - set the SSL security level + * + * @param ssl - SSL point + * @param level - security level + * + * @return none + */ +void SSL_set_security_level(SSL *ssl, int level); + +/* + * SSL_get_security_level - get the SSL security level + * + * @param ssl - SSL point + * + * @return security level + */ +int SSL_get_security_level(const SSL *ssl); + +/* + * SSL_CTX_get_verify_mode - get the SSL verifying mode of the SSL context + * + * @param ctx - SSL context point + * + * @return verifying mode + */ +int SSL_CTX_get_verify_mode(const SSL_CTX *ctx); + +/* + * SSL_CTX_get_verify_depth - get the SSL verifying depth of the SSL context + * + * @param ctx - SSL context point + * + * @return verifying depth + */ +int SSL_CTX_get_verify_depth(const SSL_CTX *ctx); + +/* + * SSL_CTX_set_verify - set the SSL context verifying of the SSL context + * + * @param ctx - SSL context point + * @param mode - verifying mode + * @param verify_callback - verifying callback function + * + * @return none + */ +void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, int (*verify_callback)(int, X509_STORE_CTX *)); + +/* + * SSL_set_verify - set the SSL verifying of the SSL context + * + * @param ctx - SSL point + * @param mode - verifying mode + * @param verify_callback - verifying callback function + * + * @return none + */ +void SSL_set_verify(SSL *s, int mode, int (*verify_callback)(int, X509_STORE_CTX *)); + +/* + * SSL_CTX_set_verify_depth - set the SSL verify depth of the SSL context + * + * @param ctx - SSL context point + * @param depth - verifying depth + * + * @return one + */ +void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth); + +/* + * verify_callback - certification verifying callback function + * + * @param preverify_ok - verifying result + * @param x509_ctx - X509 certification point + * + * @return verifying result + */ +int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx); + +/* + * SSL_CTX_set_timeout - set the session timeout time + * + * @param ctx - SSL context point + * @param t - new session timeout time + * + * @return old session timeout time + */ +long SSL_CTX_set_timeout(SSL_CTX *ctx, long t); + +/* + * SSL_CTX_get_timeout - get the session timeout time + * + * @param ctx - SSL context point + * + * @return current session timeout time + */ +long SSL_CTX_get_timeout(const SSL_CTX *ctx); + +/* + * SSL_CTX_set_cipher_list - set the SSL context cipher through the list string + * + * @param ctx - SSL context point + * @param str - cipher controller list string + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str); + +/* + * SSL_set_cipher_list - set the SSL cipher through the list string + * + * @param ssl - SSL point + * @param str - cipher controller list string + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_set_cipher_list(SSL *ssl, const char *str); + +/* + * SSL_get_cipher_list - get the SSL cipher list string + * + * @param ssl - SSL point + * + * @return cipher controller list string + */ +const char *SSL_get_cipher_list(const SSL *ssl, int n); + +/* + * SSL_get_current_cipher - get the SSL cipher + * + * @param ssl - SSL point + * + * @return current cipher + */ +const SSL_CIPHER *SSL_get_current_cipher(const SSL *ssl); + +/* + * SSL_get_cipher - get the SSL cipher string + * + * @param ssl - SSL point + * + * @return cipher string + */ +const char *SSL_get_cipher(const SSL *ssl); + +/* + * SSL_CTX_get_cert_store - get the SSL context object X509 certification storage + * + * @param ctx - SSL context point + * + * @return x509 certification storage + */ +X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx); + +/* + * SSL_CTX_set_cert_store - set the SSL context object X509 certification store + * + * @param ctx - SSL context point + * @param store - X509 certification store + * + * @return none + */ +void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store); + +/* + * SSL_want - get the SSL specifical statement + * + * @param ssl - SSL point + * + * @return specifical statement + */ +int SSL_want(const SSL *ssl); + +/* + * SSL_want_x509_lookup - check if the SSL is SSL_X509_LOOKUP state + * + * @param ssl - SSL point + * + * @return + * 1 : yes + * 0 : no + */ +int SSL_want_x509_lookup(const SSL *ssl); + +/* + * SSL_clear - reset the SSL + * + * @param ssl - SSL point + * + * @return + * 1 : yes + * 0 : no + */ +int SSL_clear(SSL *ssl); + +/* + * SSL_get_fd - get the socket handle of the SSL + * + * @param ssl - SSL point + * + * @return + * >= 0 : yes, and return socket handle + * < 0 : a error catch + */ +int SSL_get_fd(const SSL *ssl); + +/* + * SSL_get_rfd - get the read only socket handle of the SSL + * + * @param ssl - SSL point + * + * @return + * >= 0 : yes, and return socket handle + * < 0 : a error catch + */ +int SSL_get_rfd(const SSL *ssl); + +/* + * SSL_get_wfd - get the write only socket handle of the SSL + * + * @param ssl - SSL point + * + * @return + * >= 0 : yes, and return socket handle + * < 0 : a error catch + */ +int SSL_get_wfd(const SSL *ssl); + +/* + * SSL_set_read_ahead - set the SSL if we can read as many as data + * + * @param ssl - SSL point + * @param yes - enbale the function + * + * @return none + */ +void SSL_set_read_ahead(SSL *s, int yes); + +/* + * SSL_set_read_ahead - set the SSL context if we can read as many as data + * + * @param ctx - SSL context point + * @param yes - enbale the function + * + * @return none + */ +void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes); + +/* + * SSL_set_read_ahead - get the SSL ahead signal if we can read as many as data + * + * @param ssl - SSL point + * + * @return SSL context ahead signal + */ +int SSL_get_read_ahead(const SSL *ssl); + +/* + * SSL_set_read_ahead - get the SSL context ahead signal if we can read as many as data + * + * @param ctx - SSL context point + * + * @return SSL context ahead signal + */ +long SSL_CTX_get_read_ahead(SSL_CTX *ctx); + +/* + * SSL_has_pending - check if some data can be read + * + * @param ssl - SSL point + * + * @return SSL context ahead signal + */ +int SSL_has_pending(const SSL *ssl); + +/* + * SSL_CTX_use_certificate - load the X509 certification into SSL context + * + * @param ctx - SSL context point + * @param x - X509 certification point + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x);//loads the certificate x into ctx + +/* + * SSL_CTX_use_certificate_ASN1 - load the ASN1 certification into SSL context + * + * @param ctx - SSL context point + * @param len - certification length + * @param d - data point + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, unsigned char *d); + +/* + * SSL_CTX_use_certificate_file - load the certification file into SSL context + * + * @param ctx - SSL context point + * @param file - certification file name + * @param type - certification encoding type + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type); + +/* + * SSL_CTX_use_certificate_chain_file - load the certification chain file into SSL context + * + * @param ctx - SSL context point + * @param file - certification chain file name + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file); + + +/* + * SSL_CTX_use_certificate_ASN1 - load the ASN1 private key into SSL context + * + * @param ctx - SSL context point + * @param d - data point + * @param len - private key length + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, unsigned char *d, long len);//adds the private key of type pk stored at memory location d (length len) to ctx + +/* + * SSL_CTX_use_certificate_file - load the private key file into SSL context + * + * @param ctx - SSL context point + * @param file - private key file name + * @param type - private key encoding type + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type);//adds the first private key found in file to ctx, The formatting type of the certificate must be specified from the known types SSL_FILETYPE_PEM, SSL_FILETYPE_ASN1. + +/* + * SSL_CTX_use_certificate - load the RSA private key into SSL context + * + * @param ctx - SSL context point + * @param x - RSA private key point + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa); + +/* + * SSL_CTX_use_certificate_ASN1 - load the RSA ASN1 private key into SSL context + * + * @param ctx - SSL context point + * @param d - data point + * @param len - RSA private key length + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, unsigned char *d, long len); + +/* + * SSL_CTX_use_certificate_file - load the RSA private key file into SSL context + * + * @param ctx - SSL context point + * @param file - RSA private key file name + * @param type - private key encoding type + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type); + + +/* + * SSL_CTX_check_private_key - check if the private key and certification is matched + * + * @param ctx - SSL context point + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_CTX_check_private_key(const SSL_CTX *ctx); + +/* + * SSL_CTX_use_serverinfo - set the SSL context server information + * + * @param ctx - SSL context point + * @param serverinfo - server information string + * @param serverinfo_length - server information length + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo, size_t serverinfo_length); + +/* + * SSL_CTX_use_serverinfo - load the SSL context server infomation file into SSL context + * + * @param ctx - SSL context point + * @param file - server information file + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file); + +/* + * SSL_select_next_proto - SSL select next function + * + * @param out - point of output data point + * @param outlen - output data length + * @param in - input data + * @param inlen - input data length + * @param client - client data point + * @param client_len -client data length + * + * @return + * OPENSSL_NPN_UNSUPPORTED : not support + * OPENSSL_NPN_NEGOTIATED : negotiated + * OPENSSL_NPN_NO_OVERLAP : no overlap + */ +int SSL_select_next_proto(unsigned char **out, unsigned char *outlen, + const unsigned char *in, unsigned int inlen, + const unsigned char *client, unsigned int client_len); + +/* + * SSL_CTX_add_extra_chain_cert - load the extra certification chain into the SSL context + * + * @param ctx - SSL context point + * @param x509 - X509 certification + * + * @return + * 1 : OK + * 0 : failed + */ +long SSL_CTX_add_extra_chain_cert(SSL_CTX *ctx, X509 *); + +/* + * SSL_CTX_ctrl - control the SSL context + * + * @param ctx - SSL context point + * @param cmd - command + * @param larg - parameter length + * @param parg - parameter point + * + * @return + * 1 : OK + * 0 : failed + */ +long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, char *parg); + +/* + * SSL_CTX_get_ciphers - get the SSL context cipher + * + * @param ctx - SSL context point + * + * @return SSL context cipher + */ +STACK *SSL_CTX_get_ciphers(const SSL_CTX *ctx); + +/* + * SSL_CTX_get_ciphers - check if the SSL context can read as many as data + * + * @param ctx - SSL context point + * + * @return + * 1 : Yes + * 0 : No + */ +long SSL_CTX_get_default_read_ahead(SSL_CTX *ctx); + +/* + * SSL_CTX_get_ex_data - get the SSL context extra data + * + * @param ctx - SSL context point + * @param idx - index + * + * @return data point + */ +char *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx); + +/* + * SSL_CTX_get_quiet_shutdown - get the SSL context quiet shutdown option + * + * @param ctx - SSL context point + * + * @return quiet shutdown option + */ +int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx); + +/* + * SSL_CTX_get_quiet_shutdown - load the SSL context CA file + * + * @param ctx - SSL context point + * @param CAfile - CA certification file + * @param CApath - CA certification file path + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, const char *CApath); + +/* + * SSL_CTX_up_ref - add SSL context reference count by '1' + * + * @param ctx - SSL context point + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_CTX_up_ref(SSL_CTX *ctx); + +/* + * SSL_CTX_set_app_data - set SSL context application private data + * + * @param ctx - SSL context point + * @param arg - private data + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_CTX_set_app_data(SSL_CTX *ctx, void *arg); + +/* + * SSL_CTX_set_client_cert_cb - set SSL context client certification callback function + * + * @param ctx - SSL context point + * @param cb - callback function + * + * @return none + */ +void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey)); + +/* + * SSL_CTX_set_default_read_ahead - set the SSL context if we can read as many as data + * + * @param ctx - SSL context point + * @param m - enable the fuction + * + * @return none + */ +void SSL_CTX_set_default_read_ahead(SSL_CTX *ctx, int m); + +/* + * SSL_CTX_set_default_verify_paths - set SSL context default verifying path + * + * @param ctx - SSL context point + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx); + +/* + * SSL_CTX_set_default_verify_paths - set SSL context default verifying directory + * + * @param ctx - SSL context point + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_CTX_set_default_verify_dir(SSL_CTX *ctx); + +/* + * SSL_CTX_set_default_verify_paths - set SSL context default verifying file + * + * @param ctx - SSL context point + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_CTX_set_default_verify_file(SSL_CTX *ctx); + +/* + * SSL_CTX_set_ex_data - set SSL context extra data + * + * @param ctx - SSL context point + * @param idx - data index + * @param arg - data point + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_CTX_set_ex_data(SSL_CTX *s, int idx, char *arg); + +/* + * SSL_CTX_clear_options - clear the SSL context option bit of "op" + * + * @param ctx - SSL context point + * @param op - option + * + * @return SSL context option + */ +unsigned long SSL_CTX_clear_options(SSL_CTX *ctx, unsigned long op); + +/* + * SSL_CTX_clear_options - get the SSL context option + * + * @param ctx - SSL context point + * @param op - option + * + * @return SSL context option + */ +unsigned long SSL_CTX_get_options(SSL_CTX *ctx); + +/* + * SSL_CTX_set_quiet_shutdown - set the SSL context quiet shutdown mode + * + * @param ctx - SSL context point + * @param mode - mode + * + * @return none + */ +void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode); + +/* + * SSL_CTX_get0_certificate - get the SSL context X509 certification + * + * @param ctx - SSL context point + * + * @return X509 certification + */ +X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx); + +/* + * SSL_CTX_get0_certificate - get the SSL context private key + * + * @param ctx - SSL context point + * + * @return private key + */ +EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx); + +/* + * SSL_CTX_use_psk_identity_hint - set SSL context PSK identity hint + * + * @param ctx - SSL context point + * @param hint - PSK identity hint + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *hint); + +/* + * SSL_CTX_set_psk_server_callback - set SSL context PSK server callback function + * + * @param ctx - SSL context point + * @param callback - callback function + * + */ +void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx, + unsigned int (*callback)(SSL *ssl, + const char *identity, + unsigned char *psk, + int max_psk_len)); +/* + * SSL_alert_desc_string - get alert description string + * + * @param value - alert value + * + * @return alert description string + */ +const char *SSL_alert_desc_string(int value); + +/* + * SSL_alert_desc_string - get alert description long string + * + * @param value - alert value + * + * @return alert description long string + */ +const char *SSL_alert_desc_string_long(int value); + +/* + * SSL_alert_type_string - get alert type string + * + * @param value - alert value + * + * @return alert type string + */ +const char *SSL_alert_type_string(int value); + +/* + * SSL_alert_type_string_long - get alert type long string + * + * @param value - alert value + * + * @return alert type long string + */ +const char *SSL_alert_type_string_long(int value); + +/* + * SSL_get_SSL_CTX - get SSL context of the SSL + * + * @param ssl - SSL point + * + * @return SSL context + */ +SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl); + +/* + * SSL_get_app_data - get SSL application data + * + * @param ssl - SSL point + * + * @return application data + */ +char *SSL_get_app_data(SSL *ssl); + +/* + * SSL_get_cipher_bits - get SSL cipher bits + * + * @param ssl - SSL point + * @param alg_bits - algorithm bits + * + * @return strength bits + */ +int SSL_get_cipher_bits(const SSL *ssl, int *alg_bits); + +/* + * SSL_get_cipher_name - get SSL cipher name + * + * @param ssl - SSL point + * + * @return SSL cipher name + */ +char *SSL_get_cipher_name(const SSL *ssl); + +/* + * SSL_get_cipher_version - get SSL cipher version + * + * @param ssl - SSL point + * + * @return SSL cipher version + */ +char *SSL_get_cipher_version(const SSL *ssl); + +/* + * SSL_get_ex_data - get SSL extra data + * + * @param ssl - SSL point + * @param idx - data index + * + * @return extra data + */ +char *SSL_get_ex_data(const SSL *ssl, int idx); + +/* + * SSL_get_ex_data_X509_STORE_CTX_idx - get index of the SSL extra data X509 storage context + * + * @param none + * + * @return data index + */ +int SSL_get_ex_data_X509_STORE_CTX_idx(void); + +/* + * SSL_get_peer_cert_chain - get peer certification chain + * + * @param ssl - SSL point + * + * @return certification chain + */ +STACK *SSL_get_peer_cert_chain(const SSL *ssl); + +/* + * SSL_get_peer_certificate - get peer certification + * + * @param ssl - SSL point + * + * @return certification + */ +X509 *SSL_get_peer_certificate(const SSL *ssl); + +/* + * SSL_get_quiet_shutdown - get SSL quiet shutdown mode + * + * @param ssl - SSL point + * + * @return quiet shutdown mode + */ +int SSL_get_quiet_shutdown(const SSL *ssl); + +/* + * SSL_get_rbio - get SSL read only IO handle + * + * @param ssl - SSL point + * + * @return IO handle + */ +BIO *SSL_get_rbio(const SSL *ssl); + +/* + * SSL_get_shared_ciphers - get SSL shared ciphers + * + * @param ssl - SSL point + * @param buf - buffer to store the ciphers + * @param len - buffer len + * + * @return shared ciphers or NULL if failed + */ +char *SSL_get_shared_ciphers(const SSL *ssl, char *buf, int len); + +/* + * SSL_get_shutdown - get SSL shutdown mode + * + * @param ssl - SSL point + * + * @return shutdown mode + */ +int SSL_get_shutdown(const SSL *ssl); + +/* + * SSL_get_time - get SSL session time + * + * @param ssl - SSL point + * + * @return session time + */ +long SSL_get_time(const SSL *ssl); + +/* + * SSL_get_timeout - get SSL session timeout time + * + * @param ssl - SSL point + * + * @return session timeout time + */ +long SSL_get_timeout(const SSL *ssl); + +/* + * SSL_get_verify_mode - get SSL verifying mode + * + * @param ssl - SSL point + * + * @return verifying mode + */ +int SSL_get_verify_mode(const SSL *ssl); + +/* + * SSL_get_wbio - get SSL write only IO handle + * + * @param ssl - SSL point + * + * @return IO handle + */ +BIO *SSL_get_wbio(const SSL *ssl); + +/* + * SSL_load_client_CA_file - load SSL client CA certification file + * + * @param file - file name + * + * @return certification loading object + */ +STACK *SSL_load_client_CA_file(const char *file); + +/* + * SSL_up_ref - add SSL reference by '1' + * + * @param ssl - SSL point + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_up_ref(SSL *ssl); + +/* + * SSL_peek - read and put data into buf, but not clear the SSL low-level storage + * + * @param ssl - SSL point + * @param buf - storage buffer point + * @param num - data bytes + * + * @return + * > 0 : OK, and return read bytes + * = 0 : connect is closed + * < 0 : a error catch + */ +int SSL_peek(SSL *ssl, void *buf, int num); + +/* + * SSL_renegotiate - make SSL renegotiate + * + * @param ssl - SSL point + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_renegotiate(SSL *ssl); + +/* + * SSL_rstate_string - get the state string where SSL is reading + * + * @param ssl - SSL point + * + * @return state string + */ +const char *SSL_rstate_string(SSL *ssl); + +/* + * SSL_rstate_string_long - get the statement long string where SSL is reading + * + * @param ssl - SSL point + * + * @return statement long string + */ +const char *SSL_rstate_string_long(SSL *ssl); + +/* + * SSL_set_accept_state - set SSL accept statement + * + * @param ssl - SSL point + * + * @return none + */ +void SSL_set_accept_state(SSL *ssl); + +/* + * SSL_set_app_data - set SSL application data + * + * @param ssl - SSL point + * @param arg - SSL application data point + * + * @return none + */ +void SSL_set_app_data(SSL *ssl, char *arg); + +/* + * SSL_set_bio - set SSL BIO + * + * @param ssl - SSL point + * @param rbio - read only IO + * @param wbio - write only IO + * + * @return none + */ +void SSL_set_bio(SSL *ssl, BIO *rbio, BIO *wbio); + +/* + * SSL_clear_options - clear SSL option + * + * @param ssl - SSL point + * @param op - clear option + * + * @return SSL option + */ +unsigned long SSL_clear_options(SSL *ssl, unsigned long op); + +/* + * SSL_clear_options - get SSL option + * + * @param ssl - SSL point + * + * @return SSL option + */ +unsigned long SSL_get_options(SSL *ssl); + +/* + * SSL_clear_options - clear SSL option + * + * @param ssl - SSL point + * @param op - setting option + * + * @return SSL option + */ +unsigned long SSL_set_options(SSL *ssl, unsigned long op); + +/* + * SSL_set_quiet_shutdown - set SSL quiet shutdown mode + * + * @param ssl - SSL point + * @param mode - quiet shutdown mode + * + * @return none + */ +void SSL_set_quiet_shutdown(SSL *ssl, int mode); + +/* + * SSL_set_quiet_shutdown - set SSL shutdown mode + * + * @param ssl - SSL point + * @param mode - shutdown mode + * + * @return none + */ +void SSL_set_shutdown(SSL *ssl, int mode); + +/* + * SSL_set_time - set SSL session time + * + * @param ssl - SSL point + * @param t - session time + * + * @return session time + */ +void SSL_set_time(SSL *ssl, long t); + +/* + * SSL_set_time - set SSL session timeout time + * + * @param ssl - SSL point + * @param t - session timeout time + * + * @return session timeout time + */ +void SSL_set_timeout(SSL *ssl, long t); + +/* + * SSL_state_string - get SSL statement string + * + * @param ssl - SSL point + * + * @return SSL statement string + */ +char *SSL_state_string(const SSL *ssl); + +/* + * SSL_state_string_long - get SSL statement long string + * + * @param ssl - SSL point + * + * @return SSL statement long string + */ +char *SSL_state_string_long(const SSL *ssl); + +/* + * SSL_total_renegotiations - get SSL renegotiation count + * + * @param ssl - SSL point + * + * @return renegotiation count + */ +long SSL_total_renegotiations(SSL *ssl); + +/* + * SSL_version - get SSL version + * + * @param ssl - SSL point + * + * @return SSL version + */ +int SSL_version(const SSL *ssl); + +/* + * SSL_use_psk_identity_hint - set SSL PSK identity hint + * + * @param ssl - SSL point + * @param hint - identity hint + * + * @return + * 1 : oK + * 0 : failed + */ +int SSL_use_psk_identity_hint(SSL *ssl, const char *hint); + +/* + * SSL_get_psk_identity_hint - get SSL PSK identity hint + * + * @param ssl - SSL point + * + * @return identity hint + */ +const char *SSL_get_psk_identity_hint(SSL *ssl); + +/* + * SSL_get_psk_identity - get SSL PSK identity + * + * @param ssl - SSL point + * + * @return identity + */ +const char *SSL_get_psk_identity(SSL *ssl); + +#endif From 44c466c0ea077a28fa138edfdaed400c2b3bd416 Mon Sep 17 00:00:00 2001 From: dongheng Date: Tue, 20 Sep 2016 16:58:46 +0800 Subject: [PATCH 002/343] components/openssl: add base function version --- components/openssl/Makefile | 50 + components/openssl/include/internal/ssl3.h | 22 + .../openssl/include/internal/ssl_cert.h | 11 + .../openssl/include/internal/ssl_code.h | 95 + components/openssl/include/internal/ssl_dbg.h | 33 + components/openssl/include/internal/ssl_lib.h | 11 + .../openssl/include/internal/ssl_methods.h | 46 + .../openssl/include/internal/ssl_pkey.h | 11 + components/openssl/include/internal/ssl_rsa.h | 14 + .../openssl/include/internal/ssl_types.h | 190 ++ .../openssl/include/internal/ssl_x509.h | 12 + components/openssl/include/internal/tls1.h | 33 + components/openssl/include/openssl/ssl.h | 31 +- components/openssl/include/platform/ssl_pm.h | 41 + components/openssl/library/Makefile | 46 + components/openssl/library/ssl_cert.c | 28 + components/openssl/library/ssl_lib.c | 1622 +++++++++++++++++ components/openssl/library/ssl_methods.c | 43 + components/openssl/library/ssl_pkey.c | 50 + components/openssl/library/ssl_rsa.c | 70 + components/openssl/library/ssl_x509.c | 54 + components/openssl/platform/Makefile | 46 + components/openssl/platform/ssl_pm.c | 422 +++++ 23 files changed, 2976 insertions(+), 5 deletions(-) create mode 100644 components/openssl/Makefile create mode 100644 components/openssl/include/internal/ssl3.h create mode 100644 components/openssl/include/internal/ssl_cert.h create mode 100644 components/openssl/include/internal/ssl_code.h create mode 100644 components/openssl/include/internal/ssl_dbg.h create mode 100644 components/openssl/include/internal/ssl_lib.h create mode 100644 components/openssl/include/internal/ssl_methods.h create mode 100644 components/openssl/include/internal/ssl_pkey.h create mode 100644 components/openssl/include/internal/ssl_rsa.h create mode 100644 components/openssl/include/internal/ssl_types.h create mode 100644 components/openssl/include/internal/ssl_x509.h create mode 100644 components/openssl/include/internal/tls1.h create mode 100644 components/openssl/include/platform/ssl_pm.h create mode 100644 components/openssl/library/Makefile create mode 100644 components/openssl/library/ssl_cert.c create mode 100644 components/openssl/library/ssl_lib.c create mode 100644 components/openssl/library/ssl_methods.c create mode 100644 components/openssl/library/ssl_pkey.c create mode 100644 components/openssl/library/ssl_rsa.c create mode 100644 components/openssl/library/ssl_x509.c create mode 100644 components/openssl/platform/Makefile create mode 100644 components/openssl/platform/ssl_pm.c diff --git a/components/openssl/Makefile b/components/openssl/Makefile new file mode 100644 index 0000000000..bdd8a0e932 --- /dev/null +++ b/components/openssl/Makefile @@ -0,0 +1,50 @@ + +############################################################# +# Required variables for each makefile +# Discard this section from all parent makefiles +# Expected variables (with automatic defaults): +# CSRCS (all "C" files in the dir) +# SUBDIRS (all subdirs with a Makefile) +# GEN_LIBS - list of libs to be generated () +# GEN_IMAGES - list of images to be generated () +# COMPONENTS_xxx - a list of libs/objs in the form +# subdir/lib to be extracted and rolled up into +# a generated lib/image xxx.a () +# +ifndef PDIR + +UP_EXTRACT_DIR = .. +GEN_LIBS = libopenssl.a +COMPONENTS_libopenssl = library/liblibrary.a platform/libplatform.a + +endif + + +############################################################# +# Configuration i.e. compile options etc. +# Target specific stuff (defines etc.) goes in here! +# Generally values applying to a tree are captured in the +# makefile at its root level - these are then overridden +# for a subtree within the makefile rooted therein +# +#DEFINES += + +############################################################# +# Recursion Magic - Don't touch this!! +# +# Each subtree potentially has an include directory +# corresponding to the common APIs applicable to modules +# rooted at that subtree. Accordingly, the INCLUDE PATH +# of a module can only contain the include directories up +# its parent path, and not its siblings +# +# Required for each makefile to inherit from the parent +# + +INCLUDES := $(INCLUDES) -I $(PDIR)include -I $(PDIR)include/platform -I $(PDIR)include/internal +INCLUDES += -I ./inlcude +INCLUDES += -I $(SDK_PATH)/include/openssl/internal +INCLUDES += -I ./ +PDIR := ../$(PDIR) +sinclude $(PDIR)Makefile + diff --git a/components/openssl/include/internal/ssl3.h b/components/openssl/include/internal/ssl3.h new file mode 100644 index 0000000000..d7c254563b --- /dev/null +++ b/components/openssl/include/internal/ssl3.h @@ -0,0 +1,22 @@ +#ifndef _SSL3_H_ +#define _SSL3_H_ + +# define SSL3_AD_CLOSE_NOTIFY 0 +# define SSL3_AD_UNEXPECTED_MESSAGE 10/* fatal */ +# define SSL3_AD_BAD_RECORD_MAC 20/* fatal */ +# define SSL3_AD_DECOMPRESSION_FAILURE 30/* fatal */ +# define SSL3_AD_HANDSHAKE_FAILURE 40/* fatal */ +# define SSL3_AD_NO_CERTIFICATE 41 +# define SSL3_AD_BAD_CERTIFICATE 42 +# define SSL3_AD_UNSUPPORTED_CERTIFICATE 43 +# define SSL3_AD_CERTIFICATE_REVOKED 44 +# define SSL3_AD_CERTIFICATE_EXPIRED 45 +# define SSL3_AD_CERTIFICATE_UNKNOWN 46 +# define SSL3_AD_ILLEGAL_PARAMETER 47/* fatal */ + +# define SSL3_AL_WARNING 1 +# define SSL3_AL_FATAL 2 + +#define SSL3_VERSION 0x0300 + +#endif diff --git a/components/openssl/include/internal/ssl_cert.h b/components/openssl/include/internal/ssl_cert.h new file mode 100644 index 0000000000..e0b3ea75dc --- /dev/null +++ b/components/openssl/include/internal/ssl_cert.h @@ -0,0 +1,11 @@ +#ifndef _SSL_CERT_H_ +#define _SSL_CERT_H_ + +#include "ssl_pkey.h" +#include "ssl_x509.h" + +CERT *ssl_cert_new(void); + +void ssl_cert_free(CERT *c); + +#endif diff --git a/components/openssl/include/internal/ssl_code.h b/components/openssl/include/internal/ssl_code.h new file mode 100644 index 0000000000..d45abff680 --- /dev/null +++ b/components/openssl/include/internal/ssl_code.h @@ -0,0 +1,95 @@ +#ifndef _SSL_CODE_H_ +#define _SSL_CODE_H_ + +#include "ssl3.h" +#include "tls1.h" + +/* Used in SSL_set_shutdown()/SSL_get_shutdown(); */ +# define SSL_SENT_SHUTDOWN 1 +# define SSL_RECEIVED_SHUTDOWN 2 + +/* + * The following 3 states are kept in ssl->rlayer.rstate when reads fail, you + * should not need these + */ +# define SSL_ST_READ_HEADER 0xF0 +# define SSL_ST_READ_BODY 0xF1 +# define SSL_ST_READ_DONE 0xF2 + +# define SSL_NOTHING 1 +# define SSL_WRITING 2 +# define SSL_READING 3 +# define SSL_X509_LOOKUP 4 +# define SSL_ASYNC_PAUSED 5 +# define SSL_ASYNC_NO_JOBS 6 + + +# define SSL_ERROR_NONE 0 +# define SSL_ERROR_SSL 1 +# define SSL_ERROR_WANT_READ 2 +# define SSL_ERROR_WANT_WRITE 3 +# define SSL_ERROR_WANT_X509_LOOKUP 4 +# define SSL_ERROR_SYSCALL 5/* look at error stack/return value/errno */ +# define SSL_ERROR_ZERO_RETURN 6 +# define SSL_ERROR_WANT_CONNECT 7 +# define SSL_ERROR_WANT_ACCEPT 8 +# define SSL_ERROR_WANT_ASYNC 9 +# define SSL_ERROR_WANT_ASYNC_JOB 10 + +/* Message flow states */ +typedef enum { + /* No handshake in progress */ + MSG_FLOW_UNINITED, + /* A permanent error with this connection */ + MSG_FLOW_ERROR, + /* We are about to renegotiate */ + MSG_FLOW_RENEGOTIATE, + /* We are reading messages */ + MSG_FLOW_READING, + /* We are writing messages */ + MSG_FLOW_WRITING, + /* Handshake has finished */ + MSG_FLOW_FINISHED +} MSG_FLOW_STATE; + +typedef enum { + TLS_ST_BEFORE, + TLS_ST_OK, + DTLS_ST_CR_HELLO_VERIFY_REQUEST, + TLS_ST_CR_SRVR_HELLO, + TLS_ST_CR_CERT, + TLS_ST_CR_CERT_STATUS, + TLS_ST_CR_KEY_EXCH, + TLS_ST_CR_CERT_REQ, + TLS_ST_CR_SRVR_DONE, + TLS_ST_CR_SESSION_TICKET, + TLS_ST_CR_CHANGE, + TLS_ST_CR_FINISHED, + TLS_ST_CW_CLNT_HELLO, + TLS_ST_CW_CERT, + TLS_ST_CW_KEY_EXCH, + TLS_ST_CW_CERT_VRFY, + TLS_ST_CW_CHANGE, + TLS_ST_CW_NEXT_PROTO, + TLS_ST_CW_FINISHED, + TLS_ST_SW_HELLO_REQ, + TLS_ST_SR_CLNT_HELLO, + DTLS_ST_SW_HELLO_VERIFY_REQUEST, + TLS_ST_SW_SRVR_HELLO, + TLS_ST_SW_CERT, + TLS_ST_SW_KEY_EXCH, + TLS_ST_SW_CERT_REQ, + TLS_ST_SW_SRVR_DONE, + TLS_ST_SR_CERT, + TLS_ST_SR_KEY_EXCH, + TLS_ST_SR_CERT_VRFY, + TLS_ST_SR_NEXT_PROTO, + TLS_ST_SR_CHANGE, + TLS_ST_SR_FINISHED, + TLS_ST_SW_SESSION_TICKET, + TLS_ST_SW_CERT_STATUS, + TLS_ST_SW_CHANGE, + TLS_ST_SW_FINISHED +} OSSL_HANDSHAKE_STATE; + +#endif diff --git a/components/openssl/include/internal/ssl_dbg.h b/components/openssl/include/internal/ssl_dbg.h new file mode 100644 index 0000000000..436d33132f --- /dev/null +++ b/components/openssl/include/internal/ssl_dbg.h @@ -0,0 +1,33 @@ +#ifndef _SSL_DEBUG_H_ +#define _SSL_DEBUG_H_ + +#define SSL_DEBUG_ENBALE 0 +#define SSL_DEBUG_LEVEL 0 +#define SSL_ASSERT_ENABLE 1 +#define SSL_DEBUG_LOCATION_ENABLE 1 + +#if SSL_DEBUG_ENBALE + #define SSL_PRINT os_printf +#else + #define SSL_PRINT(...) +#endif + +#if SSL_DEBUG_LOCATION_ENABLE + #define SSL_DEBUG_LOCATION() SSL_PRINT("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__) +#else + #define SSL_DEBUG_LOCATION() +#endif + +#if SSL_ASSERT_ENABLE + #define SSL_ASSERT(s) { if (!(s)) { SSL_DEBUG_LOCATION(); } } +#else + #define SSL_ASSERT(s) +#endif + +#define SSL_ERR(err, go, ...) { SSL_DEBUG_LOCATION(); SSL_PRINT(__VA_ARGS__); ret = err; goto go; } + +#define SSL_RET(go, ...) { SSL_DEBUG_LOCATION(); SSL_PRINT(__VA_ARGS__); goto go; } + +#define SSL_DEBUG(level, ...) { if (level > SSL_DEBUG_LEVEL) {SSL_PRINT(__VA_ARGS__);} } + +#endif diff --git a/components/openssl/include/internal/ssl_lib.h b/components/openssl/include/internal/ssl_lib.h new file mode 100644 index 0000000000..d95d219556 --- /dev/null +++ b/components/openssl/include/internal/ssl_lib.h @@ -0,0 +1,11 @@ +#ifndef _SSL_LIB_H_ +#define _SSL_LIB_H_ + +#include "ssl_types.h" + +#define SSL_want_nothing(s) (SSL_want(s) == SSL_NOTHING) +#define SSL_want_read(s) (SSL_want(s) == SSL_READING) +#define SSL_want_write(s) (SSL_want(s) == SSL_WRITING) +#define SSL_want_x509_lookup(s) (SSL_want(s) == SSL_WRITING) + +#endif diff --git a/components/openssl/include/internal/ssl_methods.h b/components/openssl/include/internal/ssl_methods.h new file mode 100644 index 0000000000..e2806f177a --- /dev/null +++ b/components/openssl/include/internal/ssl_methods.h @@ -0,0 +1,46 @@ +#ifndef _SSL_METHODS_H_ +#define _SSL_METHODS_H_ + +#define IMPLEMENT_TLS_METHOD_FUNC(func_name, \ + new, free, \ + handshake, shutdown, clear, \ + read, send, pending, \ + set_fd, get_fd, \ + set_bufflen, \ + get_state) \ + static const SSL_METHOD_FUNC func_name = { \ + new, \ + free, \ + handshake, \ + shutdown, \ + clear, \ + read, \ + send, \ + pending, \ + set_fd, \ + get_fd, \ + set_bufflen, \ + get_state \ + }; + +#define IMPLEMENT_TLS_METHOD(ver, mode, fun, func_name) \ + const SSL_METHOD* func_name(void) { \ + static const SSL_METHOD func_name##_data = { \ + ver, \ + mode, \ + &(fun), \ + }; \ + return &func_name##_data; \ + } + +#define IMPLEMENT_SSL_METHOD(ver, mode, fun, func_name) \ + const SSL_METHOD* func_name(void) { \ + static const SSL_METHOD func_name##_data = { \ + ver, \ + mode, \ + &(fun), \ + }; \ + return &func_name##_data; \ + } + +#endif diff --git a/components/openssl/include/internal/ssl_pkey.h b/components/openssl/include/internal/ssl_pkey.h new file mode 100644 index 0000000000..cc870e18ed --- /dev/null +++ b/components/openssl/include/internal/ssl_pkey.h @@ -0,0 +1,11 @@ +#ifndef _SSL_PKEY_H_ +#define _SSL_PKEY_H_ + +#include "ssl_types.h" + +EVP_PKEY *d2i_PrivateKey(int type, + EVP_PKEY **a, + const unsigned char **pp, + long length); + +#endif diff --git a/components/openssl/include/internal/ssl_rsa.h b/components/openssl/include/internal/ssl_rsa.h new file mode 100644 index 0000000000..7530bde734 --- /dev/null +++ b/components/openssl/include/internal/ssl_rsa.h @@ -0,0 +1,14 @@ +#ifndef _SSL_RSA_H_ +#define _SSL_RSA_H_ + +#include "ssl_lib.h" + +int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x); +int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, + const unsigned char *d); + +int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey); +int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, + const unsigned char *d, long len); + +#endif diff --git a/components/openssl/include/internal/ssl_types.h b/components/openssl/include/internal/ssl_types.h new file mode 100644 index 0000000000..19eb6cb165 --- /dev/null +++ b/components/openssl/include/internal/ssl_types.h @@ -0,0 +1,190 @@ +#ifndef _SSL_TYPES_H_ +#define _SSL_TYPES_H_ + +#include "ssl_code.h" +#include + +typedef void SSL_CIPHER; + +typedef void X509_STORE_CTX; +typedef void X509_NAME; +typedef void X509_STORE; + +typedef void RSA; + +typedef void STACK; +typedef void BIO; + +#define STACK_OF(x) x + +struct ssl_method_st; +typedef struct ssl_method_st SSL_METHOD; + +struct ssl_method_func_st; +typedef struct ssl_method_func_st SSL_METHOD_FUNC; + +struct record_layer_st; +typedef struct record_layer_st RECORD_LAYER; + +struct ossl_statem_st; +typedef struct ossl_statem_st OSSL_STATEM; + +struct ssl_session_st; +typedef struct ssl_session_st SSL_SESSION; + +struct ssl_ctx_st; +typedef struct ssl_ctx_st SSL_CTX; + +struct ssl_st; +typedef struct ssl_st SSL; + +struct cert_st; +typedef struct cert_st CERT; + +struct x509_st; +typedef struct x509_st X509; + +struct evp_pkey_st; +typedef struct evp_pkey_st EVP_PKEY; + +struct evp_pkey_st { + + void *pkey_pm; +}; + +struct x509_st { + + /* X509 certification platform private point */ + void *x509_pm; +}; + +struct cert_st { + + int sec_level; + + X509 *x509; + + EVP_PKEY *pkey; + +}; + +struct ossl_statem_st { + MSG_FLOW_STATE state; + + int hand_state; +}; + +struct record_layer_st { + + int rstate; + + int read_ahead; +}; + +struct ssl_session_st { + + long timeout; + + long time; +}; + +struct ssl_ctx_st +{ + int version; + + int references; + + unsigned long options; + + #if 0 + struct alpn_protocols alpn_protocol; + #endif + + const SSL_METHOD *method; + + CERT *cert; + + X509 *client_CA; + + int verify_mode; + + long session_timeout; + + int read_ahead; +}; + +struct ssl_st +{ + /* protocol version(one of SSL3.0, TLS1.0, etc.) */ + int version; + + unsigned long options; + + /* shut things down(0x01 : sent, 0x02 : received) */ + int shutdown; + + CERT *cert; + + SSL_CTX *ctx; + + const SSL_METHOD *method; + + RECORD_LAYER rlayer; + + /* where we are */ + OSSL_STATEM statem; + + SSL_SESSION session; + + int rwstate; + + int err; + + void (*info_callback) (const SSL *ssl, int type, int val); + + /* SSL low-level system arch point */ + void *ssl_pm; +}; + +struct ssl_method_st { + /* protocol version(one of SSL3.0, TLS1.0, etc.) */ + int version; + + /* SSL mode(client(0) , server(1), not known(-1)) */ + int endpoint; + + const SSL_METHOD_FUNC *func; +}; + +struct ssl_method_func_st { + + int (*ssl_new)(SSL *ssl); + + void (*ssl_free)(SSL *ssl); + + int (*ssl_handshake)(SSL *ssl); + + int (*ssl_shutdown)(SSL *ssl); + + int (*ssl_clear)(SSL *ssl); + + int (*ssl_read)(SSL *ssl, void *buffer, int len); + + int (*ssl_send)(SSL *ssl, const void *buffer, int len); + + int (*ssl_pending)(const SSL *ssl); + + void (*ssl_set_fd)(SSL *ssl, int fd, int mode); + + int (*ssl_get_fd)(const SSL *ssl, int mode); + + void (*ssl_set_bufflen)(SSL *ssl, int len); + + OSSL_HANDSHAKE_STATE (*ssl_get_state)(const SSL *ssl); +}; + +typedef int (*next_proto_cb)(SSL *ssl, unsigned char **out, + unsigned char *outlen, const unsigned char *in, + unsigned int inlen, void *arg); + +#endif diff --git a/components/openssl/include/internal/ssl_x509.h b/components/openssl/include/internal/ssl_x509.h new file mode 100644 index 0000000000..28a7baf513 --- /dev/null +++ b/components/openssl/include/internal/ssl_x509.h @@ -0,0 +1,12 @@ +#ifndef _SSL_X509_H_ +#define _SSL_X509_H_ + +#include "ssl_types.h" + +X509* sk_X509_NAME_new_null(void); + +X509* d2i_X509(X509 **cert, const unsigned char *buffer, long len); + +void X509_free(X509 *cert); + +#endif diff --git a/components/openssl/include/internal/tls1.h b/components/openssl/include/internal/tls1.h new file mode 100644 index 0000000000..70de22bb5b --- /dev/null +++ b/components/openssl/include/internal/tls1.h @@ -0,0 +1,33 @@ +#ifndef _TLS1_H_ +#define _TLS1_H_ + +# define TLS1_AD_DECRYPTION_FAILED 21 +# define TLS1_AD_RECORD_OVERFLOW 22 +# define TLS1_AD_UNKNOWN_CA 48/* fatal */ +# define TLS1_AD_ACCESS_DENIED 49/* fatal */ +# define TLS1_AD_DECODE_ERROR 50/* fatal */ +# define TLS1_AD_DECRYPT_ERROR 51 +# define TLS1_AD_EXPORT_RESTRICTION 60/* fatal */ +# define TLS1_AD_PROTOCOL_VERSION 70/* fatal */ +# define TLS1_AD_INSUFFICIENT_SECURITY 71/* fatal */ +# define TLS1_AD_INTERNAL_ERROR 80/* fatal */ +# define TLS1_AD_INAPPROPRIATE_FALLBACK 86/* fatal */ +# define TLS1_AD_USER_CANCELLED 90 +# define TLS1_AD_NO_RENEGOTIATION 100 +/* codes 110-114 are from RFC3546 */ +# define TLS1_AD_UNSUPPORTED_EXTENSION 110 +# define TLS1_AD_CERTIFICATE_UNOBTAINABLE 111 +# define TLS1_AD_UNRECOGNIZED_NAME 112 +# define TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE 113 +# define TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 114 +# define TLS1_AD_UNKNOWN_PSK_IDENTITY 115/* fatal */ +# define TLS1_AD_NO_APPLICATION_PROTOCOL 120 /* fatal */ + +/* Special value for method supporting multiple versions */ +#define TLS_ANY_VERSION 0x10000 + +#define TLS1_VERSION 0x0301 +#define TLS1_1_VERSION 0x0302 +#define TLS1_2_VERSION 0x0303 + +#endif diff --git a/components/openssl/include/openssl/ssl.h b/components/openssl/include/openssl/ssl.h index b7b784fe71..89cb5bb9f7 100644 --- a/components/openssl/include/openssl/ssl.h +++ b/components/openssl/include/openssl/ssl.h @@ -1,7 +1,7 @@ #ifndef HEADER_SSL_H #define HEADER_SSL_H -#include "ssl_types.h" +#include "internal/ssl_types.h" /* { @@ -186,6 +186,15 @@ const SSL_METHOD* SSLv3_client_method(void); */ const SSL_METHOD* TLSv1_1_client_method(void); +/* + * TLSv1_1_client_method - create the target SSL context client method + * + * @param none + * + * @return the TLSV1.2 version SSL context client method + */ +const SSL_METHOD* TLSv1_2_client_method(void); + /* * SSLv23_server_method - create the target SSL context server method @@ -205,6 +214,15 @@ const SSL_METHOD* SSLv23_server_method(void); */ const SSL_METHOD* TLSv1_1_server_method(void); +/* + * TLSv1_1_server_method - create the target SSL context server method + * + * @param none + * + * @return the TLSV1.2 version SSL context server method + */ +const SSL_METHOD* TLSv1_2_server_method(void); + /* * TLSv1_server_method - create the target SSL context server method * @@ -774,7 +792,7 @@ int SSL_get_wfd(const SSL *ssl); * SSL_set_read_ahead - set the SSL if we can read as many as data * * @param ssl - SSL point - * @param yes - enbale the function + * @param yes - enable the function * * @return none */ @@ -813,7 +831,9 @@ long SSL_CTX_get_read_ahead(SSL_CTX *ctx); * * @param ssl - SSL point * - * @return SSL context ahead signal + * @return + * 1 : there are bytes to be read + * 0 : no data */ int SSL_has_pending(const SSL *ssl); @@ -840,7 +860,7 @@ int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x);//loads the certificate x int * 1 : OK * 0 : failed */ -int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, unsigned char *d); +int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d); /* * SSL_CTX_use_certificate_file - load the certification file into SSL context @@ -879,7 +899,7 @@ int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file); * 1 : OK * 0 : failed */ -int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, unsigned char *d, long len);//adds the private key of type pk stored at memory location d (length len) to ctx +int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, const unsigned char *d, long len);//adds the private key of type pk stored at memory location d (length len) to ctx /* * SSL_CTX_use_certificate_file - load the private key file into SSL context @@ -1648,4 +1668,5 @@ const char *SSL_get_psk_identity_hint(SSL *ssl); */ const char *SSL_get_psk_identity(SSL *ssl); + #endif diff --git a/components/openssl/include/platform/ssl_pm.h b/components/openssl/include/platform/ssl_pm.h new file mode 100644 index 0000000000..c75ae95af5 --- /dev/null +++ b/components/openssl/include/platform/ssl_pm.h @@ -0,0 +1,41 @@ +#ifndef _SSL_PM_H_ +#define _SSL_PM_H_ + +#include "ssl_types.h" +#include "esp_common.h" + +void* ssl_zalloc(size_t size); +void *ssl_malloc(size_t size); +void ssl_free(void *p); +void* ssl_memcpy(void *to, const void *from, size_t size); + +int ssl_pm_new(SSL *ssl); +void ssl_pm_free(SSL *ssl); + +int ssl_pm_handshake(SSL *ssl); +int ssl_pm_shutdown(SSL *ssl); +int ssl_pm_clear(SSL *ssl); + +int ssl_pm_read(SSL *ssl, void *buffer, int len); +int ssl_pm_send(SSL *ssl, const void *buffer, int len); +int ssl_pm_pending(const SSL *ssl); + +void ssl_pm_set_fd(SSL *ssl, int fd, int mode); +int ssl_pm_get_fd(const SSL *ssl, int mode); + +OSSL_HANDSHAKE_STATE ssl_pm_get_state(const SSL *ssl); + +void ssl_pm_set_bufflen(SSL *ssl, int len); + +void* x509_pm_new(void); +void x509_pm_free(void *pm); +int x509_pm_load_crt(void *pm, const unsigned char *buffer, int len); +void x509_pm_unload_crt(void *pm); +void x509_pm_start_ca(void *ssl, void *pm); + +void* pkey_pm_new(void); +void pkey_pm_free(void *pm); +int pkey_pm_load_crt(void *pm, const unsigned char *buffer, int len); +void pkey_pm_unload_crt(void *pm); + +#endif diff --git a/components/openssl/library/Makefile b/components/openssl/library/Makefile new file mode 100644 index 0000000000..10f4067c64 --- /dev/null +++ b/components/openssl/library/Makefile @@ -0,0 +1,46 @@ + +############################################################# +# Required variables for each makefile +# Discard this section from all parent makefiles +# Expected variables (with automatic defaults): +# CSRCS (all "C" files in the dir) +# SUBDIRS (all subdirs with a Makefile) +# GEN_LIBS - list of libs to be generated () +# GEN_IMAGES - list of images to be generated () +# COMPONENTS_xxx - a list of libs/objs in the form +# subdir/lib to be extracted and rolled up into +# a generated lib/image xxx.a () +# +ifndef PDIR + +GEN_LIBS = liblibrary.a + +endif + + +############################################################# +# Configuration i.e. compile options etc. +# Target specific stuff (defines etc.) goes in here! +# Generally values applying to a tree are captured in the +# makefile at its root level - these are then overridden +# for a subtree within the makefile rooted therein +# +#DEFINES += + +############################################################# +# Recursion Magic - Don't touch this!! +# +# Each subtree potentially has an include directory +# corresponding to the common APIs applicable to modules +# rooted at that subtree. Accordingly, the INCLUDE PATH +# of a module can only contain the include directories up +# its parent path, and not its siblings +# +# Required for each makefile to inherit from the parent +# + +INCLUDES := $(INCLUDES) -I $(PDIR)include +INCLUDES += -I ./ +PDIR := ../$(PDIR) +sinclude $(PDIR)Makefile + diff --git a/components/openssl/library/ssl_cert.c b/components/openssl/library/ssl_cert.c new file mode 100644 index 0000000000..10f723bfcb --- /dev/null +++ b/components/openssl/library/ssl_cert.c @@ -0,0 +1,28 @@ +#include "ssl_cert.h" +#include "ssl_pm.h" + +CERT *ssl_cert_new(void) +{ + return ssl_zalloc(sizeof(CERT)); +} + +void ssl_cert_free(CERT *c) +{ + if (c->x509) + X509_free(c->x509); + + if (c->pkey) + EVP_PKEY_free(c->pkey); + + ssl_free(c); +} + +int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) +{ + SSL_ASSERT(ctx); + SSL_ASSERT(x); + + ctx->client_CA = x; + + return 1; +} diff --git a/components/openssl/library/ssl_lib.c b/components/openssl/library/ssl_lib.c new file mode 100644 index 0000000000..ad78f3961a --- /dev/null +++ b/components/openssl/library/ssl_lib.c @@ -0,0 +1,1622 @@ +#include "ssl_lib.h" +#include "ssl_pkey.h" +#include "ssl_cert.h" +#include "ssl_dbg.h" +#include "ssl_pm.h" + +#define SSL_SEND_DATA_MAX_LENGTH 1460 + +static int ossl_statem_in_error(const SSL *ssl) +{ + if (ssl->statem.state == MSG_FLOW_ERROR) + return 1; + + return 0; +} + +/* + * SSL_get_error - get SSL error code + * + * @param ssl - SSL point + * @param ret_code - SSL return code + * + * @return SSL error number + */ +int SSL_get_error(const SSL *ssl, int ret_code) +{ + int ret = SSL_ERROR_SYSCALL; + + SSL_ASSERT(ssl); + + if (ret_code > 0) + ret = SSL_ERROR_NONE; + else if (ret_code < 0) + { + if (SSL_want_read(ssl)) + ret = SSL_ERROR_WANT_READ; + else if (SSL_want_write(ssl)) + ret = SSL_ERROR_WANT_WRITE; + else + ret = SSL_ERROR_SYSCALL; //unknown + } + else // ret_code == 0 + { + if (ssl->shutdown & SSL_RECEIVED_SHUTDOWN) + ret = SSL_ERROR_ZERO_RETURN; + else + ret = SSL_ERROR_SYSCALL; + } + + return ret; +} + +/* + * SSL_get_state - get the SSL state + * + * @param ssl - SSL point + * + * @return SSL state + */ +OSSL_HANDSHAKE_STATE SSL_get_state(const SSL *ssl) +{ + OSSL_HANDSHAKE_STATE state; + + SSL_ASSERT(ssl); + + state = ssl->method->func->ssl_get_state(ssl); + + return state; +} + +/* + * SSL_CTX_new - create a SSL context + * + * @param method - the SSL context configuration file + * + * @return the context point, if create failed return NULL + */ +SSL_CTX* SSL_CTX_new(const SSL_METHOD *method) +{ + int ret; + SSL_CTX *ctx; + CERT *cert; + X509 *client_ca; + + if (!method) SSL_RET(go_failed1, "method\n"); + + client_ca = sk_X509_NAME_new_null(); + if (!client_ca) + SSL_ERR(-2, go_failed1, "ssl_ctx_new:ctx:[%d]\n", ret); + + cert = ssl_cert_new(); + if (!cert) + SSL_ERR(-2, go_failed2, "ssl_ctx_new:ctx:[%d]\n", ret); + + ctx = (SSL_CTX *)ssl_zalloc(sizeof(SSL_CTX)); + if (!ctx) + SSL_ERR(-2, go_failed3, "ssl_ctx_new:ctx:[%d]\n", ret); + + ctx->method = method; + ctx->cert = cert; + ctx->client_CA = client_ca; + + ctx->version = method->version; + + return ctx; + +go_failed3: + ssl_cert_free(cert); +go_failed2: + X509_free(client_ca); +go_failed1: + return NULL; +} + +/* + * SSL_CTX_free - free a SSL context + * + * @param method - the SSL context point + * + * @return none + */ +void SSL_CTX_free(SSL_CTX* ctx) +{ + SSL_ASSERT(ctx); + + ssl_cert_free(ctx->cert); + + X509_free(ctx->client_CA); + + ssl_free(ctx); +} + +/* + * SSL_CTX_set_ssl_version - set the SSL context version + * + * @param ctx - SSL context point + * @param meth - SSL method point + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth) +{ + SSL_ASSERT(ctx); + SSL_ASSERT(meth); + + ctx->method = meth; + + return 1; +} + +/* + * SSL_CTX_get_ssl_method - get the SSL context current method + * + * @param ctx - SSL context point + * + * @return the SSL context current method + */ +const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx) +{ + SSL_ASSERT(ctx); + + return ctx->method; +} + +/* + * SSL_new - create a SSL + * + * @param ctx - the SSL context point + * + * @return the SSL point or NULL if failed + */ +SSL *SSL_new(SSL_CTX *ctx) +{ + int ret; + void *ssl_pm; + SSL *ssl; + + if (!ctx) + SSL_RET(failed1, "ctx:NULL\n"); + + ssl = (SSL *)ssl_zalloc(sizeof(SSL)); + if (!ssl) + SSL_RET(failed1, "ssl_zalloc\n"); + + ssl->ctx = ctx; + ssl->method = ctx->method; + + ssl->version = ctx->version; + ssl->options = ctx->options; + + ret = ssl->method->func->ssl_new(ssl); + if (ret) + SSL_RET(failed2, "ssl_new\n"); + + return ssl; + +failed2: + ssl_free(ssl); +failed1: + return NULL; +} + +/* + * SSL_free - free the SSL + * + * @param ssl - the SSL point + * + * @return none + */ +void SSL_free(SSL *ssl) +{ + SSL_ASSERT(ssl); + + ssl->method->func->ssl_free(ssl); + + ssl_free(ssl); +} + +/* + * SSL_do_handshake - perform the SSL handshake + * + * @param ssl - SSL point + * + * @return + * 1 : OK + * 0 : failed + * -1 : a error catch + */ +int SSL_do_handshake(SSL *ssl) +{ + int ret; + + SSL_ASSERT(ssl); + + ret = ssl->method->func->ssl_handshake(ssl); + + return ret; +} + +/* + * SSL_connect - connect to the remote SSL server + * + * @param ssl - the SSL point + * + * @return + * 1 : OK + * -1 : failed + */ +int SSL_connect(SSL *ssl) +{ + SSL_ASSERT(ssl); + + return SSL_do_handshake(ssl); +} + +/* + * SSL_accept - accept the remote connection + * + * @param ssl - the SSL point + * + * @return + * 1 : OK + * -1 : failed + */ +int SSL_accept(SSL *ssl) +{ + SSL_ASSERT(ssl); + + return SSL_do_handshake(ssl); +} + +/* + * SSL_shutdown - shutdown the connection + * + * @param ssl - the SSL point + * + * @return + * 1 : OK + * 0 : shutdown is not finished + * -1 : an error catch + */ +int SSL_shutdown(SSL *ssl) +{ + int ret; + + SSL_ASSERT(ssl); + + if (SSL_get_state(ssl) != TLS_ST_OK) return 0; + + ret = ssl->method->func->ssl_shutdown(ssl); + + return ret; +} + +/* + * SSL_clear - reset the SSL + * + * @param ssl - SSL point + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_clear(SSL *ssl) +{ + int ret; + + SSL_ASSERT(ssl); + + ret = SSL_shutdown(ssl); + if (1 != ret) + SSL_ERR(0, go_failed1, "SSL_shutdown\n"); + + ssl->method->func->ssl_free(ssl); + + ret = ssl->method->func->ssl_new(ssl); + if (!ret) + SSL_ERR(0, go_failed1, "ssl_new\n"); + + return 1; + +go_failed1: + return ret; +} + +/* + * SSL_read - read data from to remote + * + * @param ssl - the SSL point which has been connected + * @param buffer - the received data buffer point + * @param len - the received data length + * + * @return + * > 0 : OK, and return received data bytes + * = 0 : connection is closed + * < 0 : an error catch + */ +int SSL_read(SSL *ssl, void *buffer, int len) +{ + int ret; + + SSL_ASSERT(ssl); + SSL_ASSERT(buffer); + SSL_ASSERT(len); + + ret = ssl->method->func->ssl_read(ssl, buffer, len); + + return ret; +} + +/* + * SSL_write - send the data to remote + * + * @param ssl - the SSL point which has been connected + * @param buffer - the send data buffer point + * @param len - the send data length + * + * @return + * > 0 : OK, and return sent data bytes + * = 0 : connection is closed + * < 0 : an error catch + */ +int SSL_write(SSL *ssl, const void *buffer, int len) +{ + int ret; + int send_bytes; + const unsigned char *pbuf; + + SSL_ASSERT(ssl); + SSL_ASSERT(buffer); + SSL_ASSERT(len); + + send_bytes = len; + pbuf = (const unsigned char *)buffer; + + do { + int bytes; + + if (send_bytes > SSL_SEND_DATA_MAX_LENGTH) + bytes = SSL_SEND_DATA_MAX_LENGTH; + else + bytes = send_bytes; + + ret = ssl->method->func->ssl_send(ssl, buffer, len); + if (ret > 0) { + pbuf += ret; + send_bytes -= ret; + } + } while (ret > 0 && send_bytes); + + send_bytes = len - send_bytes; + if (send_bytes >= 0) + ret = send_bytes; + else + ret = -1; + + return ret; +} + +/* + * SSL_get_SSL_CTX - get SSL context of the SSL + * + * @param ssl - SSL point + * + * @return SSL context + */ +SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl) +{ + SSL_ASSERT(ssl); + + return ssl->ctx; +} + +/* + * SSL_CTX_get_ssl_method - get the SSL current method + * + * @param ssl - SSL point + * + * @return the SSL current method + */ +const SSL_METHOD *SSL_get_ssl_method(SSL *ssl) +{ + SSL_ASSERT(ssl); + + return ssl->method; +} + +/* + * SSL_set_ssl_method - set the SSL method + * + * @param ssl - SSL point + * @param meth - SSL method point + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_set_ssl_method(SSL *ssl, const SSL_METHOD *method) +{ + int ret; + + SSL_ASSERT(ssl); + SSL_ASSERT(method); + + if (ssl->version != method->version) { + + ret = SSL_shutdown(ssl); + if (1 != ret) + SSL_ERR(0, go_failed1, "SSL_shutdown\n"); + + ssl->method->func->ssl_free(ssl); + + ssl->method = method; + + ret = ssl->method->func->ssl_new(ssl); + if (!ret) + SSL_ERR(0, go_failed1, "ssl_new\n"); + } else { + ssl->method = method; + } + + + return 1; + +go_failed1: + return ret; +} + +/* + * SSL_get_shutdown - get SSL shutdown mode + * + * @param ssl - SSL point + * + * @return shutdown mode + */ +int SSL_get_shutdown(const SSL *ssl) +{ + SSL_ASSERT(ssl); + + return ssl->shutdown; +} + +/* + * SSL_set_quiet_shutdown - set SSL shutdown mode + * + * @param ssl - SSL point + * @param mode - shutdown mode + * + * @return none + */ +void SSL_set_shutdown(SSL *ssl, int mode) +{ + SSL_ASSERT(ssl); + + ssl->shutdown = mode; +} + + +/* + * SSL_pending - get the number of the bytes to be read + * + * @param ssl - SSL point + * + * @return number of the bytes + */ +int SSL_pending(const SSL *ssl) +{ + int ret; + + SSL_ASSERT(ssl); + + ret = ssl->method->func->ssl_pending(ssl); + + return ret; +} + +/* + * SSL_has_pending - check if some data can be read + * + * @param ssl - SSL point + * + * @return + * 1 : there are bytes to be read + * 0 : no data + */ +int SSL_has_pending(const SSL *ssl) +{ + int ret; + + SSL_ASSERT(ssl); + + if (SSL_pending(ssl)) + ret = 1; + else + ret = 0; + + return ret; +} + +/* + * SSL_CTX_clear_options - clear the SSL context option bit of "op" + * + * @param ctx - SSL context point + * @param op - option + * + * @return SSL context option + */ +unsigned long SSL_CTX_clear_options(SSL_CTX *ctx, unsigned long op) +{ + return ctx->options &= ~op; +} + +/* + * SSL_CTX_clear_options - get the SSL context option + * + * @param ctx - SSL context point + * @param op - option + * + * @return SSL context option + */ +unsigned long SSL_CTX_get_options(SSL_CTX *ctx) +{ + return ctx->options; +} + +/* + * SSL_CTX_set_option - set the option of the SSL context + * + * @param ctx - the SSL context + * + * @return the SSL context option + * + */ +unsigned long SSL_CTX_set_options(SSL_CTX *ctx, unsigned long opt) +{ + return ctx->options |= opt; +} + +/* + * SSL_clear_options - clear SSL option + * + * @param ssl - SSL point + * @param op - clear option + * + * @return SSL option + */ +unsigned long SSL_clear_options(SSL *ssl, unsigned long op) +{ + SSL_ASSERT(ssl); + + return ssl->options & ~op; +} + +/* + * SSL_clear_options - get SSL option + * + * @param ssl - SSL point + * + * @return SSL option + */ +unsigned long SSL_get_options(SSL *ssl) +{ + SSL_ASSERT(ssl); + + return ssl->options; +} + +/* + * SSL_clear_options - clear SSL option + * + * @param ssl - SSL point + * @param op - setting option + * + * @return SSL option + */ +unsigned long SSL_set_options(SSL *ssl, unsigned long op) +{ + SSL_ASSERT(ssl); + + return ssl->options |= op; +} + +/* + * SSL_get_fd - get the socket handle of the SSL + * + * @param ssl - SSL point + * + * @return + * >= 0 : yes, and return socket handle + * < 0 : a error catch + */ +int SSL_get_fd(const SSL *ssl) +{ + int ret; + + SSL_ASSERT(ssl); + + ret = ssl->method->func->ssl_get_fd(ssl, 0); + + return ret; +} + +/* + * SSL_get_rfd - get the read only socket handle of the SSL + * + * @param ssl - SSL point + * + * @return + * >= 0 : yes, and return socket handle + * < 0 : a error catch + */ +int SSL_get_rfd(const SSL *ssl) +{ + int ret; + + SSL_ASSERT(ssl); + + ret = ssl->method->func->ssl_get_fd(ssl, 0); + + return ret; +} + +/* + * SSL_get_wfd - get the write only socket handle of the SSL + * + * @param ssl - SSL point + * + * @return + * >= 0 : yes, and return socket handle + * < 0 : a error catch + */ +int SSL_get_wfd(const SSL *ssl) +{ + int ret; + + SSL_ASSERT(ssl); + + ret = ssl->method->func->ssl_get_fd(ssl, 0); + + return ret; +} + +/* + * SSL_set_fd - bind the socket file description into the SSL + * + * @param ssl - the SSL point + * @param fd - socket handle + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_set_fd(SSL *ssl, int fd) +{ + int ret; + + SSL_ASSERT(ssl); + SSL_ASSERT(fd >= 0); + + ssl->method->func->ssl_set_fd(ssl, fd, 0); + + return 1; +} + +/* + * SSL_set_fd - bind the read only socket file description into the SSL + * + * @param ssl - the SSL point + * @param fd - socket handle + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_set_rfd(SSL *ssl, int fd) +{ + int ret; + + SSL_ASSERT(ssl); + SSL_ASSERT(fd >= 0); + + ssl->method->func->ssl_set_fd(ssl, fd, 0); + + return 1; +} + +/* + * SSL_set_fd - bind the write only socket file description into the SSL + * + * @param ssl - the SSL point + * @param fd - socket handle + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_set_wfd(SSL *ssl, int fd) +{ + int ret; + + SSL_ASSERT(ssl); + SSL_ASSERT(fd >= 0); + + ssl->method->func->ssl_set_fd(ssl, fd, 0); + + return 1; +} + +/* + * SSL_version - get SSL version + * + * @param ssl - SSL point + * + * @return SSL version + */ +int SSL_version(const SSL *ssl) +{ + SSL_ASSERT(ssl); + + return ssl->version; +} + +/* + * ssl_protocol_to_string - get the SSL version string + * + * @param version - the SSL version + * + * @return the SSL version string + */ +static const char* ssl_protocol_to_string(int version) +{ + const char *str; + + if (version == TLS1_2_VERSION) + str = "TLSv1.2"; + else if (version == TLS1_1_VERSION) + str = "TLSv1.1"; + else if (version == TLS1_VERSION) + str = "TLSv1"; + else if (version == SSL3_VERSION) + str = "SSLv3"; + else + str = "unknown"; + + return str; +} + +/* + * SSL_get_version - get the SSL current version + * + * @param ssl - SSL point + * + * @return the version string + */ +const char *SSL_get_version(const SSL *ssl) +{ + SSL_ASSERT(ssl); + + return ssl_protocol_to_string(SSL_version(ssl)); +} + +/* + * SSL_alert_desc_string - get alert description string + * + * @param value - alert value + * + * @return alert description string + */ +const char* SSL_alert_desc_string(int value) +{ + const char *str; + + switch (value & 0xff) + { + case SSL3_AD_CLOSE_NOTIFY: + str = "CN"; + break; + case SSL3_AD_UNEXPECTED_MESSAGE: + str = "UM"; + break; + case SSL3_AD_BAD_RECORD_MAC: + str = "BM"; + break; + case SSL3_AD_DECOMPRESSION_FAILURE: + str = "DF"; + break; + case SSL3_AD_HANDSHAKE_FAILURE: + str = "HF"; + break; + case SSL3_AD_NO_CERTIFICATE: + str = "NC"; + break; + case SSL3_AD_BAD_CERTIFICATE: + str = "BC"; + break; + case SSL3_AD_UNSUPPORTED_CERTIFICATE: + str = "UC"; + break; + case SSL3_AD_CERTIFICATE_REVOKED: + str = "CR"; + break; + case SSL3_AD_CERTIFICATE_EXPIRED: + str = "CE"; + break; + case SSL3_AD_CERTIFICATE_UNKNOWN: + str = "CU"; + break; + case SSL3_AD_ILLEGAL_PARAMETER: + str = "IP"; + break; + case TLS1_AD_DECRYPTION_FAILED: + str = "DC"; + break; + case TLS1_AD_RECORD_OVERFLOW: + str = "RO"; + break; + case TLS1_AD_UNKNOWN_CA: + str = "CA"; + break; + case TLS1_AD_ACCESS_DENIED: + str = "AD"; + break; + case TLS1_AD_DECODE_ERROR: + str = "DE"; + break; + case TLS1_AD_DECRYPT_ERROR: + str = "CY"; + break; + case TLS1_AD_EXPORT_RESTRICTION: + str = "ER"; + break; + case TLS1_AD_PROTOCOL_VERSION: + str = "PV"; + break; + case TLS1_AD_INSUFFICIENT_SECURITY: + str = "IS"; + break; + case TLS1_AD_INTERNAL_ERROR: + str = "IE"; + break; + case TLS1_AD_USER_CANCELLED: + str = "US"; + break; + case TLS1_AD_NO_RENEGOTIATION: + str = "NR"; + break; + case TLS1_AD_UNSUPPORTED_EXTENSION: + str = "UE"; + break; + case TLS1_AD_CERTIFICATE_UNOBTAINABLE: + str = "CO"; + break; + case TLS1_AD_UNRECOGNIZED_NAME: + str = "UN"; + break; + case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE: + str = "BR"; + break; + case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE: + str = "BH"; + break; + case TLS1_AD_UNKNOWN_PSK_IDENTITY: + str = "UP"; + break; + default: + str = "UK"; + break; + } + + return str; +} + +/* + * SSL_alert_desc_string - get alert description long string + * + * @param value - alert value + * + * @return alert description long string + */ +const char* SSL_alert_desc_string_long(int value) +{ + const char *str; + + switch (value & 0xff) + { + case SSL3_AD_CLOSE_NOTIFY: + str = "close notify"; + break; + case SSL3_AD_UNEXPECTED_MESSAGE: + str = "unexpected_message"; + break; + case SSL3_AD_BAD_RECORD_MAC: + str = "bad record mac"; + break; + case SSL3_AD_DECOMPRESSION_FAILURE: + str = "decompression failure"; + break; + case SSL3_AD_HANDSHAKE_FAILURE: + str = "handshake failure"; + break; + case SSL3_AD_NO_CERTIFICATE: + str = "no certificate"; + break; + case SSL3_AD_BAD_CERTIFICATE: + str = "bad certificate"; + break; + case SSL3_AD_UNSUPPORTED_CERTIFICATE: + str = "unsupported certificate"; + break; + case SSL3_AD_CERTIFICATE_REVOKED: + str = "certificate revoked"; + break; + case SSL3_AD_CERTIFICATE_EXPIRED: + str = "certificate expired"; + break; + case SSL3_AD_CERTIFICATE_UNKNOWN: + str = "certificate unknown"; + break; + case SSL3_AD_ILLEGAL_PARAMETER: + str = "illegal parameter"; + break; + case TLS1_AD_DECRYPTION_FAILED: + str = "decryption failed"; + break; + case TLS1_AD_RECORD_OVERFLOW: + str = "record overflow"; + break; + case TLS1_AD_UNKNOWN_CA: + str = "unknown CA"; + break; + case TLS1_AD_ACCESS_DENIED: + str = "access denied"; + break; + case TLS1_AD_DECODE_ERROR: + str = "decode error"; + break; + case TLS1_AD_DECRYPT_ERROR: + str = "decrypt error"; + break; + case TLS1_AD_EXPORT_RESTRICTION: + str = "export restriction"; + break; + case TLS1_AD_PROTOCOL_VERSION: + str = "protocol version"; + break; + case TLS1_AD_INSUFFICIENT_SECURITY: + str = "insufficient security"; + break; + case TLS1_AD_INTERNAL_ERROR: + str = "internal error"; + break; + case TLS1_AD_USER_CANCELLED: + str = "user canceled"; + break; + case TLS1_AD_NO_RENEGOTIATION: + str = "no renegotiation"; + break; + case TLS1_AD_UNSUPPORTED_EXTENSION: + str = "unsupported extension"; + break; + case TLS1_AD_CERTIFICATE_UNOBTAINABLE: + str = "certificate unobtainable"; + break; + case TLS1_AD_UNRECOGNIZED_NAME: + str = "unrecognized name"; + break; + case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE: + str = "bad certificate status response"; + break; + case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE: + str = "bad certificate hash value"; + break; + case TLS1_AD_UNKNOWN_PSK_IDENTITY: + str = "unknown PSK identity"; + break; + default: + str = "unknown"; + break; + } + + return str; +} + +/* + * SSL_alert_type_string - get alert type string + * + * @param value - alert value + * + * @return alert type string + */ +const char *SSL_alert_type_string(int value) +{ + const char *str; + + switch (value >> 8) + { + case SSL3_AL_WARNING: + str = "W"; + break; + case SSL3_AL_FATAL: + str = "F"; + break; + default: + str = "U"; + break; + } + + return str; +} + +/* + * SSL_alert_type_string_long - get alert type long string + * + * @param value - alert value + * + * @return alert type long string + */ +const char *SSL_alert_type_string_long(int value) +{ + const char *str; + + switch (value >> 8) + { + case SSL3_AL_WARNING: + str = "warning"; + break; + case SSL3_AL_FATAL: + str = "fatal"; + break; + default: + str = "unknown"; + break; + } + + return str; +} + +/* + * SSL_rstate_string - get the state string where SSL is reading + * + * @param ssl - SSL point + * + * @return state string + */ +const char *SSL_rstate_string(SSL *ssl) +{ + const char *str; + + SSL_ASSERT(ssl); + + switch (ssl->rlayer.rstate) + { + case SSL_ST_READ_HEADER: + str = "RH"; + break; + case SSL_ST_READ_BODY: + str = "RB"; + break; + case SSL_ST_READ_DONE: + str = "RD"; + break; + default: + str = "unknown"; + break; + } + + return str; +} + +/* + * SSL_rstate_string_long - get the statement long string where SSL is reading + * + * @param ssl - SSL point + * + * @return statement long string + */ +const char *SSL_rstate_string_long(SSL *ssl) +{ + const char *str = "unknown"; + + SSL_ASSERT(ssl); + + switch (ssl->rlayer.rstate) + { + case SSL_ST_READ_HEADER: + str = "read header"; + break; + case SSL_ST_READ_BODY: + str = "read body"; + break; + case SSL_ST_READ_DONE: + str = "read done"; + break; + default: + break; + } + + return str; +} + +/* + * SSL_state_string - get SSL statement string + * + * @param ssl - SSL point + * + * @return SSL statement string + */ +char *SSL_state_string(const SSL *ssl) +{ + char *str = "UNKWN "; + + SSL_ASSERT(ssl); + + if (ossl_state_in_error(ssl)) + str = "SSLERR"; + else + { + switch (SSL_get_state(ssl)) + { + case TLS_ST_BEFORE: + str = "PINIT "; + break; + case TLS_ST_OK: + str = "SSLOK "; + break; + case TLS_ST_CW_CLNT_HELLO: + str = "TWCH"; + break; + case TLS_ST_CR_SRVR_HELLO: + str = "TRSH"; + break; + case TLS_ST_CR_CERT: + str = "TRSC"; + break; + case TLS_ST_CR_KEY_EXCH: + str = "TRSKE"; + break; + case TLS_ST_CR_CERT_REQ: + str = "TRCR"; + break; + case TLS_ST_CR_SRVR_DONE: + str = "TRSD"; + break; + case TLS_ST_CW_CERT: + str = "TWCC"; + break; + case TLS_ST_CW_KEY_EXCH: + str = "TWCKE"; + break; + case TLS_ST_CW_CERT_VRFY: + str = "TWCV"; + break; + case TLS_ST_SW_CHANGE: + case TLS_ST_CW_CHANGE: + str = "TWCCS"; + break; + case TLS_ST_SW_FINISHED: + case TLS_ST_CW_FINISHED: + str = "TWFIN"; + break; + case TLS_ST_SR_CHANGE: + case TLS_ST_CR_CHANGE: + str = "TRCCS"; + break; + case TLS_ST_SR_FINISHED: + case TLS_ST_CR_FINISHED: + str = "TRFIN"; + break; + case TLS_ST_SW_HELLO_REQ: + str = "TWHR"; + break; + case TLS_ST_SR_CLNT_HELLO: + str = "TRCH"; + break; + case TLS_ST_SW_SRVR_HELLO: + str = "TWSH"; + break; + case TLS_ST_SW_CERT: + str = "TWSC"; + break; + case TLS_ST_SW_KEY_EXCH: + str = "TWSKE"; + break; + case TLS_ST_SW_CERT_REQ: + str = "TWCR"; + break; + case TLS_ST_SW_SRVR_DONE: + str = "TWSD"; + break; + case TLS_ST_SR_CERT: + str = "TRCC"; + break; + case TLS_ST_SR_KEY_EXCH: + str = "TRCKE"; + break; + case TLS_ST_SR_CERT_VRFY: + str = "TRCV"; + break; + case DTLS_ST_CR_HELLO_VERIFY_REQUEST: + str = "DRCHV"; + break; + case DTLS_ST_SW_HELLO_VERIFY_REQUEST: + str = "DWCHV"; + break; + default: + break; + } + } + + return str; +} + +/* + * SSL_state_string_long - get SSL statement long string + * + * @param ssl - SSL point + * + * @return SSL statement long string + */ +char *SSL_state_string_long(const SSL *ssl) +{ + char *str = "UNKWN "; + + SSL_ASSERT(ssl); + + if (ossl_statem_in_error(ssl)) + str = "SSLERR"; + else + { + switch (SSL_get_state(ssl)) + { + case TLS_ST_BEFORE: + str = "before SSL initialization"; + break; + case TLS_ST_OK: + str = "SSL negotiation finished successfully"; + break; + case TLS_ST_CW_CLNT_HELLO: + str = "SSLv3/TLS write client hello"; + break; + case TLS_ST_CR_SRVR_HELLO: + str = "SSLv3/TLS read server hello"; + break; + case TLS_ST_CR_CERT: + str = "SSLv3/TLS read server certificate"; + break; + case TLS_ST_CR_KEY_EXCH: + str = "SSLv3/TLS read server key exchange"; + break; + case TLS_ST_CR_CERT_REQ: + str = "SSLv3/TLS read server certificate request"; + break; + case TLS_ST_CR_SESSION_TICKET: + str = "SSLv3/TLS read server session ticket"; + break; + case TLS_ST_CR_SRVR_DONE: + str = "SSLv3/TLS read server done"; + break; + case TLS_ST_CW_CERT: + str = "SSLv3/TLS write client certificate"; + break; + case TLS_ST_CW_KEY_EXCH: + str = "SSLv3/TLS write client key exchange"; + break; + case TLS_ST_CW_CERT_VRFY: + str = "SSLv3/TLS write certificate verify"; + break; + case TLS_ST_CW_CHANGE: + case TLS_ST_SW_CHANGE: + str = "SSLv3/TLS write change cipher spec"; + break; + case TLS_ST_CW_FINISHED: + case TLS_ST_SW_FINISHED: + str = "SSLv3/TLS write finished"; + break; + case TLS_ST_CR_CHANGE: + case TLS_ST_SR_CHANGE: + str = "SSLv3/TLS read change cipher spec"; + break; + case TLS_ST_CR_FINISHED: + case TLS_ST_SR_FINISHED: + str = "SSLv3/TLS read finished"; + break; + case TLS_ST_SR_CLNT_HELLO: + str = "SSLv3/TLS read client hello"; + break; + case TLS_ST_SW_HELLO_REQ: + str = "SSLv3/TLS write hello request"; + break; + case TLS_ST_SW_SRVR_HELLO: + str = "SSLv3/TLS write server hello"; + break; + case TLS_ST_SW_CERT: + str = "SSLv3/TLS write certificate"; + break; + case TLS_ST_SW_KEY_EXCH: + str = "SSLv3/TLS write key exchange"; + break; + case TLS_ST_SW_CERT_REQ: + str = "SSLv3/TLS write certificate request"; + break; + case TLS_ST_SW_SESSION_TICKET: + str = "SSLv3/TLS write session ticket"; + break; + case TLS_ST_SW_SRVR_DONE: + str = "SSLv3/TLS write server done"; + break; + case TLS_ST_SR_CERT: + str = "SSLv3/TLS read client certificate"; + break; + case TLS_ST_SR_KEY_EXCH: + str = "SSLv3/TLS read client key exchange"; + break; + case TLS_ST_SR_CERT_VRFY: + str = "SSLv3/TLS read certificate verify"; + break; + case DTLS_ST_CR_HELLO_VERIFY_REQUEST: + str = "DTLS1 read hello verify request"; + break; + case DTLS_ST_SW_HELLO_VERIFY_REQUEST: + str = "DTLS1 write hello verify request"; + break; + default: + break; + } + } + + return str; +} + +/* + * SSL_CTX_set_default_read_buffer_len - set the SSL context read buffer length + * + * @param ctx - SSL context point + * @param len - read buffer length + * + * @return none + */ +void SSL_CTX_set_default_read_buffer_len(SSL_CTX *ctx, size_t len) +{ + SSL_ASSERT(ctx); + SSL_ASSERT(len); + + ctx->method->func->ssl_set_bufflen(NULL, len); +} + +/* + * SSL_set_default_read_buffer_len - set the SSL read buffer length + * + * @param ssl - SSL point + * @param len - read buffer length + * + * @return none + */ +void SSL_set_default_read_buffer_len(SSL *ssl, size_t len) +{ + SSL_ASSERT(ssl); + SSL_ASSERT(len); + + ssl->method->func->ssl_set_bufflen(ssl, len); +} + +/* + * SSL_set_info_callback - set the SSL information callback function + * + * @param ssl - SSL point + * @param cb - information callback function + * + * @return none + */ +void SSL_set_info_callback(SSL *ssl, void (*cb) (const SSL *ssl, int type, int val)) +{ + SSL_ASSERT(ssl); + + ssl->info_callback = cb; +} + +/* + * SSL_CTX_up_ref - add SSL context reference count by '1' + * + * @param ctx - SSL context point + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_CTX_up_ref(SSL_CTX *ctx) +{ + SSL_ASSERT(ctx); + + /* no support multi-thread SSL here */ + ctx->references++; + + return 1; +} + +/* + * SSL_set_security_level - set the SSL security level + * + * @param ssl - SSL point + * @param level - security level + * + * @return none + */ +void SSL_set_security_level(SSL *ssl, int level) +{ + SSL_ASSERT(ssl); + + ssl->cert->sec_level = level; +} + +/* + * SSL_get_security_level - get the SSL security level + * + * @param ssl - SSL point + * + * @return security level + */ +int SSL_get_security_level(const SSL *ssl) +{ + SSL_ASSERT(ssl); + + return ssl->cert->sec_level; +} + +/* + * SSL_CTX_get_verify_mode - get the SSL verifying mode of the SSL context + * + * @param ctx - SSL context point + * + * @return verifying mode + */ +int SSL_CTX_get_verify_mode(const SSL_CTX *ctx) +{ + SSL_ASSERT(ctx); + + return ctx->verify_mode; +} + +/* + * SSL_CTX_set_timeout - set the session timeout time + * + * @param ctx - SSL context point + * @param t - new session timeout time + * + * @return old session timeout time + */ +long SSL_CTX_set_timeout(SSL_CTX *ctx, long t) +{ + long l; + + SSL_ASSERT(ctx); + + l = ctx->session_timeout; + ctx->session_timeout = t; + + return l; +} + +/* + * SSL_CTX_get_timeout - get the session timeout time + * + * @param ctx - SSL context point + * + * @return current session timeout time + */ +long SSL_CTX_get_timeout(const SSL_CTX *ctx) +{ + SSL_ASSERT(ctx); + + return ctx->session_timeout; +} + +/* + * SSL_set_read_ahead - set the SSL if we can read as many as data + * + * @param ssl - SSL point + * @param yes - enable the function + * + * @return none + */ +void SSL_set_read_ahead(SSL *ssl, int yes) +{ + SSL_ASSERT(ssl); + + ssl->rlayer.read_ahead = yes; +} + +/* + * SSL_set_read_ahead - set the SSL context if we can read as many as data + * + * @param ctx - SSL context point + * @param yes - enable the function + * + * @return none + */ +void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes) +{ + SSL_ASSERT(ctx); + + ctx->read_ahead = yes; +} + +/* + * SSL_set_read_ahead - get the SSL ahead signal if we can read as many as data + * + * @param ssl - SSL point + * + * @return SSL context ahead signal + */ +int SSL_get_read_ahead(const SSL *ssl) +{ + SSL_ASSERT(ssl); + + return ssl->rlayer.read_ahead; +} + +/* + * SSL_set_read_ahead - get the SSL context ahead signal if we can read as many as data + * + * @param ctx - SSL context point + * + * @return SSL context ahead signal + */ +long SSL_CTX_get_read_ahead(SSL_CTX *ctx) +{ + SSL_ASSERT(ctx); + + return ctx->read_ahead; +} + +/* + * SSL_CTX_get_ciphers - check if the SSL context can read as many as data + * + * @param ctx - SSL context point + * + * @return + * 1 : Yes + * 0 : No + */ +long SSL_CTX_get_default_read_ahead(SSL_CTX *ctx) +{ + SSL_ASSERT(ctx); + + return ctx->read_ahead; +} + +/* + * SSL_set_time - set SSL session time + * + * @param ssl - SSL point + * @param t - session time + * + * @return session time + */ +long SSL_set_time(SSL *ssl, long t) +{ + SSL_ASSERT(ssl); + + ssl->session.time = t; + + return t; +} + +/* + * SSL_set_time - set SSL session timeout time + * + * @param ssl - SSL point + * @param t - session timeout time + * + * @return session timeout time + */ +long SSL_set_timeout(SSL *ssl, long t) +{ + SSL_ASSERT(ssl); + + ssl->session.timeout = t; + + return t; +} diff --git a/components/openssl/library/ssl_methods.c b/components/openssl/library/ssl_methods.c new file mode 100644 index 0000000000..502262f7e9 --- /dev/null +++ b/components/openssl/library/ssl_methods.c @@ -0,0 +1,43 @@ +#include "ssl_lib.h" +#include "ssl_methods.h" +#include "ssl_pm.h" + +IMPLEMENT_TLS_METHOD_FUNC(TLS_method_func, + ssl_pm_new, ssl_pm_free, + ssl_pm_handshake, ssl_pm_shutdown, ssl_pm_clear, + ssl_pm_read, ssl_pm_send, ssl_pm_pending, + ssl_pm_set_fd, ssl_pm_get_fd, + ssl_pm_set_bufflen, + ssl_pm_get_state); + +IMPLEMENT_TLS_METHOD(TLS_ANY_VERSION, 0, TLS_method_func, TLS_client_method); + +IMPLEMENT_TLS_METHOD(TLS1_2_VERSION, 0, TLS_method_func, TLSv1_2_client_method); + +IMPLEMENT_TLS_METHOD(TLS1_1_VERSION, 0, TLS_method_func, TLSv1_1_client_method); + +IMPLEMENT_TLS_METHOD(TLS1_VERSION, 0, TLS_method_func, TLSv1_client_method); + +IMPLEMENT_SSL_METHOD(SSL3_VERSION, 0, TLS_method_func, SSLv3_client_method); + + +IMPLEMENT_TLS_METHOD(TLS_ANY_VERSION, 1, TLS_method_func, TLS_server_method); + +IMPLEMENT_TLS_METHOD(TLS1_1_VERSION, 1, TLS_method_func, TLSv1_1_server_method); + +IMPLEMENT_TLS_METHOD(TLS1_2_VERSION, 1, TLS_method_func, TLSv1_2_server_method); + +IMPLEMENT_TLS_METHOD(TLS1_VERSION, 0, TLS_method_func, TLSv1_server_method); + +IMPLEMENT_SSL_METHOD(SSL3_VERSION, 1, TLS_method_func, SSLv3_server_method); + + +IMPLEMENT_TLS_METHOD(TLS_ANY_VERSION, -1, TLS_method_func, TLS_method); + +IMPLEMENT_SSL_METHOD(TLS1_2_VERSION, -1, TLS_method_func, TLSv1_2_method); + +IMPLEMENT_SSL_METHOD(TLS1_1_VERSION, -1, TLS_method_func, TLSv1_1_method); + +IMPLEMENT_SSL_METHOD(TLS1_VERSION, -1, TLS_method_func, TLSv1_method); + +IMPLEMENT_SSL_METHOD(SSL3_VERSION, -1, TLS_method_func, SSLv3_method); diff --git a/components/openssl/library/ssl_pkey.c b/components/openssl/library/ssl_pkey.c new file mode 100644 index 0000000000..2a170716c0 --- /dev/null +++ b/components/openssl/library/ssl_pkey.c @@ -0,0 +1,50 @@ +#include "ssl_lib.h" +#include "ssl_pkey.h" +#include "ssl_dbg.h" +#include "ssl_pm.h" + +EVP_PKEY *d2i_PrivateKey(int type, + EVP_PKEY **a, + const unsigned char **pp, + long length) +{ + EVP_PKEY *pkey; + void *pkey_pm; + int ret; + + SSL_ASSERT(pp); + SSL_ASSERT(*pp); + SSL_ASSERT(length); + + pkey = ssl_malloc(sizeof(EVP_PKEY)); + if (!pkey) + SSL_RET(failed1, "ssl_malloc\n"); + + pkey_pm = pkey_pm_new(); + if (!pkey_pm) + SSL_RET(failed2, "pkey_pm_new\n"); + + ret = pkey_pm_load_crt(pkey_pm, *pp, length); + if (ret) + SSL_RET(failed3, "pkey_pm_load_crt\n"); + + pkey->pkey_pm = pkey_pm; + if (a) + *a = pkey; + + return pkey; + +failed3: + pkey_pm_free(pkey_pm); +failed2: + ssl_free(pkey); +failed1: + return NULL; +} + +void EVP_PKEY_free(EVP_PKEY *x) +{ + pkey_pm_unload_crt(x->pkey_pm); + pkey_pm_free(x->pkey_pm); + ssl_free(x); +} diff --git a/components/openssl/library/ssl_rsa.c b/components/openssl/library/ssl_rsa.c new file mode 100644 index 0000000000..9088f67f57 --- /dev/null +++ b/components/openssl/library/ssl_rsa.c @@ -0,0 +1,70 @@ +#include "ssl_lib.h" +#include "ssl_rsa.h" +#include "ssl_pkey.h" +#include "ssl_x509.h" +#include "ssl_dbg.h" +#include "ssl_pm.h" + +int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) +{ + SSL_ASSERT(ctx); + SSL_ASSERT(x); + + ctx->cert->x509 = x; + + return 1; +} + +int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, + const unsigned char *d) +{ + int ret; + X509 *cert; + + cert = d2i_X509(NULL, d, len); + if (!cert) + SSL_RET(failed1, "d2i_X509\n"); + + ret = SSL_CTX_use_certificate(ctx, cert); + if (!ret) + SSL_RET(failed2, "SSL_CTX_use_certificate\n"); + + return 1; + +failed2: + X509_free(cert); +failed1: + return 0; +} + +int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) +{ + SSL_ASSERT(ctx); + SSL_ASSERT(pkey); + + ctx->cert->pkey = pkey; + + return 1; +} + +int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, + const unsigned char *d, long len) +{ + int ret; + EVP_PKEY *pkey; + + pkey = d2i_PrivateKey(0, NULL, &d, len); + if (!pkey) + SSL_RET(failed1, "d2i_PrivateKey\n"); + + ret = SSL_CTX_use_PrivateKey(ctx, pkey); + if (!ret) + SSL_RET(failed2, "SSL_CTX_use_PrivateKey\n"); + + return 1; + +failed2: + EVP_PKEY_free(pkey); +failed1: + return 0; +} diff --git a/components/openssl/library/ssl_x509.c b/components/openssl/library/ssl_x509.c new file mode 100644 index 0000000000..23aa00681e --- /dev/null +++ b/components/openssl/library/ssl_x509.c @@ -0,0 +1,54 @@ +#include "ssl_x509.h" +#include "ssl_dbg.h" +#include "ssl_pm.h" + +X509* sk_X509_NAME_new_null(void) +{ + return ssl_malloc(sizeof(X509)); +} + +X509* d2i_X509(X509 **cert, const unsigned char *buffer, long len) +{ + X509 *x509_crt; + void *x509_pm; + int ret; + + SSL_ASSERT(cert); + SSL_ASSERT(buffer); + SSL_ASSERT(len); + + x509_crt = sk_X509_NAME_new_null(); + if (!x509_crt) + SSL_RET(failed1, ""); + + x509_pm = x509_pm_new(); + if (!x509_pm) + SSL_RET(failed2, ""); + + ret = x509_pm_load_crt(x509_pm, buffer, len); + if (ret) + SSL_RET(failed3, ""); + + x509_crt->x509_pm = x509_pm; + if (cert) + *cert = x509_crt; + + return x509_crt; + +failed3: + x509_pm_free(x509_pm); +failed2: + ssl_free(x509_crt); +failed1: + return NULL; +} + +void X509_free(X509 *cert) +{ + if (cert->x509_pm) { + x509_pm_unload_crt(cert->x509_pm); + x509_pm_free(cert->x509_pm); + } + ssl_free(cert); +}; + diff --git a/components/openssl/platform/Makefile b/components/openssl/platform/Makefile new file mode 100644 index 0000000000..749b4787ca --- /dev/null +++ b/components/openssl/platform/Makefile @@ -0,0 +1,46 @@ + +############################################################# +# Required variables for each makefile +# Discard this section from all parent makefiles +# Expected variables (with automatic defaults): +# CSRCS (all "C" files in the dir) +# SUBDIRS (all subdirs with a Makefile) +# GEN_LIBS - list of libs to be generated () +# GEN_IMAGES - list of images to be generated () +# COMPONENTS_xxx - a list of libs/objs in the form +# subdir/lib to be extracted and rolled up into +# a generated lib/image xxx.a () +# +ifndef PDIR + +GEN_LIBS = libplatform.a + +endif + + +############################################################# +# Configuration i.e. compile options etc. +# Target specific stuff (defines etc.) goes in here! +# Generally values applying to a tree are captured in the +# makefile at its root level - these are then overridden +# for a subtree within the makefile rooted therein +# +#DEFINES += + +############################################################# +# Recursion Magic - Don't touch this!! +# +# Each subtree potentially has an include directory +# corresponding to the common APIs applicable to modules +# rooted at that subtree. Accordingly, the INCLUDE PATH +# of a module can only contain the include directories up +# its parent path, and not its siblings +# +# Required for each makefile to inherit from the parent +# + +INCLUDES := $(INCLUDES) -I $(PDIR)include +INCLUDES += -I ./ +PDIR := ../$(PDIR) +sinclude $(PDIR)Makefile + diff --git a/components/openssl/platform/ssl_pm.c b/components/openssl/platform/ssl_pm.c new file mode 100644 index 0000000000..831420180c --- /dev/null +++ b/components/openssl/platform/ssl_pm.c @@ -0,0 +1,422 @@ +#include "ssl_pm.h" +#include "ssl_dbg.h" + +/* mbedtls include */ +#include "mbedtls/platform.h" +#include "mbedtls/net.h" +#include "mbedtls/debug.h" +#include "mbedtls/entropy.h" +#include "mbedtls/ctr_drbg.h" +#include "mbedtls/error.h" +#include "mbedtls/certs.h" + +struct ssl_pm +{ + /* local socket file description */ + mbedtls_net_context fd; + /* remote client socket file description */ + mbedtls_net_context cl_fd; + + mbedtls_ssl_config conf; + + mbedtls_ctr_drbg_context ctr_drbg; + + mbedtls_ssl_context ssl; + + mbedtls_entropy_context entropy; +}; + +struct x509_pm +{ + mbedtls_x509_crt x509_crt; +}; + +struct pkey_pm +{ + mbedtls_pk_context pkey; +}; + + +unsigned int max_content_len; + + +/*********************************************************************************************/ +/********************************* SSL general interface *************************************/ + +void* ssl_zalloc(size_t size) +{ + void *p = malloc(size); + + if (p) + memset(p, 0, size); + + return p; +} + +void *ssl_malloc(size_t size) +{ + return zalloc(size); +} + +void ssl_free(void *p) +{ + free(p); +} + +void* ssl_memcpy(void *to, const void *from, size_t size) +{ + return memcpy(to, from, size); +} + +void ssl_speed_up_enter(void) +{ + +} + +void ssl_speed_up_exit(void) +{ + +} + +/*********************************************************************************************/ +/************************************ SSL arch interface *************************************/ + +int ssl_pm_new(SSL *ssl) +{ + struct ssl_pm *ssl_pm; + int ret; + + char *pers; + int endpoint; + + SSL_CTX *ctx = ssl->ctx; + const SSL_METHOD *method = ssl->method; + + ssl_pm = malloc(sizeof(struct ssl_pm)); + if (!ssl_pm) + return -1; + + if (method->endpoint) { + pers = "server"; + endpoint = MBEDTLS_SSL_IS_SERVER; + } else { + pers = "client"; + endpoint = MBEDTLS_SSL_IS_CLIENT; + } + + //max_content_len = 4096; + + mbedtls_net_init(&ssl_pm->fd); + mbedtls_net_init(&ssl_pm->cl_fd); + + mbedtls_ssl_config_init(&ssl_pm->conf); + mbedtls_ctr_drbg_init(&ssl_pm->ctr_drbg); + mbedtls_entropy_init(&ssl_pm->entropy); + mbedtls_ssl_init(&ssl_pm->ssl); + + ret = mbedtls_ctr_drbg_seed(&ssl_pm->ctr_drbg, mbedtls_entropy_func, &ssl_pm->entropy, (const unsigned char *)pers, strlen(pers)); + if (ret) + SSL_ERR(ret, failed1, "mbedtls_ctr_drbg_seed:[-0x%x]\n", -ret); + + ret = mbedtls_ssl_config_defaults(&ssl_pm->conf, endpoint, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT); + if (ret) + SSL_ERR(ret, failed2, "mbedtls_ssl_config_defaults:[-0x%x]\n", -ret); + + mbedtls_ssl_conf_rng(&ssl_pm->conf, mbedtls_ctr_drbg_random, &ssl_pm->ctr_drbg); + mbedtls_ssl_conf_dbg(&ssl_pm->conf, NULL, NULL); + + if (ctx->client_CA->x509_pm) { + struct x509_pm *x509_pm = (struct x509_pm *)ctx->client_CA->x509_pm; + + mbedtls_ssl_conf_ca_chain(&ssl_pm->conf, &x509_pm->x509_crt, NULL); + mbedtls_ssl_conf_authmode(&ssl_pm->conf, MBEDTLS_SSL_VERIFY_REQUIRED); + } else { + mbedtls_ssl_conf_authmode(&ssl_pm->conf, MBEDTLS_SSL_VERIFY_NONE); + } + if (ctx->cert->x509 && + ctx->cert->pkey) { + struct x509_pm *x509_pm = (struct x509_pm *)ctx->cert->x509->x509_pm; + struct pkey_pm *pkey_pm = (struct pkey_pm *)ctx->cert->pkey->pkey_pm; + + ret = mbedtls_ssl_conf_own_cert(&ssl_pm->conf, &x509_pm->x509_crt, &pkey_pm->pkey); + if (ret) + SSL_ERR(ret, failed4, "mbedtls_ssl_conf_own_cert:[%d]\n", ret); + } + + ret = mbedtls_ssl_setup(&ssl_pm->ssl, &ssl_pm->conf); + if (ret) + SSL_ERR(ret, failed4, "mbedtls_ssl_setup:[-0x%x]\n", -ret); + + mbedtls_ssl_set_bio(&ssl_pm->ssl, &ssl_pm->fd, mbedtls_net_send, mbedtls_net_recv, NULL); + + ssl->ssl_pm = ssl_pm; + + return 0; + +failed4: + mbedtls_ssl_config_free(&ssl_pm->conf); +failed3: + mbedtls_ctr_drbg_free(&ssl_pm->ctr_drbg); +failed2: + mbedtls_entropy_free(&ssl_pm->entropy); +failed1: + return -1; +} + +void ssl_pm_free(SSL *ssl) +{ + struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; + + mbedtls_ssl_config_free(&ssl_pm->conf); + mbedtls_ctr_drbg_free(&ssl_pm->ctr_drbg); + mbedtls_entropy_free(&ssl_pm->entropy); + mbedtls_ssl_free(&ssl_pm->ssl); + + mbedtls_net_free(&ssl_pm->fd); + mbedtls_net_free(&ssl_pm->cl_fd); +} + +int ssl_pm_handshake(SSL *ssl) +{ + int ret, mbed_ret; + struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; + + ssl_speed_up_enter(); + while((mbed_ret = mbedtls_ssl_handshake(&ssl_pm->ssl)) != 0) { + if (mbed_ret != MBEDTLS_ERR_SSL_WANT_READ && mbed_ret != MBEDTLS_ERR_SSL_WANT_WRITE) { + break; + } + } + ssl_speed_up_exit(); + + if (!mbed_ret) + ret = 1; + else { + ret = 0; + SSL_DEBUG(1, "mbedtls_ssl_handshake [-0x%x]\n", -mbed_ret); + } + + return ret; +} + +int ssl_pm_shutdown(SSL *ssl) +{ + int ret, mbed_ret; + struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; + + mbed_ret = mbedtls_ssl_close_notify(&ssl_pm->ssl); + if (!mbed_ret) + ret = 0; + else + ret = -1; + + return ret; +} + +int ssl_pm_clear(SSL *ssl) +{ + return ssl_pm_shutdown(ssl); +} + + +int ssl_pm_read(SSL *ssl, void *buffer, int len) +{ + int ret, mbed_ret; + struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; + + mbed_ret = mbedtls_ssl_read(&ssl_pm->ssl, buffer, len); + if (mbed_ret < 0) + ret = -1; + else if (mbed_ret == 0) + ret = 0; + else + ret = mbed_ret; + + return ret; +} + +int ssl_pm_send(SSL *ssl, const void *buffer, int len) +{ + int ret, mbed_ret; + struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; + + mbed_ret = mbedtls_ssl_write(&ssl_pm->ssl, buffer, len); + if (mbed_ret < 0) + ret = -1; + else if (mbed_ret == 0) + ret = 0; + else + ret = mbed_ret; + + return ret; +} + +int ssl_pm_pending(const SSL *ssl) +{ + struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; + + return mbedtls_ssl_get_bytes_avail(&ssl_pm->ssl); +} + +void ssl_pm_set_fd(SSL *ssl, int fd, int mode) +{ + struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; + + ssl_pm->fd.fd = fd; +} + +int ssl_pm_get_fd(const SSL *ssl, int mode) +{ + struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; + + return ssl_pm->fd.fd; +} + +OSSL_HANDSHAKE_STATE ssl_pm_get_state(const SSL *ssl) +{ + OSSL_HANDSHAKE_STATE state; + + struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; + + switch (ssl_pm->ssl.state) + { + case MBEDTLS_SSL_CLIENT_HELLO: + state = TLS_ST_CW_CLNT_HELLO; + break; + case MBEDTLS_SSL_SERVER_HELLO: + state = TLS_ST_SW_SRVR_HELLO; + break; + case MBEDTLS_SSL_SERVER_CERTIFICATE: + state = TLS_ST_SW_CERT; + break; + case MBEDTLS_SSL_SERVER_HELLO_DONE: + state = TLS_ST_SW_SRVR_DONE; + break; + case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE: + state = TLS_ST_CW_KEY_EXCH; + break; + case MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC: + state = TLS_ST_CW_CHANGE; + break; + case MBEDTLS_SSL_CLIENT_FINISHED: + state = TLS_ST_CW_FINISHED; + break; + case MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC: + state = TLS_ST_SW_CHANGE; + break; + case MBEDTLS_SSL_SERVER_FINISHED: + state = TLS_ST_SW_FINISHED; + break; + case MBEDTLS_SSL_CLIENT_CERTIFICATE: + state = TLS_ST_CW_CERT; + break; + case MBEDTLS_SSL_SERVER_KEY_EXCHANGE: + state = TLS_ST_SR_KEY_EXCH; + break; + case MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET: + state = TLS_ST_SW_SESSION_TICKET; + break; + case MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT: + state = TLS_ST_SW_CERT_REQ; + break; + case MBEDTLS_SSL_HANDSHAKE_OVER: + state = TLS_ST_OK; + break; + default : + state = TLS_ST_BEFORE; + break; + } + + return state; +} + +void* x509_pm_new(void) +{ + return ssl_malloc(sizeof(struct x509_pm)); +} + +void x509_pm_free(void *pm) +{ + ssl_free(pm); +} + +int x509_pm_load_crt(void *pm, const unsigned char *buffer, int len) +{ + int ret; + unsigned char *load_buf; + struct x509_pm *x509_pm = (struct x509_pm *)pm; + + load_buf = ssl_malloc(len + 1); + if (!load_buf) + SSL_RET(failed1, ""); + + ssl_memcpy(load_buf, buffer, len); + load_buf[len] = '\0'; + + mbedtls_x509_crt_init(&x509_pm->x509_crt); + ret = mbedtls_x509_crt_parse(&x509_pm->x509_crt, load_buf, len); + ssl_free(load_buf); + + if (ret) + SSL_RET(failed1, ""); + + return 0; + +failed1: + return -1; +} + +void x509_pm_unload_crt(void *pm) +{ + struct x509_pm *x509_pm = (struct x509_pm *)pm; + + mbedtls_x509_crt_free(&x509_pm->x509_crt); +} + +void* pkey_pm_new(void) +{ + return ssl_malloc(sizeof(struct pkey_pm)); +} + +void pkey_pm_free(void *pm) +{ + ssl_free(pm); +} + +int pkey_pm_load_crt(void *pm, const unsigned char *buffer, int len) +{ + int ret; + unsigned char *load_buf; + struct pkey_pm *pkey_pm = (struct pkey_pm *)pm; + + load_buf = ssl_malloc(len + 1); + if (!load_buf) + SSL_RET(failed1, ""); + + ssl_memcpy(load_buf, buffer, len); + load_buf[len] = '\0'; + + mbedtls_pk_init(&pkey_pm->pkey); + ret = mbedtls_pk_parse_key(&pkey_pm->pkey, load_buf, len, NULL, 0); + ssl_free(load_buf); + + if (ret) + SSL_RET(failed1, ""); + + return 0; + +failed1: + return -1; +} + +void pkey_pm_unload_crt(void *pm) +{ + struct pkey_pm *pkey_pm = (struct pkey_pm *)pm; + + mbedtls_pk_free(&pkey_pm->pkey); +} + +void ssl_pm_set_bufflen(SSL *ssl, int len) +{ + max_content_len = len; +} From 5adc661d05ea0ab75e68674aae3ba6b2a7795824 Mon Sep 17 00:00:00 2001 From: dongheng Date: Wed, 21 Sep 2016 09:23:29 +0800 Subject: [PATCH 003/343] components/openssl: add more interface for application --- components/openssl/Makefile | 50 ------------- components/openssl/Makefile.projbuild | 4 ++ components/openssl/component.mk | 9 +++ components/openssl/include/internal/ssl_lib.h | 5 -- .../openssl/include/internal/ssl_pkey.h | 2 + components/openssl/include/platform/ssl_pm.h | 3 +- components/openssl/library/Makefile | 46 ------------ components/openssl/library/ssl_cert.c | 1 + components/openssl/library/ssl_lib.c | 72 ++++++++++++++++++- components/openssl/platform/Makefile | 46 ------------ components/openssl/platform/ssl_pm.c | 6 +- 11 files changed, 92 insertions(+), 152 deletions(-) delete mode 100644 components/openssl/Makefile create mode 100644 components/openssl/Makefile.projbuild create mode 100644 components/openssl/component.mk delete mode 100644 components/openssl/library/Makefile delete mode 100644 components/openssl/platform/Makefile diff --git a/components/openssl/Makefile b/components/openssl/Makefile deleted file mode 100644 index bdd8a0e932..0000000000 --- a/components/openssl/Makefile +++ /dev/null @@ -1,50 +0,0 @@ - -############################################################# -# Required variables for each makefile -# Discard this section from all parent makefiles -# Expected variables (with automatic defaults): -# CSRCS (all "C" files in the dir) -# SUBDIRS (all subdirs with a Makefile) -# GEN_LIBS - list of libs to be generated () -# GEN_IMAGES - list of images to be generated () -# COMPONENTS_xxx - a list of libs/objs in the form -# subdir/lib to be extracted and rolled up into -# a generated lib/image xxx.a () -# -ifndef PDIR - -UP_EXTRACT_DIR = .. -GEN_LIBS = libopenssl.a -COMPONENTS_libopenssl = library/liblibrary.a platform/libplatform.a - -endif - - -############################################################# -# Configuration i.e. compile options etc. -# Target specific stuff (defines etc.) goes in here! -# Generally values applying to a tree are captured in the -# makefile at its root level - these are then overridden -# for a subtree within the makefile rooted therein -# -#DEFINES += - -############################################################# -# Recursion Magic - Don't touch this!! -# -# Each subtree potentially has an include directory -# corresponding to the common APIs applicable to modules -# rooted at that subtree. Accordingly, the INCLUDE PATH -# of a module can only contain the include directories up -# its parent path, and not its siblings -# -# Required for each makefile to inherit from the parent -# - -INCLUDES := $(INCLUDES) -I $(PDIR)include -I $(PDIR)include/platform -I $(PDIR)include/internal -INCLUDES += -I ./inlcude -INCLUDES += -I $(SDK_PATH)/include/openssl/internal -INCLUDES += -I ./ -PDIR := ../$(PDIR) -sinclude $(PDIR)Makefile - diff --git a/components/openssl/Makefile.projbuild b/components/openssl/Makefile.projbuild new file mode 100644 index 0000000000..51300efd11 --- /dev/null +++ b/components/openssl/Makefile.projbuild @@ -0,0 +1,4 @@ +# Anyone compiling mbedTLS code needs the name of the +# alternative config file +CFLAGS += -DMBEDTLS_CONFIG_FILE='"mbedtls/esp_config.h"' + diff --git a/components/openssl/component.mk b/components/openssl/component.mk new file mode 100644 index 0000000000..97de6975c9 --- /dev/null +++ b/components/openssl/component.mk @@ -0,0 +1,9 @@ +# +# Component Makefile +# + +COMPONENT_ADD_INCLUDEDIRS := include include/internal include/platform include/oepnssl + +COMPONENT_SRCDIRS := library platform + +include $(IDF_PATH)/make/component_common.mk diff --git a/components/openssl/include/internal/ssl_lib.h b/components/openssl/include/internal/ssl_lib.h index d95d219556..0881fbbfdb 100644 --- a/components/openssl/include/internal/ssl_lib.h +++ b/components/openssl/include/internal/ssl_lib.h @@ -3,9 +3,4 @@ #include "ssl_types.h" -#define SSL_want_nothing(s) (SSL_want(s) == SSL_NOTHING) -#define SSL_want_read(s) (SSL_want(s) == SSL_READING) -#define SSL_want_write(s) (SSL_want(s) == SSL_WRITING) -#define SSL_want_x509_lookup(s) (SSL_want(s) == SSL_WRITING) - #endif diff --git a/components/openssl/include/internal/ssl_pkey.h b/components/openssl/include/internal/ssl_pkey.h index cc870e18ed..c7170244a6 100644 --- a/components/openssl/include/internal/ssl_pkey.h +++ b/components/openssl/include/internal/ssl_pkey.h @@ -8,4 +8,6 @@ EVP_PKEY *d2i_PrivateKey(int type, const unsigned char **pp, long length); +void EVP_PKEY_free(EVP_PKEY *x); + #endif diff --git a/components/openssl/include/platform/ssl_pm.h b/components/openssl/include/platform/ssl_pm.h index c75ae95af5..a6731cff7f 100644 --- a/components/openssl/include/platform/ssl_pm.h +++ b/components/openssl/include/platform/ssl_pm.h @@ -2,7 +2,8 @@ #define _SSL_PM_H_ #include "ssl_types.h" -#include "esp_common.h" +#include "esp_types.h" +#include "esp_system.h" void* ssl_zalloc(size_t size); void *ssl_malloc(size_t size); diff --git a/components/openssl/library/Makefile b/components/openssl/library/Makefile deleted file mode 100644 index 10f4067c64..0000000000 --- a/components/openssl/library/Makefile +++ /dev/null @@ -1,46 +0,0 @@ - -############################################################# -# Required variables for each makefile -# Discard this section from all parent makefiles -# Expected variables (with automatic defaults): -# CSRCS (all "C" files in the dir) -# SUBDIRS (all subdirs with a Makefile) -# GEN_LIBS - list of libs to be generated () -# GEN_IMAGES - list of images to be generated () -# COMPONENTS_xxx - a list of libs/objs in the form -# subdir/lib to be extracted and rolled up into -# a generated lib/image xxx.a () -# -ifndef PDIR - -GEN_LIBS = liblibrary.a - -endif - - -############################################################# -# Configuration i.e. compile options etc. -# Target specific stuff (defines etc.) goes in here! -# Generally values applying to a tree are captured in the -# makefile at its root level - these are then overridden -# for a subtree within the makefile rooted therein -# -#DEFINES += - -############################################################# -# Recursion Magic - Don't touch this!! -# -# Each subtree potentially has an include directory -# corresponding to the common APIs applicable to modules -# rooted at that subtree. Accordingly, the INCLUDE PATH -# of a module can only contain the include directories up -# its parent path, and not its siblings -# -# Required for each makefile to inherit from the parent -# - -INCLUDES := $(INCLUDES) -I $(PDIR)include -INCLUDES += -I ./ -PDIR := ../$(PDIR) -sinclude $(PDIR)Makefile - diff --git a/components/openssl/library/ssl_cert.c b/components/openssl/library/ssl_cert.c index 10f723bfcb..5332592460 100644 --- a/components/openssl/library/ssl_cert.c +++ b/components/openssl/library/ssl_cert.c @@ -1,4 +1,5 @@ #include "ssl_cert.h" +#include "ssl_dbg.h" #include "ssl_pm.h" CERT *ssl_cert_new(void) diff --git a/components/openssl/library/ssl_lib.c b/components/openssl/library/ssl_lib.c index ad78f3961a..e1e112cc7b 100644 --- a/components/openssl/library/ssl_lib.c +++ b/components/openssl/library/ssl_lib.c @@ -6,7 +6,7 @@ #define SSL_SEND_DATA_MAX_LENGTH 1460 -static int ossl_statem_in_error(const SSL *ssl) +int ossl_statem_in_error(const SSL *ssl) { if (ssl->statem.state == MSG_FLOW_ERROR) return 1; @@ -14,6 +14,74 @@ static int ossl_statem_in_error(const SSL *ssl) return 0; } +/* + * SSL_want - get the SSL specifical statement + * + * @param ssl - SSL point + * + * @return specifical statement + */ +int SSL_want(const SSL *ssl) +{ + return 0; +} + +/* + * SSL_want_nothing - check if SSL want nothing + * + * @param ssl - SSL point + * + * @return + * 1 : yes + * 0 : no + */ +int SSL_want_nothing(const SSL *ssl) +{ + return (SSL_want(ssl) == SSL_NOTHING); +} + +/* + * SSL_want_read - check if SSL want to read + * + * @param ssl - SSL point + * + * @return + * 1 : yes + * 0 : no + */ +int SSL_want_read(const SSL *ssl) +{ + return (SSL_want(ssl) == SSL_READING); +} + +/* + * SSL_want_read - check if SSL want to write + * + * @param ssl - SSL point + * + * @return + * 1 : yes + * 0 : no + */ +int SSL_want_write(const SSL *ssl) +{ + return (SSL_want(ssl) == SSL_WRITING); +} + +/* + * SSL_want_read - check if SSL want to lookup X509 certification + * + * @param ssl - SSL point + * + * @return + * 1 : yes + * 0 : no + */ +int SSL_want_x509_lookup(const SSL *ssl) +{ + return (SSL_want(ssl) == SSL_WRITING); +} + /* * SSL_get_error - get SSL error code * @@ -1153,7 +1221,7 @@ char *SSL_state_string(const SSL *ssl) SSL_ASSERT(ssl); - if (ossl_state_in_error(ssl)) + if (ossl_statem_in_error(ssl)) str = "SSLERR"; else { diff --git a/components/openssl/platform/Makefile b/components/openssl/platform/Makefile deleted file mode 100644 index 749b4787ca..0000000000 --- a/components/openssl/platform/Makefile +++ /dev/null @@ -1,46 +0,0 @@ - -############################################################# -# Required variables for each makefile -# Discard this section from all parent makefiles -# Expected variables (with automatic defaults): -# CSRCS (all "C" files in the dir) -# SUBDIRS (all subdirs with a Makefile) -# GEN_LIBS - list of libs to be generated () -# GEN_IMAGES - list of images to be generated () -# COMPONENTS_xxx - a list of libs/objs in the form -# subdir/lib to be extracted and rolled up into -# a generated lib/image xxx.a () -# -ifndef PDIR - -GEN_LIBS = libplatform.a - -endif - - -############################################################# -# Configuration i.e. compile options etc. -# Target specific stuff (defines etc.) goes in here! -# Generally values applying to a tree are captured in the -# makefile at its root level - these are then overridden -# for a subtree within the makefile rooted therein -# -#DEFINES += - -############################################################# -# Recursion Magic - Don't touch this!! -# -# Each subtree potentially has an include directory -# corresponding to the common APIs applicable to modules -# rooted at that subtree. Accordingly, the INCLUDE PATH -# of a module can only contain the include directories up -# its parent path, and not its siblings -# -# Required for each makefile to inherit from the parent -# - -INCLUDES := $(INCLUDES) -I $(PDIR)include -INCLUDES += -I ./ -PDIR := ../$(PDIR) -sinclude $(PDIR)Makefile - diff --git a/components/openssl/platform/ssl_pm.c b/components/openssl/platform/ssl_pm.c index 831420180c..9d207b3a0e 100644 --- a/components/openssl/platform/ssl_pm.c +++ b/components/openssl/platform/ssl_pm.c @@ -1,6 +1,8 @@ #include "ssl_pm.h" #include "ssl_dbg.h" +#include + /* mbedtls include */ #include "mbedtls/platform.h" #include "mbedtls/net.h" @@ -55,7 +57,7 @@ void* ssl_zalloc(size_t size) void *ssl_malloc(size_t size) { - return zalloc(size); + return ssl_zalloc(size); } void ssl_free(void *p) @@ -140,7 +142,7 @@ int ssl_pm_new(SSL *ssl) ret = mbedtls_ssl_conf_own_cert(&ssl_pm->conf, &x509_pm->x509_crt, &pkey_pm->pkey); if (ret) - SSL_ERR(ret, failed4, "mbedtls_ssl_conf_own_cert:[%d]\n", ret); + SSL_ERR(ret, failed3, "mbedtls_ssl_conf_own_cert:[%d]\n", ret); } ret = mbedtls_ssl_setup(&ssl_pm->ssl, &ssl_pm->conf); From b89168d0f1be251fce1b37bfe0684ae097da30f7 Mon Sep 17 00:00:00 2001 From: dongheng Date: Wed, 21 Sep 2016 17:51:12 +0800 Subject: [PATCH 004/343] components/openssl: add ssl_port.c & .h file --- .../openssl/include/platform/ssl_port.h | 29 ++++++++++ components/openssl/platform/ssl_port.c | 56 +++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 components/openssl/include/platform/ssl_port.h create mode 100644 components/openssl/platform/ssl_port.c diff --git a/components/openssl/include/platform/ssl_port.h b/components/openssl/include/platform/ssl_port.h new file mode 100644 index 0000000000..252e2566c3 --- /dev/null +++ b/components/openssl/include/platform/ssl_port.h @@ -0,0 +1,29 @@ +/* Copyright 2015-2016 Espressif Systems (Wuxi) PTE LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _SSL_PORT_H_ +#define _SSL_PORT_H_ + +#include "esp_types.h" + +void* ssl_zalloc(size_t size); +void *ssl_malloc(size_t size); +void ssl_free(void *p); +void* ssl_memcpy(void *to, const void *from, size_t size); + +void ssl_speed_up_enter(void); +void ssl_speed_up_exit(void); + +#endif diff --git a/components/openssl/platform/ssl_port.c b/components/openssl/platform/ssl_port.c new file mode 100644 index 0000000000..66aac5f6d9 --- /dev/null +++ b/components/openssl/platform/ssl_port.c @@ -0,0 +1,56 @@ +/* Copyright 2015-2016 Espressif Systems (Wuxi) PTE LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "ssl_port.h" +#include "malloc.h" + +/*********************************************************************************************/ +/********************************* SSL general interface *************************************/ + +void* ssl_zalloc(size_t size) +{ + void *p = malloc(size); + + if (p) + memset(p, 0, size); + + return p; +} + +void *ssl_malloc(size_t size) +{ + return ssl_zalloc(size); +} + +void ssl_free(void *p) +{ + free(p); +} + +void* ssl_memcpy(void *to, const void *from, size_t size) +{ + return memcpy(to, from, size); +} + +void ssl_speed_up_enter(void) +{ + +} + +void ssl_speed_up_exit(void) +{ + +} From 6bd3d62d7ceadb11c814459dfbe68160aa511409 Mon Sep 17 00:00:00 2001 From: dongheng Date: Thu, 22 Sep 2016 10:28:08 +0800 Subject: [PATCH 005/343] components/openssl: add license header --- components/openssl/Makefile.projbuild | 1 - components/openssl/include/internal/ssl3.h | 14 ++ .../openssl/include/internal/ssl_cert.h | 20 ++- .../openssl/include/internal/ssl_code.h | 14 ++ components/openssl/include/internal/ssl_dbg.h | 20 ++- components/openssl/include/internal/ssl_lib.h | 14 ++ .../openssl/include/internal/ssl_methods.h | 53 +++++- .../openssl/include/internal/ssl_pkey.h | 18 +- components/openssl/include/internal/ssl_rsa.h | 14 ++ .../openssl/include/internal/ssl_types.h | 53 +++++- .../openssl/include/internal/ssl_x509.h | 14 ++ components/openssl/include/internal/tls1.h | 14 ++ components/openssl/include/openssl/ssl.h | 19 +- components/openssl/include/platform/ssl_pm.h | 40 +++-- .../openssl/include/platform/ssl_port.h | 27 ++- components/openssl/library/ssl_cert.c | 75 ++++++-- components/openssl/library/ssl_lib.c | 101 ++++++++--- components/openssl/library/ssl_methods.c | 42 ++++- components/openssl/library/ssl_pkey.c | 111 +++++++++--- components/openssl/library/ssl_rsa.c | 82 ++++++++- components/openssl/library/ssl_x509.c | 118 +++++++++---- components/openssl/platform/ssl_pm.c | 163 ++++++++++-------- components/openssl/platform/ssl_port.c | 27 ++- 23 files changed, 819 insertions(+), 235 deletions(-) diff --git a/components/openssl/Makefile.projbuild b/components/openssl/Makefile.projbuild index 51300efd11..b1d5641231 100644 --- a/components/openssl/Makefile.projbuild +++ b/components/openssl/Makefile.projbuild @@ -1,4 +1,3 @@ # Anyone compiling mbedTLS code needs the name of the # alternative config file -CFLAGS += -DMBEDTLS_CONFIG_FILE='"mbedtls/esp_config.h"' diff --git a/components/openssl/include/internal/ssl3.h b/components/openssl/include/internal/ssl3.h index d7c254563b..c90d546df0 100644 --- a/components/openssl/include/internal/ssl3.h +++ b/components/openssl/include/internal/ssl3.h @@ -1,3 +1,17 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #ifndef _SSL3_H_ #define _SSL3_H_ diff --git a/components/openssl/include/internal/ssl_cert.h b/components/openssl/include/internal/ssl_cert.h index e0b3ea75dc..109012a194 100644 --- a/components/openssl/include/internal/ssl_cert.h +++ b/components/openssl/include/internal/ssl_cert.h @@ -1,11 +1,23 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #ifndef _SSL_CERT_H_ #define _SSL_CERT_H_ -#include "ssl_pkey.h" -#include "ssl_x509.h" - -CERT *ssl_cert_new(void); +#include "ssl_types.h" +CERT* ssl_cert_new(void); void ssl_cert_free(CERT *c); #endif diff --git a/components/openssl/include/internal/ssl_code.h b/components/openssl/include/internal/ssl_code.h index d45abff680..1510ce6ff4 100644 --- a/components/openssl/include/internal/ssl_code.h +++ b/components/openssl/include/internal/ssl_code.h @@ -1,3 +1,17 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #ifndef _SSL_CODE_H_ #define _SSL_CODE_H_ diff --git a/components/openssl/include/internal/ssl_dbg.h b/components/openssl/include/internal/ssl_dbg.h index 436d33132f..27a192b28f 100644 --- a/components/openssl/include/internal/ssl_dbg.h +++ b/components/openssl/include/internal/ssl_dbg.h @@ -1,13 +1,29 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #ifndef _SSL_DEBUG_H_ #define _SSL_DEBUG_H_ -#define SSL_DEBUG_ENBALE 0 +#define SSL_DEBUG_ENBALE 1 #define SSL_DEBUG_LEVEL 0 #define SSL_ASSERT_ENABLE 1 #define SSL_DEBUG_LOCATION_ENABLE 1 #if SSL_DEBUG_ENBALE - #define SSL_PRINT os_printf + extern int ets_printf(const char *fmt, ...); + + #define SSL_PRINT ets_printf #else #define SSL_PRINT(...) #endif diff --git a/components/openssl/include/internal/ssl_lib.h b/components/openssl/include/internal/ssl_lib.h index 0881fbbfdb..6ea547a7c5 100644 --- a/components/openssl/include/internal/ssl_lib.h +++ b/components/openssl/include/internal/ssl_lib.h @@ -1,3 +1,17 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #ifndef _SSL_LIB_H_ #define _SSL_LIB_H_ diff --git a/components/openssl/include/internal/ssl_methods.h b/components/openssl/include/internal/ssl_methods.h index e2806f177a..b72b17ad3d 100644 --- a/components/openssl/include/internal/ssl_methods.h +++ b/components/openssl/include/internal/ssl_methods.h @@ -1,3 +1,17 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #ifndef _SSL_METHODS_H_ #define _SSL_METHODS_H_ @@ -8,7 +22,7 @@ set_fd, get_fd, \ set_bufflen, \ get_state) \ - static const SSL_METHOD_FUNC func_name = { \ + static const SSL_METHOD_FUNC func_name LOCAL_ATRR = { \ new, \ free, \ handshake, \ @@ -25,7 +39,7 @@ #define IMPLEMENT_TLS_METHOD(ver, mode, fun, func_name) \ const SSL_METHOD* func_name(void) { \ - static const SSL_METHOD func_name##_data = { \ + static const SSL_METHOD func_name##_data LOCAL_ATRR = { \ ver, \ mode, \ &(fun), \ @@ -35,7 +49,7 @@ #define IMPLEMENT_SSL_METHOD(ver, mode, fun, func_name) \ const SSL_METHOD* func_name(void) { \ - static const SSL_METHOD func_name##_data = { \ + static const SSL_METHOD func_name##_data LOCAL_ATRR = { \ ver, \ mode, \ &(fun), \ @@ -43,4 +57,37 @@ return &func_name##_data; \ } +#define IMPLEMENT_X509_METHOD(func_name, \ + new, \ + free, \ + load, \ + unload) \ + const X509_METHOD* func_name(void) { \ + static const X509_METHOD func_name##_data LOCAL_ATRR = { \ + new, \ + free, \ + load, \ + unload, \ + }; \ + return &func_name##_data; \ + } + +#define IMPLEMENT_PKEY_METHOD(func_name, \ + new, \ + free, \ + load, \ + unload) \ + const PKEY_METHOD* func_name(void) { \ + static const PKEY_METHOD func_name##_data LOCAL_ATRR = { \ + new, \ + free, \ + load, \ + unload, \ + }; \ + return &func_name##_data; \ + } + +const X509_METHOD* X509_method(void); +const PKEY_METHOD* EVP_PKEY_method(void); + #endif diff --git a/components/openssl/include/internal/ssl_pkey.h b/components/openssl/include/internal/ssl_pkey.h index c7170244a6..34be294efe 100644 --- a/components/openssl/include/internal/ssl_pkey.h +++ b/components/openssl/include/internal/ssl_pkey.h @@ -1,9 +1,25 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #ifndef _SSL_PKEY_H_ #define _SSL_PKEY_H_ #include "ssl_types.h" -EVP_PKEY *d2i_PrivateKey(int type, +EVP_PKEY* EVP_PKEY_new(void); + +EVP_PKEY* d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, long length); diff --git a/components/openssl/include/internal/ssl_rsa.h b/components/openssl/include/internal/ssl_rsa.h index 7530bde734..d0ce40312c 100644 --- a/components/openssl/include/internal/ssl_rsa.h +++ b/components/openssl/include/internal/ssl_rsa.h @@ -1,3 +1,17 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #ifndef _SSL_RSA_H_ #define _SSL_RSA_H_ diff --git a/components/openssl/include/internal/ssl_types.h b/components/openssl/include/internal/ssl_types.h index 19eb6cb165..417350627c 100644 --- a/components/openssl/include/internal/ssl_types.h +++ b/components/openssl/include/internal/ssl_types.h @@ -1,8 +1,21 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #ifndef _SSL_TYPES_H_ #define _SSL_TYPES_H_ #include "ssl_code.h" -#include typedef void SSL_CIPHER; @@ -47,15 +60,25 @@ typedef struct x509_st X509; struct evp_pkey_st; typedef struct evp_pkey_st EVP_PKEY; +struct x509_method_st; +typedef struct x509_method_st X509_METHOD; + +struct pkey_method_st; +typedef struct pkey_method_st PKEY_METHOD; + struct evp_pkey_st { void *pkey_pm; + + const PKEY_METHOD *method; }; struct x509_st { /* X509 certification platform private point */ void *x509_pm; + + const X509_METHOD *method; }; struct cert_st { @@ -111,6 +134,8 @@ struct ssl_ctx_st long session_timeout; int read_ahead; + + int read_buffer_len; }; struct ssl_st @@ -183,8 +208,34 @@ struct ssl_method_func_st { OSSL_HANDSHAKE_STATE (*ssl_get_state)(const SSL *ssl); }; +struct x509_method_st { + + int (*x509_new)(X509 *x); + + void (*x509_free)(X509 *x); + + int (*x509_load)(X509 *x, const unsigned char *buf, int len); + + void (*x509_unload)(X509 *x); +}; + +struct pkey_method_st { + + int (*pkey_new)(EVP_PKEY *pkey); + + void (*pkey_free)(EVP_PKEY *pkey); + + int (*pkey_load)(EVP_PKEY *pkey, const unsigned char *buf, int len); + + void (*pkey_unload)(EVP_PKEY *pkey); +}; + typedef int (*next_proto_cb)(SSL *ssl, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg); +#define SSL_METHOD_CALL(f, s, ...) s->method->func->ssl_##f(s, ##__VA_ARGS__) +#define X509_METHOD_CALL(f, x, ...) x->method->x509_##f(x, ##__VA_ARGS__) +#define EVP_PKEY_METHOD_CALL(f, k, ...) k->method->pkey_##f(k, ##__VA_ARGS__) + #endif diff --git a/components/openssl/include/internal/ssl_x509.h b/components/openssl/include/internal/ssl_x509.h index 28a7baf513..a169352bac 100644 --- a/components/openssl/include/internal/ssl_x509.h +++ b/components/openssl/include/internal/ssl_x509.h @@ -1,3 +1,17 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #ifndef _SSL_X509_H_ #define _SSL_X509_H_ diff --git a/components/openssl/include/internal/tls1.h b/components/openssl/include/internal/tls1.h index 70de22bb5b..b2da639194 100644 --- a/components/openssl/include/internal/tls1.h +++ b/components/openssl/include/internal/tls1.h @@ -1,3 +1,17 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #ifndef _TLS1_H_ #define _TLS1_H_ diff --git a/components/openssl/include/openssl/ssl.h b/components/openssl/include/openssl/ssl.h index 89cb5bb9f7..0d4c9c2080 100644 --- a/components/openssl/include/openssl/ssl.h +++ b/components/openssl/include/openssl/ssl.h @@ -1,6 +1,21 @@ -#ifndef HEADER_SSL_H -#define HEADER_SSL_H +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef _SSL_H_ +#define _SSL_H_ + +#include "ssl_port.h" #include "internal/ssl_types.h" /* diff --git a/components/openssl/include/platform/ssl_pm.h b/components/openssl/include/platform/ssl_pm.h index a6731cff7f..783ba5445e 100644 --- a/components/openssl/include/platform/ssl_pm.h +++ b/components/openssl/include/platform/ssl_pm.h @@ -1,14 +1,24 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #ifndef _SSL_PM_H_ #define _SSL_PM_H_ #include "ssl_types.h" -#include "esp_types.h" -#include "esp_system.h" +#include "ssl_port.h" -void* ssl_zalloc(size_t size); -void *ssl_malloc(size_t size); -void ssl_free(void *p); -void* ssl_memcpy(void *to, const void *from, size_t size); +#define LOCAL_ATRR int ssl_pm_new(SSL *ssl); void ssl_pm_free(SSL *ssl); @@ -28,15 +38,15 @@ OSSL_HANDSHAKE_STATE ssl_pm_get_state(const SSL *ssl); void ssl_pm_set_bufflen(SSL *ssl, int len); -void* x509_pm_new(void); -void x509_pm_free(void *pm); -int x509_pm_load_crt(void *pm, const unsigned char *buffer, int len); -void x509_pm_unload_crt(void *pm); -void x509_pm_start_ca(void *ssl, void *pm); +int x509_pm_new(X509 *x); +void x509_pm_free(X509 *x); +int x509_pm_load(X509 *x, const unsigned char *buffer, int len); +void x509_pm_unload(X509 *x); +void x509_pm_start_ca(X509 *x); -void* pkey_pm_new(void); -void pkey_pm_free(void *pm); -int pkey_pm_load_crt(void *pm, const unsigned char *buffer, int len); -void pkey_pm_unload_crt(void *pm); +int pkey_pm_new(EVP_PKEY *pkey); +void pkey_pm_free(EVP_PKEY *pkey); +int pkey_pm_load(EVP_PKEY *pkey, const unsigned char *buffer, int len); +void pkey_pm_unload(EVP_PKEY *pkey); #endif diff --git a/components/openssl/include/platform/ssl_port.h b/components/openssl/include/platform/ssl_port.h index 252e2566c3..48a7c7ca97 100644 --- a/components/openssl/include/platform/ssl_port.h +++ b/components/openssl/include/platform/ssl_port.h @@ -1,17 +1,16 @@ -/* Copyright 2015-2016 Espressif Systems (Wuxi) PTE LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. #ifndef _SSL_PORT_H_ #define _SSL_PORT_H_ diff --git a/components/openssl/library/ssl_cert.c b/components/openssl/library/ssl_cert.c index 5332592460..0bdba459d3 100644 --- a/components/openssl/library/ssl_cert.c +++ b/components/openssl/library/ssl_cert.c @@ -1,29 +1,68 @@ -#include "ssl_cert.h" -#include "ssl_dbg.h" -#include "ssl_pm.h" +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "ssl_cert.h" +#include "ssl_pkey.h" +#include "ssl_x509.h" +#include "ssl_dbg.h" +#include "ssl_port.h" + +/* + * ssl_cert_new - create a certification object include private key object + * + * @param none + * + * @return certification object point or NULL if failed + */ CERT *ssl_cert_new(void) { - return ssl_zalloc(sizeof(CERT)); + CERT *cert; + + cert = ssl_zalloc(sizeof(CERT)); + if (!cert) + SSL_RET(failed1, "ssl_zalloc\n"); + + cert->pkey = EVP_PKEY_new(); + if (!cert->pkey) + SSL_RET(failed2, "EVP_PKEY_new\n"); + + cert->x509 = sk_X509_NAME_new_null(); + if (!cert->x509) + SSL_RET(failed3, "sk_X509_NAME_new_null\n"); + + return cert; + +failed3: + EVP_PKEY_free(cert->pkey); +failed2: + ssl_free(cert); +failed1: + return NULL; } +/* + * ssl_cert_free - free a certification object + * + * @param c - certification object point + * + * @return none + */ void ssl_cert_free(CERT *c) { - if (c->x509) - X509_free(c->x509); + X509_free(c->x509); - if (c->pkey) - EVP_PKEY_free(c->pkey); + EVP_PKEY_free(c->pkey); ssl_free(c); } - -int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) -{ - SSL_ASSERT(ctx); - SSL_ASSERT(x); - - ctx->client_CA = x; - - return 1; -} diff --git a/components/openssl/library/ssl_lib.c b/components/openssl/library/ssl_lib.c index e1e112cc7b..331ed17bd5 100644 --- a/components/openssl/library/ssl_lib.c +++ b/components/openssl/library/ssl_lib.c @@ -1,11 +1,35 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #include "ssl_lib.h" #include "ssl_pkey.h" +#include "ssl_x509.h" #include "ssl_cert.h" #include "ssl_dbg.h" -#include "ssl_pm.h" +#include "ssl_port.h" #define SSL_SEND_DATA_MAX_LENGTH 1460 +/* + * ossl_statem_in_error - Discover whether the current connection is in the error state + * + * @param ssl - SSL point + * + * @return + * 1 : Yes + * 0 : no + */ int ossl_statem_in_error(const SSL *ssl) { if (ssl->statem.state == MSG_FLOW_ERROR) @@ -23,7 +47,7 @@ int ossl_statem_in_error(const SSL *ssl) */ int SSL_want(const SSL *ssl) { - return 0; + return ssl->rwstate; } /* @@ -131,7 +155,7 @@ OSSL_HANDSHAKE_STATE SSL_get_state(const SSL *ssl) SSL_ASSERT(ssl); - state = ssl->method->func->ssl_get_state(ssl); + state = SSL_METHOD_CALL(get_state, ssl); return state; } @@ -154,15 +178,15 @@ SSL_CTX* SSL_CTX_new(const SSL_METHOD *method) client_ca = sk_X509_NAME_new_null(); if (!client_ca) - SSL_ERR(-2, go_failed1, "ssl_ctx_new:ctx:[%d]\n", ret); + SSL_ERR(-2, go_failed1, "sk_X509_NAME_new_null\n"); cert = ssl_cert_new(); if (!cert) - SSL_ERR(-2, go_failed2, "ssl_ctx_new:ctx:[%d]\n", ret); + SSL_ERR(-2, go_failed2, "ssl_cert_new\n"); ctx = (SSL_CTX *)ssl_zalloc(sizeof(SSL_CTX)); if (!ctx) - SSL_ERR(-2, go_failed3, "ssl_ctx_new:ctx:[%d]\n", ret); + SSL_ERR(-2, go_failed3, "ssl_ctx_new:ctx\n"); ctx->method = method; ctx->cert = cert; @@ -215,6 +239,8 @@ int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth) ctx->method = meth; + ctx->version = meth->version; + return 1; } @@ -258,10 +284,12 @@ SSL *SSL_new(SSL_CTX *ctx) ssl->version = ctx->version; ssl->options = ctx->options; - ret = ssl->method->func->ssl_new(ssl); + ret = SSL_METHOD_CALL(new, ssl); if (ret) SSL_RET(failed2, "ssl_new\n"); + ssl->rwstate = SSL_NOTHING; + return ssl; failed2: @@ -281,7 +309,7 @@ void SSL_free(SSL *ssl) { SSL_ASSERT(ssl); - ssl->method->func->ssl_free(ssl); + SSL_METHOD_CALL(free, ssl); ssl_free(ssl); } @@ -302,7 +330,7 @@ int SSL_do_handshake(SSL *ssl) SSL_ASSERT(ssl); - ret = ssl->method->func->ssl_handshake(ssl); + ret = SSL_METHOD_CALL(handshake, ssl); return ret; } @@ -357,7 +385,7 @@ int SSL_shutdown(SSL *ssl) if (SSL_get_state(ssl) != TLS_ST_OK) return 0; - ret = ssl->method->func->ssl_shutdown(ssl); + ret = SSL_METHOD_CALL(shutdown, ssl); return ret; } @@ -381,9 +409,9 @@ int SSL_clear(SSL *ssl) if (1 != ret) SSL_ERR(0, go_failed1, "SSL_shutdown\n"); - ssl->method->func->ssl_free(ssl); + SSL_METHOD_CALL(free, ssl); - ret = ssl->method->func->ssl_new(ssl); + ret = SSL_METHOD_CALL(new, ssl); if (!ret) SSL_ERR(0, go_failed1, "ssl_new\n"); @@ -413,7 +441,11 @@ int SSL_read(SSL *ssl, void *buffer, int len) SSL_ASSERT(buffer); SSL_ASSERT(len); - ret = ssl->method->func->ssl_read(ssl, buffer, len); + ssl->rwstate = SSL_READING; + + ret = SSL_METHOD_CALL(read, ssl, buffer, len); + + ssl->rwstate = SSL_NOTHING; return ret; } @@ -440,6 +472,8 @@ int SSL_write(SSL *ssl, const void *buffer, int len) SSL_ASSERT(buffer); SSL_ASSERT(len); + ssl->rwstate = SSL_WRITING; + send_bytes = len; pbuf = (const unsigned char *)buffer; @@ -451,13 +485,15 @@ int SSL_write(SSL *ssl, const void *buffer, int len) else bytes = send_bytes; - ret = ssl->method->func->ssl_send(ssl, buffer, len); + ret = SSL_METHOD_CALL(send, ssl, buffer, len); if (ret > 0) { pbuf += ret; send_bytes -= ret; } } while (ret > 0 && send_bytes); + ssl->rwstate = SSL_NOTHING; + send_bytes = len - send_bytes; if (send_bytes >= 0) ret = send_bytes; @@ -518,11 +554,11 @@ int SSL_set_ssl_method(SSL *ssl, const SSL_METHOD *method) if (1 != ret) SSL_ERR(0, go_failed1, "SSL_shutdown\n"); - ssl->method->func->ssl_free(ssl); + SSL_METHOD_CALL(free, ssl); ssl->method = method; - ret = ssl->method->func->ssl_new(ssl); + ret = SSL_METHOD_CALL(new, ssl); if (!ret) SSL_ERR(0, go_failed1, "ssl_new\n"); } else { @@ -579,7 +615,7 @@ int SSL_pending(const SSL *ssl) SSL_ASSERT(ssl); - ret = ssl->method->func->ssl_pending(ssl); + ret = SSL_METHOD_CALL(pending, ssl); return ret; } @@ -705,7 +741,7 @@ int SSL_get_fd(const SSL *ssl) SSL_ASSERT(ssl); - ret = ssl->method->func->ssl_get_fd(ssl, 0); + ret = SSL_METHOD_CALL(get_fd, ssl, 0); return ret; } @@ -725,7 +761,7 @@ int SSL_get_rfd(const SSL *ssl) SSL_ASSERT(ssl); - ret = ssl->method->func->ssl_get_fd(ssl, 0); + ret = SSL_METHOD_CALL(get_fd, ssl, 0); return ret; } @@ -745,7 +781,7 @@ int SSL_get_wfd(const SSL *ssl) SSL_ASSERT(ssl); - ret = ssl->method->func->ssl_get_fd(ssl, 0); + ret = SSL_METHOD_CALL(get_fd, ssl, 0); return ret; } @@ -767,7 +803,7 @@ int SSL_set_fd(SSL *ssl, int fd) SSL_ASSERT(ssl); SSL_ASSERT(fd >= 0); - ssl->method->func->ssl_set_fd(ssl, fd, 0); + SSL_METHOD_CALL(set_fd, ssl, fd, 0); return 1; } @@ -789,7 +825,7 @@ int SSL_set_rfd(SSL *ssl, int fd) SSL_ASSERT(ssl); SSL_ASSERT(fd >= 0); - ssl->method->func->ssl_set_fd(ssl, fd, 0); + SSL_METHOD_CALL(set_fd, ssl, fd, 0); return 1; } @@ -811,7 +847,7 @@ int SSL_set_wfd(SSL *ssl, int fd) SSL_ASSERT(ssl); SSL_ASSERT(fd >= 0); - ssl->method->func->ssl_set_fd(ssl, fd, 0); + SSL_METHOD_CALL(set_fd, ssl, fd, 0); return 1; } @@ -1451,7 +1487,7 @@ void SSL_CTX_set_default_read_buffer_len(SSL_CTX *ctx, size_t len) SSL_ASSERT(ctx); SSL_ASSERT(len); - ctx->method->func->ssl_set_bufflen(NULL, len); + ctx->read_buffer_len = len; } /* @@ -1467,7 +1503,7 @@ void SSL_set_default_read_buffer_len(SSL *ssl, size_t len) SSL_ASSERT(ssl); SSL_ASSERT(len); - ssl->method->func->ssl_set_bufflen(ssl, len); + SSL_METHOD_CALL(set_bufflen, ssl, len); } /* @@ -1688,3 +1724,18 @@ long SSL_set_timeout(SSL *ssl, long t) return t; } + +/* + * SSL_set_verify - set the SSL verifying of the SSL context + * + * @param ctx - SSL point + * @param mode - verifying mode + * @param verify_callback - verifying callback function + * + * @return none + */ +void SSL_set_verify(SSL *ssl, int mode, int (*verify_callback)(int, X509_STORE_CTX *)) +{ + SSL_ASSERT(ssl); + SSL_ASSERT(verify_callback); +} diff --git a/components/openssl/library/ssl_methods.c b/components/openssl/library/ssl_methods.c index 502262f7e9..0c5c6e7fa4 100644 --- a/components/openssl/library/ssl_methods.c +++ b/components/openssl/library/ssl_methods.c @@ -1,7 +1,24 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #include "ssl_lib.h" #include "ssl_methods.h" #include "ssl_pm.h" +/* + * TLS method function collection + */ IMPLEMENT_TLS_METHOD_FUNC(TLS_method_func, ssl_pm_new, ssl_pm_free, ssl_pm_handshake, ssl_pm_shutdown, ssl_pm_clear, @@ -10,6 +27,9 @@ IMPLEMENT_TLS_METHOD_FUNC(TLS_method_func, ssl_pm_set_bufflen, ssl_pm_get_state); +/* + * TLS or SSL client method collection + */ IMPLEMENT_TLS_METHOD(TLS_ANY_VERSION, 0, TLS_method_func, TLS_client_method); IMPLEMENT_TLS_METHOD(TLS1_2_VERSION, 0, TLS_method_func, TLSv1_2_client_method); @@ -20,7 +40,9 @@ IMPLEMENT_TLS_METHOD(TLS1_VERSION, 0, TLS_method_func, TLSv1_client_method); IMPLEMENT_SSL_METHOD(SSL3_VERSION, 0, TLS_method_func, SSLv3_client_method); - +/* + * TLS or SSL server method collection + */ IMPLEMENT_TLS_METHOD(TLS_ANY_VERSION, 1, TLS_method_func, TLS_server_method); IMPLEMENT_TLS_METHOD(TLS1_1_VERSION, 1, TLS_method_func, TLSv1_1_server_method); @@ -31,7 +53,9 @@ IMPLEMENT_TLS_METHOD(TLS1_VERSION, 0, TLS_method_func, TLSv1_server_method); IMPLEMENT_SSL_METHOD(SSL3_VERSION, 1, TLS_method_func, SSLv3_server_method); - +/* + * TLS or SSL method collection + */ IMPLEMENT_TLS_METHOD(TLS_ANY_VERSION, -1, TLS_method_func, TLS_method); IMPLEMENT_SSL_METHOD(TLS1_2_VERSION, -1, TLS_method_func, TLSv1_2_method); @@ -41,3 +65,17 @@ IMPLEMENT_SSL_METHOD(TLS1_1_VERSION, -1, TLS_method_func, TLSv1_1_method); IMPLEMENT_SSL_METHOD(TLS1_VERSION, -1, TLS_method_func, TLSv1_method); IMPLEMENT_SSL_METHOD(SSL3_VERSION, -1, TLS_method_func, SSLv3_method); + +/* + * X509 certification method collection + */ +IMPLEMENT_X509_METHOD(X509_method, + x509_pm_new, x509_pm_free, + x509_pm_load, x509_pm_unload); + +/* + * private key method collection + */ +IMPLEMENT_PKEY_METHOD(EVP_PKEY_method, + pkey_pm_new, pkey_pm_free, + pkey_pm_load, pkey_pm_unload); diff --git a/components/openssl/library/ssl_pkey.c b/components/openssl/library/ssl_pkey.c index 2a170716c0..785ebf41db 100644 --- a/components/openssl/library/ssl_pkey.c +++ b/components/openssl/library/ssl_pkey.c @@ -1,50 +1,109 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #include "ssl_lib.h" #include "ssl_pkey.h" +#include "ssl_methods.h" #include "ssl_dbg.h" -#include "ssl_pm.h" +#include "ssl_port.h" -EVP_PKEY *d2i_PrivateKey(int type, - EVP_PKEY **a, - const unsigned char **pp, - long length) +/* + * EVP_PKEY_new - create a private key object + * + * @param none + * + * @return private key object point or NULL if failed + */ +EVP_PKEY* EVP_PKEY_new(void) { - EVP_PKEY *pkey; - void *pkey_pm; int ret; - - SSL_ASSERT(pp); - SSL_ASSERT(*pp); - SSL_ASSERT(length); + EVP_PKEY *pkey; pkey = ssl_malloc(sizeof(EVP_PKEY)); if (!pkey) SSL_RET(failed1, "ssl_malloc\n"); - pkey_pm = pkey_pm_new(); - if (!pkey_pm) - SSL_RET(failed2, "pkey_pm_new\n"); + pkey->method = EVP_PKEY_method(); - ret = pkey_pm_load_crt(pkey_pm, *pp, length); + ret = EVP_PKEY_METHOD_CALL(new, pkey); if (ret) - SSL_RET(failed3, "pkey_pm_load_crt\n"); - - pkey->pkey_pm = pkey_pm; - if (a) - *a = pkey; + SSL_RET(failed2, "pkey_new\n"); return pkey; -failed3: - pkey_pm_free(pkey_pm); failed2: ssl_free(pkey); failed1: return NULL; } -void EVP_PKEY_free(EVP_PKEY *x) +/* + * EVP_PKEY_free - free a private key object + * + * @param pkey - private key object point + * + * @return none + */ +void EVP_PKEY_free(EVP_PKEY *pkey) { - pkey_pm_unload_crt(x->pkey_pm); - pkey_pm_free(x->pkey_pm); - ssl_free(x); + EVP_PKEY_METHOD_CALL(free, pkey); + + ssl_free(pkey); +} + +/* + * d2i_PrivateKey - load a character key context into system context. If '*a' is pointed to the + * private key, then load key into it. Or create a new private key object + * + * @param type - private key type + * @param a - a point pointed to a private key point + * @param pp - a point pointed to the key context memory point + * @param length - key bytes + * + * @return private key object point or NULL if failed + */ +EVP_PKEY *d2i_PrivateKey(int type, + EVP_PKEY **a, + const unsigned char **pp, + long length) +{ + int ret; + EVP_PKEY *pkey; + + SSL_ASSERT(pp); + SSL_ASSERT(*pp); + SSL_ASSERT(length); + + if (a && *a) { + pkey = *a; + } else { + pkey = EVP_PKEY_new();; + if (!pkey) + SSL_RET(failed1, "ssl_malloc\n"); + } + + ret = EVP_PKEY_METHOD_CALL(load, pkey, *pp, length); + if (ret) + SSL_RET(failed2, "pkey_pm_load_crt\n"); + + if (a) + *a = pkey; + + return pkey; + +failed2: + EVP_PKEY_free(pkey); +failed1: + return NULL; } diff --git a/components/openssl/library/ssl_rsa.c b/components/openssl/library/ssl_rsa.c index 9088f67f57..75a2d3baa7 100644 --- a/components/openssl/library/ssl_rsa.c +++ b/components/openssl/library/ssl_rsa.c @@ -1,10 +1,33 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #include "ssl_lib.h" #include "ssl_rsa.h" #include "ssl_pkey.h" #include "ssl_x509.h" #include "ssl_dbg.h" -#include "ssl_pm.h" +/* + * SSL_CTX_use_certificate - set the SSL context certification + * + * @param ctx - SSL context point + * @param x - X509 certification point + * + * @return + * 1 : OK + * 0 : failed + */ int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) { SSL_ASSERT(ctx); @@ -15,13 +38,24 @@ int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) return 1; } +/* + * SSL_CTX_use_certificate_ASN1 - load certification into the SSL context + * + * @param ctx - SSL context point + * @param len - certification context bytes + * @param d - certification context point + * + * @return + * 1 : OK + * 0 : failed + */ int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d) { int ret; X509 *cert; - cert = d2i_X509(NULL, d, len); + cert = d2i_X509(&ctx->cert->x509, d, len); if (!cert) SSL_RET(failed1, "d2i_X509\n"); @@ -37,6 +71,16 @@ failed1: return 0; } +/* + * SSL_CTX_use_certificate - set the SSL context private key + * + * @param ctx - SSL context point + * @param x - private key point + * + * @return + * 1 : OK + * 0 : failed + */ int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) { SSL_ASSERT(ctx); @@ -47,13 +91,25 @@ int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) return 1; } +/* + * SSL_CTX_use_PrivateKey_ASN1 - load private key into the SSL context + * + * @param type - private key type + * @param ctx - SSL context point + * @param d - private key context point + * @param len - private key context bytes + * + * @return + * 1 : OK + * 0 : failed + */ int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const unsigned char *d, long len) { int ret; EVP_PKEY *pkey; - pkey = d2i_PrivateKey(0, NULL, &d, len); + pkey = d2i_PrivateKey(0, &ctx->cert->pkey, &d, len); if (!pkey) SSL_RET(failed1, "d2i_PrivateKey\n"); @@ -68,3 +124,23 @@ failed2: failed1: return 0; } + +/* + * SSL_CTX_add_client_CA - set SSL context client CA certification + * + * @param ctx - SSL context point + * @param x - client CA certification point + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) +{ + SSL_ASSERT(ctx); + SSL_ASSERT(x); + + ctx->client_CA = x; + + return 1; +} diff --git a/components/openssl/library/ssl_x509.c b/components/openssl/library/ssl_x509.c index 23aa00681e..fd2643e6b7 100644 --- a/components/openssl/library/ssl_x509.c +++ b/components/openssl/library/ssl_x509.c @@ -1,54 +1,100 @@ -#include "ssl_x509.h" -#include "ssl_dbg.h" -#include "ssl_pm.h" +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "ssl_x509.h" +#include "ssl_methods.h" +#include "ssl_dbg.h" +#include "ssl_port.h" + +/* + * sk_X509_NAME_new_null - create a X509 certification object + * + * @param none + * + * @return X509 certification object point or NULL if failed + */ X509* sk_X509_NAME_new_null(void) { - return ssl_malloc(sizeof(X509)); -} - -X509* d2i_X509(X509 **cert, const unsigned char *buffer, long len) -{ - X509 *x509_crt; - void *x509_pm; int ret; + X509 *x; - SSL_ASSERT(cert); - SSL_ASSERT(buffer); - SSL_ASSERT(len); + x = ssl_malloc(sizeof(X509)); + if (!x) + SSL_RET(failed1, "ssl_malloc\n"); - x509_crt = sk_X509_NAME_new_null(); - if (!x509_crt) - SSL_RET(failed1, ""); + x->method = X509_method(); - x509_pm = x509_pm_new(); - if (!x509_pm) - SSL_RET(failed2, ""); - - ret = x509_pm_load_crt(x509_pm, buffer, len); + ret = x->method->x509_new(x); if (ret) - SSL_RET(failed3, ""); + SSL_RET(failed2, "x509_new\n"); - x509_crt->x509_pm = x509_pm; - if (cert) - *cert = x509_crt; + return x; - return x509_crt; - -failed3: - x509_pm_free(x509_pm); failed2: - ssl_free(x509_crt); + ssl_free(x); failed1: return NULL; } -void X509_free(X509 *cert) +/* + * X509_free - free a X509 certification object + * + * @param x - X509 certification object point + * + * @return none + */ +void X509_free(X509 *x) { - if (cert->x509_pm) { - x509_pm_unload_crt(cert->x509_pm); - x509_pm_free(cert->x509_pm); - } - ssl_free(cert); + X509_METHOD_CALL(free, x); + + ssl_free(x); }; +/* + * d2i_X509 - load a character certification context into system context. If '*cert' is pointed to the + * certification, then load certification into it. Or create a new X509 certification object + * + * @param cert - a point pointed to X509 certification + * @param buffer - a point pointed to the certification context memory point + * @param length - certification bytes + * + * @return X509 certification object point or NULL if failed + */ +X509* d2i_X509(X509 **cert, const unsigned char *buffer, long len) +{ + int ret; + X509 *x; + + SSL_ASSERT(buffer); + SSL_ASSERT(len); + + if (cert && *cert) { + x = *cert; + } else { + x = sk_X509_NAME_new_null(); + if (!x) + SSL_RET(failed1, "sk_X509_NAME_new_null\n"); + } + + ret = X509_METHOD_CALL(load, x, buffer, len); + if (ret) + SSL_RET(failed2, "x509_load\n"); + + return x; + +failed2: + X509_free(x); +failed1: + return NULL; +} diff --git a/components/openssl/platform/ssl_pm.c b/components/openssl/platform/ssl_pm.c index 9d207b3a0e..b8a046aa1e 100644 --- a/components/openssl/platform/ssl_pm.c +++ b/components/openssl/platform/ssl_pm.c @@ -1,4 +1,19 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #include "ssl_pm.h" +#include "ssl_port.h" #include "ssl_dbg.h" #include @@ -30,11 +45,15 @@ struct ssl_pm struct x509_pm { + int load; + mbedtls_x509_crt x509_crt; }; struct pkey_pm { + int load; + mbedtls_pk_context pkey; }; @@ -42,44 +61,6 @@ struct pkey_pm unsigned int max_content_len; -/*********************************************************************************************/ -/********************************* SSL general interface *************************************/ - -void* ssl_zalloc(size_t size) -{ - void *p = malloc(size); - - if (p) - memset(p, 0, size); - - return p; -} - -void *ssl_malloc(size_t size) -{ - return ssl_zalloc(size); -} - -void ssl_free(void *p) -{ - free(p); -} - -void* ssl_memcpy(void *to, const void *from, size_t size) -{ - return memcpy(to, from, size); -} - -void ssl_speed_up_enter(void) -{ - -} - -void ssl_speed_up_exit(void) -{ - -} - /*********************************************************************************************/ /************************************ SSL arch interface *************************************/ @@ -90,13 +71,18 @@ int ssl_pm_new(SSL *ssl) char *pers; int endpoint; + int mode; + int version; SSL_CTX *ctx = ssl->ctx; const SSL_METHOD *method = ssl->method; - ssl_pm = malloc(sizeof(struct ssl_pm)); + struct x509_pm *x509_pm; + struct pkey_pm *pkey_pm; + + ssl_pm = ssl_malloc(sizeof(struct ssl_pm)); if (!ssl_pm) - return -1; + SSL_ERR(ret, failed1, "ssl_malloc\n"); if (method->endpoint) { pers = "server"; @@ -124,21 +110,34 @@ int ssl_pm_new(SSL *ssl) if (ret) SSL_ERR(ret, failed2, "mbedtls_ssl_config_defaults:[-0x%x]\n", -ret); + if (TLS1_2_VERSION == ssl->version) + version = MBEDTLS_SSL_MINOR_VERSION_3; + else if (TLS1_1_VERSION == ssl->version) + version = MBEDTLS_SSL_MINOR_VERSION_2; + else if (TLS1_VERSION == ssl->version) + version = MBEDTLS_SSL_MINOR_VERSION_1; + else + version = MBEDTLS_SSL_MINOR_VERSION_0; + + mbedtls_ssl_conf_max_version(&ssl_pm->conf, MBEDTLS_SSL_MAJOR_VERSION_3, version); + mbedtls_ssl_conf_rng(&ssl_pm->conf, mbedtls_ctr_drbg_random, &ssl_pm->ctr_drbg); + mbedtls_ssl_conf_dbg(&ssl_pm->conf, NULL, NULL); - if (ctx->client_CA->x509_pm) { - struct x509_pm *x509_pm = (struct x509_pm *)ctx->client_CA->x509_pm; + x509_pm = (struct x509_pm *)ctx->client_CA->x509_pm; + if (x509_pm->load) { + mbedtls_ssl_conf_ca_chain(&ssl_pm->conf, &x509_pm->x509_crt, NULL); - mbedtls_ssl_conf_ca_chain(&ssl_pm->conf, &x509_pm->x509_crt, NULL); - mbedtls_ssl_conf_authmode(&ssl_pm->conf, MBEDTLS_SSL_VERIFY_REQUIRED); + mode = MBEDTLS_SSL_VERIFY_REQUIRED; } else { - mbedtls_ssl_conf_authmode(&ssl_pm->conf, MBEDTLS_SSL_VERIFY_NONE); + mode = MBEDTLS_SSL_VERIFY_NONE; } - if (ctx->cert->x509 && - ctx->cert->pkey) { - struct x509_pm *x509_pm = (struct x509_pm *)ctx->cert->x509->x509_pm; - struct pkey_pm *pkey_pm = (struct pkey_pm *)ctx->cert->pkey->pkey_pm; + mbedtls_ssl_conf_authmode(&ssl_pm->conf, mode); + + pkey_pm = (struct pkey_pm *)ctx->cert->pkey->pkey_pm; + if (pkey_pm->load) { + x509_pm = (struct x509_pm *)ctx->cert->x509->x509_pm; ret = mbedtls_ssl_conf_own_cert(&ssl_pm->conf, &x509_pm->x509_crt, &pkey_pm->pkey); if (ret) @@ -332,21 +331,24 @@ OSSL_HANDSHAKE_STATE ssl_pm_get_state(const SSL *ssl) return state; } -void* x509_pm_new(void) +int x509_pm_new(X509 *x) { - return ssl_malloc(sizeof(struct x509_pm)); + struct x509_pm *x509_pm; + + x509_pm = ssl_malloc(sizeof(struct x509_pm)); + if (!x509_pm) + return -1; + + x->x509_pm = x509_pm; + + return 0; } -void x509_pm_free(void *pm) -{ - ssl_free(pm); -} - -int x509_pm_load_crt(void *pm, const unsigned char *buffer, int len) +int x509_pm_load(X509 *x, const unsigned char *buffer, int len) { int ret; unsigned char *load_buf; - struct x509_pm *x509_pm = (struct x509_pm *)pm; + struct x509_pm *x509_pm = (struct x509_pm *)x->x509_pm; load_buf = ssl_malloc(len + 1); if (!load_buf) @@ -362,34 +364,48 @@ int x509_pm_load_crt(void *pm, const unsigned char *buffer, int len) if (ret) SSL_RET(failed1, ""); + x509_pm->load = 1; + return 0; failed1: return -1; } -void x509_pm_unload_crt(void *pm) +void x509_pm_unload(X509 *x) { - struct x509_pm *x509_pm = (struct x509_pm *)pm; + struct x509_pm *x509_pm = (struct x509_pm *)x->x509_pm; mbedtls_x509_crt_free(&x509_pm->x509_crt); + + x509_pm->load = 0; } -void* pkey_pm_new(void) +void x509_pm_free(X509 *x) { - return ssl_malloc(sizeof(struct pkey_pm)); + x509_pm_unload(x); + + ssl_free(x->x509_pm); } -void pkey_pm_free(void *pm) +int pkey_pm_new(EVP_PKEY *pkey) { - ssl_free(pm); + struct pkey_pm *pkey_pm; + + pkey_pm = ssl_malloc(sizeof(struct pkey_pm)); + if (!pkey_pm) + return -1; + + pkey->pkey_pm = pkey_pm; + + return 0; } -int pkey_pm_load_crt(void *pm, const unsigned char *buffer, int len) +int pkey_pm_load(EVP_PKEY *pkey, const unsigned char *buffer, int len) { int ret; unsigned char *load_buf; - struct pkey_pm *pkey_pm = (struct pkey_pm *)pm; + struct pkey_pm *pkey_pm = (struct pkey_pm *)pkey->pkey_pm; load_buf = ssl_malloc(len + 1); if (!load_buf) @@ -405,17 +421,28 @@ int pkey_pm_load_crt(void *pm, const unsigned char *buffer, int len) if (ret) SSL_RET(failed1, ""); + pkey_pm->load = 1; + return 0; failed1: return -1; } -void pkey_pm_unload_crt(void *pm) +void pkey_pm_unload(EVP_PKEY *pkey) { - struct pkey_pm *pkey_pm = (struct pkey_pm *)pm; + struct pkey_pm *pkey_pm = (struct pkey_pm *)pkey->pkey_pm; mbedtls_pk_free(&pkey_pm->pkey); + + pkey_pm->load = 0; +} + +void pkey_pm_free(EVP_PKEY *pkey) +{ + pkey_pm_unload(pkey); + + ssl_free(pkey->pkey_pm); } void ssl_pm_set_bufflen(SSL *ssl, int len) diff --git a/components/openssl/platform/ssl_port.c b/components/openssl/platform/ssl_port.c index 66aac5f6d9..4045e29116 100644 --- a/components/openssl/platform/ssl_port.c +++ b/components/openssl/platform/ssl_port.c @@ -1,17 +1,16 @@ -/* Copyright 2015-2016 Espressif Systems (Wuxi) PTE LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. #include #include "ssl_port.h" From 845ca8b34ffce008f8992b5799964da14209739f Mon Sep 17 00:00:00 2001 From: dongheng Date: Thu, 22 Sep 2016 11:43:59 +0800 Subject: [PATCH 006/343] components/openssl: delete ssl_rsa.c & .h file --- components/openssl/include/internal/ssl_rsa.h | 28 ---- .../openssl/include/platform/ssl_port.h | 2 + components/openssl/library/ssl_pkey.c | 55 +++++++ components/openssl/library/ssl_rsa.c | 146 ------------------ components/openssl/library/ssl_x509.c | 74 +++++++++ components/openssl/platform/ssl_pm.c | 23 ++- components/openssl/platform/ssl_port.c | 7 +- 7 files changed, 146 insertions(+), 189 deletions(-) delete mode 100644 components/openssl/include/internal/ssl_rsa.h delete mode 100644 components/openssl/library/ssl_rsa.c diff --git a/components/openssl/include/internal/ssl_rsa.h b/components/openssl/include/internal/ssl_rsa.h deleted file mode 100644 index d0ce40312c..0000000000 --- a/components/openssl/include/internal/ssl_rsa.h +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef _SSL_RSA_H_ -#define _SSL_RSA_H_ - -#include "ssl_lib.h" - -int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x); -int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, - const unsigned char *d); - -int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey); -int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, - const unsigned char *d, long len); - -#endif diff --git a/components/openssl/include/platform/ssl_port.h b/components/openssl/include/platform/ssl_port.h index 48a7c7ca97..23ef5a8757 100644 --- a/components/openssl/include/platform/ssl_port.h +++ b/components/openssl/include/platform/ssl_port.h @@ -20,7 +20,9 @@ void* ssl_zalloc(size_t size); void *ssl_malloc(size_t size); void ssl_free(void *p); + void* ssl_memcpy(void *to, const void *from, size_t size); +size_t ssl_strlen(const char *src); void ssl_speed_up_enter(void); void ssl_speed_up_exit(void); diff --git a/components/openssl/library/ssl_pkey.c b/components/openssl/library/ssl_pkey.c index 785ebf41db..0c8d9de8fa 100644 --- a/components/openssl/library/ssl_pkey.c +++ b/components/openssl/library/ssl_pkey.c @@ -107,3 +107,58 @@ failed2: failed1: return NULL; } + +/* + * SSL_CTX_use_certificate - set the SSL context private key + * + * @param ctx - SSL context point + * @param x - private key point + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) +{ + SSL_ASSERT(ctx); + SSL_ASSERT(pkey); + + ctx->cert->pkey = pkey; + + return 1; +} + +/* + * SSL_CTX_use_PrivateKey_ASN1 - load private key into the SSL context + * + * @param type - private key type + * @param ctx - SSL context point + * @param d - private key context point + * @param len - private key context bytes + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, + const unsigned char *d, long len) +{ + int ret; + EVP_PKEY *pkey; + + pkey = d2i_PrivateKey(0, &ctx->cert->pkey, &d, len); + if (!pkey) + SSL_RET(failed1, "d2i_PrivateKey\n"); + + ret = SSL_CTX_use_PrivateKey(ctx, pkey); + if (!ret) + SSL_RET(failed2, "SSL_CTX_use_PrivateKey\n"); + + return 1; + +failed2: + EVP_PKEY_free(pkey); +failed1: + return 0; +} + diff --git a/components/openssl/library/ssl_rsa.c b/components/openssl/library/ssl_rsa.c deleted file mode 100644 index 75a2d3baa7..0000000000 --- a/components/openssl/library/ssl_rsa.c +++ /dev/null @@ -1,146 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "ssl_lib.h" -#include "ssl_rsa.h" -#include "ssl_pkey.h" -#include "ssl_x509.h" -#include "ssl_dbg.h" - -/* - * SSL_CTX_use_certificate - set the SSL context certification - * - * @param ctx - SSL context point - * @param x - X509 certification point - * - * @return - * 1 : OK - * 0 : failed - */ -int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) -{ - SSL_ASSERT(ctx); - SSL_ASSERT(x); - - ctx->cert->x509 = x; - - return 1; -} - -/* - * SSL_CTX_use_certificate_ASN1 - load certification into the SSL context - * - * @param ctx - SSL context point - * @param len - certification context bytes - * @param d - certification context point - * - * @return - * 1 : OK - * 0 : failed - */ -int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, - const unsigned char *d) -{ - int ret; - X509 *cert; - - cert = d2i_X509(&ctx->cert->x509, d, len); - if (!cert) - SSL_RET(failed1, "d2i_X509\n"); - - ret = SSL_CTX_use_certificate(ctx, cert); - if (!ret) - SSL_RET(failed2, "SSL_CTX_use_certificate\n"); - - return 1; - -failed2: - X509_free(cert); -failed1: - return 0; -} - -/* - * SSL_CTX_use_certificate - set the SSL context private key - * - * @param ctx - SSL context point - * @param x - private key point - * - * @return - * 1 : OK - * 0 : failed - */ -int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) -{ - SSL_ASSERT(ctx); - SSL_ASSERT(pkey); - - ctx->cert->pkey = pkey; - - return 1; -} - -/* - * SSL_CTX_use_PrivateKey_ASN1 - load private key into the SSL context - * - * @param type - private key type - * @param ctx - SSL context point - * @param d - private key context point - * @param len - private key context bytes - * - * @return - * 1 : OK - * 0 : failed - */ -int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, - const unsigned char *d, long len) -{ - int ret; - EVP_PKEY *pkey; - - pkey = d2i_PrivateKey(0, &ctx->cert->pkey, &d, len); - if (!pkey) - SSL_RET(failed1, "d2i_PrivateKey\n"); - - ret = SSL_CTX_use_PrivateKey(ctx, pkey); - if (!ret) - SSL_RET(failed2, "SSL_CTX_use_PrivateKey\n"); - - return 1; - -failed2: - EVP_PKEY_free(pkey); -failed1: - return 0; -} - -/* - * SSL_CTX_add_client_CA - set SSL context client CA certification - * - * @param ctx - SSL context point - * @param x - client CA certification point - * - * @return - * 1 : OK - * 0 : failed - */ -int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) -{ - SSL_ASSERT(ctx); - SSL_ASSERT(x); - - ctx->client_CA = x; - - return 1; -} diff --git a/components/openssl/library/ssl_x509.c b/components/openssl/library/ssl_x509.c index fd2643e6b7..219f283991 100644 --- a/components/openssl/library/ssl_x509.c +++ b/components/openssl/library/ssl_x509.c @@ -98,3 +98,77 @@ failed2: failed1: return NULL; } + +/* + * SSL_CTX_add_client_CA - set SSL context client CA certification + * + * @param ctx - SSL context point + * @param x - client CA certification point + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) +{ + SSL_ASSERT(ctx); + SSL_ASSERT(x); + + ctx->client_CA = x; + + return 1; +} + +/* + * SSL_CTX_use_certificate - set the SSL context certification + * + * @param ctx - SSL context point + * @param x - X509 certification point + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) +{ + SSL_ASSERT(ctx); + SSL_ASSERT(x); + + ctx->cert->x509 = x; + + return 1; +} + +/* + * SSL_CTX_use_certificate_ASN1 - load certification into the SSL context + * + * @param ctx - SSL context point + * @param len - certification context bytes + * @param d - certification context point + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, + const unsigned char *d) +{ + int ret; + X509 *cert; + + cert = d2i_X509(&ctx->cert->x509, d, len); + if (!cert) + SSL_RET(failed1, "d2i_X509\n"); + + ret = SSL_CTX_use_certificate(ctx, cert); + if (!ret) + SSL_RET(failed2, "SSL_CTX_use_certificate\n"); + + return 1; + +failed2: + X509_free(cert); +failed1: + return 0; +} + diff --git a/components/openssl/platform/ssl_pm.c b/components/openssl/platform/ssl_pm.c index b8a046aa1e..948c1bc4ee 100644 --- a/components/openssl/platform/ssl_pm.c +++ b/components/openssl/platform/ssl_pm.c @@ -16,8 +16,6 @@ #include "ssl_port.h" #include "ssl_dbg.h" -#include - /* mbedtls include */ #include "mbedtls/platform.h" #include "mbedtls/net.h" @@ -69,7 +67,9 @@ int ssl_pm_new(SSL *ssl) struct ssl_pm *ssl_pm; int ret; - char *pers; + const unsigned char pers[] = "OpenSSL PM"; + size_t pers_len = sizeof(pers); + int endpoint; int mode; int version; @@ -84,16 +84,6 @@ int ssl_pm_new(SSL *ssl) if (!ssl_pm) SSL_ERR(ret, failed1, "ssl_malloc\n"); - if (method->endpoint) { - pers = "server"; - endpoint = MBEDTLS_SSL_IS_SERVER; - } else { - pers = "client"; - endpoint = MBEDTLS_SSL_IS_CLIENT; - } - - //max_content_len = 4096; - mbedtls_net_init(&ssl_pm->fd); mbedtls_net_init(&ssl_pm->cl_fd); @@ -102,10 +92,15 @@ int ssl_pm_new(SSL *ssl) mbedtls_entropy_init(&ssl_pm->entropy); mbedtls_ssl_init(&ssl_pm->ssl); - ret = mbedtls_ctr_drbg_seed(&ssl_pm->ctr_drbg, mbedtls_entropy_func, &ssl_pm->entropy, (const unsigned char *)pers, strlen(pers)); + ret = mbedtls_ctr_drbg_seed(&ssl_pm->ctr_drbg, mbedtls_entropy_func, &ssl_pm->entropy, pers, pers_len); if (ret) SSL_ERR(ret, failed1, "mbedtls_ctr_drbg_seed:[-0x%x]\n", -ret); + if (method->endpoint) { + endpoint = MBEDTLS_SSL_IS_SERVER; + } else { + endpoint = MBEDTLS_SSL_IS_CLIENT; + } ret = mbedtls_ssl_config_defaults(&ssl_pm->conf, endpoint, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT); if (ret) SSL_ERR(ret, failed2, "mbedtls_ssl_config_defaults:[-0x%x]\n", -ret); diff --git a/components/openssl/platform/ssl_port.c b/components/openssl/platform/ssl_port.c index 4045e29116..3e6ada5cc9 100644 --- a/components/openssl/platform/ssl_port.c +++ b/components/openssl/platform/ssl_port.c @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include #include "ssl_port.h" +#include "string.h" #include "malloc.h" /*********************************************************************************************/ @@ -44,6 +44,11 @@ void* ssl_memcpy(void *to, const void *from, size_t size) return memcpy(to, from, size); } +size_t ssl_strlen(const char *src) +{ + return strlen(src); +} + void ssl_speed_up_enter(void) { From c504fe4856ed259b995dc1eb3cfa72b7dade21aa Mon Sep 17 00:00:00 2001 From: dongheng Date: Thu, 22 Sep 2016 12:57:39 +0800 Subject: [PATCH 007/343] components/openssl: 1. add stack_st structure and its advanced defination including its derived child defination 2. add SSL_add_client_CA & SSL_get_certificate --- .../openssl/include/internal/ssl_types.h | 19 +++++++++++-- .../openssl/include/internal/ssl_x509.h | 2 ++ components/openssl/library/ssl_x509.c | 27 +++++++++++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/components/openssl/include/internal/ssl_types.h b/components/openssl/include/internal/ssl_types.h index 417350627c..7f8503e2ab 100644 --- a/components/openssl/include/internal/ssl_types.h +++ b/components/openssl/include/internal/ssl_types.h @@ -20,7 +20,6 @@ typedef void SSL_CIPHER; typedef void X509_STORE_CTX; -typedef void X509_NAME; typedef void X509_STORE; typedef void RSA; @@ -28,7 +27,19 @@ typedef void RSA; typedef void STACK; typedef void BIO; -#define STACK_OF(x) x +#define STACK_OF(type) struct stack_st_##type + +#define SKM_DEFINE_STACK_OF(t1, t2, t3) \ + STACK_OF(t1); \ + static ossl_inline STACK_OF(t1) *sk_##t1##_new_null(void) \ + { \ + return (STACK_OF(t1) *)OPENSSL_sk_new_null(); \ + } \ + +#define DEFINE_STACK_OF(t) SKM_DEFINE_STACK_OF(t, t, t) + +struct stack_st; +typedef struct stack_st OPENSSL_STACK; struct ssl_method_st; typedef struct ssl_method_st SSL_METHOD; @@ -66,6 +77,10 @@ typedef struct x509_method_st X509_METHOD; struct pkey_method_st; typedef struct pkey_method_st PKEY_METHOD; +struct stack_st { + char *data; +}; + struct evp_pkey_st { void *pkey_pm; diff --git a/components/openssl/include/internal/ssl_x509.h b/components/openssl/include/internal/ssl_x509.h index a169352bac..0583cd94e4 100644 --- a/components/openssl/include/internal/ssl_x509.h +++ b/components/openssl/include/internal/ssl_x509.h @@ -17,6 +17,8 @@ #include "ssl_types.h" +DEFINE_STACK_OF(X509_NAME) + X509* sk_X509_NAME_new_null(void); X509* d2i_X509(X509 **cert, const unsigned char *buffer, long len); diff --git a/components/openssl/library/ssl_x509.c b/components/openssl/library/ssl_x509.c index 219f283991..e322b6ad3d 100644 --- a/components/openssl/library/ssl_x509.c +++ b/components/openssl/library/ssl_x509.c @@ -119,6 +119,21 @@ int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) return 1; } +/* + * SSL_add_client_CA - add CA client certification into the SSL + * + * @param ssl - SSL point + * @param x - CA certification point + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_add_client_CA(SSL *ssl, X509 *x) +{ + +} + /* * SSL_CTX_use_certificate - set the SSL context certification * @@ -139,6 +154,18 @@ int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) return 1; } +/* + * SSL_get_certificate - get the SSL certification point + * + * @param ssl - SSL point + * + * @return SSL certification point + */ +X509 *SSL_get_certificate(const SSL *ssl) +{ + return ssl->cert->x509; +} + /* * SSL_CTX_use_certificate_ASN1 - load certification into the SSL context * From 01d17dd5f9f9c87f0a90aea328ccff74e319999a Mon Sep 17 00:00:00 2001 From: daniel Date: Thu, 22 Sep 2016 12:20:56 +0800 Subject: [PATCH 008/343] Backport the static allocation feature from FreeRTOS V9.0.0 This feature allows to use static buffers (or from a pool of memory which is not controlled by FreeRTOS). In order to reduce the impact of the changes, the static feature has only been added to the queus (and in consequence to the semaphores and the mutexes) and the tasks. The Timer task is always dynamically allocated and also the idle task(s), which in the case of the ESP-IDF is ok, since we always need to have dynamic allocation enabled. --- .../freertos/include/freertos/FreeRTOS.h | 162 ++++ .../include/freertos/FreeRTOSConfig.h | 2 + components/freertos/include/freertos/queue.h | 110 ++- components/freertos/include/freertos/semphr.h | 382 +++++++- components/freertos/include/freertos/task.h | 161 +++- components/freertos/queue.c | 351 +++++--- components/freertos/tasks.c | 839 +++++++++++------- 7 files changed, 1523 insertions(+), 484 deletions(-) diff --git a/components/freertos/include/freertos/FreeRTOS.h b/components/freertos/include/freertos/FreeRTOS.h index 04b39b65e9..f6c9aa497d 100644 --- a/components/freertos/include/freertos/FreeRTOS.h +++ b/components/freertos/include/freertos/FreeRTOS.h @@ -74,6 +74,7 @@ * Include the generic headers required for the FreeRTOS port being used. */ #include +#include "sys/reent.h" /* * If stdint.h cannot be located then: @@ -739,6 +740,20 @@ extern "C" { #define portTICK_TYPE_IS_ATOMIC 0 #endif +#ifndef configSUPPORT_STATIC_ALLOCATION + /* Defaults to 0 for backward compatibility. */ + #define configSUPPORT_STATIC_ALLOCATION 0 +#endif + +#ifndef configSUPPORT_DYNAMIC_ALLOCATION + /* Defaults to 1 for backward compatibility. */ + #define configSUPPORT_DYNAMIC_ALLOCATION 1 +#endif + +#if( ( configSUPPORT_STATIC_ALLOCATION == 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) ) + #error configSUPPORT_STATIC_ALLOCATION and configSUPPORT_DYNAMIC_ALLOCATION cannot both be 0, but can both be 1. +#endif + #if( portTICK_TYPE_IS_ATOMIC == 0 ) /* Either variables of tick type cannot be read atomically, or portTICK_TYPE_IS_ATOMIC was not set - map the critical sections used when @@ -791,6 +806,153 @@ V8 if desired. */ #define configESP32_PER_TASK_DATA 1 #endif +/* + * In line with software engineering best practice, FreeRTOS implements a strict + * data hiding policy, so the real structures used by FreeRTOS to maintain the + * state of tasks, queues, semaphores, etc. are not accessible to the application + * code. However, if the application writer wants to statically allocate such + * an object then the size of the object needs to be know. Dummy structures + * that are guaranteed to have the same size and alignment requirements of the + * real objects are used for this purpose. The dummy list and list item + * structures below are used for inclusion in such a dummy structure. + */ +struct xSTATIC_LIST_ITEM +{ + TickType_t xDummy1; + void *pvDummy2[ 4 ]; +}; +typedef struct xSTATIC_LIST_ITEM StaticListItem_t; + +/* See the comments above the struct xSTATIC_LIST_ITEM definition. */ +struct xSTATIC_MINI_LIST_ITEM +{ + TickType_t xDummy1; + void *pvDummy2[ 2 ]; +}; +typedef struct xSTATIC_MINI_LIST_ITEM StaticMiniListItem_t; + +/* See the comments above the struct xSTATIC_LIST_ITEM definition. */ +typedef struct xSTATIC_LIST +{ + UBaseType_t uxDummy1; + void *pvDummy2; + StaticMiniListItem_t xDummy3; +} StaticList_t; + +/* + * In line with software engineering best practice, especially when supplying a + * library that is likely to change in future versions, FreeRTOS implements a + * strict data hiding policy. This means the Task structure used internally by + * FreeRTOS is not accessible to application code. However, if the application + * writer wants to statically allocate the memory required to create a task then + * the size of the task object needs to be know. The StaticTask_t structure + * below is provided for this purpose. Its sizes and alignment requirements are + * guaranteed to match those of the genuine structure, no matter which + * architecture is being used, and no matter how the values in FreeRTOSConfig.h + * are set. Its contents are somewhat obfuscated in the hope users will + * recognise that it would be unwise to make direct use of the structure members. + */ +typedef struct xSTATIC_TCB +{ + void *pxDummy1; + #if ( portUSING_MPU_WRAPPERS == 1 ) + xMPU_SETTINGS xDummy2; + #endif + StaticListItem_t xDummy3[ 2 ]; + UBaseType_t uxDummy5; + void *pxDummy6; + uint8_t ucDummy7[ configMAX_TASK_NAME_LEN ]; + UBaseType_t uxDummyCoreId; + #if ( portSTACK_GROWTH > 0 ) + void *pxDummy8; + #endif + #if ( portCRITICAL_NESTING_IN_TCB == 1 ) + UBaseType_t uxDummy9; + uint32_t OldInterruptState; + #endif + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy10[ 2 ]; + #endif + #if ( configUSE_MUTEXES == 1 ) + UBaseType_t uxDummy12[ 2 ]; + #endif + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + void *pxDummy14; + #endif + #if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) + void *pvDummy15[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ]; + #if ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS ) + void *pvDummyLocalStorageCallBack[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ]; + #endif + #endif + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + uint32_t ulDummy16; + #endif + #if ( configUSE_NEWLIB_REENTRANT == 1 ) + struct _reent xDummy17; + #endif + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + uint32_t ulDummy18; + uint32_t ucDummy19; + #endif + #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + uint8_t uxDummy20; + #endif + +} StaticTask_t; + +/* + * In line with software engineering best practice, especially when supplying a + * library that is likely to change in future versions, FreeRTOS implements a + * strict data hiding policy. This means the Queue structure used internally by + * FreeRTOS is not accessible to application code. However, if the application + * writer wants to statically allocate the memory required to create a queue + * then the size of the queue object needs to be know. The StaticQueue_t + * structure below is provided for this purpose. Its sizes and alignment + * requirements are guaranteed to match those of the genuine structure, no + * matter which architecture is being used, and no matter how the values in + * FreeRTOSConfig.h are set. Its contents are somewhat obfuscated in the hope + * users will recognise that it would be unwise to make direct use of the + * structure members. + */ +typedef struct xSTATIC_QUEUE +{ + void *pvDummy1[ 3 ]; + + union + { + void *pvDummy2; + UBaseType_t uxDummy2; + } u; + + StaticList_t xDummy3[ 2 ]; + UBaseType_t uxDummy4[ 3 ]; + BaseType_t ucDummy5[ 2 ]; + + #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + uint8_t ucDummy6; + #endif + + #if ( configUSE_QUEUE_SETS == 1 ) + void *pvDummy7; + #endif + + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy8; + uint8_t ucDummy9; + #endif + + struct { + volatile uint32_t mux; + #ifdef CONFIG_FREERTOS_PORTMUX_DEBUG + const char *lastLockedFn; + int lastLockedLine; + #endif + } mux; + +} StaticQueue_t; +typedef StaticQueue_t StaticSemaphore_t; + #ifdef __cplusplus } #endif diff --git a/components/freertos/include/freertos/FreeRTOSConfig.h b/components/freertos/include/freertos/FreeRTOSConfig.h index 089d799dda..f3f2df73cf 100644 --- a/components/freertos/include/freertos/FreeRTOSConfig.h +++ b/components/freertos/include/freertos/FreeRTOSConfig.h @@ -241,6 +241,8 @@ #define configUSE_NEWLIB_REENTRANT 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 1 + /* Test FreeRTOS timers (with timer task) and more. */ /* Some files don't compile if this flag is disabled */ #define configUSE_TIMERS 1 diff --git a/components/freertos/include/freertos/queue.h b/components/freertos/include/freertos/queue.h index 2095c59b0c..876f1a1b30 100644 --- a/components/freertos/include/freertos/queue.h +++ b/components/freertos/include/freertos/queue.h @@ -170,7 +170,95 @@ typedef void * QueueSetMemberHandle_t; * \defgroup xQueueCreate xQueueCreate * \ingroup QueueManagement */ -#define xQueueCreate( uxQueueLength, uxItemSize ) xQueueGenericCreate( uxQueueLength, uxItemSize, queueQUEUE_TYPE_BASE ) +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + #define xQueueCreate( uxQueueLength, uxItemSize ) xQueueGenericCreate( ( uxQueueLength ), ( uxItemSize ), ( queueQUEUE_TYPE_BASE ) ) +#endif + +/** + * queue. h + *
+ QueueHandle_t xQueueCreateStatic(
+							  UBaseType_t uxQueueLength,
+							  UBaseType_t uxItemSize,
+							  uint8_t *pucQueueStorageBuffer,
+							  StaticQueue_t *pxQueueBuffer
+						  );
+ * 
+ * + * Creates a new queue instance, and returns a handle by which the new queue + * can be referenced. + * + * Internally, within the FreeRTOS implementation, queues use two blocks of + * memory. The first block is used to hold the queue's data structures. The + * second block is used to hold items placed into the queue. If a queue is + * created using xQueueCreate() then both blocks of memory are automatically + * dynamically allocated inside the xQueueCreate() function. (see + * http://www.freertos.org/a00111.html). If a queue is created using + * xQueueCreateStatic() then the application writer must provide the memory that + * will get used by the queue. xQueueCreateStatic() therefore allows a queue to + * be created without using any dynamic memory allocation. + * + * http://www.FreeRTOS.org/Embedded-RTOS-Queues.html + * + * @param uxQueueLength The maximum number of items that the queue can contain. + * + * @param uxItemSize The number of bytes each item in the queue will require. + * Items are queued by copy, not by reference, so this is the number of bytes + * that will be copied for each posted item. Each item on the queue must be + * the same size. + * + * @param pucQueueStorageBuffer If uxItemSize is not zero then + * pucQueueStorageBuffer must point to a uint8_t array that is at least large + * enough to hold the maximum number of items that can be in the queue at any + * one time - which is ( uxQueueLength * uxItemsSize ) bytes. If uxItemSize is + * zero then pucQueueStorageBuffer can be NULL. + * + * @param pxQueueBuffer Must point to a variable of type StaticQueue_t, which + * will be used to hold the queue's data structure. + * + * @return If the queue is created then a handle to the created queue is + * returned. If pxQueueBuffer is NULL then NULL is returned. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ };
+
+ #define QUEUE_LENGTH 10
+ #define ITEM_SIZE sizeof( uint32_t )
+
+ // xQueueBuffer will hold the queue structure.
+ StaticQueue_t xQueueBuffer;
+
+ // ucQueueStorage will hold the items posted to the queue.  Must be at least
+ // [(queue length) * ( queue item size)] bytes long.
+ uint8_t ucQueueStorage[ QUEUE_LENGTH * ITEM_SIZE ];
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1;
+
+	// Create a queue capable of containing 10 uint32_t values.
+	xQueue1 = xQueueCreate( QUEUE_LENGTH, // The number of items the queue can hold.
+							ITEM_SIZE	  // The size of each item in the queue
+							&( ucQueueStorage[ 0 ] ), // The buffer that will hold the items in the queue.
+							&xQueueBuffer ); // The buffer that will hold the queue structure.
+
+	// The queue is guaranteed to be created successfully as no dynamic memory
+	// allocation is used.  Therefore xQueue1 is now a handle to a valid queue.
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueCreateStatic xQueueCreateStatic + * \ingroup QueueManagement + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + #define xQueueCreateStatic( uxQueueLength, uxItemSize, pucQueueStorage, pxQueueBuffer ) xQueueGenericCreateStatic( ( uxQueueLength ), ( uxItemSize ), ( pucQueueStorage ), ( pxQueueBuffer ), ( queueQUEUE_TYPE_BASE ) ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ /** * queue. h @@ -1479,7 +1567,9 @@ BaseType_t xQueueCRReceive( QueueHandle_t xQueue, void *pvBuffer, TickType_t xTi * these functions directly. */ QueueHandle_t xQueueCreateMutex( const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; +QueueHandle_t xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue ) PRIVILEGED_FUNCTION; QueueHandle_t xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount ) PRIVILEGED_FUNCTION; +QueueHandle_t xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue ) PRIVILEGED_FUNCTION; void* xQueueGetMutexHolder( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION; /* @@ -1538,10 +1628,22 @@ BaseType_t xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) PRIVILEGED_FUNCTION #endif /* - * Generic version of the queue creation function, which is in turn called by - * any queue, semaphore or mutex creation function or macro. + * Generic version of the function used to creaet a queue using dynamic memory + * allocation. This is called by other functions and macros that create other + * RTOS objects that use the queue structure as their base. */ -QueueHandle_t xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + QueueHandle_t xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; +#endif + +/* + * Generic version of the function used to creaet a queue using dynamic memory + * allocation. This is called by other functions and macros that create other + * RTOS objects that use the queue structure as their base. + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + QueueHandle_t xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; +#endif /* * Queue sets provide a mechanism to allow a task to block (pend) on a read diff --git a/components/freertos/include/freertos/semphr.h b/components/freertos/include/freertos/semphr.h index 5866ab1ec5..6343d0190a 100644 --- a/components/freertos/include/freertos/semphr.h +++ b/components/freertos/include/freertos/semphr.h @@ -128,19 +128,37 @@ typedef QueueHandle_t SemaphoreHandle_t; * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary * \ingroup Semaphores */ -#define vSemaphoreCreateBinary( xSemaphore ) \ - { \ - ( xSemaphore ) = xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ); \ - if( ( xSemaphore ) != NULL ) \ - { \ - ( void ) xSemaphoreGive( ( xSemaphore ) ); \ - } \ - } +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + #define vSemaphoreCreateBinary( xSemaphore ) \ + { \ + ( xSemaphore ) = xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ); \ + if( ( xSemaphore ) != NULL ) \ + { \ + ( void ) xSemaphoreGive( ( xSemaphore ) ); \ + } \ + } +#endif /** * semphr. h *
SemaphoreHandle_t xSemaphoreCreateBinary( void )
* + * Creates a new binary semaphore instance, and returns a handle by which the + * new semaphore can be referenced. + * + * In many usage scenarios it is faster and more memory efficient to use a + * direct to task notification in place of a binary semaphore! + * http://www.freertos.org/RTOS-task-notifications.html + * + * Internally, within the FreeRTOS implementation, binary semaphores use a block + * of memory, in which the semaphore structure is stored. If a binary semaphore + * is created using xSemaphoreCreateBinary() then the required memory is + * automatically dynamically allocated inside the xSemaphoreCreateBinary() + * function. (see http://www.freertos.org/a00111.html). If a binary semaphore + * is created using xSemaphoreCreateBinaryStatic() then the application writer + * must provide the memory. xSemaphoreCreateBinaryStatic() therefore allows a + * binary semaphore to be created without using any dynamic memory allocation. + * * The old vSemaphoreCreateBinary() macro is now deprecated in favour of this * xSemaphoreCreateBinary() function. Note that binary semaphores created using * the vSemaphoreCreateBinary() macro are created in a state such that the @@ -182,7 +200,68 @@ typedef QueueHandle_t SemaphoreHandle_t; * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary * \ingroup Semaphores */ -#define xSemaphoreCreateBinary() xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ) +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + #define xSemaphoreCreateBinary() xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ) +#endif + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateBinaryStatic( StaticSemaphore_t *pxSemaphoreBuffer )
+ * + * Creates a new binary semaphore instance, and returns a handle by which the + * new semaphore can be referenced. + * + * NOTE: In many usage scenarios it is faster and more memory efficient to use a + * direct to task notification in place of a binary semaphore! + * http://www.freertos.org/RTOS-task-notifications.html + * + * Internally, within the FreeRTOS implementation, binary semaphores use a block + * of memory, in which the semaphore structure is stored. If a binary semaphore + * is created using xSemaphoreCreateBinary() then the required memory is + * automatically dynamically allocated inside the xSemaphoreCreateBinary() + * function. (see http://www.freertos.org/a00111.html). If a binary semaphore + * is created using xSemaphoreCreateBinaryStatic() then the application writer + * must provide the memory. xSemaphoreCreateBinaryStatic() therefore allows a + * binary semaphore to be created without using any dynamic memory allocation. + * + * This type of semaphore can be used for pure synchronisation between tasks or + * between an interrupt and a task. The semaphore need not be given back once + * obtained, so one task/interrupt can continuously 'give' the semaphore while + * another continuously 'takes' the semaphore. For this reason this type of + * semaphore does not use a priority inheritance mechanism. For an alternative + * that does use priority inheritance see xSemaphoreCreateMutex(). + * + * @param pxSemaphoreBuffer Must point to a variable of type StaticSemaphore_t, + * which will then be used to hold the semaphore's data structure, removing the + * need for the memory to be allocated dynamically. + * + * @return If the semaphore is created then a handle to the created semaphore is + * returned. If pxSemaphoreBuffer is NULL then NULL is returned. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore = NULL;
+ StaticSemaphore_t xSemaphoreBuffer;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to xSemaphoreCreateBinary().
+    // The semaphore's data structures will be placed in the xSemaphoreBuffer
+    // variable, the address of which is passed into the function.  The
+    // function's parameter is not NULL, so the function will not attempt any
+    // dynamic memory allocation, and therefore the function will not return
+    // return NULL.
+    xSemaphore = xSemaphoreCreateBinary( &xSemaphoreBuffer );
+
+    // Rest of task code goes here.
+ }
+ 
+ * \defgroup xSemaphoreCreateBinaryStatic xSemaphoreCreateBinaryStatic + * \ingroup Semaphores + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + #define xSemaphoreCreateBinaryStatic( pxStaticSemaphore ) xQueueGenericCreateStatic( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, NULL, pxStaticSemaphore, queueQUEUE_TYPE_BINARY_SEMAPHORE ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ /** * semphr. h @@ -652,9 +731,18 @@ typedef QueueHandle_t SemaphoreHandle_t; * Macro that implements a mutex semaphore by using the existing queue * mechanism. * - * Mutexes created using this macro can be accessed using the xSemaphoreTake() + * Internally, within the FreeRTOS implementation, mutex semaphores use a block + * of memory, in which the mutex structure is stored. If a mutex is created + * using xSemaphoreCreateMutex() then the required memory is automatically + * dynamically allocated inside the xSemaphoreCreateMutex() function. (see + * http://www.freertos.org/a00111.html). If a mutex is created using + * xSemaphoreCreateMutexStatic() then the application writer must provided the + * memory. xSemaphoreCreateMutexStatic() therefore allows a mutex to be created + * without using any dynamic memory allocation. + * + * Mutexes created using this function can be accessed using the xSemaphoreTake() * and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and - * xSemaphoreGiveRecursive() macros should not be used. + * xSemaphoreGiveRecursive() macros must not be used. * * This type of semaphore uses a priority inheritance mechanism so a task * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the @@ -667,8 +755,9 @@ typedef QueueHandle_t SemaphoreHandle_t; * semaphore and another always 'takes' the semaphore) and from within interrupt * service routines. * - * @return xSemaphore Handle to the created mutex semaphore. Should be of type - * SemaphoreHandle_t. + * @return If the mutex was successfully created then a handle to the created + * semaphore is returned. If there was not enough heap to allocate the mutex + * data structures then NULL is returned. * * Example usage:
@@ -690,19 +779,93 @@ typedef QueueHandle_t SemaphoreHandle_t;
  * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex
  * \ingroup Semaphores
  */
-#define xSemaphoreCreateMutex() xQueueCreateMutex( queueQUEUE_TYPE_MUTEX )
+#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
+	#define xSemaphoreCreateMutex() xQueueCreateMutex( queueQUEUE_TYPE_MUTEX )
+#endif
+
+/**
+ * semphr. h
+ * 
SemaphoreHandle_t xSemaphoreCreateMutexStatic( StaticSemaphore_t *pxMutexBuffer )
+ * + * Creates a new mutex type semaphore instance, and returns a handle by which + * the new mutex can be referenced. + * + * Internally, within the FreeRTOS implementation, mutex semaphores use a block + * of memory, in which the mutex structure is stored. If a mutex is created + * using xSemaphoreCreateMutex() then the required memory is automatically + * dynamically allocated inside the xSemaphoreCreateMutex() function. (see + * http://www.freertos.org/a00111.html). If a mutex is created using + * xSemaphoreCreateMutexStatic() then the application writer must provided the + * memory. xSemaphoreCreateMutexStatic() therefore allows a mutex to be created + * without using any dynamic memory allocation. + * + * Mutexes created using this function can be accessed using the xSemaphoreTake() + * and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and + * xSemaphoreGiveRecursive() macros must not be used. + * + * This type of semaphore uses a priority inheritance mechanism so a task + * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the + * semaphore it is no longer required. + * + * Mutex type semaphores cannot be used from within interrupt service routines. + * + * See xSemaphoreCreateBinary() for an alternative implementation that can be + * used for pure synchronisation (where one task or interrupt always 'gives' the + * semaphore and another always 'takes' the semaphore) and from within interrupt + * service routines. + * + * @param pxMutexBuffer Must point to a variable of type StaticSemaphore_t, + * which will be used to hold the mutex's data structure, removing the need for + * the memory to be allocated dynamically. + * + * @return If the mutex was successfully created then a handle to the created + * mutex is returned. If pxMutexBuffer was NULL then NULL is returned. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore;
+ StaticSemaphore_t xMutexBuffer;
+
+ void vATask( void * pvParameters )
+ {
+    // A mutex cannot be used before it has been created.  xMutexBuffer is
+    // into xSemaphoreCreateMutexStatic() so no dynamic memory allocation is
+    // attempted.
+    xSemaphore = xSemaphoreCreateMutexStatic( &xMutexBuffer );
+
+    // As no dynamic memory allocation was performed, xSemaphore cannot be NULL,
+    // so there is no need to check it.
+ }
+ 
+ * \defgroup xSemaphoreCreateMutexStatic xSemaphoreCreateMutexStatic + * \ingroup Semaphores + */ + #if( configSUPPORT_STATIC_ALLOCATION == 1 ) + #define xSemaphoreCreateMutexStatic( pxMutexBuffer ) xQueueCreateMutexStatic( queueQUEUE_TYPE_MUTEX, ( pxMutexBuffer ) ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ /** * semphr. h *
SemaphoreHandle_t xSemaphoreCreateRecursiveMutex( void )
* - * Macro that implements a recursive mutex by using the existing queue - * mechanism. + * Creates a new recursive mutex type semaphore instance, and returns a handle + * by which the new recursive mutex can be referenced. + * + * Internally, within the FreeRTOS implementation, recursive mutexs use a block + * of memory, in which the mutex structure is stored. If a recursive mutex is + * created using xSemaphoreCreateRecursiveMutex() then the required memory is + * automatically dynamically allocated inside the + * xSemaphoreCreateRecursiveMutex() function. (see + * http://www.freertos.org/a00111.html). If a recursive mutex is created using + * xSemaphoreCreateRecursiveMutexStatic() then the application writer must + * provide the memory that will get used by the mutex. + * xSemaphoreCreateRecursiveMutexStatic() therefore allows a recursive mutex to + * be created without using any dynamic memory allocation. * * Mutexes created using this macro can be accessed using the * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The - * xSemaphoreTake() and xSemaphoreGive() macros should not be used. + * xSemaphoreTake() and xSemaphoreGive() macros must not be used. * * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex * doesn't become available again until the owner has called @@ -745,14 +908,104 @@ typedef QueueHandle_t SemaphoreHandle_t; * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex * \ingroup Semaphores */ -#define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex( queueQUEUE_TYPE_RECURSIVE_MUTEX ) +#if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_RECURSIVE_MUTEXES == 1 ) ) + #define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex( queueQUEUE_TYPE_RECURSIVE_MUTEX ) +#endif + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateRecursiveMutexStatic( StaticSemaphore_t *pxMutexBuffer )
+ * + * Creates a new recursive mutex type semaphore instance, and returns a handle + * by which the new recursive mutex can be referenced. + * + * Internally, within the FreeRTOS implementation, recursive mutexs use a block + * of memory, in which the mutex structure is stored. If a recursive mutex is + * created using xSemaphoreCreateRecursiveMutex() then the required memory is + * automatically dynamically allocated inside the + * xSemaphoreCreateRecursiveMutex() function. (see + * http://www.freertos.org/a00111.html). If a recursive mutex is created using + * xSemaphoreCreateRecursiveMutexStatic() then the application writer must + * provide the memory that will get used by the mutex. + * xSemaphoreCreateRecursiveMutexStatic() therefore allows a recursive mutex to + * be created without using any dynamic memory allocation. + * + * Mutexes created using this macro can be accessed using the + * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The + * xSemaphoreTake() and xSemaphoreGive() macros must not be used. + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * This type of semaphore uses a priority inheritance mechanism so a task + * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the + * semaphore it is no longer required. + * + * Mutex type semaphores cannot be used from within interrupt service routines. + * + * See xSemaphoreCreateBinary() for an alternative implementation that can be + * used for pure synchronisation (where one task or interrupt always 'gives' the + * semaphore and another always 'takes' the semaphore) and from within interrupt + * service routines. + * + * @param pxMutexBuffer Must point to a variable of type StaticSemaphore_t, + * which will then be used to hold the recursive mutex's data structure, + * removing the need for the memory to be allocated dynamically. + * + * @return If the recursive mutex was successfully created then a handle to the + * created recursive mutex is returned. If pxMutexBuffer was NULL then NULL is + * returned. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore;
+ StaticSemaphore_t xMutexBuffer;
+
+ void vATask( void * pvParameters )
+ {
+    // A recursive semaphore cannot be used before it is created.  Here a
+    // recursive mutex is created using xSemaphoreCreateRecursiveMutexStatic().
+    // The address of xMutexBuffer is passed into the function, and will hold
+    // the mutexes data structures - so no dynamic memory allocation will be
+    // attempted.
+    xSemaphore = xSemaphoreCreateRecursiveMutexStatic( &xMutexBuffer );
+
+    // As no dynamic memory allocation was performed, xSemaphore cannot be NULL,
+    // so there is no need to check it.
+ }
+ 
+ * \defgroup xSemaphoreCreateRecursiveMutexStatic xSemaphoreCreateRecursiveMutexStatic + * \ingroup Semaphores + */ +#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_RECURSIVE_MUTEXES == 1 ) ) + #define xSemaphoreCreateRecursiveMutexStatic( pxStaticSemaphore ) xQueueCreateMutexStatic( queueQUEUE_TYPE_RECURSIVE_MUTEX, pxStaticSemaphore ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ /** * semphr. h *
SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount )
* - * Macro that creates a counting semaphore by using the existing - * queue mechanism. + * Creates a new counting semaphore instance, and returns a handle by which the + * new counting semaphore can be referenced. + * + * In many usage scenarios it is faster and more memory efficient to use a + * direct to task notification in place of a counting semaphore! + * http://www.freertos.org/RTOS-task-notifications.html + * + * Internally, within the FreeRTOS implementation, counting semaphores use a + * block of memory, in which the counting semaphore structure is stored. If a + * counting semaphore is created using xSemaphoreCreateCounting() then the + * required memory is automatically dynamically allocated inside the + * xSemaphoreCreateCounting() function. (see + * http://www.freertos.org/a00111.html). If a counting semaphore is created + * using xSemaphoreCreateCountingStatic() then the application writer can + * instead optionally provide the memory that will get used by the counting + * semaphore. xSemaphoreCreateCountingStatic() therefore allows a counting + * semaphore to be created without using any dynamic memory allocation. * * Counting semaphores are typically used for two things: * @@ -808,7 +1061,94 @@ typedef QueueHandle_t SemaphoreHandle_t; * \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting * \ingroup Semaphores */ -#define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) ) +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + #define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) ) +#endif + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateCountingStatic( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount, StaticSemaphore_t *pxSemaphoreBuffer )
+ * + * Creates a new counting semaphore instance, and returns a handle by which the + * new counting semaphore can be referenced. + * + * In many usage scenarios it is faster and more memory efficient to use a + * direct to task notification in place of a counting semaphore! + * http://www.freertos.org/RTOS-task-notifications.html + * + * Internally, within the FreeRTOS implementation, counting semaphores use a + * block of memory, in which the counting semaphore structure is stored. If a + * counting semaphore is created using xSemaphoreCreateCounting() then the + * required memory is automatically dynamically allocated inside the + * xSemaphoreCreateCounting() function. (see + * http://www.freertos.org/a00111.html). If a counting semaphore is created + * using xSemaphoreCreateCountingStatic() then the application writer must + * provide the memory. xSemaphoreCreateCountingStatic() therefore allows a + * counting semaphore to be created without using any dynamic memory allocation. + * + * Counting semaphores are typically used for two things: + * + * 1) Counting events. + * + * In this usage scenario an event handler will 'give' a semaphore each time + * an event occurs (incrementing the semaphore count value), and a handler + * task will 'take' a semaphore each time it processes an event + * (decrementing the semaphore count value). The count value is therefore + * the difference between the number of events that have occurred and the + * number that have been processed. In this case it is desirable for the + * initial count value to be zero. + * + * 2) Resource management. + * + * In this usage scenario the count value indicates the number of resources + * available. To obtain control of a resource a task must first obtain a + * semaphore - decrementing the semaphore count value. When the count value + * reaches zero there are no free resources. When a task finishes with the + * resource it 'gives' the semaphore back - incrementing the semaphore count + * value. In this case it is desirable for the initial count value to be + * equal to the maximum count value, indicating that all resources are free. + * + * @param uxMaxCount The maximum count value that can be reached. When the + * semaphore reaches this value it can no longer be 'given'. + * + * @param uxInitialCount The count value assigned to the semaphore when it is + * created. + * + * @param pxSemaphoreBuffer Must point to a variable of type StaticSemaphore_t, + * which will then be used to hold the semaphore's data structure, removing the + * need for the memory to be allocated dynamically. + * + * @return If the counting semaphore was successfully created then a handle to + * the created counting semaphore is returned. If pxSemaphoreBuffer was NULL + * then NULL is returned. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore;
+ StaticSemaphore_t xSemaphoreBuffer;
+
+ void vATask( void * pvParameters )
+ {
+ SemaphoreHandle_t xSemaphore = NULL;
+
+    // Counting semaphore cannot be used before they have been created.  Create
+    // a counting semaphore using xSemaphoreCreateCountingStatic().  The max
+    // value to which the semaphore can count is 10, and the initial value
+    // assigned to the count will be 0.  The address of xSemaphoreBuffer is
+    // passed in and will be used to hold the semaphore structure, so no dynamic
+    // memory allocation will be used.
+    xSemaphore = xSemaphoreCreateCounting( 10, 0, &xSemaphoreBuffer );
+
+    // No memory allocation was attempted so xSemaphore cannot be NULL, so there
+    // is no need to check its value.
+ }
+ 
+ * \defgroup xSemaphoreCreateCountingStatic xSemaphoreCreateCountingStatic + * \ingroup Semaphores + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + #define xSemaphoreCreateCountingStatic( uxMaxCount, uxInitialCount, pxSemaphoreBuffer ) xQueueCreateCountingSemaphoreStatic( ( uxMaxCount ), ( uxInitialCount ), ( pxSemaphoreBuffer ) ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ /** * semphr. h diff --git a/components/freertos/include/freertos/task.h b/components/freertos/include/freertos/task.h index ddf7a7589d..6a781dc8c2 100644 --- a/components/freertos/include/freertos/task.h +++ b/components/freertos/include/freertos/task.h @@ -177,6 +177,7 @@ typedef struct xTASK_STATUS UBaseType_t uxCurrentPriority; /* The priority at which the task was running (may be inherited) when the structure was populated. */ UBaseType_t uxBasePriority; /* The priority to which the task will return if the task's current priority has been inherited to avoid unbounded priority inversion when obtaining a mutex. Only valid if configUSE_MUTEXES is defined as 1 in FreeRTOSConfig.h. */ uint32_t ulRunTimeCounter; /* The total run time allocated to the task so far, as defined by the run time stats clock. See http://www.freertos.org/rtos-run-time-stats.html. Only valid when configGENERATE_RUN_TIME_STATS is defined as 1 in FreeRTOSConfig.h. */ + StackType_t *pxStackBase; /* Points to the lowest address of the task's stack area. */ uint16_t usStackHighWaterMark; /* The minimum amount of stack space that has remained for the task since the task was created. The closer this value is to zero the closer the task has come to overflowing its stack. */ } TaskStatus_t; @@ -281,8 +282,19 @@ is used in assert() statements. */ );
* * Create a new task and add it to the list of tasks that are ready to run. - * On multicore environments, this will give no specific affinity to the task. - * Use xTaskCreatePinnedToCore to give affinity. + * + * Internally, within the FreeRTOS implementation, tasks use two blocks of + * memory. The first block is used to hold the task's data structures. The + * second block is used by the task as its stack. If a task is created using + * xTaskCreate() then both blocks of memory are automatically dynamically + * allocated inside the xTaskCreate() function. (see + * http://www.freertos.org/a00111.html). If a task is created using + * xTaskCreateStatic() then the application writer must provide the required + * memory. xTaskCreateStatic() therefore allows a task to be created without + * using any dynamic memory allocation. + * + * See xTaskCreateStatic() for a version that does not use any dynamic memory + * allocation. * * xTaskCreate() can only be used to create a task that has unrestricted * access to the entire microcontroller memory map. Systems that include MPU @@ -350,8 +362,139 @@ is used in assert() statements. */ * \defgroup xTaskCreate xTaskCreate * \ingroup Tasks */ -#define xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ) xTaskGenericCreate( ( pvTaskCode ), ( pcName ), ( usStackDepth ), ( pvParameters ), ( uxPriority ), ( pxCreatedTask ), ( NULL ), ( NULL ), tskNO_AFFINITY ) -#define xTaskCreatePinnedToCore( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask, xCoreID ) xTaskGenericCreate( ( pvTaskCode ), ( pcName ), ( usStackDepth ), ( pvParameters ), ( uxPriority ), ( pxCreatedTask ), ( NULL ), ( NULL ), xCoreID ) +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + BaseType_t xTaskCreatePinnedToCore( TaskFunction_t pxTaskCode, + const char * const pcName, + const uint16_t usStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * const pxCreatedTask, + const BaseType_t xCoreID); + +#define xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ) xTaskCreatePinnedToCore( ( pvTaskCode ), ( pcName ), ( usStackDepth ), ( pvParameters ), ( uxPriority ), ( pxCreatedTask ), tskNO_AFFINITY ) +#endif + +/** + * task. h + *
+ TaskHandle_t xTaskCreateStatic( TaskFunction_t pvTaskCode,
+								 const char * const pcName,
+								 uint32_t ulStackDepth,
+								 void *pvParameters,
+								 UBaseType_t uxPriority,
+								 StackType_t *pxStackBuffer,
+								 StaticTask_t *pxTaskBuffer,
+                                 const BaseType_t xCoreID );
+ + * + * Create a new task and add it to the list of tasks that are ready to run. + * + * Internally, within the FreeRTOS implementation, tasks use two blocks of + * memory. The first block is used to hold the task's data structures. The + * second block is used by the task as its stack. If a task is created using + * xTaskCreate() then both blocks of memory are automatically dynamically + * allocated inside the xTaskCreate() function. (see + * http://www.freertos.org/a00111.html). If a task is created using + * xTaskCreateStatic() then the application writer must provide the required + * memory. xTaskCreateStatic() therefore allows a task to be created without + * using any dynamic memory allocation. + * + * @param pvTaskCode Pointer to the task entry function. Tasks + * must be implemented to never return (i.e. continuous loop). + * + * @param pcName A descriptive name for the task. This is mainly used to + * facilitate debugging. The maximum length of the string is defined by + * configMAX_TASK_NAME_LEN in FreeRTOSConfig.h. + * + * @param ulStackDepth The size of the task stack specified as the number of + * variables the stack can hold - not the number of bytes. For example, if + * the stack is 32-bits wide and ulStackDepth is defined as 100 then 400 bytes + * will be allocated for stack storage. + * + * @param pvParameters Pointer that will be used as the parameter for the task + * being created. + * + * @param uxPriority The priority at which the task will run. + * + * @param pxStackBuffer Must point to a StackType_t array that has at least + * ulStackDepth indexes - the array will then be used as the task's stack, + * removing the need for the stack to be allocated dynamically. + * + * @param pxTaskBuffer Must point to a variable of type StaticTask_t, which will + * then be used to hold the task's data structures, removing the need for the + * memory to be allocated dynamically. + * + * @return If neither pxStackBuffer or pxTaskBuffer are NULL, then the task will + * be created and pdPASS is returned. If either pxStackBuffer or pxTaskBuffer + * are NULL then the task will not be created and + * errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY is returned. + * + * Example usage: +
+
+    // Dimensions the buffer that the task being created will use as its stack.
+    // NOTE:  This is the number of words the stack will hold, not the number of
+    // bytes.  For example, if each stack item is 32-bits, and this is set to 100,
+    // then 400 bytes (100 * 32-bits) will be allocated.
+    #define STACK_SIZE 200
+
+    // Structure that will hold the TCB of the task being created.
+    StaticTask_t xTaskBuffer;
+
+    // Buffer that the task being created will use as its stack.  Note this is
+    // an array of StackType_t variables.  The size of StackType_t is dependent on
+    // the RTOS port.
+    StackType_t xStack[ STACK_SIZE ];
+
+    // Function that implements the task being created.
+    void vTaskCode( void * pvParameters )
+    {
+        // The parameter value is expected to be 1 as 1 is passed in the
+        // pvParameters value in the call to xTaskCreateStatic().
+        configASSERT( ( uint32_t ) pvParameters == 1UL );
+
+        for( ;; )
+        {
+            // Task code goes here.
+        }
+    }
+
+    // Function that creates a task.
+    void vOtherFunction( void )
+    {
+        TaskHandle_t xHandle = NULL;
+
+        // Create the task without using any dynamic memory allocation.
+        xHandle = xTaskCreateStatic(
+                      vTaskCode,       // Function that implements the task.
+                      "NAME",          // Text name for the task.
+                      STACK_SIZE,      // Stack size in words, not bytes.
+                      ( void * ) 1,    // Parameter passed into the task.
+                      tskIDLE_PRIORITY,// Priority at which the task is created.
+                      xStack,          // Array to use as the task's stack.
+                      &xTaskBuffer );  // Variable to hold the task's data structure.
+
+        // puxStackBuffer and pxTaskBuffer were not NULL, so the task will have
+        // been created, and xHandle will be the task's handle.  Use the handle
+        // to suspend the task.
+        vTaskSuspend( xHandle );
+    }
+   
+ * \defgroup xTaskCreateStatic xTaskCreateStatic + * \ingroup Tasks + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + TaskHandle_t xTaskCreateStaticPinnedToCore( TaskFunction_t pxTaskCode, + const char * const pcName, + const uint32_t ulStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + StackType_t * const puxStackBuffer, + StaticTask_t * const pxTaskBuffer, + const BaseType_t xCoreID ); + +#define xTaskCreateStatic( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxStackBuffer, pxTaskBuffer ) xTaskCreateStaticPinnedToCore( ( pvTaskCode ), ( pcName ), ( usStackDepth ), ( pvParameters ), ( uxPriority ), ( pxStackBuffer ), ( pxTaskBuffer ), tskNO_AFFINITY ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ /** * task. h @@ -420,7 +563,9 @@ TaskHandle_t xHandle; * \defgroup xTaskCreateRestricted xTaskCreateRestricted * \ingroup Tasks */ -#define xTaskCreateRestricted( x, pxCreatedTask ) xTaskGenericCreate( ((x)->pvTaskCode), ((x)->pcName), ((x)->usStackDepth), ((x)->pvParameters), ((x)->uxPriority), (pxCreatedTask), ((x)->puxStackBuffer), ((x)->xRegions) ) +#if( portUSING_MPU_WRAPPERS == 1 ) + BaseType_t xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) PRIVILEGED_FUNCTION; +#endif /** * task. h @@ -1968,12 +2113,6 @@ void vTaskPriorityInherit( TaskHandle_t const pxMutexHolder ) PRIVILEGED_FUNCTIO */ BaseType_t xTaskPriorityDisinherit( TaskHandle_t const pxMutexHolder ) PRIVILEGED_FUNCTION; -/* - * Generic version of the task creation function which is in turn called by the - * xTaskCreate() and xTaskCreateRestricted() macros. - */ -BaseType_t xTaskGenericCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask, StackType_t * const puxStackBuffer, const MemoryRegion_t * const xRegions, const BaseType_t xCoreID) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ - /* * Get the uxTCBNumber assigned to the task referenced by the xTask parameter. */ diff --git a/components/freertos/queue.c b/components/freertos/queue.c index 248ae7c00a..445a9e2e91 100644 --- a/components/freertos/queue.c +++ b/components/freertos/queue.c @@ -166,15 +166,19 @@ typedef struct QueueDefinition volatile BaseType_t xRxLock; /*< Stores the number of items received from the queue (removed from the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */ volatile BaseType_t xTxLock; /*< Stores the number of items transmitted to the queue (added to the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */ - #if ( configUSE_TRACE_FACILITY == 1 ) - UBaseType_t uxQueueNumber; - uint8_t ucQueueType; + #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the memory used by the queue was statically allocated to ensure no attempt is made to free the memory. */ #endif #if ( configUSE_QUEUE_SETS == 1 ) struct QueueDefinition *pxQueueSetContainer; #endif + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxQueueNumber; + uint8_t ucQueueType; + #endif + portMUX_TYPE mux; } xQUEUE; @@ -255,6 +259,21 @@ static void prvCopyDataFromQueue( Queue_t * const pxQueue, void * const pvBuffer static BaseType_t prvNotifyQueueSetContainer( const Queue_t * const pxQueue, const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION; #endif +/* + * Called after a Queue_t structure has been allocated either statically or + * dynamically to fill in the structure's members. + */ +static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, const uint8_t ucQueueType, Queue_t *pxNewQueue ) PRIVILEGED_FUNCTION; + +/* + * Mutexes are a special type of queue. When a mutex is created, first the + * queue is created, then prvInitialiseMutex() is called to configure the queue + * as a mutex. + */ +#if( configUSE_MUTEXES == 1 ) + static void prvInitialiseMutex( Queue_t *pxNewQueue ) PRIVILEGED_FUNCTION; +#endif + /*-----------------------------------------------------------*/ /* @@ -333,134 +352,165 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue; } /*-----------------------------------------------------------*/ -QueueHandle_t xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType ) -{ -Queue_t *pxNewQueue; -size_t xQueueSizeInBytes; -QueueHandle_t xReturn = NULL; -int8_t *pcAllocatedBuffer; +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + QueueHandle_t xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, const uint8_t ucQueueType ) + { + Queue_t *pxNewQueue; + + configASSERT( uxQueueLength > ( UBaseType_t ) 0 ); + + /* The StaticQueue_t structure and the queue storage area must be + supplied. */ + configASSERT( pxStaticQueue != NULL ); + + /* A queue storage area should be provided if the item size is not 0, and + should not be provided if the item size is 0. */ + configASSERT( !( ( pucQueueStorage != NULL ) && ( uxItemSize == 0 ) ) ); + configASSERT( !( ( pucQueueStorage == NULL ) && ( uxItemSize != 0 ) ) ); + + #if( configASSERT_DEFINED == 1 ) + { + /* Sanity check that the size of the structure used to declare a + variable of type StaticQueue_t or StaticSemaphore_t equals the size of + the real queue and semaphore structures. */ + volatile size_t xSize = sizeof( StaticQueue_t ); + configASSERT( xSize == sizeof( Queue_t ) ); + } + #endif /* configASSERT_DEFINED */ + + /* The address of a statically allocated queue was passed in, use it. + The address of a statically allocated storage area was also passed in + but is already set. */ + pxNewQueue = ( Queue_t * ) pxStaticQueue; /*lint !e740 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */ + + if( pxNewQueue != NULL ) + { + #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + /* Queues can be allocated wither statically or dynamically, so + note this queue was allocated statically in case the queue is + later deleted. */ + pxNewQueue->ucStaticallyAllocated = pdTRUE; + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + + prvInitialiseNewQueue( uxQueueLength, uxItemSize, pucQueueStorage, ucQueueType, pxNewQueue ); + } + + return pxNewQueue; + } + +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + + QueueHandle_t xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType ) + { + Queue_t *pxNewQueue; + size_t xQueueSizeInBytes; + uint8_t *pucQueueStorage; + + configASSERT( uxQueueLength > ( UBaseType_t ) 0 ); + + if( uxItemSize == ( UBaseType_t ) 0 ) + { + /* There is not going to be a queue storage area. */ + xQueueSizeInBytes = ( size_t ) 0; + } + else + { + /* Allocate enough space to hold the maximum number of items that + can be in the queue at any time. */ + xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + } + + pxNewQueue = ( Queue_t * ) pvPortMalloc( sizeof( Queue_t ) + xQueueSizeInBytes ); + + if( pxNewQueue != NULL ) + { + /* Jump past the queue structure to find the location of the queue + storage area. */ + pucQueueStorage = ( ( uint8_t * ) pxNewQueue ) + sizeof( Queue_t ); + + #if( configSUPPORT_STATIC_ALLOCATION == 1 ) + { + /* Queues can be created either statically or dynamically, so + note this task was created dynamically in case it is later + deleted. */ + pxNewQueue->ucStaticallyAllocated = pdFALSE; + } + #endif /* configSUPPORT_STATIC_ALLOCATION */ + + prvInitialiseNewQueue( uxQueueLength, uxItemSize, pucQueueStorage, ucQueueType, pxNewQueue ); + } + + return pxNewQueue; + } + +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, const uint8_t ucQueueType, Queue_t *pxNewQueue ) +{ /* Remove compiler warnings about unused parameters should configUSE_TRACE_FACILITY not be set to 1. */ ( void ) ucQueueType; - configASSERT( uxQueueLength > ( UBaseType_t ) 0 ); - if( uxItemSize == ( UBaseType_t ) 0 ) { - /* There is not going to be a queue storage area. */ - xQueueSizeInBytes = ( size_t ) 0; + /* No RAM was allocated for the queue storage area, but PC head cannot + be set to NULL because NULL is used as a key to say the queue is used as + a mutex. Therefore just set pcHead to point to the queue as a benign + value that is known to be within the memory map. */ + pxNewQueue->pcHead = ( int8_t * ) pxNewQueue; } else { - /* The queue is one byte longer than asked for to make wrap checking - easier/faster. */ - xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ) + ( size_t ) 1; /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + /* Set the head to the start of the queue storage area. */ + pxNewQueue->pcHead = ( int8_t * ) pucQueueStorage; } - /* Allocate the new queue structure and storage area. */ - pcAllocatedBuffer = ( int8_t * ) pvPortMalloc( sizeof( Queue_t ) + xQueueSizeInBytes ); + /* Initialise the queue members as described where the queue type is + defined. */ + pxNewQueue->uxLength = uxQueueLength; + pxNewQueue->uxItemSize = uxItemSize; + ( void ) xQueueGenericReset( pxNewQueue, pdTRUE ); - if( pcAllocatedBuffer != NULL ) + #if ( configUSE_TRACE_FACILITY == 1 ) { - pxNewQueue = ( Queue_t * ) pcAllocatedBuffer; /*lint !e826 MISRA The buffer cannot be to small because it was dimensioned by sizeof( Queue_t ) + xQueueSizeInBytes. */ - - if( uxItemSize == ( UBaseType_t ) 0 ) - { - /* No RAM was allocated for the queue storage area, but PC head - cannot be set to NULL because NULL is used as a key to say the queue - is used as a mutex. Therefore just set pcHead to point to the queue - as a benign value that is known to be within the memory map. */ - pxNewQueue->pcHead = ( int8_t * ) pxNewQueue; - } - else - { - /* Jump past the queue structure to find the location of the queue - storage area - adding the padding bytes to get a better alignment. */ - pxNewQueue->pcHead = pcAllocatedBuffer + sizeof( Queue_t ); - } - - /* Initialise the queue members as described above where the queue type - is defined. */ - pxNewQueue->uxLength = uxQueueLength; - pxNewQueue->uxItemSize = uxItemSize; - ( void ) xQueueGenericReset( pxNewQueue, pdTRUE ); - - #if ( configUSE_TRACE_FACILITY == 1 ) - { - pxNewQueue->ucQueueType = ucQueueType; - } - #endif /* configUSE_TRACE_FACILITY */ - - #if( configUSE_QUEUE_SETS == 1 ) - { - pxNewQueue->pxQueueSetContainer = NULL; - } - #endif /* configUSE_QUEUE_SETS */ - - traceQUEUE_CREATE( pxNewQueue ); - xReturn = pxNewQueue; + pxNewQueue->ucQueueType = ucQueueType; } - else + #endif /* configUSE_TRACE_FACILITY */ + + #if( configUSE_QUEUE_SETS == 1 ) { - mtCOVERAGE_TEST_MARKER(); + pxNewQueue->pxQueueSetContainer = NULL; } + #endif /* configUSE_QUEUE_SETS */ - configASSERT( xReturn ); - - return xReturn; + traceQUEUE_CREATE( pxNewQueue ); } /*-----------------------------------------------------------*/ -#if ( configUSE_MUTEXES == 1 ) +#if( configUSE_MUTEXES == 1 ) - QueueHandle_t xQueueCreateMutex( const uint8_t ucQueueType ) + static void prvInitialiseMutex( Queue_t *pxNewQueue ) { - Queue_t *pxNewQueue; - - /* Prevent compiler warnings about unused parameters if - configUSE_TRACE_FACILITY does not equal 1. */ - ( void ) ucQueueType; - - /* Allocate the new queue structure. */ - pxNewQueue = ( Queue_t * ) pvPortMalloc( sizeof( Queue_t ) ); if( pxNewQueue != NULL ) { - /* Information required for priority inheritance. */ + /* The queue create function will set all the queue structure members + correctly for a generic queue, but this function is creating a + mutex. Overwrite those members that need to be set differently - + in particular the information required for priority inheritance. */ pxNewQueue->pxMutexHolder = NULL; pxNewQueue->uxQueueType = queueQUEUE_IS_MUTEX; - /* Queues used as a mutex no data is actually copied into or out - of the queue. */ - pxNewQueue->pcWriteTo = NULL; - pxNewQueue->u.pcReadFrom = NULL; + /* In case this is a recursive mutex. */ + pxNewQueue->u.uxRecursiveCallCount = 0; - /* Each mutex has a length of 1 (like a binary semaphore) and - an item size of 0 as nothing is actually copied into or out - of the mutex. */ - pxNewQueue->uxMessagesWaiting = ( UBaseType_t ) 0U; - pxNewQueue->uxLength = ( UBaseType_t ) 1U; - pxNewQueue->uxItemSize = ( UBaseType_t ) 0U; - pxNewQueue->xRxLock = queueUNLOCKED; - pxNewQueue->xTxLock = queueUNLOCKED; - - #if ( configUSE_TRACE_FACILITY == 1 ) - { - pxNewQueue->ucQueueType = ucQueueType; - } - #endif - - #if ( configUSE_QUEUE_SETS == 1 ) - { - pxNewQueue->pxQueueSetContainer = NULL; - } - #endif - - /* Ensure the event queues start with the correct state. */ - vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) ); - vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) ); - - vPortCPUInitializeMutex(&pxNewQueue->mux); + vPortCPUInitializeMutex(&pxNewQueue->mux); traceCREATE_MUTEX( pxNewQueue ); @@ -471,8 +521,41 @@ int8_t *pcAllocatedBuffer; { traceCREATE_MUTEX_FAILED(); } + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + + QueueHandle_t xQueueCreateMutex( const uint8_t ucQueueType ) + { + Queue_t *pxNewQueue; + const UBaseType_t uxMutexLength = ( UBaseType_t ) 1, uxMutexSize = ( UBaseType_t ) 0; + + pxNewQueue = ( Queue_t * ) xQueueGenericCreate( uxMutexLength, uxMutexSize, ucQueueType ); + prvInitialiseMutex( pxNewQueue ); + + return pxNewQueue; + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + + QueueHandle_t xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue ) + { + Queue_t *pxNewQueue; + const UBaseType_t uxMutexLength = ( UBaseType_t ) 1, uxMutexSize = ( UBaseType_t ) 0; + + /* Prevent compiler warnings about unused parameters if + configUSE_TRACE_FACILITY does not equal 1. */ + ( void ) ucQueueType; + + pxNewQueue = ( Queue_t * ) xQueueGenericCreateStatic( uxMutexLength, uxMutexSize, NULL, pxStaticQueue, ucQueueType ); + prvInitialiseMutex( pxNewQueue ); - configASSERT( pxNewQueue ); return pxNewQueue; } @@ -607,7 +690,35 @@ int8_t *pcAllocatedBuffer; #endif /* configUSE_RECURSIVE_MUTEXES */ /*-----------------------------------------------------------*/ -#if ( configUSE_COUNTING_SEMAPHORES == 1 ) +#if( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + + QueueHandle_t xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue ) + { + QueueHandle_t xHandle; + + configASSERT( uxMaxCount != 0 ); + configASSERT( uxInitialCount <= uxMaxCount ); + + xHandle = xQueueGenericCreateStatic( uxMaxCount, queueSEMAPHORE_QUEUE_ITEM_LENGTH, NULL, pxStaticQueue, queueQUEUE_TYPE_COUNTING_SEMAPHORE ); + + if( xHandle != NULL ) + { + ( ( Queue_t * ) xHandle )->uxMessagesWaiting = uxInitialCount; + + traceCREATE_COUNTING_SEMAPHORE(); + } + else + { + traceCREATE_COUNTING_SEMAPHORE_FAILED(); + } + + return xHandle; + } + +#endif /* ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) QueueHandle_t xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount ) { @@ -633,7 +744,7 @@ int8_t *pcAllocatedBuffer; return xHandle; } -#endif /* configUSE_COUNTING_SEMAPHORES */ +#endif /* ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ /*-----------------------------------------------------------*/ BaseType_t xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition ) @@ -1777,7 +1888,33 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue; vQueueUnregisterQueue( pxQueue ); } #endif - vPortFree( pxQueue ); + + #if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) ) + { + /* The queue can only have been allocated dynamically - free it + again. */ + vPortFree( pxQueue ); + } + #elif( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + { + /* The queue could have been allocated statically or dynamically, so + check before attempting to free the memory. */ + if( pxQueue->ucStaticallyAllocated == ( uint8_t ) pdFALSE ) + { + vPortFree( pxQueue ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #else + { + /* The queue must have been statically allocated, so is not going to be + deleted. Avoid compiler warnings about the unused parameter. */ + ( void ) pxQueue; + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ } /*-----------------------------------------------------------*/ @@ -2477,7 +2614,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue; #endif /* configUSE_TIMERS */ /*-----------------------------------------------------------*/ -#if ( configUSE_QUEUE_SETS == 1 ) +#if( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) QueueSetHandle_t xQueueCreateSet( const UBaseType_t uxEventQueueLength ) { diff --git a/components/freertos/tasks.c b/components/freertos/tasks.c index ff3a0530d6..034ffc08ed 100644 --- a/components/freertos/tasks.c +++ b/components/freertos/tasks.c @@ -85,7 +85,6 @@ task.h is included from an application file. */ #include "StackMacros.h" #include "portmacro.h" #include "semphr.h" -#include "sys/reent.h" /* Lint e961 and e750 are suppressed as a MISRA exception justified because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the @@ -129,6 +128,8 @@ functions but without including stdio.h here. */ } while(0) #endif + + /* Value that can be assigned to the eNotifyState member of the TCB. */ typedef enum { @@ -137,6 +138,26 @@ typedef enum eNotified } eNotifyValue; +/* Sometimes the FreeRTOSConfig.h settings only allow a task to be created using +dynamically allocated RAM, in which case when any task is deleted it is known +that both the task's stack and TCB need to be freed. Sometimes the +FreeRTOSConfig.h settings only allow a task to be created using statically +allocated RAM, in which case when any task is deleted it is known that neither +the task's stack or TCB should be freed. Sometimes the FreeRTOSConfig.h +settings allow a task to be created using either statically or dynamically +allocated RAM, in which case a member of the TCB is used to record whether the +stack and/or TCB were allocated statically or dynamically, so when a task is +deleted the RAM that was allocated dynamically is freed again and no attempt is +made to free the RAM that was allocated statically. +tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE is only true if it is possible for a +task to be created using either statically or dynamically allocated RAM. Note +that if portUSING_MPU_WRAPPERS is 1 then a protected task can be created with +a statically allocated stack and a dynamically allocated TCB. */ +#define tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE ( ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) || ( portUSING_MPU_WRAPPERS == 1 ) ) +#define tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB ( ( uint8_t ) 0 ) +#define tskSTATICALLY_ALLOCATED_STACK_ONLY ( ( uint8_t ) 1 ) +#define tskSTATICALLY_ALLOCATED_STACK_AND_TCB ( ( uint8_t ) 2 ) + /* * Task control block. A task control block (TCB) is allocated for each task, * and stores task state information, including a pointer to the task's context @@ -148,7 +169,6 @@ typedef struct tskTaskControlBlock #if ( portUSING_MPU_WRAPPERS == 1 ) xMPU_SETTINGS xMPUSettings; /*< The MPU settings are defined as part of the port layer. THIS MUST BE THE SECOND MEMBER OF THE TCB STRUCT. */ - BaseType_t xUsingStaticallyAllocatedStack; /* Set to pdTRUE if the stack is a statically allocated array, and pdFALSE if the stack is dynamically allocated. */ #endif ListItem_t xGenericListItem; /*< The list that the state list item of a task is reference from denotes the state of that task (Ready, Blocked, Suspended ). */ @@ -208,6 +228,12 @@ typedef struct tskTaskControlBlock volatile eNotifyValue eNotifyState; #endif + /* See the comments above the definition of + tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE. */ + #if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) + uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the task is a statically allocated to ensure no attempt is made to free the memory. */ + #endif + } tskTCB; /* The old tskTCB name is maintained above then typedefed to the new TCB_t name @@ -455,12 +481,6 @@ to its original value when it is released. */ /* File private functions. --------------------------------*/ -/* - * Utility to ready a TCB for a given task. Mainly just copies the parameters - * into the TCB structure. - */ -static void prvInitialiseTCBVariables( TCB_t * const pxTCB, const char * const pcName, UBaseType_t uxPriority, const MemoryRegion_t * const xRegions, const uint16_t usStackDepth, const BaseType_t xCoreID ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ - /** * Utility task that simply returns pdTRUE if the task referenced by xTask is * currently in the Suspended state, or pdFALSE if the task referenced by xTask @@ -515,12 +535,6 @@ static void prvCheckTasksWaitingTermination( void ) PRIVILEGED_FUNCTION; */ static void prvAddCurrentTaskToDelayedList( const portBASE_TYPE xCoreID, const TickType_t xTimeToWake ) PRIVILEGED_FUNCTION; -/* - * Allocates memory from the heap for a TCB and associated stack. Checks the - * allocation was successful. - */ -static TCB_t *prvAllocateTCBAndStack( const uint16_t usStackDepth, StackType_t * const puxStackBuffer ) PRIVILEGED_FUNCTION; - /* * Fills an TaskStatus_t structure with information on each task that is * referenced from the pxList list (which may be a ready list, a delayed list, @@ -577,6 +591,26 @@ static void prvResetNextTaskUnblockTime( void ); #endif +/* + * Called after a Task_t structure has been allocated either statically or + * dynamically to fill in the structure's members. + */ +static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, + const char * const pcName, + const uint32_t ulStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * const pxCreatedTask, + TCB_t *pxNewTCB, + const MemoryRegion_t * const xRegions ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/* + * Called after a new task has been created and initialised to place the task + * under the control of the scheduler. + */ +static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB, TaskFunction_t pxTaskCode, const BaseType_t xCoreID ) PRIVILEGED_FUNCTION; + + /*-----------------------------------------------------------*/ @@ -589,114 +623,403 @@ static void vTaskInitializeLocalMuxes( void ) /*-----------------------------------------------------------*/ -BaseType_t xTaskGenericCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask, StackType_t * const puxStackBuffer, const MemoryRegion_t * const xRegions, const BaseType_t xCoreID) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ -{ -BaseType_t xReturn; -TCB_t * pxNewTCB; -StackType_t *pxTopOfStack; -BaseType_t i; - - /* Initialize mutexes, if they're not already initialized. */ - if (xMutexesInitialised == pdFALSE) vTaskInitializeLocalMuxes(); - - configASSERT( pxTaskCode ); - configASSERT( ( ( uxPriority & ( ~portPRIVILEGE_BIT ) ) < configMAX_PRIORITIES ) ); - configASSERT( (xCoreID>=0 && xCoreIDxUsingStaticallyAllocatedStack = pdTRUE; - } - else - { - /* The stack was allocated dynamically. Note this so it can be - deleted again if the task is deleted. */ - pxNewTCB->xUsingStaticallyAllocatedStack = pdFALSE; - } - #endif /* portUSING_MPU_WRAPPERS == 1 */ + configASSERT( puxStackBuffer != NULL ); + configASSERT( pxTaskBuffer != NULL ); + configASSERT( (xCoreID>=0 && xCoreIDpxStack + ( usStackDepth - ( uint16_t ) 1 ); - pxTopOfStack = ( StackType_t * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) & ( ( portPOINTER_SIZE_TYPE ) ~portBYTE_ALIGNMENT_MASK ) ); /*lint !e923 MISRA exception. Avoiding casts between pointers and integers is not practical. Size differences accounted for using portPOINTER_SIZE_TYPE type. */ + /* The memory used for the task's TCB and stack are passed into this + function - use them. */ + pxNewTCB = ( TCB_t * ) pxTaskBuffer; /*lint !e740 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */ + pxNewTCB->pxStack = ( StackType_t * ) puxStackBuffer; - /* Check the alignment of the calculated top of stack is correct. */ - configASSERT( ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack & ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) == 0UL ) ); + #if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) + { + /* Tasks can be created statically or dynamically, so note this + task was created statically in case the task is later deleted. */ + pxNewTCB->ucStaticallyAllocated = tskSTATICALLY_ALLOCATED_STACK_AND_TCB; + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + + prvInitialiseNewTask( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, &xReturn, pxNewTCB, NULL ); + prvAddNewTaskToReadyList( pxNewTCB, pxTaskCode, xCoreID ); + } + else + { + xReturn = NULL; + } + + return xReturn; + } + +#endif /* SUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( portUSING_MPU_WRAPPERS == 1 ) + + BaseType_t xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) + { + TCB_t *pxNewTCB; + BaseType_t xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; + + configASSERT( pxTaskDefinition->puxStackBuffer ); + + if( pxTaskDefinition->puxStackBuffer != NULL ) + { + /* Allocate space for the TCB. Where the memory comes from depends + on the implementation of the port malloc function and whether or + not static allocation is being used. */ + pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); + + if( pxNewTCB != NULL ) + { + /* Store the stack location in the TCB. */ + pxNewTCB->pxStack = pxTaskDefinition->puxStackBuffer; + + /* Tasks can be created statically or dynamically, so note + this task had a statically allocated stack in case it is + later deleted. The TCB was allocated dynamically. */ + pxNewTCB->ucStaticallyAllocated = tskSTATICALLY_ALLOCATED_STACK_ONLY; + + prvInitialiseNewTask( pxTaskDefinition->pvTaskCode, + pxTaskDefinition->pcName, + ( uint32_t ) pxTaskDefinition->usStackDepth, + pxTaskDefinition->pvParameters, + pxTaskDefinition->uxPriority, + pxCreatedTask, pxNewTCB, + pxTaskDefinition->xRegions ); + + prvAddNewTaskToReadyList( pxNewTCB, pxTaskDefinition->pvTaskCode, tskNO_AFFINITY ); + xReturn = pdPASS; + } + } + + return xReturn; + } + +#endif /* portUSING_MPU_WRAPPERS */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + + BaseType_t xTaskCreatePinnedToCore( TaskFunction_t pxTaskCode, + const char * const pcName, + const uint16_t usStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * const pxCreatedTask, + const BaseType_t xCoreID ) + { + TCB_t *pxNewTCB; + BaseType_t xReturn; + + /* If the stack grows down then allocate the stack then the TCB so the stack + does not grow into the TCB. Likewise if the stack grows up then allocate + the TCB then the stack. */ + #if( portSTACK_GROWTH > 0 ) + { + /* Allocate space for the TCB. Where the memory comes from depends on + the implementation of the port malloc function and whether or not static + allocation is being used. */ + pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); + + if( pxNewTCB != NULL ) + { + /* Allocate space for the stack used by the task being created. + The base of the stack memory stored in the TCB so the task can + be deleted later if required. */ + pxNewTCB->pxStack = ( StackType_t * ) pvPortMalloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + + if( pxNewTCB->pxStack == NULL ) + { + /* Could not allocate the stack. Delete the allocated TCB. */ + vPortFree( pxNewTCB ); + pxNewTCB = NULL; + } + } } #else /* portSTACK_GROWTH */ { - pxTopOfStack = pxNewTCB->pxStack; + StackType_t *pxStack; - /* Check the alignment of the stack buffer is correct. */ - configASSERT( ( ( ( portPOINTER_SIZE_TYPE ) pxNewTCB->pxStack & ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) == 0UL ) ); + /* Allocate space for the stack used by the task being created. */ + pxStack = ( StackType_t * ) pvPortMalloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ - /* If we want to use stack checking on architectures that use - a positive stack growth direction then we also need to store the - other extreme of the stack space. */ - pxNewTCB->pxEndOfStack = pxNewTCB->pxStack + ( usStackDepth - 1 ); + if( pxStack != NULL ) + { + /* Allocate space for the TCB. */ + pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); /*lint !e961 MISRA exception as the casts are only redundant for some paths. */ + + if( pxNewTCB != NULL ) + { + /* Store the stack location in the TCB. */ + pxNewTCB->pxStack = pxStack; + } + else + { + /* The stack cannot be used as the TCB was not created. Free + it again. */ + vPortFree( pxStack ); + } + } + else + { + pxNewTCB = NULL; + } } #endif /* portSTACK_GROWTH */ - /* Setup the newly allocated TCB with the initial state of the task. */ - prvInitialiseTCBVariables( pxNewTCB, pcName, uxPriority, xRegions, usStackDepth, xCoreID ); + if( pxNewTCB != NULL ) + { + #if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) + { + /* Tasks can be created statically or dynamically, so note this + task was created dynamically in case it is later deleted. */ + pxNewTCB->ucStaticallyAllocated = tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB; + } + #endif /* configSUPPORT_STATIC_ALLOCATION */ - /* Initialize the TCB stack to look as if the task was already running, - but had been interrupted by the scheduler. The return address is set - to the start of the task function. Once the stack has been initialised - the top of stack variable is updated. */ - #if( portUSING_MPU_WRAPPERS == 1 ) - { - pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters, xRunPrivileged ); + prvInitialiseNewTask( pxTaskCode, pcName, ( uint32_t ) usStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB, NULL ); + prvAddNewTaskToReadyList( pxNewTCB, pxTaskCode, xCoreID ); + xReturn = pdPASS; } - #else /* portUSING_MPU_WRAPPERS */ + else { - pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters ); + xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; } - #endif /* portUSING_MPU_WRAPPERS */ - if( ( void * ) pxCreatedTask != NULL ) + return xReturn; + } + +#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, + const char * const pcName, + const uint32_t ulStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * const pxCreatedTask, + TCB_t *pxNewTCB, + const MemoryRegion_t * const xRegions ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ +{ +StackType_t *pxTopOfStack; +UBaseType_t x; + + #if( portUSING_MPU_WRAPPERS == 1 ) + /* Should the task be created in privileged mode? */ + BaseType_t xRunPrivileged; + if( ( uxPriority & portPRIVILEGE_BIT ) != 0U ) { - /* Pass the TCB out - in an anonymous way. The calling function/ - task can use this as a handle to delete the task later if - required.*/ - *pxCreatedTask = ( TaskHandle_t ) pxNewTCB; + xRunPrivileged = pdTRUE; + } + else + { + xRunPrivileged = pdFALSE; + } + uxPriority &= ~portPRIVILEGE_BIT; + #endif /* portUSING_MPU_WRAPPERS == 1 */ + + /* Avoid dependency on memset() if it is not required. */ + #if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) || ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) + { + /* Fill the stack with a known value to assist debugging. */ + ( void ) memset( pxNewTCB->pxStack, ( int ) tskSTACK_FILL_BYTE, ( size_t ) ulStackDepth * sizeof( StackType_t ) ); + } + #endif /* ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) || ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) ) */ + + /* Calculate the top of stack address. This depends on whether the stack + grows from high memory to low (as per the 80x86) or vice versa. + portSTACK_GROWTH is used to make the result positive or negative as required + by the port. */ + #if( portSTACK_GROWTH < 0 ) + { + pxTopOfStack = pxNewTCB->pxStack + ( ulStackDepth - ( uint32_t ) 1 ); + pxTopOfStack = ( StackType_t * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) ); /*lint !e923 MISRA exception. Avoiding casts between pointers and integers is not practical. Size differences accounted for using portPOINTER_SIZE_TYPE type. */ + + /* Check the alignment of the calculated top of stack is correct. */ + configASSERT( ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack & ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) == 0UL ) ); + } + #else /* portSTACK_GROWTH */ + { + pxTopOfStack = pxNewTCB->pxStack; + + /* Check the alignment of the stack buffer is correct. */ + configASSERT( ( ( ( portPOINTER_SIZE_TYPE ) pxNewTCB->pxStack & ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) == 0UL ) ); + + /* The other extreme of the stack space is required if stack checking is + performed. */ + pxNewTCB->pxEndOfStack = pxNewTCB->pxStack + ( ulStackDepth - ( uint32_t ) 1 ); + } + #endif /* portSTACK_GROWTH */ + + /* Store the task name in the TCB. */ + for( x = ( UBaseType_t ) 0; x < ( UBaseType_t ) configMAX_TASK_NAME_LEN; x++ ) + { + pxNewTCB->pcTaskName[ x ] = pcName[ x ]; + + /* Don't copy all configMAX_TASK_NAME_LEN if the string is shorter than + configMAX_TASK_NAME_LEN characters just in case the memory after the + string is not accessible (extremely unlikely). */ + if( pcName[ x ] == 0x00 ) + { + break; } else { mtCOVERAGE_TEST_MARKER(); } + } - /* Ensure interrupts don't access the task lists while they are being - updated. */ - taskENTER_CRITICAL(&xTaskQueueMutex); + /* Ensure the name string is terminated in the case that the string length + was greater or equal to configMAX_TASK_NAME_LEN. */ + pxNewTCB->pcTaskName[ configMAX_TASK_NAME_LEN - 1 ] = '\0'; + + /* This is used as an array index so must ensure it's not too large. First + remove the privilege bit if one is present. */ + if( uxPriority >= ( UBaseType_t ) configMAX_PRIORITIES ) + { + uxPriority = ( UBaseType_t ) configMAX_PRIORITIES - ( UBaseType_t ) 1U; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + pxNewTCB->uxPriority = uxPriority; + #if ( configUSE_MUTEXES == 1 ) + { + pxNewTCB->uxBasePriority = uxPriority; + pxNewTCB->uxMutexesHeld = 0; + } + #endif /* configUSE_MUTEXES */ + + vListInitialiseItem( &( pxNewTCB->xGenericListItem ) ); + vListInitialiseItem( &( pxNewTCB->xEventListItem ) ); + + /* Set the pxNewTCB as a link back from the ListItem_t. This is so we can get + back to the containing TCB from a generic item in a list. */ + listSET_LIST_ITEM_OWNER( &( pxNewTCB->xGenericListItem ), pxNewTCB ); + + /* Event lists are always in priority order. */ + listSET_LIST_ITEM_VALUE( &( pxNewTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + listSET_LIST_ITEM_OWNER( &( pxNewTCB->xEventListItem ), pxNewTCB ); + + #if ( portCRITICAL_NESTING_IN_TCB == 1 ) + { + pxNewTCB->uxCriticalNesting = ( UBaseType_t ) 0U; + } + #endif /* portCRITICAL_NESTING_IN_TCB */ + + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + { + pxNewTCB->pxTaskTag = NULL; + } + #endif /* configUSE_APPLICATION_TASK_TAG */ + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + { + pxNewTCB->ulRunTimeCounter = 0UL; + } + #endif /* configGENERATE_RUN_TIME_STATS */ + + #if ( portUSING_MPU_WRAPPERS == 1 ) + { + vPortStoreTaskMPUSettings( &( pxNewTCB->xMPUSettings ), xRegions, pxNewTCB->pxStack, ulStackDepth ); + } + #else + { + /* Avoid compiler warning about unreferenced parameter. */ + ( void ) xRegions; + } + #endif + + #if( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + { + for( x = 0; x < ( UBaseType_t ) configNUM_THREAD_LOCAL_STORAGE_POINTERS; x++ ) { - uxCurrentNumberOfTasks++; + pxNewTCB->pvThreadLocalStoragePointers[ x ] = NULL; + } + } + #endif + + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + { + pxNewTCB->ulNotifiedValue = 0; + pxNewTCB->eNotifyState = eNotWaitingNotification; + } + #endif + + #if ( configUSE_NEWLIB_REENTRANT == 1 ) + { + /* Initialise this task's Newlib reent structure. */ + _REENT_INIT_PTR( ( &( pxNewTCB->xNewLib_reent ) ) ); + } + #endif + + #if( INCLUDE_xTaskAbortDelay == 1 ) + { + pxNewTCB->ucDelayAborted = pdFALSE; + } + #endif + + /* Initialize the TCB stack to look as if the task was already running, + but had been interrupted by the scheduler. The return address is set + to the start of the task function. Once the stack has been initialised + the top of stack variable is updated. */ + #if( portUSING_MPU_WRAPPERS == 1 ) + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters, xRunPrivileged ); + } + #else /* portUSING_MPU_WRAPPERS */ + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters ); + } + #endif /* portUSING_MPU_WRAPPERS */ + + if( ( void * ) pxCreatedTask != NULL ) + { + /* Pass the handle out in an anonymous way. The handle can be used to + change the created task's priority, delete the created task, etc.*/ + *pxCreatedTask = ( TaskHandle_t ) pxNewTCB; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } +} +/*-----------------------------------------------------------*/ + +static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB, TaskFunction_t pxTaskCode, const BaseType_t xCoreID ) +{ + BaseType_t i; + + /* Ensure interrupts don't access the task lists while the lists are being + updated. */ + taskENTER_CRITICAL(&xTaskQueueMutex); + { + uxCurrentNumberOfTasks++; + if( pxCurrentTCB[ xPortGetCoreID() ] == NULL ) + { + /* There are no other tasks, or all the other tasks are in + the suspended state - make this the current task. */ + pxCurrentTCB[ xPortGetCoreID() ] = pxNewTCB; + if( uxCurrentNumberOfTasks == ( UBaseType_t ) 1 ) { /* This is the first task to be created so do the preliminary @@ -704,6 +1027,16 @@ BaseType_t i; fails, but we will report the failure. */ prvInitialiseTaskLists(); } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* If the scheduler is not already running, make this task the + current task if it is the highest priority task to be created + so far. */ if( xSchedulerRunning == pdFALSE ) { /* Scheduler isn't running yet. We need to determine on which CPU to run this task. */ @@ -713,7 +1046,7 @@ BaseType_t i; if (xCoreID == tskNO_AFFINITY || xCoreID == i) { /* Schedule if nothing is scheduled yet, or overwrite a task of lower prio. */ - if ( pxCurrentTCB[i] == NULL || pxCurrentTCB[i]->uxPriority <= uxPriority ) + if ( pxCurrentTCB[i] == NULL || pxCurrentTCB[i]->uxPriority <= pxNewTCB->uxPriority ) { #if portFIRST_TASK_HOOK if ( i == 0) { @@ -731,56 +1064,45 @@ BaseType_t i; { mtCOVERAGE_TEST_MARKER(); } - - uxTaskNumber++; - - #if ( configUSE_TRACE_FACILITY == 1 ) - { - /* Add a counter into the TCB for tracing only. */ - pxNewTCB->uxTCBNumber = uxTaskNumber; - } - #endif /* configUSE_TRACE_FACILITY */ - traceTASK_CREATE( pxNewTCB ); - - prvAddTaskToReadyList( pxNewTCB ); - - xReturn = pdPASS; - portSETUP_TCB( pxNewTCB ); } - taskEXIT_CRITICAL(&xTaskQueueMutex); - } - else - { - xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; - traceTASK_CREATE_FAILED(); - } - if( xReturn == pdPASS ) - { - if( xSchedulerRunning != pdFALSE ) + uxTaskNumber++; + + #if ( configUSE_TRACE_FACILITY == 1 ) { - /* Scheduler is running. If the created task is of a higher priority than an executing task - then it should run now. - ToDo: This only works for the current core. If a task is scheduled on an other processor, - the other processor will keep running the task it's working on, and only switch to the newer - task on a timer interrupt. */ - //No mux here, uxPriority is mostly atomic and there's not really any harm if this check misfires. - if( pxCurrentTCB[ xPortGetCoreID() ]->uxPriority < uxPriority ) - { - taskYIELD_IF_USING_PREEMPTION(); - } - else - { - mtCOVERAGE_TEST_MARKER(); - } + /* Add a counter into the TCB for tracing only. */ + pxNewTCB->uxTCBNumber = uxTaskNumber; + } + #endif /* configUSE_TRACE_FACILITY */ + traceTASK_CREATE( pxNewTCB ); + + prvAddTaskToReadyList( pxNewTCB ); + + portSETUP_TCB( pxNewTCB ); + } + taskEXIT_CRITICAL(&xTaskQueueMutex); + + if( xSchedulerRunning != pdFALSE ) + { + /* Scheduler is running. If the created task is of a higher priority than an executing task + then it should run now. + ToDo: This only works for the current core. If a task is scheduled on an other processor, + the other processor will keep running the task it's working on, and only switch to the newer + task on a timer interrupt. */ + //No mux here, uxPriority is mostly atomic and there's not really any harm if this check misfires. + if( pxCurrentTCB[ xPortGetCoreID() ]->uxPriority < pxNewTCB->uxPriority ) + { + taskYIELD_IF_USING_PREEMPTION(); } else { mtCOVERAGE_TEST_MARKER(); } } - - return xReturn; + else + { + mtCOVERAGE_TEST_MARKER(); + } } /*-----------------------------------------------------------*/ @@ -2971,120 +3293,6 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters ) #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ -static void prvInitialiseTCBVariables( TCB_t * const pxTCB, const char * const pcName, UBaseType_t uxPriority, const MemoryRegion_t * const xRegions, const uint16_t usStackDepth, const BaseType_t xCoreID ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ -{ -UBaseType_t x; - - /* Store the task name in the TCB. */ - for( x = ( UBaseType_t ) 0; x < ( UBaseType_t ) configMAX_TASK_NAME_LEN; x++ ) - { - pxTCB->pcTaskName[ x ] = pcName[ x ]; - - /* Don't copy all configMAX_TASK_NAME_LEN if the string is shorter than - configMAX_TASK_NAME_LEN characters just in case the memory after the - string is not accessible (extremely unlikely). */ - if( pcName[ x ] == 0x00 ) - { - break; - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - } - - /* Ensure the name string is terminated in the case that the string length - was greater or equal to configMAX_TASK_NAME_LEN. */ - pxTCB->pcTaskName[ configMAX_TASK_NAME_LEN - 1 ] = '\0'; - - /* This is used as an array index so must ensure it's not too large. First - remove the privilege bit if one is present. */ - if( uxPriority >= ( UBaseType_t ) configMAX_PRIORITIES ) - { - uxPriority = ( UBaseType_t ) configMAX_PRIORITIES - ( UBaseType_t ) 1U; - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - - pxTCB->uxPriority = uxPriority; - pxTCB->xCoreID = xCoreID; - #if ( configUSE_MUTEXES == 1 ) - { - pxTCB->uxBasePriority = uxPriority; - pxTCB->uxMutexesHeld = 0; - } - #endif /* configUSE_MUTEXES */ - - vListInitialiseItem( &( pxTCB->xGenericListItem ) ); - vListInitialiseItem( &( pxTCB->xEventListItem ) ); - - /* Set the pxTCB as a link back from the ListItem_t. This is so we can get - back to the containing TCB from a generic item in a list. */ - listSET_LIST_ITEM_OWNER( &( pxTCB->xGenericListItem ), pxTCB ); - - /* Event lists are always in priority order. */ - listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ - listSET_LIST_ITEM_OWNER( &( pxTCB->xEventListItem ), pxTCB ); - - #if ( portCRITICAL_NESTING_IN_TCB == 1 ) - { - pxTCB->uxCriticalNesting = ( UBaseType_t ) 0U; - } - #endif /* portCRITICAL_NESTING_IN_TCB */ - - #if ( configUSE_APPLICATION_TASK_TAG == 1 ) - { - pxTCB->pxTaskTag = NULL; - } - #endif /* configUSE_APPLICATION_TASK_TAG */ - - #if ( configGENERATE_RUN_TIME_STATS == 1 ) - { - pxTCB->ulRunTimeCounter = 0UL; - } - #endif /* configGENERATE_RUN_TIME_STATS */ - - #if ( portUSING_MPU_WRAPPERS == 1 ) - { - vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), xRegions, pxTCB->pxStack, usStackDepth ); - } - #else /* portUSING_MPU_WRAPPERS */ - { - ( void ) xRegions; - ( void ) usStackDepth; - } - #endif /* portUSING_MPU_WRAPPERS */ - - #if( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) - { - for( x = 0; x < ( UBaseType_t ) configNUM_THREAD_LOCAL_STORAGE_POINTERS; x++ ) - { - pxTCB->pvThreadLocalStoragePointers[ x ] = NULL; - #if ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS ) - pxTCB->pvThreadLocalStoragePointersDelCallback[ x ] = (TlsDeleteCallbackFunction_t)NULL; - #endif - } - } - #endif - - - #if ( configUSE_TASK_NOTIFICATIONS == 1 ) - { - pxTCB->ulNotifiedValue = 0; - pxTCB->eNotifyState = eNotWaitingNotification; - } - #endif - - #if ( configUSE_NEWLIB_REENTRANT == 1 ) - { - /* Initialise this task's Newlib reent structure. */ - _REENT_INIT_PTR( ( &( pxTCB->xNewLib_reent ) ) ); - } - #endif /* configUSE_NEWLIB_REENTRANT */ -} -/*-----------------------------------------------------------*/ #if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) #if ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS ) @@ -3280,81 +3488,6 @@ static void prvAddCurrentTaskToDelayedList( const BaseType_t xCoreID, const Tick } /*-----------------------------------------------------------*/ -static TCB_t *prvAllocateTCBAndStack( const uint16_t usStackDepth, StackType_t * const puxStackBuffer ) -{ -TCB_t *pxNewTCB; - - /* If the stack grows down then allocate the stack then the TCB so the stack - does not grow into the TCB. Likewise if the stack grows up then allocate - the TCB then the stack. */ - #if( portSTACK_GROWTH > 0 ) - { - /* Allocate space for the TCB. Where the memory comes from depends on - the implementation of the port malloc function. */ - pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); - - if( pxNewTCB != NULL ) - { - /* Allocate space for the stack used by the task being created. - The base of the stack memory stored in the TCB so the task can - be deleted later if required. */ - pxNewTCB->pxStack = ( StackType_t * ) pvPortMallocAligned( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ), puxStackBuffer ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ - - if( pxNewTCB->pxStack == NULL ) - { - /* Could not allocate the stack. Delete the allocated TCB. */ - vPortFree( pxNewTCB ); - pxNewTCB = NULL; - } - } - } - #else /* portSTACK_GROWTH */ - { - StackType_t *pxStack; - - /* Allocate space for the stack used by the task being created. */ - pxStack = ( StackType_t * ) pvPortMallocAligned( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ), puxStackBuffer ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ - - if( pxStack != NULL ) - { - /* Allocate space for the TCB. Where the memory comes from depends - on the implementation of the port malloc function. */ - pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); - - if( pxNewTCB != NULL ) - { - /* Store the stack location in the TCB. */ - pxNewTCB->pxStack = pxStack; - } - else - { - /* The stack cannot be used as the TCB was not created. Free it - again. */ - vPortFree( pxStack ); - } - } - else - { - pxNewTCB = NULL; - } - } - #endif /* portSTACK_GROWTH */ - - if( pxNewTCB != NULL ) - { - /* Avoid dependency on memset() if it is not required. */ - #if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) || ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) - { - /* Just to help debugging. */ - ( void ) memset( pxNewTCB->pxStack, ( int ) tskSTACK_FILL_BYTE, ( size_t ) usStackDepth * sizeof( StackType_t ) ); - } - #endif /* ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) || ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) ) */ - } - - return pxNewTCB; -} -/*-----------------------------------------------------------*/ - #if ( configUSE_TRACE_FACILITY == 1 ) static UBaseType_t prvListTaskWithinSingleList( TaskStatus_t *pxTaskStatusArray, List_t *pxList, eTaskState eState ) @@ -3509,22 +3642,40 @@ TCB_t *pxNewTCB; } #endif /* configUSE_NEWLIB_REENTRANT */ - #if( portUSING_MPU_WRAPPERS == 1 ) + #if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) && ( portUSING_MPU_WRAPPERS == 0 ) ) { - /* Only free the stack if it was allocated dynamically in the first - place. */ - if( pxTCB->xUsingStaticallyAllocatedStack == pdFALSE ) + /* The task can only have been allocated dynamically - free both + the stack and TCB. */ + vPortFreeAligned( pxTCB->pxStack ); + vPortFree( pxTCB ); + } + #elif( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE == 1 ) + { + /* The task could have been allocated statically or dynamically, so + check what was statically allocated before trying to free the + memory. */ + if( pxTCB->ucStaticallyAllocated == tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB ) { + /* Both the stack and TCB were allocated dynamically, so both + must be freed. */ vPortFreeAligned( pxTCB->pxStack ); + vPortFree( pxTCB ); + } + else if( pxTCB->ucStaticallyAllocated == tskSTATICALLY_ALLOCATED_STACK_ONLY ) + { + /* Only the stack was statically allocated, so the TCB is the + only memory that must be freed. */ + vPortFree( pxTCB ); + } + else + { + /* Neither the stack nor the TCB were allocated dynamically, so + nothing needs to be freed. */ + configASSERT( pxTCB->ucStaticallyAllocated == tskSTATICALLY_ALLOCATED_STACK_AND_TCB ) + mtCOVERAGE_TEST_MARKER(); } } - #else - { - vPortFreeAligned( pxTCB->pxStack ); - } - #endif - - vPortFree( pxTCB ); + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ } #endif /* INCLUDE_vTaskDelete */ @@ -3932,7 +4083,9 @@ scheduler will re-enable the interrupts instead. */ function is executing. */ uxArraySize = uxCurrentNumberOfTasks; - /* Allocate an array index for each task. */ + /* Allocate an array index for each task. NOTE! if + configSUPPORT_DYNAMIC_ALLOCATION is set to 0 then pvPortMalloc() will + equate to NULL. */ pxTaskStatusArray = pvPortMalloc( uxCurrentNumberOfTasks * sizeof( TaskStatus_t ) ); if( pxTaskStatusArray != NULL ) @@ -3972,7 +4125,8 @@ scheduler will re-enable the interrupts instead. */ pcWriteBuffer += strlen( pcWriteBuffer ); } - /* Free the array again. */ + /* Free the array again. NOTE! If configSUPPORT_DYNAMIC_ALLOCATION + is 0 then vPortFree() will be #defined to nothing. */ vPortFree( pxTaskStatusArray ); } else @@ -4030,7 +4184,9 @@ scheduler will re-enable the interrupts instead. */ function is executing. */ uxArraySize = uxCurrentNumberOfTasks; - /* Allocate an array index for each task. */ + /* Allocate an array index for each task. NOTE! If + configSUPPORT_DYNAMIC_ALLOCATION is set to 0 then pvPortMalloc() will + equate to NULL. */ pxTaskStatusArray = pvPortMalloc( uxCurrentNumberOfTasks * sizeof( TaskStatus_t ) ); if( pxTaskStatusArray != NULL ) @@ -4096,7 +4252,8 @@ scheduler will re-enable the interrupts instead. */ mtCOVERAGE_TEST_MARKER(); } - /* Free the array again. */ + /* Free the array again. NOTE! If configSUPPORT_DYNAMIC_ALLOCATION + is 0 then vPortFree() will be #defined to nothing. */ vPortFree( pxTaskStatusArray ); } else From 2cc32db52dd4d4de8a0521153f5dbd598106ec19 Mon Sep 17 00:00:00 2001 From: dongheng Date: Thu, 22 Sep 2016 14:42:49 +0800 Subject: [PATCH 009/343] component/openssl: add openssl stack function and clear unused variate 1. add openssl 'new' and 'free' function 2. add clear unused variate to void warning to appear when compile 3. add internal function 'X509_new' to take the place of 'sk_X509_NAME_new_null' function whitch is openssl stack function --- components/openssl/include/internal/ssl_dbg.h | 6 ++--- .../openssl/include/internal/ssl_types.h | 21 ++++++++++++---- .../openssl/include/internal/ssl_x509.h | 10 +++++++- components/openssl/include/openssl/ssl.h | 4 ++-- components/openssl/library/ssl_cert.c | 2 +- components/openssl/library/ssl_lib.c | 20 +++++----------- components/openssl/library/ssl_pkey.c | 5 +++- components/openssl/library/ssl_x509.c | 24 ++++++++++++++++--- 8 files changed, 62 insertions(+), 30 deletions(-) diff --git a/components/openssl/include/internal/ssl_dbg.h b/components/openssl/include/internal/ssl_dbg.h index 27a192b28f..745de536ff 100644 --- a/components/openssl/include/internal/ssl_dbg.h +++ b/components/openssl/include/internal/ssl_dbg.h @@ -15,10 +15,10 @@ #ifndef _SSL_DEBUG_H_ #define _SSL_DEBUG_H_ -#define SSL_DEBUG_ENBALE 1 +#define SSL_DEBUG_ENBALE 0 #define SSL_DEBUG_LEVEL 0 -#define SSL_ASSERT_ENABLE 1 -#define SSL_DEBUG_LOCATION_ENABLE 1 +#define SSL_ASSERT_ENABLE 0 +#define SSL_DEBUG_LOCATION_ENABLE 0 #if SSL_DEBUG_ENBALE extern int ets_printf(const char *fmt, ...); diff --git a/components/openssl/include/internal/ssl_types.h b/components/openssl/include/internal/ssl_types.h index 7f8503e2ab..133feb9dc1 100644 --- a/components/openssl/include/internal/ssl_types.h +++ b/components/openssl/include/internal/ssl_types.h @@ -27,6 +27,12 @@ typedef void RSA; typedef void STACK; typedef void BIO; +#define ossl_inline inline + +#define SSL_METHOD_CALL(f, s, ...) s->method->func->ssl_##f(s, ##__VA_ARGS__) +#define X509_METHOD_CALL(f, x, ...) x->method->x509_##f(x, ##__VA_ARGS__) +#define EVP_PKEY_METHOD_CALL(f, k, ...) k->method->pkey_##f(k, ##__VA_ARGS__) + #define STACK_OF(type) struct stack_st_##type #define SKM_DEFINE_STACK_OF(t1, t2, t3) \ @@ -38,6 +44,8 @@ typedef void BIO; #define DEFINE_STACK_OF(t) SKM_DEFINE_STACK_OF(t, t, t) +typedef int (*OPENSSL_sk_compfunc)(const void *, const void *); + struct stack_st; typedef struct stack_st OPENSSL_STACK; @@ -78,7 +86,12 @@ struct pkey_method_st; typedef struct pkey_method_st PKEY_METHOD; struct stack_st { - char *data; + + char **data; + + int num_alloc; + + OPENSSL_sk_compfunc c; }; struct evp_pkey_st { @@ -178,6 +191,8 @@ struct ssl_st int rwstate; + X509 *client_CA; + int err; void (*info_callback) (const SSL *ssl, int type, int val); @@ -249,8 +264,4 @@ typedef int (*next_proto_cb)(SSL *ssl, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg); -#define SSL_METHOD_CALL(f, s, ...) s->method->func->ssl_##f(s, ##__VA_ARGS__) -#define X509_METHOD_CALL(f, x, ...) x->method->x509_##f(x, ##__VA_ARGS__) -#define EVP_PKEY_METHOD_CALL(f, k, ...) k->method->pkey_##f(k, ##__VA_ARGS__) - #endif diff --git a/components/openssl/include/internal/ssl_x509.h b/components/openssl/include/internal/ssl_x509.h index 0583cd94e4..ee3448544b 100644 --- a/components/openssl/include/internal/ssl_x509.h +++ b/components/openssl/include/internal/ssl_x509.h @@ -16,10 +16,18 @@ #define _SSL_X509_H_ #include "ssl_types.h" +#include "ssl_stack.h" DEFINE_STACK_OF(X509_NAME) -X509* sk_X509_NAME_new_null(void); +/* + * sk_X509_NAME_new_null - create a X509 certification object + * + * @param none + * + * @return X509 certification object point or NULL if failed + */ +X509* X509_new(void); X509* d2i_X509(X509 **cert, const unsigned char *buffer, long len); diff --git a/components/openssl/include/openssl/ssl.h b/components/openssl/include/openssl/ssl.h index 0d4c9c2080..b7506c8fb0 100644 --- a/components/openssl/include/openssl/ssl.h +++ b/components/openssl/include/openssl/ssl.h @@ -15,8 +15,8 @@ #ifndef _SSL_H_ #define _SSL_H_ -#include "ssl_port.h" -#include "internal/ssl_types.h" +#include "platform/ssl_port.h" +#include "internal/ssl_x509.h" /* { diff --git a/components/openssl/library/ssl_cert.c b/components/openssl/library/ssl_cert.c index 0bdba459d3..caa901b660 100644 --- a/components/openssl/library/ssl_cert.c +++ b/components/openssl/library/ssl_cert.c @@ -37,7 +37,7 @@ CERT *ssl_cert_new(void) if (!cert->pkey) SSL_RET(failed2, "EVP_PKEY_new\n"); - cert->x509 = sk_X509_NAME_new_null(); + cert->x509 = X509_new(); if (!cert->x509) SSL_RET(failed3, "sk_X509_NAME_new_null\n"); diff --git a/components/openssl/library/ssl_lib.c b/components/openssl/library/ssl_lib.c index 331ed17bd5..36e8cdf794 100644 --- a/components/openssl/library/ssl_lib.c +++ b/components/openssl/library/ssl_lib.c @@ -169,28 +169,27 @@ OSSL_HANDSHAKE_STATE SSL_get_state(const SSL *ssl) */ SSL_CTX* SSL_CTX_new(const SSL_METHOD *method) { - int ret; SSL_CTX *ctx; CERT *cert; X509 *client_ca; if (!method) SSL_RET(go_failed1, "method\n"); - client_ca = sk_X509_NAME_new_null(); + client_ca = X509_new(); if (!client_ca) - SSL_ERR(-2, go_failed1, "sk_X509_NAME_new_null\n"); + SSL_RET(go_failed1, "sk_X509_NAME_new_null\n"); cert = ssl_cert_new(); if (!cert) - SSL_ERR(-2, go_failed2, "ssl_cert_new\n"); + SSL_RET(go_failed2, "ssl_cert_new\n"); ctx = (SSL_CTX *)ssl_zalloc(sizeof(SSL_CTX)); if (!ctx) - SSL_ERR(-2, go_failed3, "ssl_ctx_new:ctx\n"); + SSL_RET(go_failed3, "ssl_ctx_new:ctx\n"); ctx->method = method; - ctx->cert = cert; ctx->client_CA = client_ca; + ctx->cert = cert; ctx->version = method->version; @@ -268,7 +267,6 @@ const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx) SSL *SSL_new(SSL_CTX *ctx) { int ret; - void *ssl_pm; SSL *ssl; if (!ctx) @@ -485,7 +483,7 @@ int SSL_write(SSL *ssl, const void *buffer, int len) else bytes = send_bytes; - ret = SSL_METHOD_CALL(send, ssl, buffer, len); + ret = SSL_METHOD_CALL(send, ssl, buffer, bytes); if (ret > 0) { pbuf += ret; send_bytes -= ret; @@ -798,8 +796,6 @@ int SSL_get_wfd(const SSL *ssl) */ int SSL_set_fd(SSL *ssl, int fd) { - int ret; - SSL_ASSERT(ssl); SSL_ASSERT(fd >= 0); @@ -820,8 +816,6 @@ int SSL_set_fd(SSL *ssl, int fd) */ int SSL_set_rfd(SSL *ssl, int fd) { - int ret; - SSL_ASSERT(ssl); SSL_ASSERT(fd >= 0); @@ -842,8 +836,6 @@ int SSL_set_rfd(SSL *ssl, int fd) */ int SSL_set_wfd(SSL *ssl, int fd) { - int ret; - SSL_ASSERT(ssl); SSL_ASSERT(fd >= 0); diff --git a/components/openssl/library/ssl_pkey.c b/components/openssl/library/ssl_pkey.c index 0c8d9de8fa..c9866e27b5 100644 --- a/components/openssl/library/ssl_pkey.c +++ b/components/openssl/library/ssl_pkey.c @@ -78,6 +78,7 @@ EVP_PKEY *d2i_PrivateKey(int type, const unsigned char **pp, long length) { + int m = 0; int ret; EVP_PKEY *pkey; @@ -91,6 +92,7 @@ EVP_PKEY *d2i_PrivateKey(int type, pkey = EVP_PKEY_new();; if (!pkey) SSL_RET(failed1, "ssl_malloc\n"); + m = 1; } ret = EVP_PKEY_METHOD_CALL(load, pkey, *pp, length); @@ -103,7 +105,8 @@ EVP_PKEY *d2i_PrivateKey(int type, return pkey; failed2: - EVP_PKEY_free(pkey); + if (m) + EVP_PKEY_free(pkey); failed1: return NULL; } diff --git a/components/openssl/library/ssl_x509.c b/components/openssl/library/ssl_x509.c index e322b6ad3d..9c38849dd6 100644 --- a/components/openssl/library/ssl_x509.c +++ b/components/openssl/library/ssl_x509.c @@ -24,7 +24,7 @@ * * @return X509 certification object point or NULL if failed */ -X509* sk_X509_NAME_new_null(void) +X509* X509_new(void) { int ret; X509 *x; @@ -73,6 +73,7 @@ void X509_free(X509 *x) */ X509* d2i_X509(X509 **cert, const unsigned char *buffer, long len) { + int m = 0; int ret; X509 *x; @@ -82,9 +83,10 @@ X509* d2i_X509(X509 **cert, const unsigned char *buffer, long len) if (cert && *cert) { x = *cert; } else { - x = sk_X509_NAME_new_null(); + x = X509_new(); if (!x) SSL_RET(failed1, "sk_X509_NAME_new_null\n"); + m = 1; } ret = X509_METHOD_CALL(load, x, buffer, len); @@ -94,7 +96,8 @@ X509* d2i_X509(X509 **cert, const unsigned char *buffer, long len) return x; failed2: - X509_free(x); + if (m) + X509_free(x); failed1: return NULL; } @@ -111,9 +114,14 @@ failed1: */ int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) { + int ret; + SSL_ASSERT(ctx); SSL_ASSERT(x); + if (ctx->client_CA) + X509_free(ctx->client_CA); + ctx->client_CA = x; return 1; @@ -131,7 +139,17 @@ int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) */ int SSL_add_client_CA(SSL *ssl, X509 *x) { + int ret; + SSL_ASSERT(ssl); + SSL_ASSERT(x); + + if (ssl->client_CA) + X509_free(ssl->client_CA); + + ssl->client_CA = x; + + return 1; } /* From b3145446aa31118a3ab8d58f771ebc3998cd10cb Mon Sep 17 00:00:00 2001 From: dongheng Date: Thu, 22 Sep 2016 15:15:16 +0800 Subject: [PATCH 010/343] components/openssl: add function "ssl_pm_get_verify_result" 1. add function ssl_pm_get_verify_result 2. add its platform low-level interface --- components/openssl/include/internal/ssl_code.h | 1 + .../openssl/include/internal/ssl_methods.h | 2 ++ components/openssl/include/internal/ssl_types.h | 4 ++++ components/openssl/include/platform/ssl_pm.h | 2 ++ components/openssl/library/ssl_lib.c | 14 ++++++++++++++ components/openssl/library/ssl_methods.c | 1 + components/openssl/library/ssl_x509.c | 4 ---- components/openssl/platform/ssl_pm.c | 16 ++++++++++++++++ 8 files changed, 40 insertions(+), 4 deletions(-) diff --git a/components/openssl/include/internal/ssl_code.h b/components/openssl/include/internal/ssl_code.h index 1510ce6ff4..de86e07df1 100644 --- a/components/openssl/include/internal/ssl_code.h +++ b/components/openssl/include/internal/ssl_code.h @@ -17,6 +17,7 @@ #include "ssl3.h" #include "tls1.h" +#include "x509_vfy.h" /* Used in SSL_set_shutdown()/SSL_get_shutdown(); */ # define SSL_SENT_SHUTDOWN 1 diff --git a/components/openssl/include/internal/ssl_methods.h b/components/openssl/include/internal/ssl_methods.h index b72b17ad3d..244eec38dd 100644 --- a/components/openssl/include/internal/ssl_methods.h +++ b/components/openssl/include/internal/ssl_methods.h @@ -21,6 +21,7 @@ read, send, pending, \ set_fd, get_fd, \ set_bufflen, \ + get_verify_result, \ get_state) \ static const SSL_METHOD_FUNC func_name LOCAL_ATRR = { \ new, \ @@ -34,6 +35,7 @@ set_fd, \ get_fd, \ set_bufflen, \ + get_verify_result, \ get_state \ }; diff --git a/components/openssl/include/internal/ssl_types.h b/components/openssl/include/internal/ssl_types.h index 133feb9dc1..761250eef7 100644 --- a/components/openssl/include/internal/ssl_types.h +++ b/components/openssl/include/internal/ssl_types.h @@ -193,6 +193,8 @@ struct ssl_st X509 *client_CA; + long verify_result; + int err; void (*info_callback) (const SSL *ssl, int type, int val); @@ -235,6 +237,8 @@ struct ssl_method_func_st { void (*ssl_set_bufflen)(SSL *ssl, int len); + long (*ssl_get_verify_result)(const SSL *ssl); + OSSL_HANDSHAKE_STATE (*ssl_get_state)(const SSL *ssl); }; diff --git a/components/openssl/include/platform/ssl_pm.h b/components/openssl/include/platform/ssl_pm.h index 783ba5445e..3f64a4ae32 100644 --- a/components/openssl/include/platform/ssl_pm.h +++ b/components/openssl/include/platform/ssl_pm.h @@ -49,4 +49,6 @@ void pkey_pm_free(EVP_PKEY *pkey); int pkey_pm_load(EVP_PKEY *pkey, const unsigned char *buffer, int len); void pkey_pm_unload(EVP_PKEY *pkey); +long ssl_pm_get_verify_result(const SSL *ssl); + #endif diff --git a/components/openssl/library/ssl_lib.c b/components/openssl/library/ssl_lib.c index 36e8cdf794..ac41be6276 100644 --- a/components/openssl/library/ssl_lib.c +++ b/components/openssl/library/ssl_lib.c @@ -1731,3 +1731,17 @@ void SSL_set_verify(SSL *ssl, int mode, int (*verify_callback)(int, X509_STORE_C SSL_ASSERT(ssl); SSL_ASSERT(verify_callback); } + +/* + * SSL_get_verify_result - get the verifying result of the SSL certification + * + * @param ssl - the SSL point + * + * @return the result of verifying + */ +long SSL_get_verify_result(const SSL *ssl) +{ + SSL_ASSERT(ssl); + + return SSL_METHOD_CALL(get_verify_result, ssl); +} diff --git a/components/openssl/library/ssl_methods.c b/components/openssl/library/ssl_methods.c index 0c5c6e7fa4..c6fb40e59c 100644 --- a/components/openssl/library/ssl_methods.c +++ b/components/openssl/library/ssl_methods.c @@ -25,6 +25,7 @@ IMPLEMENT_TLS_METHOD_FUNC(TLS_method_func, ssl_pm_read, ssl_pm_send, ssl_pm_pending, ssl_pm_set_fd, ssl_pm_get_fd, ssl_pm_set_bufflen, + ssl_pm_get_verify_result, ssl_pm_get_state); /* diff --git a/components/openssl/library/ssl_x509.c b/components/openssl/library/ssl_x509.c index 9c38849dd6..102e5a543a 100644 --- a/components/openssl/library/ssl_x509.c +++ b/components/openssl/library/ssl_x509.c @@ -114,8 +114,6 @@ failed1: */ int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) { - int ret; - SSL_ASSERT(ctx); SSL_ASSERT(x); @@ -139,8 +137,6 @@ int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) */ int SSL_add_client_CA(SSL *ssl, X509 *x) { - int ret; - SSL_ASSERT(ssl); SSL_ASSERT(x); diff --git a/components/openssl/platform/ssl_pm.c b/components/openssl/platform/ssl_pm.c index 948c1bc4ee..ebb9687ea8 100644 --- a/components/openssl/platform/ssl_pm.c +++ b/components/openssl/platform/ssl_pm.c @@ -444,3 +444,19 @@ void ssl_pm_set_bufflen(SSL *ssl, int len) { max_content_len = len; } + +long ssl_pm_get_verify_result(const SSL *ssl) +{ + long ret; + long verify_result; + struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; + + ret = mbedtls_ssl_get_verify_result(&ssl_pm->ssl); + + if (!ret) + verify_result = X509_V_OK; + else + verify_result = X509_V_ERR_UNSPECIFIED; + + return verify_result; +} From 6f07409d7c639bfa9a6eecbf97a74d4c8d762861 Mon Sep 17 00:00:00 2001 From: dongheng Date: Thu, 22 Sep 2016 15:30:25 +0800 Subject: [PATCH 011/343] components/openssl: add function to set and get verify depth 1. add function to set and get SSL verify depth 2. add function to set and get SSL context verify depth 3. add X509_VERIFY_PARAM structure --- .../openssl/include/internal/ssl_types.h | 13 +++++ components/openssl/library/ssl_lib.c | 58 +++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/components/openssl/include/internal/ssl_types.h b/components/openssl/include/internal/ssl_types.h index 761250eef7..d001befdb9 100644 --- a/components/openssl/include/internal/ssl_types.h +++ b/components/openssl/include/internal/ssl_types.h @@ -76,6 +76,9 @@ typedef struct cert_st CERT; struct x509_st; typedef struct x509_st X509; +struct X509_VERIFY_PARAM_st; +typedef struct X509_VERIFY_PARAM_st X509_VERIFY_PARAM; + struct evp_pkey_st; typedef struct evp_pkey_st EVP_PKEY; @@ -139,6 +142,12 @@ struct ssl_session_st { long time; }; +struct X509_VERIFY_PARAM_st { + + int depth; + +}; + struct ssl_ctx_st { int version; @@ -164,6 +173,8 @@ struct ssl_ctx_st int read_ahead; int read_buffer_len; + + X509_VERIFY_PARAM param; }; struct ssl_st @@ -195,6 +206,8 @@ struct ssl_st long verify_result; + X509_VERIFY_PARAM param; + int err; void (*info_callback) (const SSL *ssl, int type, int val); diff --git a/components/openssl/library/ssl_lib.c b/components/openssl/library/ssl_lib.c index ac41be6276..442920f119 100644 --- a/components/openssl/library/ssl_lib.c +++ b/components/openssl/library/ssl_lib.c @@ -1745,3 +1745,61 @@ long SSL_get_verify_result(const SSL *ssl) return SSL_METHOD_CALL(get_verify_result, ssl); } + +/* + * SSL_CTX_get_verify_depth - get the SSL verifying depth of the SSL context + * + * @param ctx - SSL context point + * + * @return verifying depth + */ +int SSL_CTX_get_verify_depth(const SSL_CTX *ctx) +{ + SSL_ASSERT(ctx); + + return ctx->param.depth; +} + +/* + * SSL_CTX_set_verify_depth - set the SSL verify depth of the SSL context + * + * @param ctx - SSL context point + * @param depth - verifying depth + * + * @return one + */ +void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth) +{ + SSL_ASSERT(ctx); + + ctx->param.depth = depth; +} + +/* + * SSL_get_verify_depth - get the SSL verifying depth of the SSL + * + * @param ctx - SSL point + * + * @return verifying depth + */ +int SSL_get_verify_depth(const SSL *ssl) +{ + SSL_ASSERT(ssl); + + return ssl->param.depth; +} + +/* + * SSL_set_verify_depth - set the SSL verify depth of the SSL + * + * @param ctx - SSL point + * @param depth - verifying depth + * + * @return one + */ +void SSL_set_verify_depth(SSL *ssl, int depth) +{ + SSL_ASSERT(ssl); + + ssl->param.depth = depth; +} From 2faa2376a0de66af42ff2c55e00106472090677a Mon Sep 17 00:00:00 2001 From: dongheng Date: Thu, 22 Sep 2016 15:39:28 +0800 Subject: [PATCH 012/343] components/openssl: add empty function to load verify file into SSL context 1. add empty function to load private key into SSL context 2. add empty function to load certification into SSL context 3. add function to load RSA private key --- components/openssl/include/openssl/ssl.h | 4 +-- components/openssl/library/ssl_pkey.c | 31 ++++++++++++++++++++++++ components/openssl/library/ssl_x509.c | 15 ++++++++++++ 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/components/openssl/include/openssl/ssl.h b/components/openssl/include/openssl/ssl.h index b7506c8fb0..865405d868 100644 --- a/components/openssl/include/openssl/ssl.h +++ b/components/openssl/include/openssl/ssl.h @@ -927,7 +927,7 @@ int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, const unsigned char *d, l * 1 : OK * 0 : failed */ -int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type);//adds the first private key found in file to ctx, The formatting type of the certificate must be specified from the known types SSL_FILETYPE_PEM, SSL_FILETYPE_ASN1. +int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type); /* * SSL_CTX_use_certificate - load the RSA private key into SSL context @@ -952,7 +952,7 @@ int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa); * 1 : OK * 0 : failed */ -int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, unsigned char *d, long len); +int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len); /* * SSL_CTX_use_certificate_file - load the RSA private key file into SSL context diff --git a/components/openssl/library/ssl_pkey.c b/components/openssl/library/ssl_pkey.c index c9866e27b5..1ab080ac28 100644 --- a/components/openssl/library/ssl_pkey.c +++ b/components/openssl/library/ssl_pkey.c @@ -165,3 +165,34 @@ failed1: return 0; } +/* + * SSL_CTX_use_certificate_file - load the private key file into SSL context + * + * @param ctx - SSL context point + * @param file - private key file name + * @param type - private key encoding type + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) +{ + return 0; +} + +/* + * SSL_CTX_use_certificate_ASN1 - load the RSA ASN1 private key into SSL context + * + * @param ctx - SSL context point + * @param d - data point + * @param len - RSA private key length + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len) +{ + return SSL_CTX_use_PrivateKey_ASN1(0, ctx, d, len); +} diff --git a/components/openssl/library/ssl_x509.c b/components/openssl/library/ssl_x509.c index 102e5a543a..b0ddd42593 100644 --- a/components/openssl/library/ssl_x509.c +++ b/components/openssl/library/ssl_x509.c @@ -213,3 +213,18 @@ failed1: return 0; } +/* + * SSL_CTX_use_certificate_file - load the certification file into SSL context + * + * @param ctx - SSL context point + * @param file - certification file name + * @param type - certification encoding type + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) +{ + return 0; +} From a99f6bd727cea8d8cdee32d2f28b09c6cf4fae99 Mon Sep 17 00:00:00 2001 From: dongheng Date: Thu, 22 Sep 2016 15:56:56 +0800 Subject: [PATCH 013/343] components/openssl: add function load verify data into SSL 1. add function to load private key into SSL 1. add function to load certification into SSL --- components/openssl/library/ssl_pkey.c | 70 ++++++++++++++++++++++++++ components/openssl/library/ssl_x509.c | 71 +++++++++++++++++++++++++++ 2 files changed, 141 insertions(+) diff --git a/components/openssl/library/ssl_pkey.c b/components/openssl/library/ssl_pkey.c index 1ab080ac28..a86a257e98 100644 --- a/components/openssl/library/ssl_pkey.c +++ b/components/openssl/library/ssl_pkey.c @@ -131,6 +131,26 @@ int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) return 1; } +/* + * SSL_CTX_use_certificate - set the SSL private key + * + * @param ctx - SSL point + * @param x - private key point + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) +{ + SSL_ASSERT(ctx); + SSL_ASSERT(pkey); + + ssl->cert->pkey = pkey; + + return 1; +} + /* * SSL_CTX_use_PrivateKey_ASN1 - load private key into the SSL context * @@ -165,6 +185,40 @@ failed1: return 0; } +/* + * SSL_use_PrivateKey_ASN1 - load private key into the SSL + * + * @param type - private key type + * @param ctx - SSL context point + * @param d - private key context point + * @param len - private key context bytes + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, + const unsigned char *d, long len) +{ + int ret; + EVP_PKEY *pkey; + + pkey = d2i_PrivateKey(0, &ssl->cert->pkey, &d, len); + if (!pkey) + SSL_RET(failed1, "d2i_PrivateKey\n"); + + ret = SSL_use_PrivateKey(ssl, pkey); + if (!ret) + SSL_RET(failed2, "SSL_CTX_use_PrivateKey\n"); + + return 1; + +failed2: + EVP_PKEY_free(pkey); +failed1: + return 0; +} + /* * SSL_CTX_use_certificate_file - load the private key file into SSL context * @@ -181,6 +235,22 @@ int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) return 0; } +/* + * SSL_use_PrivateKey_file - load the private key file into SSL + * + * @param ctx - SSL point + * @param file - private key file name + * @param type - private key encoding type + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) +{ + return 0; +} + /* * SSL_CTX_use_certificate_ASN1 - load the RSA ASN1 private key into SSL context * diff --git a/components/openssl/library/ssl_x509.c b/components/openssl/library/ssl_x509.c index b0ddd42593..ba5c924e75 100644 --- a/components/openssl/library/ssl_x509.c +++ b/components/openssl/library/ssl_x509.c @@ -168,6 +168,26 @@ int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) return 1; } +/* + * SSL_CTX_use_certificate - set the SSL certification + * + * @param ctx - SSL point + * @param x - X509 certification point + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_use_certificate(SSL *ssl, X509 *x) +{ + SSL_ASSERT(ctx); + SSL_ASSERT(x); + + ssl->cert->x509 = x; + + return 1; +} + /* * SSL_get_certificate - get the SSL certification point * @@ -177,6 +197,8 @@ int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) */ X509 *SSL_get_certificate(const SSL *ssl) { + SSL_ASSERT(ssl); + return ssl->cert->x509; } @@ -213,6 +235,39 @@ failed1: return 0; } +/* + * SSL_use_certificate_ASN1 - load certification into the SSL + * + * @param ctx - SSL point + * @param len - certification context bytes + * @param d - certification context point + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_use_certificate_ASN1(SSL *ssl, int len, + const unsigned char *d) +{ + int ret; + X509 *cert; + + cert = d2i_X509(&ssl->cert->x509, d, len); + if (!cert) + SSL_RET(failed1, "d2i_X509\n"); + + ret = SSL_use_certificate(ssl, cert); + if (!ret) + SSL_RET(failed2, "SSL_use_certificate\n"); + + return 1; + +failed2: + X509_free(cert); +failed1: + return 0; +} + /* * SSL_CTX_use_certificate_file - load the certification file into SSL context * @@ -228,3 +283,19 @@ int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) { return 0; } + +/* + * SSL_use_certificate_file - load the certification file into SSL + * + * @param ctx - SSL point + * @param file - certification file name + * @param type - certification encoding type + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_use_certificate_file(SSL *ssl, const char *file, int type) +{ + return 0; +} From fa6f03f77f3ff81f676d6bad017194c50d7cc2a1 Mon Sep 17 00:00:00 2001 From: dongheng Date: Thu, 22 Sep 2016 16:08:36 +0800 Subject: [PATCH 014/343] components/openssl: add function to load certification or private key more than one time --- components/openssl/platform/ssl_pm.c | 42 ++++++++++++++++------------ 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/components/openssl/platform/ssl_pm.c b/components/openssl/platform/ssl_pm.c index ebb9687ea8..17cc080bb6 100644 --- a/components/openssl/platform/ssl_pm.c +++ b/components/openssl/platform/ssl_pm.c @@ -339,6 +339,16 @@ int x509_pm_new(X509 *x) return 0; } +void x509_pm_unload(X509 *x) +{ + struct x509_pm *x509_pm = (struct x509_pm *)x->x509_pm; + + if (x509_pm->load) + mbedtls_x509_crt_free(&x509_pm->x509_crt); + + x509_pm->load = 0; +} + int x509_pm_load(X509 *x, const unsigned char *buffer, int len) { int ret; @@ -352,6 +362,8 @@ int x509_pm_load(X509 *x, const unsigned char *buffer, int len) ssl_memcpy(load_buf, buffer, len); load_buf[len] = '\0'; + x509_pm_unload(x); + mbedtls_x509_crt_init(&x509_pm->x509_crt); ret = mbedtls_x509_crt_parse(&x509_pm->x509_crt, load_buf, len); ssl_free(load_buf); @@ -367,15 +379,6 @@ failed1: return -1; } -void x509_pm_unload(X509 *x) -{ - struct x509_pm *x509_pm = (struct x509_pm *)x->x509_pm; - - mbedtls_x509_crt_free(&x509_pm->x509_crt); - - x509_pm->load = 0; -} - void x509_pm_free(X509 *x) { x509_pm_unload(x); @@ -396,6 +399,16 @@ int pkey_pm_new(EVP_PKEY *pkey) return 0; } +void pkey_pm_unload(EVP_PKEY *pkey) +{ + struct pkey_pm *pkey_pm = (struct pkey_pm *)pkey->pkey_pm; + + if (pkey_pm->load) + mbedtls_pk_free(&pkey_pm->pkey); + + pkey_pm->load = 0; +} + int pkey_pm_load(EVP_PKEY *pkey, const unsigned char *buffer, int len) { int ret; @@ -409,6 +422,8 @@ int pkey_pm_load(EVP_PKEY *pkey, const unsigned char *buffer, int len) ssl_memcpy(load_buf, buffer, len); load_buf[len] = '\0'; + pkey_pm_unload(pkey); + mbedtls_pk_init(&pkey_pm->pkey); ret = mbedtls_pk_parse_key(&pkey_pm->pkey, load_buf, len, NULL, 0); ssl_free(load_buf); @@ -424,15 +439,6 @@ failed1: return -1; } -void pkey_pm_unload(EVP_PKEY *pkey) -{ - struct pkey_pm *pkey_pm = (struct pkey_pm *)pkey->pkey_pm; - - mbedtls_pk_free(&pkey_pm->pkey); - - pkey_pm->load = 0; -} - void pkey_pm_free(EVP_PKEY *pkey) { pkey_pm_unload(pkey); From f796b4e58ef2311e11b51f15ef5e8807c84c5272 Mon Sep 17 00:00:00 2001 From: dongheng Date: Thu, 22 Sep 2016 16:41:51 +0800 Subject: [PATCH 015/343] components/openssl: SSL load verify data from itself structure when "new" --- components/openssl/include/internal/ssl_types.h | 4 ++++ components/openssl/library/ssl_lib.c | 3 +++ components/openssl/library/ssl_pkey.c | 9 ++++++++- components/openssl/library/ssl_x509.c | 12 ++++++++++-- components/openssl/platform/ssl_pm.c | 6 +++--- 5 files changed, 28 insertions(+), 6 deletions(-) diff --git a/components/openssl/include/internal/ssl_types.h b/components/openssl/include/internal/ssl_types.h index d001befdb9..6f2fb5a2f2 100644 --- a/components/openssl/include/internal/ssl_types.h +++ b/components/openssl/include/internal/ssl_types.h @@ -99,6 +99,8 @@ struct stack_st { struct evp_pkey_st { + int ref; + void *pkey_pm; const PKEY_METHOD *method; @@ -106,6 +108,8 @@ struct evp_pkey_st { struct x509_st { + int ref; + /* X509 certification platform private point */ void *x509_pm; diff --git a/components/openssl/library/ssl_lib.c b/components/openssl/library/ssl_lib.c index 442920f119..7e3b4554d6 100644 --- a/components/openssl/library/ssl_lib.c +++ b/components/openssl/library/ssl_lib.c @@ -282,6 +282,9 @@ SSL *SSL_new(SSL_CTX *ctx) ssl->version = ctx->version; ssl->options = ctx->options; + ssl->cert = ctx->cert; + ssl->client_CA = ctx->client_CA; + ret = SSL_METHOD_CALL(new, ssl); if (ret) SSL_RET(failed2, "ssl_new\n"); diff --git a/components/openssl/library/ssl_pkey.c b/components/openssl/library/ssl_pkey.c index a86a257e98..15c4977b0f 100644 --- a/components/openssl/library/ssl_pkey.c +++ b/components/openssl/library/ssl_pkey.c @@ -177,6 +177,8 @@ int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, if (!ret) SSL_RET(failed2, "SSL_CTX_use_PrivateKey\n"); + ctx->cert->pkey->ref++; + return 1; failed2: @@ -203,7 +205,10 @@ int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, int ret; EVP_PKEY *pkey; - pkey = d2i_PrivateKey(0, &ssl->cert->pkey, &d, len); + if (ssl->cert->pkey->ref) + SSL_RET(failed1); + + pkey = d2i_PrivateKey(0, NULL, &d, len); if (!pkey) SSL_RET(failed1, "d2i_PrivateKey\n"); @@ -211,6 +216,8 @@ int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, if (!ret) SSL_RET(failed2, "SSL_CTX_use_PrivateKey\n"); + ssl->cert->pkey->ref++; + return 1; failed2: diff --git a/components/openssl/library/ssl_x509.c b/components/openssl/library/ssl_x509.c index ba5c924e75..6e249eef58 100644 --- a/components/openssl/library/ssl_x509.c +++ b/components/openssl/library/ssl_x509.c @@ -85,7 +85,7 @@ X509* d2i_X509(X509 **cert, const unsigned char *buffer, long len) } else { x = X509_new(); if (!x) - SSL_RET(failed1, "sk_X509_NAME_new_null\n"); + SSL_RET(failed1, "X509_new\n"); m = 1; } @@ -218,6 +218,7 @@ int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, { int ret; X509 *cert; + const unsigned char *pbuf; cert = d2i_X509(&ctx->cert->x509, d, len); if (!cert) @@ -227,6 +228,8 @@ int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, if (!ret) SSL_RET(failed2, "SSL_CTX_use_certificate\n"); + ctx->cert->x509->ref++; + return 1; failed2: @@ -252,7 +255,10 @@ int SSL_use_certificate_ASN1(SSL *ssl, int len, int ret; X509 *cert; - cert = d2i_X509(&ssl->cert->x509, d, len); + if (ssl->cert->x509->ref) + SSL_RET(failed1); + + cert = d2i_X509(NULL, d, len); if (!cert) SSL_RET(failed1, "d2i_X509\n"); @@ -260,6 +266,8 @@ int SSL_use_certificate_ASN1(SSL *ssl, int len, if (!ret) SSL_RET(failed2, "SSL_use_certificate\n"); + ssl->cert->x509->ref++; + return 1; failed2: diff --git a/components/openssl/platform/ssl_pm.c b/components/openssl/platform/ssl_pm.c index 17cc080bb6..d4ed2ececb 100644 --- a/components/openssl/platform/ssl_pm.c +++ b/components/openssl/platform/ssl_pm.c @@ -120,7 +120,7 @@ int ssl_pm_new(SSL *ssl) mbedtls_ssl_conf_dbg(&ssl_pm->conf, NULL, NULL); - x509_pm = (struct x509_pm *)ctx->client_CA->x509_pm; + x509_pm = (struct x509_pm *)ssl->client_CA->x509_pm; if (x509_pm->load) { mbedtls_ssl_conf_ca_chain(&ssl_pm->conf, &x509_pm->x509_crt, NULL); @@ -130,9 +130,9 @@ int ssl_pm_new(SSL *ssl) } mbedtls_ssl_conf_authmode(&ssl_pm->conf, mode); - pkey_pm = (struct pkey_pm *)ctx->cert->pkey->pkey_pm; + pkey_pm = (struct pkey_pm *)ssl->cert->pkey->pkey_pm; if (pkey_pm->load) { - x509_pm = (struct x509_pm *)ctx->cert->x509->x509_pm; + x509_pm = (struct x509_pm *)ssl->cert->x509->x509_pm; ret = mbedtls_ssl_conf_own_cert(&ssl_pm->conf, &x509_pm->x509_crt, &pkey_pm->pkey); if (ret) From 18787fd4fc9e1a0defb66cb29541432b8c76c4a9 Mon Sep 17 00:00:00 2001 From: dongheng Date: Thu, 22 Sep 2016 17:20:07 +0800 Subject: [PATCH 016/343] components/openssl: add empty fucntion to get peer certification and fix ref overflow --- .../openssl/include/internal/ssl_types.h | 2 ++ components/openssl/library/ssl_pkey.c | 4 ++-- components/openssl/library/ssl_x509.c | 19 ++++++++++++++++--- components/openssl/platform/ssl_pm.c | 5 ++--- 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/components/openssl/include/internal/ssl_types.h b/components/openssl/include/internal/ssl_types.h index 6f2fb5a2f2..7a0bd0d76f 100644 --- a/components/openssl/include/internal/ssl_types.h +++ b/components/openssl/include/internal/ssl_types.h @@ -144,6 +144,8 @@ struct ssl_session_st { long timeout; long time; + + X509 *peer; }; struct X509_VERIFY_PARAM_st { diff --git a/components/openssl/library/ssl_pkey.c b/components/openssl/library/ssl_pkey.c index 15c4977b0f..7278287a63 100644 --- a/components/openssl/library/ssl_pkey.c +++ b/components/openssl/library/ssl_pkey.c @@ -177,7 +177,7 @@ int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, if (!ret) SSL_RET(failed2, "SSL_CTX_use_PrivateKey\n"); - ctx->cert->pkey->ref++; + ctx->cert->pkey->ref = 1; return 1; @@ -216,7 +216,7 @@ int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, if (!ret) SSL_RET(failed2, "SSL_CTX_use_PrivateKey\n"); - ssl->cert->pkey->ref++; + ssl->cert->pkey->ref = 1; return 1; diff --git a/components/openssl/library/ssl_x509.c b/components/openssl/library/ssl_x509.c index 6e249eef58..19c94c3eca 100644 --- a/components/openssl/library/ssl_x509.c +++ b/components/openssl/library/ssl_x509.c @@ -218,7 +218,6 @@ int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, { int ret; X509 *cert; - const unsigned char *pbuf; cert = d2i_X509(&ctx->cert->x509, d, len); if (!cert) @@ -228,7 +227,7 @@ int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, if (!ret) SSL_RET(failed2, "SSL_CTX_use_certificate\n"); - ctx->cert->x509->ref++; + ctx->cert->x509->ref = 1; return 1; @@ -266,7 +265,7 @@ int SSL_use_certificate_ASN1(SSL *ssl, int len, if (!ret) SSL_RET(failed2, "SSL_use_certificate\n"); - ssl->cert->x509->ref++; + ssl->cert->x509->ref = 1; return 1; @@ -307,3 +306,17 @@ int SSL_use_certificate_file(SSL *ssl, const char *file, int type) { return 0; } + +/* + * SSL_get_peer_certificate - get peer certification + * + * @param ssl - SSL point + * + * @return certification + */ +X509 *SSL_get_peer_certificate(const SSL *ssl) +{ + SSL_ASSERT(ssl); + + return ssl->session.peer; +} diff --git a/components/openssl/platform/ssl_pm.c b/components/openssl/platform/ssl_pm.c index d4ed2ececb..1ddd1f30d2 100644 --- a/components/openssl/platform/ssl_pm.c +++ b/components/openssl/platform/ssl_pm.c @@ -74,7 +74,6 @@ int ssl_pm_new(SSL *ssl) int mode; int version; - SSL_CTX *ctx = ssl->ctx; const SSL_METHOD *method = ssl->method; struct x509_pm *x509_pm; @@ -185,9 +184,9 @@ int ssl_pm_handshake(SSL *ssl) } ssl_speed_up_exit(); - if (!mbed_ret) + if (!mbed_ret) { ret = 1; - else { + } else { ret = 0; SSL_DEBUG(1, "mbedtls_ssl_handshake [-0x%x]\n", -mbed_ret); } From 1bfedf9816a12581a35a053b964b40b8182c44d9 Mon Sep 17 00:00:00 2001 From: dongheng Date: Thu, 22 Sep 2016 18:33:55 +0800 Subject: [PATCH 017/343] components/openssl: fix the SSL_free memory leak --- components/openssl/library/ssl_lib.c | 2 +- components/openssl/platform/ssl_pm.c | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/components/openssl/library/ssl_lib.c b/components/openssl/library/ssl_lib.c index 7e3b4554d6..20c8931457 100644 --- a/components/openssl/library/ssl_lib.c +++ b/components/openssl/library/ssl_lib.c @@ -266,7 +266,7 @@ const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx) */ SSL *SSL_new(SSL_CTX *ctx) { - int ret; + int ret = 0; SSL *ssl; if (!ctx) diff --git a/components/openssl/platform/ssl_pm.c b/components/openssl/platform/ssl_pm.c index 1ddd1f30d2..04e370f9fc 100644 --- a/components/openssl/platform/ssl_pm.c +++ b/components/openssl/platform/ssl_pm.c @@ -162,13 +162,13 @@ void ssl_pm_free(SSL *ssl) { struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; - mbedtls_ssl_config_free(&ssl_pm->conf); mbedtls_ctr_drbg_free(&ssl_pm->ctr_drbg); mbedtls_entropy_free(&ssl_pm->entropy); + mbedtls_ssl_config_free(&ssl_pm->conf); mbedtls_ssl_free(&ssl_pm->ssl); - mbedtls_net_free(&ssl_pm->fd); - mbedtls_net_free(&ssl_pm->cl_fd); + ssl_free(ssl_pm); + ssl->ssl_pm = NULL; } int ssl_pm_handshake(SSL *ssl) @@ -383,6 +383,7 @@ void x509_pm_free(X509 *x) x509_pm_unload(x); ssl_free(x->x509_pm); + x->x509_pm = NULL; } int pkey_pm_new(EVP_PKEY *pkey) @@ -443,6 +444,7 @@ void pkey_pm_free(EVP_PKEY *pkey) pkey_pm_unload(pkey); ssl_free(pkey->pkey_pm); + pkey->pkey_pm = NULL; } void ssl_pm_set_bufflen(SSL *ssl, int len) From 9fc054bb553c3df68eb3f956c4496ac178422c3f Mon Sep 17 00:00:00 2001 From: dongheng Date: Fri, 23 Sep 2016 10:33:31 +0800 Subject: [PATCH 018/343] components/openssl: SSL load cert with creating new cert object 1. when 'SSL_new' SSL's cert is pointed to SSL context cert If SSL load new cert, it will create a new cert object 2. change some debug informaion --- .../openssl/include/internal/ssl_types.h | 13 ++--- components/openssl/library/ssl_cert.c | 2 +- components/openssl/library/ssl_lib.c | 6 +++ components/openssl/library/ssl_pkey.c | 44 +++++++++++----- components/openssl/library/ssl_x509.c | 50 +++++++++++++------ components/openssl/platform/ssl_pm.c | 32 +++++++----- 6 files changed, 100 insertions(+), 47 deletions(-) diff --git a/components/openssl/include/internal/ssl_types.h b/components/openssl/include/internal/ssl_types.h index 7a0bd0d76f..c872c5191c 100644 --- a/components/openssl/include/internal/ssl_types.h +++ b/components/openssl/include/internal/ssl_types.h @@ -99,8 +99,6 @@ struct stack_st { struct evp_pkey_st { - int ref; - void *pkey_pm; const PKEY_METHOD *method; @@ -108,8 +106,6 @@ struct evp_pkey_st { struct x509_st { - int ref; - /* X509 certification platform private point */ void *x509_pm; @@ -127,6 +123,7 @@ struct cert_st { }; struct ossl_statem_st { + MSG_FLOW_STATE state; int hand_state; @@ -193,8 +190,14 @@ struct ssl_st /* shut things down(0x01 : sent, 0x02 : received) */ int shutdown; + int crt_reload; + CERT *cert; + int ca_reload; + + X509 *client_CA; + SSL_CTX *ctx; const SSL_METHOD *method; @@ -208,8 +211,6 @@ struct ssl_st int rwstate; - X509 *client_CA; - long verify_result; X509_VERIFY_PARAM param; diff --git a/components/openssl/library/ssl_cert.c b/components/openssl/library/ssl_cert.c index caa901b660..2d82e62aaa 100644 --- a/components/openssl/library/ssl_cert.c +++ b/components/openssl/library/ssl_cert.c @@ -39,7 +39,7 @@ CERT *ssl_cert_new(void) cert->x509 = X509_new(); if (!cert->x509) - SSL_RET(failed3, "sk_X509_NAME_new_null\n"); + SSL_RET(failed3, "X509_new\n"); return cert; diff --git a/components/openssl/library/ssl_lib.c b/components/openssl/library/ssl_lib.c index 20c8931457..cc218f9a26 100644 --- a/components/openssl/library/ssl_lib.c +++ b/components/openssl/library/ssl_lib.c @@ -312,6 +312,12 @@ void SSL_free(SSL *ssl) SSL_METHOD_CALL(free, ssl); + if (ssl->ca_reload) + X509_free(ssl->client_CA); + + if (ssl->crt_reload) + ssl_cert_free(ssl->cert); + ssl_free(ssl); } diff --git a/components/openssl/library/ssl_pkey.c b/components/openssl/library/ssl_pkey.c index 7278287a63..c77785f473 100644 --- a/components/openssl/library/ssl_pkey.c +++ b/components/openssl/library/ssl_pkey.c @@ -14,6 +14,7 @@ #include "ssl_lib.h" #include "ssl_pkey.h" +#include "ssl_cert.h" #include "ssl_methods.h" #include "ssl_dbg.h" #include "ssl_port.h" @@ -38,7 +39,7 @@ EVP_PKEY* EVP_PKEY_new(void) ret = EVP_PKEY_METHOD_CALL(new, pkey); if (ret) - SSL_RET(failed2, "pkey_new\n"); + SSL_RET(failed2, "EVP_PKEY_METHOD_CALL\n"); return pkey; @@ -91,13 +92,13 @@ EVP_PKEY *d2i_PrivateKey(int type, } else { pkey = EVP_PKEY_new();; if (!pkey) - SSL_RET(failed1, "ssl_malloc\n"); + SSL_RET(failed1, "EVP_PKEY_new\n"); m = 1; } ret = EVP_PKEY_METHOD_CALL(load, pkey, *pp, length); if (ret) - SSL_RET(failed2, "pkey_pm_load_crt\n"); + SSL_RET(failed2, "EVP_PKEY_METHOD_CALL\n"); if (a) *a = pkey; @@ -177,8 +178,6 @@ int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, if (!ret) SSL_RET(failed2, "SSL_CTX_use_PrivateKey\n"); - ctx->cert->pkey->ref = 1; - return 1; failed2: @@ -203,25 +202,44 @@ int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d, long len) { int ret; + int reload; EVP_PKEY *pkey; + CERT *cert; + CERT *old_cert; - if (ssl->cert->pkey->ref) - SSL_RET(failed1); + if (!ssl->crt_reload) { + cert = ssl_cert_new(); + if (!cert) + SSL_RET(failed1, "ssl_cert_new\n"); - pkey = d2i_PrivateKey(0, NULL, &d, len); + old_cert = ssl->cert ; + ssl->cert = cert; + + ssl->crt_reload = 1; + + reload = 1; + } else { + reload = 0; + } + + pkey = d2i_PrivateKey(0, &ssl->cert->pkey, &d, len); if (!pkey) - SSL_RET(failed1, "d2i_PrivateKey\n"); + SSL_RET(failed2, "d2i_PrivateKey\n"); ret = SSL_use_PrivateKey(ssl, pkey); if (!ret) - SSL_RET(failed2, "SSL_CTX_use_PrivateKey\n"); - - ssl->cert->pkey->ref = 1; + SSL_RET(failed3, "SSL_use_PrivateKey\n"); return 1; -failed2: +failed3: EVP_PKEY_free(pkey); +failed2: + if (reload) { + ssl->cert = old_cert; + ssl_cert_free(cert); + ssl->crt_reload = 0; + } failed1: return 0; } diff --git a/components/openssl/library/ssl_x509.c b/components/openssl/library/ssl_x509.c index 19c94c3eca..9ca60d8b31 100644 --- a/components/openssl/library/ssl_x509.c +++ b/components/openssl/library/ssl_x509.c @@ -13,6 +13,7 @@ // limitations under the License. #include "ssl_x509.h" +#include "ssl_cert.h" #include "ssl_methods.h" #include "ssl_dbg.h" #include "ssl_port.h" @@ -91,7 +92,7 @@ X509* d2i_X509(X509 **cert, const unsigned char *buffer, long len) ret = X509_METHOD_CALL(load, x, buffer, len); if (ret) - SSL_RET(failed2, "x509_load\n"); + SSL_RET(failed2, "X509_METHOD_CALL\n"); return x; @@ -140,7 +141,9 @@ int SSL_add_client_CA(SSL *ssl, X509 *x) SSL_ASSERT(ssl); SSL_ASSERT(x); - if (ssl->client_CA) + if (!ssl->ca_reload) + ssl->ca_reload = 1; + else X509_free(ssl->client_CA); ssl->client_CA = x; @@ -227,8 +230,6 @@ int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, if (!ret) SSL_RET(failed2, "SSL_CTX_use_certificate\n"); - ctx->cert->x509->ref = 1; - return 1; failed2: @@ -252,25 +253,44 @@ int SSL_use_certificate_ASN1(SSL *ssl, int len, const unsigned char *d) { int ret; - X509 *cert; + int reload; + X509 *x; + CERT *cert; + CERT *old_cert; - if (ssl->cert->x509->ref) - SSL_RET(failed1); + if (!ssl->crt_reload) { + cert = ssl_cert_new(); + if (!cert) + SSL_RET(failed1, "ssl_cert_new\n"); - cert = d2i_X509(NULL, d, len); - if (!cert) - SSL_RET(failed1, "d2i_X509\n"); + old_cert = ssl->cert ; + ssl->cert = cert; - ret = SSL_use_certificate(ssl, cert); + ssl->crt_reload = 1; + + reload = 1; + } else { + reload = 0; + } + + x = d2i_X509(&ssl->cert->x509, d, len); + if (!x) + SSL_RET(failed2, "d2i_X509\n"); + + ret = SSL_use_certificate(ssl, x); if (!ret) - SSL_RET(failed2, "SSL_use_certificate\n"); - - ssl->cert->x509->ref = 1; + SSL_RET(failed3, "SSL_use_certificate\n"); return 1; +failed3: + X509_free(x); failed2: - X509_free(cert); + if (reload) { + ssl->cert = old_cert; + ssl_cert_free(cert); + ssl->crt_reload = 0; + } failed1: return 0; } diff --git a/components/openssl/platform/ssl_pm.c b/components/openssl/platform/ssl_pm.c index 04e370f9fc..54e6cba25c 100644 --- a/components/openssl/platform/ssl_pm.c +++ b/components/openssl/platform/ssl_pm.c @@ -43,16 +43,16 @@ struct ssl_pm struct x509_pm { - int load; - mbedtls_x509_crt x509_crt; + + int load; }; struct pkey_pm { - int load; - mbedtls_pk_context pkey; + + int load; }; @@ -79,9 +79,13 @@ int ssl_pm_new(SSL *ssl) struct x509_pm *x509_pm; struct pkey_pm *pkey_pm; + ssl->session.peer = ssl_malloc(sizeof(X509)); + if (!ssl->session.peer) + SSL_ERR(ret, failed1, "ssl_malloc\n"); + ssl_pm = ssl_malloc(sizeof(struct ssl_pm)); if (!ssl_pm) - SSL_ERR(ret, failed1, "ssl_malloc\n"); + SSL_ERR(ret, failed2, "ssl_malloc\n"); mbedtls_net_init(&ssl_pm->fd); mbedtls_net_init(&ssl_pm->cl_fd); @@ -93,7 +97,7 @@ int ssl_pm_new(SSL *ssl) ret = mbedtls_ctr_drbg_seed(&ssl_pm->ctr_drbg, mbedtls_entropy_func, &ssl_pm->entropy, pers, pers_len); if (ret) - SSL_ERR(ret, failed1, "mbedtls_ctr_drbg_seed:[-0x%x]\n", -ret); + SSL_ERR(ret, failed3, "mbedtls_ctr_drbg_seed:[-0x%x]\n", -ret); if (method->endpoint) { endpoint = MBEDTLS_SSL_IS_SERVER; @@ -102,7 +106,7 @@ int ssl_pm_new(SSL *ssl) } ret = mbedtls_ssl_config_defaults(&ssl_pm->conf, endpoint, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT); if (ret) - SSL_ERR(ret, failed2, "mbedtls_ssl_config_defaults:[-0x%x]\n", -ret); + SSL_ERR(ret, failed3, "mbedtls_ssl_config_defaults:[-0x%x]\n", -ret); if (TLS1_2_VERSION == ssl->version) version = MBEDTLS_SSL_MINOR_VERSION_3; @@ -135,12 +139,12 @@ int ssl_pm_new(SSL *ssl) ret = mbedtls_ssl_conf_own_cert(&ssl_pm->conf, &x509_pm->x509_crt, &pkey_pm->pkey); if (ret) - SSL_ERR(ret, failed3, "mbedtls_ssl_conf_own_cert:[%d]\n", ret); + SSL_ERR(ret, failed4, "mbedtls_ssl_conf_own_cert:[%d]\n", ret); } ret = mbedtls_ssl_setup(&ssl_pm->ssl, &ssl_pm->conf); if (ret) - SSL_ERR(ret, failed4, "mbedtls_ssl_setup:[-0x%x]\n", -ret); + SSL_ERR(ret, failed5, "mbedtls_ssl_setup:[-0x%x]\n", -ret); mbedtls_ssl_set_bio(&ssl_pm->ssl, &ssl_pm->fd, mbedtls_net_send, mbedtls_net_recv, NULL); @@ -148,12 +152,14 @@ int ssl_pm_new(SSL *ssl) return 0; -failed4: +failed5: mbedtls_ssl_config_free(&ssl_pm->conf); -failed3: +failed4: mbedtls_ctr_drbg_free(&ssl_pm->ctr_drbg); -failed2: +failed3: mbedtls_entropy_free(&ssl_pm->entropy); +failed2: + ssl_free(ssl->session.peer); failed1: return -1; } @@ -186,6 +192,8 @@ int ssl_pm_handshake(SSL *ssl) if (!mbed_ret) { ret = 1; + + ssl->session.peer = (X509 *)mbedtls_ssl_get_peer_cert(&ssl_pm->ssl); } else { ret = 0; SSL_DEBUG(1, "mbedtls_ssl_handshake [-0x%x]\n", -mbed_ret); From 07c8bbca6c70836b46cf040a472eb348b1d9f59d Mon Sep 17 00:00:00 2001 From: dongheng Date: Fri, 23 Sep 2016 10:53:18 +0800 Subject: [PATCH 019/343] components/openssl: SSL low-level reload cert when user add new cert --- .../openssl/include/internal/ssl_methods.h | 2 ++ .../openssl/include/internal/ssl_types.h | 2 ++ components/openssl/include/platform/ssl_pm.h | 2 ++ components/openssl/library/ssl_methods.c | 1 + components/openssl/library/ssl_pkey.c | 19 +++++++++++- components/openssl/library/ssl_x509.c | 11 ++++++- components/openssl/platform/ssl_pm.c | 30 +++++++++++++++++++ 7 files changed, 65 insertions(+), 2 deletions(-) diff --git a/components/openssl/include/internal/ssl_methods.h b/components/openssl/include/internal/ssl_methods.h index 244eec38dd..2893db1888 100644 --- a/components/openssl/include/internal/ssl_methods.h +++ b/components/openssl/include/internal/ssl_methods.h @@ -22,6 +22,7 @@ set_fd, get_fd, \ set_bufflen, \ get_verify_result, \ + ssl_reload_crt, \ get_state) \ static const SSL_METHOD_FUNC func_name LOCAL_ATRR = { \ new, \ @@ -36,6 +37,7 @@ get_fd, \ set_bufflen, \ get_verify_result, \ + ssl_reload_crt, \ get_state \ }; diff --git a/components/openssl/include/internal/ssl_types.h b/components/openssl/include/internal/ssl_types.h index c872c5191c..47e6b0bf65 100644 --- a/components/openssl/include/internal/ssl_types.h +++ b/components/openssl/include/internal/ssl_types.h @@ -259,6 +259,8 @@ struct ssl_method_func_st { long (*ssl_get_verify_result)(const SSL *ssl); + int (*ssl_reload_crt)(SSL *ssl); + OSSL_HANDSHAKE_STATE (*ssl_get_state)(const SSL *ssl); }; diff --git a/components/openssl/include/platform/ssl_pm.h b/components/openssl/include/platform/ssl_pm.h index 3f64a4ae32..53bff0d80e 100644 --- a/components/openssl/include/platform/ssl_pm.h +++ b/components/openssl/include/platform/ssl_pm.h @@ -51,4 +51,6 @@ void pkey_pm_unload(EVP_PKEY *pkey); long ssl_pm_get_verify_result(const SSL *ssl); +int ssl_pm_reload_crt(SSL *ssl); + #endif diff --git a/components/openssl/library/ssl_methods.c b/components/openssl/library/ssl_methods.c index c6fb40e59c..0674f40587 100644 --- a/components/openssl/library/ssl_methods.c +++ b/components/openssl/library/ssl_methods.c @@ -26,6 +26,7 @@ IMPLEMENT_TLS_METHOD_FUNC(TLS_method_func, ssl_pm_set_fd, ssl_pm_get_fd, ssl_pm_set_bufflen, ssl_pm_get_verify_result, + ssl_pm_reload_crt, ssl_pm_get_state); /* diff --git a/components/openssl/library/ssl_pkey.c b/components/openssl/library/ssl_pkey.c index c77785f473..893a391dd8 100644 --- a/components/openssl/library/ssl_pkey.c +++ b/components/openssl/library/ssl_pkey.c @@ -127,6 +127,9 @@ int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) SSL_ASSERT(ctx); SSL_ASSERT(pkey); + if (ctx->cert->pkey) + EVP_PKEY_free(ctx->cert->pkey); + ctx->cert->pkey = pkey; return 1; @@ -144,12 +147,26 @@ int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) */ int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) { + int ret; + int ssl_ret; + SSL_ASSERT(ctx); SSL_ASSERT(pkey); + if (!ssl->ca_reload) + ssl->ca_reload = 1; + else + EVP_PKEY_free(ssl->cert->pkey); + ssl->cert->pkey = pkey; - return 1; + ssl_ret = SSL_METHOD_CALL(reload_crt, ssl); + if (ssl_ret) + ret = 0; + else + ret = 1; + + return ret; } /* diff --git a/components/openssl/library/ssl_x509.c b/components/openssl/library/ssl_x509.c index 9ca60d8b31..2368344a7a 100644 --- a/components/openssl/library/ssl_x509.c +++ b/components/openssl/library/ssl_x509.c @@ -138,6 +138,9 @@ int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) */ int SSL_add_client_CA(SSL *ssl, X509 *x) { + int ret; + int ssl_ret; + SSL_ASSERT(ssl); SSL_ASSERT(x); @@ -148,7 +151,13 @@ int SSL_add_client_CA(SSL *ssl, X509 *x) ssl->client_CA = x; - return 1; + ssl_ret = SSL_METHOD_CALL(reload_crt, ssl); + if (ssl_ret) + ret = 0; + else + ret = 1; + + return ret; } /* diff --git a/components/openssl/platform/ssl_pm.c b/components/openssl/platform/ssl_pm.c index 54e6cba25c..00c8f83020 100644 --- a/components/openssl/platform/ssl_pm.c +++ b/components/openssl/platform/ssl_pm.c @@ -475,3 +475,33 @@ long ssl_pm_get_verify_result(const SSL *ssl) return verify_result; } + +int ssl_pm_reload_crt(SSL *ssl) +{ + int ret; + int mode; + struct ssl_pm *ssl_pm = ssl->ssl_pm; + struct x509_pm *x509_pm; + struct pkey_pm *pkey_pm; + + x509_pm = (struct x509_pm *)ssl->client_CA->x509_pm; + if (x509_pm->load) { + mbedtls_ssl_conf_ca_chain(&ssl_pm->conf, &x509_pm->x509_crt, NULL); + + mode = MBEDTLS_SSL_VERIFY_REQUIRED; + } else { + mode = MBEDTLS_SSL_VERIFY_NONE; + } + mbedtls_ssl_conf_authmode(&ssl_pm->conf, mode); + + pkey_pm = (struct pkey_pm *)ssl->cert->pkey->pkey_pm; + if (pkey_pm->load) { + x509_pm = (struct x509_pm *)ssl->cert->x509->x509_pm; + + ret = mbedtls_ssl_conf_own_cert(&ssl_pm->conf, &x509_pm->x509_crt, &pkey_pm->pkey); + if (ret) + return -1; + } + + return 0; +} From f5d9bfc7aecdda78f849e0f9bd7dd4b228feb8ab Mon Sep 17 00:00:00 2001 From: dongheng Date: Fri, 23 Sep 2016 11:03:13 +0800 Subject: [PATCH 020/343] components/openssl: fix SSL get peer cert struct point type error 1. fix SSL get peer cert struct point type error 2. some function use "zalloc" instead of "malloc" --- components/openssl/library/ssl_pkey.c | 2 +- components/openssl/library/ssl_x509.c | 2 +- components/openssl/platform/ssl_pm.c | 18 +++++++++--------- components/openssl/platform/ssl_port.c | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/components/openssl/library/ssl_pkey.c b/components/openssl/library/ssl_pkey.c index 893a391dd8..ab56fe789d 100644 --- a/components/openssl/library/ssl_pkey.c +++ b/components/openssl/library/ssl_pkey.c @@ -31,7 +31,7 @@ EVP_PKEY* EVP_PKEY_new(void) int ret; EVP_PKEY *pkey; - pkey = ssl_malloc(sizeof(EVP_PKEY)); + pkey = ssl_zalloc(sizeof(EVP_PKEY)); if (!pkey) SSL_RET(failed1, "ssl_malloc\n"); diff --git a/components/openssl/library/ssl_x509.c b/components/openssl/library/ssl_x509.c index 2368344a7a..431f03caa9 100644 --- a/components/openssl/library/ssl_x509.c +++ b/components/openssl/library/ssl_x509.c @@ -30,7 +30,7 @@ X509* X509_new(void) int ret; X509 *x; - x = ssl_malloc(sizeof(X509)); + x = ssl_zalloc(sizeof(X509)); if (!x) SSL_RET(failed1, "ssl_malloc\n"); diff --git a/components/openssl/platform/ssl_pm.c b/components/openssl/platform/ssl_pm.c index 00c8f83020..10b736aa9c 100644 --- a/components/openssl/platform/ssl_pm.c +++ b/components/openssl/platform/ssl_pm.c @@ -79,13 +79,13 @@ int ssl_pm_new(SSL *ssl) struct x509_pm *x509_pm; struct pkey_pm *pkey_pm; - ssl->session.peer = ssl_malloc(sizeof(X509)); + ssl->session.peer = ssl_zalloc(sizeof(X509)); if (!ssl->session.peer) - SSL_ERR(ret, failed1, "ssl_malloc\n"); + SSL_ERR(ret, failed1, "ssl_zalloc\n"); - ssl_pm = ssl_malloc(sizeof(struct ssl_pm)); + ssl_pm = ssl_zalloc(sizeof(struct ssl_pm)); if (!ssl_pm) - SSL_ERR(ret, failed2, "ssl_malloc\n"); + SSL_ERR(ret, failed2, "ssl_zalloc\n"); mbedtls_net_init(&ssl_pm->fd); mbedtls_net_init(&ssl_pm->cl_fd); @@ -193,7 +193,7 @@ int ssl_pm_handshake(SSL *ssl) if (!mbed_ret) { ret = 1; - ssl->session.peer = (X509 *)mbedtls_ssl_get_peer_cert(&ssl_pm->ssl); + ssl->session.peer->x509_pm = (struct x509_pm *)mbedtls_ssl_get_peer_cert(&ssl_pm->ssl); } else { ret = 0; SSL_DEBUG(1, "mbedtls_ssl_handshake [-0x%x]\n", -mbed_ret); @@ -337,7 +337,7 @@ int x509_pm_new(X509 *x) { struct x509_pm *x509_pm; - x509_pm = ssl_malloc(sizeof(struct x509_pm)); + x509_pm = ssl_zalloc(sizeof(struct x509_pm)); if (!x509_pm) return -1; @@ -364,7 +364,7 @@ int x509_pm_load(X509 *x, const unsigned char *buffer, int len) load_buf = ssl_malloc(len + 1); if (!load_buf) - SSL_RET(failed1, ""); + SSL_RET(failed1); ssl_memcpy(load_buf, buffer, len); load_buf[len] = '\0'; @@ -398,7 +398,7 @@ int pkey_pm_new(EVP_PKEY *pkey) { struct pkey_pm *pkey_pm; - pkey_pm = ssl_malloc(sizeof(struct pkey_pm)); + pkey_pm = ssl_zalloc(sizeof(struct pkey_pm)); if (!pkey_pm) return -1; @@ -425,7 +425,7 @@ int pkey_pm_load(EVP_PKEY *pkey, const unsigned char *buffer, int len) load_buf = ssl_malloc(len + 1); if (!load_buf) - SSL_RET(failed1, ""); + SSL_RET(failed1); ssl_memcpy(load_buf, buffer, len); load_buf[len] = '\0'; diff --git a/components/openssl/platform/ssl_port.c b/components/openssl/platform/ssl_port.c index 3e6ada5cc9..b57e703a17 100644 --- a/components/openssl/platform/ssl_port.c +++ b/components/openssl/platform/ssl_port.c @@ -31,7 +31,7 @@ void* ssl_zalloc(size_t size) void *ssl_malloc(size_t size) { - return ssl_zalloc(size); + return malloc(size); } void ssl_free(void *p) From e475d0539eb8c960f7996d0ec6c0842f4534a235 Mon Sep 17 00:00:00 2001 From: dongheng Date: Fri, 23 Sep 2016 11:41:57 +0800 Subject: [PATCH 021/343] components/openssl: add SSL and SSL context verify mode selection --- .../openssl/include/internal/ssl_code.h | 5 + .../openssl/include/internal/ssl_methods.h | 2 - .../openssl/include/internal/ssl_types.h | 8 +- components/openssl/include/platform/ssl_pm.h | 2 - components/openssl/library/ssl_lib.c | 50 +++++++--- components/openssl/library/ssl_methods.c | 1 - components/openssl/library/ssl_pkey.c | 8 +- components/openssl/library/ssl_x509.c | 11 +-- components/openssl/platform/ssl_pm.c | 96 ++++++++----------- 9 files changed, 88 insertions(+), 95 deletions(-) diff --git a/components/openssl/include/internal/ssl_code.h b/components/openssl/include/internal/ssl_code.h index de86e07df1..e76b35abe9 100644 --- a/components/openssl/include/internal/ssl_code.h +++ b/components/openssl/include/internal/ssl_code.h @@ -23,6 +23,11 @@ # define SSL_SENT_SHUTDOWN 1 # define SSL_RECEIVED_SHUTDOWN 2 +# define SSL_VERIFY_NONE 0x00 +# define SSL_VERIFY_PEER 0x01 +# define SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02 +# define SSL_VERIFY_CLIENT_ONCE 0x04 + /* * The following 3 states are kept in ssl->rlayer.rstate when reads fail, you * should not need these diff --git a/components/openssl/include/internal/ssl_methods.h b/components/openssl/include/internal/ssl_methods.h index 2893db1888..244eec38dd 100644 --- a/components/openssl/include/internal/ssl_methods.h +++ b/components/openssl/include/internal/ssl_methods.h @@ -22,7 +22,6 @@ set_fd, get_fd, \ set_bufflen, \ get_verify_result, \ - ssl_reload_crt, \ get_state) \ static const SSL_METHOD_FUNC func_name LOCAL_ATRR = { \ new, \ @@ -37,7 +36,6 @@ get_fd, \ set_bufflen, \ get_verify_result, \ - ssl_reload_crt, \ get_state \ }; diff --git a/components/openssl/include/internal/ssl_types.h b/components/openssl/include/internal/ssl_types.h index 47e6b0bf65..6da6076148 100644 --- a/components/openssl/include/internal/ssl_types.h +++ b/components/openssl/include/internal/ssl_types.h @@ -171,6 +171,8 @@ struct ssl_ctx_st int verify_mode; + int (*default_verify_callback) (int ok, X509_STORE_CTX *ctx); + long session_timeout; int read_ahead; @@ -209,6 +211,10 @@ struct ssl_st SSL_SESSION session; + int verify_mode; + + int (*verify_callback) (int ok, X509_STORE_CTX *ctx); + int rwstate; long verify_result; @@ -259,8 +265,6 @@ struct ssl_method_func_st { long (*ssl_get_verify_result)(const SSL *ssl); - int (*ssl_reload_crt)(SSL *ssl); - OSSL_HANDSHAKE_STATE (*ssl_get_state)(const SSL *ssl); }; diff --git a/components/openssl/include/platform/ssl_pm.h b/components/openssl/include/platform/ssl_pm.h index 53bff0d80e..3f64a4ae32 100644 --- a/components/openssl/include/platform/ssl_pm.h +++ b/components/openssl/include/platform/ssl_pm.h @@ -51,6 +51,4 @@ void pkey_pm_unload(EVP_PKEY *pkey); long ssl_pm_get_verify_result(const SSL *ssl); -int ssl_pm_reload_crt(SSL *ssl); - #endif diff --git a/components/openssl/library/ssl_lib.c b/components/openssl/library/ssl_lib.c index cc218f9a26..ae517b0a40 100644 --- a/components/openssl/library/ssl_lib.c +++ b/components/openssl/library/ssl_lib.c @@ -284,6 +284,7 @@ SSL *SSL_new(SSL_CTX *ctx) ssl->cert = ctx->cert; ssl->client_CA = ctx->client_CA; + ssl->verify_mode = ctx->verify_mode; ret = SSL_METHOD_CALL(new, ssl); if (ret) @@ -1726,21 +1727,6 @@ long SSL_set_timeout(SSL *ssl, long t) return t; } -/* - * SSL_set_verify - set the SSL verifying of the SSL context - * - * @param ctx - SSL point - * @param mode - verifying mode - * @param verify_callback - verifying callback function - * - * @return none - */ -void SSL_set_verify(SSL *ssl, int mode, int (*verify_callback)(int, X509_STORE_CTX *)) -{ - SSL_ASSERT(ssl); - SSL_ASSERT(verify_callback); -} - /* * SSL_get_verify_result - get the verifying result of the SSL certification * @@ -1812,3 +1798,37 @@ void SSL_set_verify_depth(SSL *ssl, int depth) ssl->param.depth = depth; } + +/* + * SSL_CTX_set_verify - set the SSL context verifying of the SSL context + * + * @param ctx - SSL context point + * @param mode - verifying mode + * @param verify_callback - verifying callback function + * + * @return none + */ +void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, int (*verify_callback)(int, X509_STORE_CTX *)) +{ + SSL_ASSERT(ctx); + + ctx->verify_mode = mode; + ctx->default_verify_callback = verify_callback; +} + +/* + * SSL_set_verify - set the SSL verifying of the SSL context + * + * @param ctx - SSL point + * @param mode - verifying mode + * @param verify_callback - verifying callback function + * + * @return none + */ +void SSL_set_verify(SSL *ssl, int mode, int (*verify_callback)(int, X509_STORE_CTX *)) +{ + SSL_ASSERT(ctx); + + ssl->verify_mode = mode; + ssl->verify_callback = verify_callback; +} diff --git a/components/openssl/library/ssl_methods.c b/components/openssl/library/ssl_methods.c index 0674f40587..c6fb40e59c 100644 --- a/components/openssl/library/ssl_methods.c +++ b/components/openssl/library/ssl_methods.c @@ -26,7 +26,6 @@ IMPLEMENT_TLS_METHOD_FUNC(TLS_method_func, ssl_pm_set_fd, ssl_pm_get_fd, ssl_pm_set_bufflen, ssl_pm_get_verify_result, - ssl_pm_reload_crt, ssl_pm_get_state); /* diff --git a/components/openssl/library/ssl_pkey.c b/components/openssl/library/ssl_pkey.c index ab56fe789d..e13870344f 100644 --- a/components/openssl/library/ssl_pkey.c +++ b/components/openssl/library/ssl_pkey.c @@ -160,13 +160,7 @@ int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) ssl->cert->pkey = pkey; - ssl_ret = SSL_METHOD_CALL(reload_crt, ssl); - if (ssl_ret) - ret = 0; - else - ret = 1; - - return ret; + return 1; } /* diff --git a/components/openssl/library/ssl_x509.c b/components/openssl/library/ssl_x509.c index 431f03caa9..6eb3c1d461 100644 --- a/components/openssl/library/ssl_x509.c +++ b/components/openssl/library/ssl_x509.c @@ -138,9 +138,6 @@ int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) */ int SSL_add_client_CA(SSL *ssl, X509 *x) { - int ret; - int ssl_ret; - SSL_ASSERT(ssl); SSL_ASSERT(x); @@ -151,13 +148,7 @@ int SSL_add_client_CA(SSL *ssl, X509 *x) ssl->client_CA = x; - ssl_ret = SSL_METHOD_CALL(reload_crt, ssl); - if (ssl_ret) - ret = 0; - else - ret = 1; - - return ret; + return 1; } /* diff --git a/components/openssl/platform/ssl_pm.c b/components/openssl/platform/ssl_pm.c index 10b736aa9c..cd29882dfa 100644 --- a/components/openssl/platform/ssl_pm.c +++ b/components/openssl/platform/ssl_pm.c @@ -71,14 +71,10 @@ int ssl_pm_new(SSL *ssl) size_t pers_len = sizeof(pers); int endpoint; - int mode; int version; const SSL_METHOD *method = ssl->method; - struct x509_pm *x509_pm; - struct pkey_pm *pkey_pm; - ssl->session.peer = ssl_zalloc(sizeof(X509)); if (!ssl->session.peer) SSL_ERR(ret, failed1, "ssl_zalloc\n"); @@ -123,28 +119,9 @@ int ssl_pm_new(SSL *ssl) mbedtls_ssl_conf_dbg(&ssl_pm->conf, NULL, NULL); - x509_pm = (struct x509_pm *)ssl->client_CA->x509_pm; - if (x509_pm->load) { - mbedtls_ssl_conf_ca_chain(&ssl_pm->conf, &x509_pm->x509_crt, NULL); - - mode = MBEDTLS_SSL_VERIFY_REQUIRED; - } else { - mode = MBEDTLS_SSL_VERIFY_NONE; - } - mbedtls_ssl_conf_authmode(&ssl_pm->conf, mode); - - pkey_pm = (struct pkey_pm *)ssl->cert->pkey->pkey_pm; - if (pkey_pm->load) { - x509_pm = (struct x509_pm *)ssl->cert->x509->x509_pm; - - ret = mbedtls_ssl_conf_own_cert(&ssl_pm->conf, &x509_pm->x509_crt, &pkey_pm->pkey); - if (ret) - SSL_ERR(ret, failed4, "mbedtls_ssl_conf_own_cert:[%d]\n", ret); - } - ret = mbedtls_ssl_setup(&ssl_pm->ssl, &ssl_pm->conf); if (ret) - SSL_ERR(ret, failed5, "mbedtls_ssl_setup:[-0x%x]\n", -ret); + SSL_ERR(ret, failed4, "mbedtls_ssl_setup:[-0x%x]\n", -ret); mbedtls_ssl_set_bio(&ssl_pm->ssl, &ssl_pm->fd, mbedtls_net_send, mbedtls_net_recv, NULL); @@ -152,9 +129,8 @@ int ssl_pm_new(SSL *ssl) return 0; -failed5: - mbedtls_ssl_config_free(&ssl_pm->conf); failed4: + mbedtls_ssl_config_free(&ssl_pm->conf); mbedtls_ctr_drbg_free(&ssl_pm->ctr_drbg); failed3: mbedtls_entropy_free(&ssl_pm->entropy); @@ -177,11 +153,49 @@ void ssl_pm_free(SSL *ssl) ssl->ssl_pm = NULL; } +static int ssl_pm_reload_crt(SSL *ssl) +{ + int ret; + int mode; + struct ssl_pm *ssl_pm = ssl->ssl_pm; + struct x509_pm *ca_pm = (struct x509_pm *)ssl->client_CA->x509_pm; + + struct pkey_pm *pkey_pm = (struct pkey_pm *)ssl->cert->pkey->pkey_pm; + struct x509_pm *crt_pm = (struct x509_pm *)ssl->cert->x509->x509_pm; + + if (ssl->verify_mode == SSL_VERIFY_PEER) + mode = MBEDTLS_SSL_VERIFY_REQUIRED; + else if (ssl->verify_mode == SSL_VERIFY_FAIL_IF_NO_PEER_CERT) + mode = MBEDTLS_SSL_VERIFY_NONE; + else if (ssl->verify_mode == SSL_VERIFY_CLIENT_ONCE) + mode = MBEDTLS_SSL_VERIFY_UNSET; + else + mode = MBEDTLS_SSL_VERIFY_NONE; + + mbedtls_ssl_conf_authmode(&ssl_pm->conf, mode); + + if (ca_pm->load) { + mbedtls_ssl_conf_ca_chain(&ssl_pm->conf, &ca_pm->x509_crt, NULL); + } + + if (pkey_pm->load) { + ret = mbedtls_ssl_conf_own_cert(&ssl_pm->conf, &crt_pm->x509_crt, &pkey_pm->pkey); + if (ret) + return -1; + } + + return 0; +} + int ssl_pm_handshake(SSL *ssl) { int ret, mbed_ret; struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; + mbed_ret = ssl_pm_reload_crt(ssl); + if (mbed_ret) + return 0; + ssl_speed_up_enter(); while((mbed_ret = mbedtls_ssl_handshake(&ssl_pm->ssl)) != 0) { if (mbed_ret != MBEDTLS_ERR_SSL_WANT_READ && mbed_ret != MBEDTLS_ERR_SSL_WANT_WRITE) { @@ -475,33 +489,3 @@ long ssl_pm_get_verify_result(const SSL *ssl) return verify_result; } - -int ssl_pm_reload_crt(SSL *ssl) -{ - int ret; - int mode; - struct ssl_pm *ssl_pm = ssl->ssl_pm; - struct x509_pm *x509_pm; - struct pkey_pm *pkey_pm; - - x509_pm = (struct x509_pm *)ssl->client_CA->x509_pm; - if (x509_pm->load) { - mbedtls_ssl_conf_ca_chain(&ssl_pm->conf, &x509_pm->x509_crt, NULL); - - mode = MBEDTLS_SSL_VERIFY_REQUIRED; - } else { - mode = MBEDTLS_SSL_VERIFY_NONE; - } - mbedtls_ssl_conf_authmode(&ssl_pm->conf, mode); - - pkey_pm = (struct pkey_pm *)ssl->cert->pkey->pkey_pm; - if (pkey_pm->load) { - x509_pm = (struct x509_pm *)ssl->cert->x509->x509_pm; - - ret = mbedtls_ssl_conf_own_cert(&ssl_pm->conf, &x509_pm->x509_crt, &pkey_pm->pkey); - if (ret) - return -1; - } - - return 0; -} From db9becfa744b651080c435eefe48adc0cf24cdba Mon Sep 17 00:00:00 2001 From: dongheng Date: Fri, 23 Sep 2016 13:38:11 +0800 Subject: [PATCH 022/343] components/openssl: free peer cert X509 object when SSL_free --- components/openssl/platform/ssl_pm.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/components/openssl/platform/ssl_pm.c b/components/openssl/platform/ssl_pm.c index cd29882dfa..b03aee3e37 100644 --- a/components/openssl/platform/ssl_pm.c +++ b/components/openssl/platform/ssl_pm.c @@ -149,6 +149,9 @@ void ssl_pm_free(SSL *ssl) mbedtls_ssl_config_free(&ssl_pm->conf); mbedtls_ssl_free(&ssl_pm->ssl); + ssl_free(ssl->session.peer); + ssl->session.peer = NULL; + ssl_free(ssl_pm); ssl->ssl_pm = NULL; } From 59bb9a9a011050c2a9af55c6da2f37a22337b527 Mon Sep 17 00:00:00 2001 From: dongheng Date: Fri, 23 Sep 2016 14:50:27 +0800 Subject: [PATCH 023/343] components/openssl: [TW7411] supply doxygen type note --- .../openssl/include/internal/ssl_cert.h | 17 +- .../openssl/include/internal/ssl_code.h | 1 + .../openssl/include/internal/ssl_methods.h | 18 + .../openssl/include/internal/ssl_pkey.h | 25 + .../openssl/include/internal/ssl_x509.h | 25 +- components/openssl/include/openssl/ssl.h | 953 +++++++++--------- components/openssl/library/ssl_cert.c | 24 +- components/openssl/library/ssl_lib.c | 677 +++---------- components/openssl/library/ssl_methods.c | 16 +- components/openssl/library/ssl_pkey.c | 113 +-- components/openssl/library/ssl_x509.c | 136 +-- components/openssl/platform/ssl_pm.c | 9 + 12 files changed, 782 insertions(+), 1232 deletions(-) diff --git a/components/openssl/include/internal/ssl_cert.h b/components/openssl/include/internal/ssl_cert.h index 109012a194..b0bd09d480 100644 --- a/components/openssl/include/internal/ssl_cert.h +++ b/components/openssl/include/internal/ssl_cert.h @@ -17,7 +17,22 @@ #include "ssl_types.h" +/** + * @brief create a certification object include private key object + * + * @param none + * + * @return certification object point + */ CERT* ssl_cert_new(void); -void ssl_cert_free(CERT *c); + +/** + * @brief free a certification object + * + * @param cert - certification object point + * + * @return none + */ +void ssl_cert_free(CERT *cert); #endif diff --git a/components/openssl/include/internal/ssl_code.h b/components/openssl/include/internal/ssl_code.h index e76b35abe9..34107d432d 100644 --- a/components/openssl/include/internal/ssl_code.h +++ b/components/openssl/include/internal/ssl_code.h @@ -72,6 +72,7 @@ typedef enum { MSG_FLOW_FINISHED } MSG_FLOW_STATE; +/* SSL subsystem states */ typedef enum { TLS_ST_BEFORE, TLS_ST_OK, diff --git a/components/openssl/include/internal/ssl_methods.h b/components/openssl/include/internal/ssl_methods.h index 244eec38dd..68737b4381 100644 --- a/components/openssl/include/internal/ssl_methods.h +++ b/components/openssl/include/internal/ssl_methods.h @@ -15,6 +15,9 @@ #ifndef _SSL_METHODS_H_ #define _SSL_METHODS_H_ +/** + * TLS method function implement + */ #define IMPLEMENT_TLS_METHOD_FUNC(func_name, \ new, free, \ handshake, shutdown, clear, \ @@ -89,7 +92,22 @@ return &func_name##_data; \ } +/** + * @brief get X509 object method + * + * @param none + * + * @return X509 object method point + */ const X509_METHOD* X509_method(void); + +/** + * @brief get private key object method + * + * @param none + * + * @return private key object method point + */ const PKEY_METHOD* EVP_PKEY_method(void); #endif diff --git a/components/openssl/include/internal/ssl_pkey.h b/components/openssl/include/internal/ssl_pkey.h index 34be294efe..d9a22ee02c 100644 --- a/components/openssl/include/internal/ssl_pkey.h +++ b/components/openssl/include/internal/ssl_pkey.h @@ -17,13 +17,38 @@ #include "ssl_types.h" +/** + * @brief create a private key object + * + * @param none + * + * @return private key object point + */ EVP_PKEY* EVP_PKEY_new(void); +/** + * @brief load a character key context into system context. If '*a' is pointed to the + * private key, then load key into it. Or create a new private key object + * + * @param type - private key type + * @param a - a point pointed to a private key point + * @param pp - a point pointed to the key context memory point + * @param length - key bytes + * + * @return private key object point + */ EVP_PKEY* d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, long length); +/** + * @brief free a private key object + * + * @param pkey - private key object point + * + * @return none + */ void EVP_PKEY_free(EVP_PKEY *x); #endif diff --git a/components/openssl/include/internal/ssl_x509.h b/components/openssl/include/internal/ssl_x509.h index ee3448544b..9359073b69 100644 --- a/components/openssl/include/internal/ssl_x509.h +++ b/components/openssl/include/internal/ssl_x509.h @@ -20,17 +20,34 @@ DEFINE_STACK_OF(X509_NAME) -/* - * sk_X509_NAME_new_null - create a X509 certification object +/** + * @brief create a X509 certification object * * @param none * - * @return X509 certification object point or NULL if failed + * @return X509 certification object point */ X509* X509_new(void); +/** + * @brief load a character certification context into system context. If '*cert' is pointed to the + * certification, then load certification into it. Or create a new X509 certification object + * + * @param cert - a point pointed to X509 certification + * @param buffer - a point pointed to the certification context memory point + * @param length - certification bytes + * + * @return X509 certification object point + */ X509* d2i_X509(X509 **cert, const unsigned char *buffer, long len); -void X509_free(X509 *cert); +/** + * @brief free a X509 certification object + * + * @param x - X509 certification object point + * + * @return none + */ +void X509_free(X509 *x); #endif diff --git a/components/openssl/include/openssl/ssl.h b/components/openssl/include/openssl/ssl.h index 865405d868..3f92a68d70 100644 --- a/components/openssl/include/openssl/ssl.h +++ b/components/openssl/include/openssl/ssl.h @@ -22,17 +22,17 @@ { */ -/* - * SSL_CTX_new - create a SSL context +/** + * @brief create a SSL context * * @param method - the SSL context method point * - * @return the context point, if create failed return NULL + * @return the context point */ SSL_CTX* SSL_CTX_new(const SSL_METHOD *method); -/* - * SSL_CTX_free - free a SSL context +/** + * @brief free a SSL context * * @param method - the SSL context point * @@ -40,17 +40,17 @@ SSL_CTX* SSL_CTX_new(const SSL_METHOD *method); */ void SSL_CTX_free(SSL_CTX *ctx); -/* - * SSL_new - create a SSL +/** + * @brief create a SSL * * @param ctx - the SSL context point * - * @return the SSL point or NULL if failed + * @return the SSL point */ SSL* SSL_new(SSL_CTX *ctx); -/* - * SSL_free - free the SSL +/** + * @brief free the SSL * * @param ssl - the SSL point * @@ -58,58 +58,58 @@ SSL* SSL_new(SSL_CTX *ctx); */ void SSL_free(SSL *ssl); -/* - * SSL_connect - connect to the remote SSL server +/** + * @brief connect to the remote SSL server * * @param ssl - the SSL point * - * @return - * 1 : OK - * -1 : failed + * @return result + * 1 : OK + * -1 : failed */ int SSL_connect(SSL *ssl); -/* - * SSL_accept - accept the remote connection +/** + * @brief accept the remote connection * * @param ssl - the SSL point * - * @return - * 1 : OK - * -1 : failed + * @return result + * 1 : OK + * -1 : failed */ int SSL_accept(SSL *ssl); -/* - * SSL_read - read data from to remote +/** + * @brief read data from to remote * * @param ssl - the SSL point which has been connected * @param buffer - the received data buffer point * @param len - the received data length * - * @return - * > 0 : OK, and return received data bytes - * = 0 : connection is closed - * < 0 : an error catch + * @return result + * > 0 : OK, and return received data bytes + * = 0 : connection is closed + * < 0 : an error catch */ int SSL_read(SSL *ssl, void *buffer, int len); -/* - * SSL_write - send the data to remote +/** + * @brief send the data to remote * * @param ssl - the SSL point which has been connected * @param buffer - the send data buffer point * @param len - the send data length * - * @return - * > 0 : OK, and return sent data bytes - * = 0 : connection is closed - * < 0 : an error catch + * @return result + * > 0 : OK, and return sent data bytes + * = 0 : connection is closed + * < 0 : an error catch */ int SSL_write(SSL *ssl, const void *buffer, int len); -/* - * SSL_get_verify_result - get the verifying result of the SSL certification +/** + * @brief get the verifying result of the SSL certification * * @param ssl - the SSL point * @@ -117,56 +117,56 @@ int SSL_write(SSL *ssl, const void *buffer, int len); */ long SSL_get_verify_result(const SSL *ssl); -/* - * SSL_shutdown - shutdown the connection +/** + * @brief shutdown the connection * * @param ssl - the SSL point * - * @return - * 1 : OK - * 0 : shutdown is not finished - * -1 : an error catch + * @return result + * 1 : OK + * 0 : shutdown is not finished + * -1 : an error catch */ int SSL_shutdown(SSL *ssl); -/* - * SSL_set_fd - bind the socket file description into the SSL +/** + * @brief bind the socket file description into the SSL * * @param ssl - the SSL point * @param fd - socket handle * - * @return - * 1 : OK - * 0 : failed + * @return result + * 1 : OK + * 0 : failed */ int SSL_set_fd(SSL *ssl, int fd); -/* - * SSL_CTX_use_PrivateKey - These functions load the private key into the SSL_CTX or SSL object +/** + * @brief These functions load the private key into the SSL_CTX or SSL object * * @param ctx - the SSL context point * @param pkey - private key object point * - * @return - * 1 : OK - * 0 : failed + * @return result + * 1 : OK + * 0 : failed */ int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey); -/* - * SSL_CTX_use_PrivateKey - These functions load the certification into the SSL_CTX or SSL object +/** + * @brief These functions load the certification into the SSL_CTX or SSL object * * @param ctx - the SSL context point * @param pkey - certification object point * - * @return - * 1 : OK - * 0 : failed + * @return result + * 1 : OK + * 0 : failed */ int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x); -/* - * SSLv23_client_method - create the target SSL context client method +/** + * @brief create the target SSL context client method * * @param none * @@ -174,8 +174,8 @@ int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x); */ const SSL_METHOD* SSLv23_client_method(void); -/* - * TLSv1_client_method - create the target SSL context client method +/** + * @brief create the target SSL context client method * * @param none * @@ -183,8 +183,8 @@ const SSL_METHOD* SSLv23_client_method(void); */ const SSL_METHOD* TLSv1_client_method(void); -/* - * SSLv3_client_method - create the target SSL context client method +/** + * @brief create the target SSL context client method * * @param none * @@ -192,8 +192,8 @@ const SSL_METHOD* TLSv1_client_method(void); */ const SSL_METHOD* SSLv3_client_method(void); -/* - * TLSv1_1_client_method - create the target SSL context client method +/** + * @brief create the target SSL context client method * * @param none * @@ -201,8 +201,8 @@ const SSL_METHOD* SSLv3_client_method(void); */ const SSL_METHOD* TLSv1_1_client_method(void); -/* - * TLSv1_1_client_method - create the target SSL context client method +/** + * @brief create the target SSL context client method * * @param none * @@ -211,8 +211,8 @@ const SSL_METHOD* TLSv1_1_client_method(void); const SSL_METHOD* TLSv1_2_client_method(void); -/* - * SSLv23_server_method - create the target SSL context server method +/** + * @brief create the target SSL context server method * * @param none * @@ -220,8 +220,8 @@ const SSL_METHOD* TLSv1_2_client_method(void); */ const SSL_METHOD* SSLv23_server_method(void); -/* - * TLSv1_1_server_method - create the target SSL context server method +/** + * @brief create the target SSL context server method * * @param none * @@ -229,8 +229,8 @@ const SSL_METHOD* SSLv23_server_method(void); */ const SSL_METHOD* TLSv1_1_server_method(void); -/* - * TLSv1_1_server_method - create the target SSL context server method +/** + * @brief create the target SSL context server method * * @param none * @@ -238,8 +238,8 @@ const SSL_METHOD* TLSv1_1_server_method(void); */ const SSL_METHOD* TLSv1_2_server_method(void); -/* - * TLSv1_server_method - create the target SSL context server method +/** + * @brief create the target SSL context server method * * @param none * @@ -247,8 +247,8 @@ const SSL_METHOD* TLSv1_2_server_method(void); */ const SSL_METHOD* TLSv1_server_method(void); -/* - * SSLv3_server_method - create the target SSL context server method +/** + * @brief create the target SSL context server method * * @param none * @@ -256,8 +256,8 @@ const SSL_METHOD* TLSv1_server_method(void); */ const SSL_METHOD* SSLv3_server_method(void); -/* - * SSL_CTX_set_alpn_select_cb - set the SSL context ALPN select callback function +/** + * @brief set the SSL context ALPN select callback function * * @param ctx - SSL context point * @param cb - ALPN select callback function @@ -275,21 +275,21 @@ void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx, void *arg); -/* - * SSL_CTX_set_alpn_protos - set the SSL context ALPN select protocol +/** + * @brief set the SSL context ALPN select protocol * * @param ctx - SSL context point * @param protos - ALPN protocol name * @param protos_len - ALPN protocol name bytes * - * @return - * 0 : OK - * 1 : failed + * @return result + * 0 : OK + * 1 : failed */ int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos, unsigned int protos_len); -/* - * SSL_CTX_set_next_proto_select_cb - set the SSL context next ALPN select callback function +/** + * @brief set the SSL context next ALPN select callback function * * @param ctx - SSL context point * @param cb - ALPN select callback function @@ -306,8 +306,8 @@ void SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx, void *arg), void *arg); -/* - * SSL_get_error - get SSL error code +/** + * @brief get SSL error code * * @param ssl - SSL point * @param ret_code - SSL return code @@ -316,8 +316,8 @@ void SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx, */ int SSL_get_error(const SSL *ssl, int ret_code); -/* - * ERR_clear_error - clear the SSL error code +/** + * @brief clear the SSL error code * * @param none * @@ -325,8 +325,8 @@ int SSL_get_error(const SSL *ssl, int ret_code); */ void ERR_clear_error(void); -/* - * ERR_get_error - get the current SSL error code +/** + * @brief get the current SSL error code * * @param none * @@ -334,8 +334,8 @@ void ERR_clear_error(void); */ int ERR_get_error(void); -/* - * ERR_load_SSL_strings - register the SSL error strings +/** + * @brief register the SSL error strings * * @param none * @@ -343,8 +343,8 @@ int ERR_get_error(void); */ void ERR_load_SSL_strings(void); -/* - * SSL_library_init - initialize the SSL library +/** + * @brief initialize the SSL library * * @param none * @@ -352,9 +352,9 @@ void ERR_load_SSL_strings(void); */ void SSL_library_init(void); -/* - * ERR_error_string - generates a human-readable string representing the error code e - * and store it into the "ret" point memory +/** + * @brief generates a human-readable string representing the error code e + * and store it into the "ret" point memory * * @param e - error code * @param ret - memory point to store the string @@ -363,8 +363,8 @@ void SSL_library_init(void); */ char *ERR_error_string(unsigned long e, char *ret); -/* - * SSL_CTX_set_options - add the SSL context option +/** + * @brief add the SSL context option * * @param ctx - SSL context point * @param opt - new SSL context option @@ -373,15 +373,15 @@ char *ERR_error_string(unsigned long e, char *ret); */ unsigned long SSL_CTX_set_options(SSL_CTX *ctx, unsigned long opt); -/* - * SSL_CTX_set_options - add the SSL context mode +/** + * @brief add the SSL context mode * * @param ctx - SSL context point * @param mod - new SSL context mod * - * @return - * 1 : OK - * 0 : failed + * @return result + * 1 : OK + * 0 : failed */ int SSL_CTX_set_mode(SSL_CTX *ctx, int mod); @@ -389,20 +389,20 @@ int SSL_CTX_set_mode(SSL_CTX *ctx, int mod); } */ -/* - * SSL_do_handshake - perform the SSL handshake +/** + * @brief perform the SSL handshake * * @param ssl - SSL point * - * @return - * 1 : OK - * 0 : failed - * -1 : a error catch + * @return result + * 1 : OK + * 0 : failed + * -1 : a error catch */ int SSL_do_handshake(SSL *ssl); -/* - * SSL_get_version - get the SSL current version +/** + * @brief get the SSL current version * * @param ssl - SSL point * @@ -410,20 +410,20 @@ int SSL_do_handshake(SSL *ssl); */ const char *SSL_get_version(const SSL *ssl); -/* - * SSL_CTX_set_ssl_version - set the SSL context version +/** + * @brief set the SSL context version * * @param ctx - SSL context point * @param meth - SSL method point * - * @return - * 1 : OK - * 0 : failed + * @return result + * 1 : OK + * 0 : failed */ int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth); -/* - * SSL_CTX_get_ssl_method - get the SSL context current method +/** + * @brief get the SSL context current method * * @param ctx - SSL context point * @@ -431,8 +431,8 @@ int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth); */ const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx); -/* - * SSL_CTX_get_ssl_method - get the SSL current method +/** + * @brief get the SSL current method * * @param ssl - SSL point * @@ -440,44 +440,44 @@ const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx); */ const SSL_METHOD *SSL_get_ssl_method(SSL *ssl); -/* - * SSL_set_ssl_method - set the SSL method +/** + * @brief set the SSL method * * @param ssl - SSL point * @param meth - SSL method point * - * @return - * 1 : OK - * 0 : failed + * @return result + * 1 : OK + * 0 : failed */ int SSL_set_ssl_method(SSL *ssl, const SSL_METHOD *method); -/* - * SSL_add_client_CA - add CA client certification into the SSL +/** + * @brief add CA client certification into the SSL * * @param ssl - SSL point * @param x - CA certification point * - * @return - * 1 : OK - * 0 : failed + * @return result + * 1 : OK + * 0 : failed */ int SSL_add_client_CA(SSL *ssl, X509 *x); -/* - * SSL_add_client_CA - add CA client certification into the SSL context +/** + * @brief add CA client certification into the SSL context * * @param ctx - SSL context point * @param x - CA certification point * - * @return - * 1 : OK - * 0 : failed + * @return result + * 1 : OK + * 0 : failed */ int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x); -/* - * SSL_set_client_CA_list - set the SSL CA certification list +/** + * @brief set the SSL CA certification list * * @param ssl - SSL point * @param name_list - CA certification list @@ -486,8 +486,8 @@ int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x); */ void SSL_set_client_CA_list(SSL *ssl, STACK_OF(X509_NAME) *name_list); -/* - * SSL_CTX_set_client_CA_list - set the SSL context CA certification list +/** + * @brief set the SSL context CA certification list * * @param ctx - SSL context point * @param name_list - CA certification list @@ -496,8 +496,8 @@ void SSL_set_client_CA_list(SSL *ssl, STACK_OF(X509_NAME) *name_list); */ void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list); -/* - * SSL_get_client_CA_list - get the SSL CA certification list +/** + * @briefget the SSL CA certification list * * @param ssl - SSL point * @@ -505,8 +505,8 @@ void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list); */ STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *ssl); -/* - * SSL_CTX_get_client_CA_list - get the SSL context CA certification list +/** + * @brief get the SSL context CA certification list * * @param ctx - SSL context point * @@ -514,8 +514,8 @@ STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *ssl); */ STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx); -/* - * SSL_get_certificate - get the SSL certification point +/** + * @brief get the SSL certification point * * @param ssl - SSL point * @@ -523,8 +523,8 @@ STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx); */ X509 *SSL_get_certificate(const SSL *ssl); -/* - * SSL_get_privatekey - get the SSL private key point +/** + * @brief get the SSL private key point * * @param ssl - SSL point * @@ -532,8 +532,8 @@ X509 *SSL_get_certificate(const SSL *ssl); */ EVP_PKEY *SSL_get_privatekey(const SSL *ssl); -/* - * SSL_set_info_callback - set the SSL information callback function +/** + * @brief set the SSL information callback function * * @param ssl - SSL point * @param cb - information callback function @@ -542,8 +542,8 @@ EVP_PKEY *SSL_get_privatekey(const SSL *ssl); */ void SSL_set_info_callback(SSL *ssl, void (*cb) (const SSL *ssl, int type, int val)); -/* - * SSL_get_state - get the SSL state +/** + * @brief get the SSL state * * @param ssl - SSL point * @@ -551,8 +551,8 @@ void SSL_set_info_callback(SSL *ssl, void (*cb) (const SSL *ssl, int type, int v */ OSSL_HANDSHAKE_STATE SSL_get_state(const SSL *ssl); -/* - * SSL_CTX_set_default_read_buffer_len - set the SSL context read buffer length +/** + * @brief set the SSL context read buffer length * * @param ctx - SSL context point * @param len - read buffer length @@ -561,8 +561,8 @@ OSSL_HANDSHAKE_STATE SSL_get_state(const SSL *ssl); */ void SSL_CTX_set_default_read_buffer_len(SSL_CTX *ctx, size_t len); -/* - * SSL_set_default_read_buffer_len - set the SSL read buffer length +/** + * @brief set the SSL read buffer length * * @param ssl - SSL point * @param len - read buffer length @@ -571,8 +571,8 @@ void SSL_CTX_set_default_read_buffer_len(SSL_CTX *ctx, size_t len); */ void SSL_set_default_read_buffer_len(SSL *ssl, size_t len); -/* - * SSL_set_security_level - set the SSL security level +/** + * @brief set the SSL security level * * @param ssl - SSL point * @param level - security level @@ -581,8 +581,8 @@ void SSL_set_default_read_buffer_len(SSL *ssl, size_t len); */ void SSL_set_security_level(SSL *ssl, int level); -/* - * SSL_get_security_level - get the SSL security level +/** + * @brief get the SSL security level * * @param ssl - SSL point * @@ -590,8 +590,8 @@ void SSL_set_security_level(SSL *ssl, int level); */ int SSL_get_security_level(const SSL *ssl); -/* - * SSL_CTX_get_verify_mode - get the SSL verifying mode of the SSL context +/** + * @brief get the SSL verifying mode of the SSL context * * @param ctx - SSL context point * @@ -599,8 +599,8 @@ int SSL_get_security_level(const SSL *ssl); */ int SSL_CTX_get_verify_mode(const SSL_CTX *ctx); -/* - * SSL_CTX_get_verify_depth - get the SSL verifying depth of the SSL context +/** + * @brief get the SSL verifying depth of the SSL context * * @param ctx - SSL context point * @@ -608,8 +608,8 @@ int SSL_CTX_get_verify_mode(const SSL_CTX *ctx); */ int SSL_CTX_get_verify_depth(const SSL_CTX *ctx); -/* - * SSL_CTX_set_verify - set the SSL context verifying of the SSL context +/** + * @brief set the SSL context verifying of the SSL context * * @param ctx - SSL context point * @param mode - verifying mode @@ -619,8 +619,8 @@ int SSL_CTX_get_verify_depth(const SSL_CTX *ctx); */ void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, int (*verify_callback)(int, X509_STORE_CTX *)); -/* - * SSL_set_verify - set the SSL verifying of the SSL context +/** + * @brief set the SSL verifying of the SSL context * * @param ctx - SSL point * @param mode - verifying mode @@ -630,18 +630,18 @@ void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, int (*verify_callback)(int, X509 */ void SSL_set_verify(SSL *s, int mode, int (*verify_callback)(int, X509_STORE_CTX *)); -/* - * SSL_CTX_set_verify_depth - set the SSL verify depth of the SSL context +/** + * @brief set the SSL verify depth of the SSL context * * @param ctx - SSL context point * @param depth - verifying depth * - * @return one + * @return none */ void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth); -/* - * verify_callback - certification verifying callback function +/** + * @brief certification verifying callback function * * @param preverify_ok - verifying result * @param x509_ctx - X509 certification point @@ -650,8 +650,8 @@ void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth); */ int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx); -/* - * SSL_CTX_set_timeout - set the session timeout time +/** + * @brief set the session timeout time * * @param ctx - SSL context point * @param t - new session timeout time @@ -660,8 +660,8 @@ int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx); */ long SSL_CTX_set_timeout(SSL_CTX *ctx, long t); -/* - * SSL_CTX_get_timeout - get the session timeout time +/** + * @brief get the session timeout time * * @param ctx - SSL context point * @@ -669,32 +669,32 @@ long SSL_CTX_set_timeout(SSL_CTX *ctx, long t); */ long SSL_CTX_get_timeout(const SSL_CTX *ctx); -/* - * SSL_CTX_set_cipher_list - set the SSL context cipher through the list string +/** + * @brief set the SSL context cipher through the list string * * @param ctx - SSL context point * @param str - cipher controller list string * - * @return - * 1 : OK - * 0 : failed + * @return result + * 1 : OK + * 0 : failed */ int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str); -/* - * SSL_set_cipher_list - set the SSL cipher through the list string +/** + * @brief set the SSL cipher through the list string * * @param ssl - SSL point * @param str - cipher controller list string * - * @return - * 1 : OK - * 0 : failed + * @return result + * 1 : OK + * 0 : failed */ int SSL_set_cipher_list(SSL *ssl, const char *str); -/* - * SSL_get_cipher_list - get the SSL cipher list string +/** + * @brief get the SSL cipher list string * * @param ssl - SSL point * @@ -702,8 +702,8 @@ int SSL_set_cipher_list(SSL *ssl, const char *str); */ const char *SSL_get_cipher_list(const SSL *ssl, int n); -/* - * SSL_get_current_cipher - get the SSL cipher +/** + * @brief get the SSL cipher * * @param ssl - SSL point * @@ -711,8 +711,8 @@ const char *SSL_get_cipher_list(const SSL *ssl, int n); */ const SSL_CIPHER *SSL_get_current_cipher(const SSL *ssl); -/* - * SSL_get_cipher - get the SSL cipher string +/** + * @brief get the SSL cipher string * * @param ssl - SSL point * @@ -720,8 +720,8 @@ const SSL_CIPHER *SSL_get_current_cipher(const SSL *ssl); */ const char *SSL_get_cipher(const SSL *ssl); -/* - * SSL_CTX_get_cert_store - get the SSL context object X509 certification storage +/** + * @brief get the SSL context object X509 certification storage * * @param ctx - SSL context point * @@ -729,8 +729,8 @@ const char *SSL_get_cipher(const SSL *ssl); */ X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx); -/* - * SSL_CTX_set_cert_store - set the SSL context object X509 certification store +/** + * @brief set the SSL context object X509 certification store * * @param ctx - SSL context point * @param store - X509 certification store @@ -739,8 +739,8 @@ X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx); */ void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store); -/* - * SSL_want - get the SSL specifical statement +/** + * @brief get the SSL specifical statement * * @param ssl - SSL point * @@ -748,63 +748,63 @@ void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store); */ int SSL_want(const SSL *ssl); -/* - * SSL_want_x509_lookup - check if the SSL is SSL_X509_LOOKUP state +/** + * @brief check if the SSL is SSL_X509_LOOKUP state * * @param ssl - SSL point * - * @return - * 1 : yes - * 0 : no + * @return result + * 1 : OK + * 0 : failed */ int SSL_want_x509_lookup(const SSL *ssl); -/* - * SSL_clear - reset the SSL +/** + * @brief reset the SSL * * @param ssl - SSL point * - * @return - * 1 : yes - * 0 : no + * @return result + * 1 : OK + * 0 : failed */ int SSL_clear(SSL *ssl); -/* - * SSL_get_fd - get the socket handle of the SSL +/** + * @brief get the socket handle of the SSL * * @param ssl - SSL point * - * @return - * >= 0 : yes, and return socket handle - * < 0 : a error catch + * @return result + * >= 0 : yes, and return socket handle + * < 0 : a error catch */ int SSL_get_fd(const SSL *ssl); -/* - * SSL_get_rfd - get the read only socket handle of the SSL +/** + * @brief get the read only socket handle of the SSL * * @param ssl - SSL point * - * @return - * >= 0 : yes, and return socket handle - * < 0 : a error catch + * @return result + * >= 0 : yes, and return socket handle + * < 0 : a error catch */ int SSL_get_rfd(const SSL *ssl); -/* - * SSL_get_wfd - get the write only socket handle of the SSL +/** + * @brief get the write only socket handle of the SSL * * @param ssl - SSL point * - * @return - * >= 0 : yes, and return socket handle - * < 0 : a error catch + * @return result + * >= 0 : yes, and return socket handle + * < 0 : a error catch */ int SSL_get_wfd(const SSL *ssl); -/* - * SSL_set_read_ahead - set the SSL if we can read as many as data +/** + * @brief set the SSL if we can read as many as data * * @param ssl - SSL point * @param yes - enable the function @@ -813,8 +813,8 @@ int SSL_get_wfd(const SSL *ssl); */ void SSL_set_read_ahead(SSL *s, int yes); -/* - * SSL_set_read_ahead - set the SSL context if we can read as many as data +/** + * @brief set the SSL context if we can read as many as data * * @param ctx - SSL context point * @param yes - enbale the function @@ -823,8 +823,8 @@ void SSL_set_read_ahead(SSL *s, int yes); */ void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes); -/* - * SSL_set_read_ahead - get the SSL ahead signal if we can read as many as data +/** + * @brief get the SSL ahead signal if we can read as many as data * * @param ssl - SSL point * @@ -832,8 +832,8 @@ void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes); */ int SSL_get_read_ahead(const SSL *ssl); -/* - * SSL_set_read_ahead - get the SSL context ahead signal if we can read as many as data +/** + * @brief get the SSL context ahead signal if we can read as many as data * * @param ctx - SSL context point * @@ -841,8 +841,8 @@ int SSL_get_read_ahead(const SSL *ssl); */ long SSL_CTX_get_read_ahead(SSL_CTX *ctx); -/* - * SSL_has_pending - check if some data can be read +/** + * @brief check if some data can be read * * @param ssl - SSL point * @@ -852,160 +852,160 @@ long SSL_CTX_get_read_ahead(SSL_CTX *ctx); */ int SSL_has_pending(const SSL *ssl); -/* - * SSL_CTX_use_certificate - load the X509 certification into SSL context +/** + * @brief load the X509 certification into SSL context * * @param ctx - SSL context point * @param x - X509 certification point * - * @return - * 1 : OK - * 0 : failed + * @return result + * 1 : OK + * 0 : failed */ int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x);//loads the certificate x into ctx -/* - * SSL_CTX_use_certificate_ASN1 - load the ASN1 certification into SSL context +/** + * @brief load the ASN1 certification into SSL context * * @param ctx - SSL context point * @param len - certification length * @param d - data point * - * @return - * 1 : OK - * 0 : failed + * @return result + * 1 : OK + * 0 : failed */ int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d); -/* - * SSL_CTX_use_certificate_file - load the certification file into SSL context +/** + * @brief load the certification file into SSL context * * @param ctx - SSL context point * @param file - certification file name * @param type - certification encoding type * - * @return - * 1 : OK - * 0 : failed + * @return result + * 1 : OK + * 0 : failed */ int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type); -/* - * SSL_CTX_use_certificate_chain_file - load the certification chain file into SSL context +/** + * @brief load the certification chain file into SSL context * * @param ctx - SSL context point * @param file - certification chain file name * - * @return - * 1 : OK - * 0 : failed + * @return result + * 1 : OK + * 0 : failed */ int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file); -/* - * SSL_CTX_use_certificate_ASN1 - load the ASN1 private key into SSL context +/** + * @brief load the ASN1 private key into SSL context * * @param ctx - SSL context point * @param d - data point * @param len - private key length * - * @return - * 1 : OK - * 0 : failed + * @return result + * 1 : OK + * 0 : failed */ int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, const unsigned char *d, long len);//adds the private key of type pk stored at memory location d (length len) to ctx -/* - * SSL_CTX_use_certificate_file - load the private key file into SSL context +/** + * @brief load the private key file into SSL context * * @param ctx - SSL context point * @param file - private key file name * @param type - private key encoding type * - * @return - * 1 : OK - * 0 : failed + * @return result + * 1 : OK + * 0 : failed */ int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type); -/* - * SSL_CTX_use_certificate - load the RSA private key into SSL context +/** + * @brief load the RSA private key into SSL context * * @param ctx - SSL context point * @param x - RSA private key point * - * @return - * 1 : OK - * 0 : failed + * @return result + * 1 : OK + * 0 : failed */ int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa); -/* - * SSL_CTX_use_certificate_ASN1 - load the RSA ASN1 private key into SSL context +/** + * @brief load the RSA ASN1 private key into SSL context * * @param ctx - SSL context point * @param d - data point * @param len - RSA private key length * - * @return - * 1 : OK - * 0 : failed + * @return result + * 1 : OK + * 0 : failed */ int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len); -/* - * SSL_CTX_use_certificate_file - load the RSA private key file into SSL context +/** + * @brief load the RSA private key file into SSL context * * @param ctx - SSL context point * @param file - RSA private key file name * @param type - private key encoding type * - * @return - * 1 : OK - * 0 : failed + * @return result + * 1 : OK + * 0 : failed */ int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type); -/* - * SSL_CTX_check_private_key - check if the private key and certification is matched +/** + * @brief check if the private key and certification is matched * * @param ctx - SSL context point * - * @return - * 1 : OK - * 0 : failed + * @return result + * 1 : OK + * 0 : failed */ int SSL_CTX_check_private_key(const SSL_CTX *ctx); -/* - * SSL_CTX_use_serverinfo - set the SSL context server information +/** + * @brief set the SSL context server information * * @param ctx - SSL context point * @param serverinfo - server information string * @param serverinfo_length - server information length * - * @return - * 1 : OK - * 0 : failed + * @return result + * 1 : OK + * 0 : failed */ int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo, size_t serverinfo_length); -/* - * SSL_CTX_use_serverinfo - load the SSL context server infomation file into SSL context +/** + * @brief load the SSL context server infomation file into SSL context * * @param ctx - SSL context point * @param file - server information file * - * @return - * 1 : OK - * 0 : failed + * @return result + * 1 : OK + * 0 : failed */ int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file); -/* - * SSL_select_next_proto - SSL select next function +/** + * @brief SSL select next function * * @param out - point of output data point * @param outlen - output data length @@ -1014,7 +1014,7 @@ int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file); * @param client - client data point * @param client_len -client data length * - * @return + * @return NPN state * OPENSSL_NPN_UNSUPPORTED : not support * OPENSSL_NPN_NEGOTIATED : negotiated * OPENSSL_NPN_NO_OVERLAP : no overlap @@ -1023,34 +1023,34 @@ int SSL_select_next_proto(unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, const unsigned char *client, unsigned int client_len); -/* - * SSL_CTX_add_extra_chain_cert - load the extra certification chain into the SSL context +/** + * @brief load the extra certification chain into the SSL context * * @param ctx - SSL context point * @param x509 - X509 certification * - * @return - * 1 : OK - * 0 : failed + * @return result + * 1 : OK + * 0 : failed */ long SSL_CTX_add_extra_chain_cert(SSL_CTX *ctx, X509 *); -/* - * SSL_CTX_ctrl - control the SSL context +/** + * @brief control the SSL context * * @param ctx - SSL context point * @param cmd - command * @param larg - parameter length * @param parg - parameter point * - * @return - * 1 : OK - * 0 : failed + * @return result + * 1 : OK + * 0 : failed */ long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, char *parg); -/* - * SSL_CTX_get_ciphers - get the SSL context cipher +/** + * @brief get the SSL context cipher * * @param ctx - SSL context point * @@ -1058,19 +1058,19 @@ long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, char *parg); */ STACK *SSL_CTX_get_ciphers(const SSL_CTX *ctx); -/* - * SSL_CTX_get_ciphers - check if the SSL context can read as many as data +/** + * @brief check if the SSL context can read as many as data * * @param ctx - SSL context point * - * @return - * 1 : Yes - * 0 : No + * @return result + * 1 : OK + * 0 : failed */ long SSL_CTX_get_default_read_ahead(SSL_CTX *ctx); -/* - * SSL_CTX_get_ex_data - get the SSL context extra data +/** + * @brief get the SSL context extra data * * @param ctx - SSL context point * @param idx - index @@ -1079,8 +1079,8 @@ long SSL_CTX_get_default_read_ahead(SSL_CTX *ctx); */ char *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx); -/* - * SSL_CTX_get_quiet_shutdown - get the SSL context quiet shutdown option +/** + * @brief get the SSL context quiet shutdown option * * @param ctx - SSL context point * @@ -1088,44 +1088,44 @@ char *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx); */ int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx); -/* - * SSL_CTX_get_quiet_shutdown - load the SSL context CA file +/** + * @brief load the SSL context CA file * * @param ctx - SSL context point * @param CAfile - CA certification file * @param CApath - CA certification file path * - * @return - * 1 : OK - * 0 : failed + * @return result + * 1 : OK + * 0 : failed */ int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, const char *CApath); -/* - * SSL_CTX_up_ref - add SSL context reference count by '1' +/** + * @brief add SSL context reference count by '1' * * @param ctx - SSL context point * - * @return - * 1 : OK - * 0 : failed + * @return result + * 1 : OK + * 0 : failed */ int SSL_CTX_up_ref(SSL_CTX *ctx); -/* - * SSL_CTX_set_app_data - set SSL context application private data +/** + * @brief set SSL context application private data * * @param ctx - SSL context point * @param arg - private data * - * @return - * 1 : OK - * 0 : failed + * @return result + * 1 : OK + * 0 : failed */ int SSL_CTX_set_app_data(SSL_CTX *ctx, void *arg); -/* - * SSL_CTX_set_client_cert_cb - set SSL context client certification callback function +/** + * @brief set SSL context client certification callback function * * @param ctx - SSL context point * @param cb - callback function @@ -1134,8 +1134,8 @@ int SSL_CTX_set_app_data(SSL_CTX *ctx, void *arg); */ void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey)); -/* - * SSL_CTX_set_default_read_ahead - set the SSL context if we can read as many as data +/** + * @brief set the SSL context if we can read as many as data * * @param ctx - SSL context point * @param m - enable the fuction @@ -1144,54 +1144,54 @@ void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*cb)(SSL *ssl, X509 **x509, E */ void SSL_CTX_set_default_read_ahead(SSL_CTX *ctx, int m); -/* - * SSL_CTX_set_default_verify_paths - set SSL context default verifying path +/** + * @brief set SSL context default verifying path * * @param ctx - SSL context point * - * @return - * 1 : OK - * 0 : failed + * @return result + * 1 : OK + * 0 : failed */ int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx); -/* - * SSL_CTX_set_default_verify_paths - set SSL context default verifying directory +/** + * @brief set SSL context default verifying directory * * @param ctx - SSL context point * - * @return - * 1 : OK - * 0 : failed + * @return result + * 1 : OK + * 0 : failed */ int SSL_CTX_set_default_verify_dir(SSL_CTX *ctx); -/* - * SSL_CTX_set_default_verify_paths - set SSL context default verifying file +/** + * @brief set SSL context default verifying file * * @param ctx - SSL context point * - * @return - * 1 : OK - * 0 : failed + * @return result + * 1 : OK + * 0 : failed */ int SSL_CTX_set_default_verify_file(SSL_CTX *ctx); -/* - * SSL_CTX_set_ex_data - set SSL context extra data +/** + * @brief set SSL context extra data * * @param ctx - SSL context point * @param idx - data index * @param arg - data point * - * @return - * 1 : OK - * 0 : failed + * @return result + * 1 : OK + * 0 : failed */ int SSL_CTX_set_ex_data(SSL_CTX *s, int idx, char *arg); -/* - * SSL_CTX_clear_options - clear the SSL context option bit of "op" +/** + * @brief clear the SSL context option bit of "op" * * @param ctx - SSL context point * @param op - option @@ -1200,8 +1200,8 @@ int SSL_CTX_set_ex_data(SSL_CTX *s, int idx, char *arg); */ unsigned long SSL_CTX_clear_options(SSL_CTX *ctx, unsigned long op); -/* - * SSL_CTX_clear_options - get the SSL context option +/** + * @brief get the SSL context option * * @param ctx - SSL context point * @param op - option @@ -1210,8 +1210,8 @@ unsigned long SSL_CTX_clear_options(SSL_CTX *ctx, unsigned long op); */ unsigned long SSL_CTX_get_options(SSL_CTX *ctx); -/* - * SSL_CTX_set_quiet_shutdown - set the SSL context quiet shutdown mode +/** + * @brief set the SSL context quiet shutdown mode * * @param ctx - SSL context point * @param mode - mode @@ -1220,8 +1220,8 @@ unsigned long SSL_CTX_get_options(SSL_CTX *ctx); */ void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode); -/* - * SSL_CTX_get0_certificate - get the SSL context X509 certification +/** + * @brief get the SSL context X509 certification * * @param ctx - SSL context point * @@ -1229,8 +1229,8 @@ void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode); */ X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx); -/* - * SSL_CTX_get0_certificate - get the SSL context private key +/** + * @brief get the SSL context private key * * @param ctx - SSL context point * @@ -1238,32 +1238,33 @@ X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx); */ EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx); -/* - * SSL_CTX_use_psk_identity_hint - set SSL context PSK identity hint +/** + * @brief set SSL context PSK identity hint * * @param ctx - SSL context point * @param hint - PSK identity hint * - * @return - * 1 : OK - * 0 : failed + * @return result + * 1 : OK + * 0 : failed */ int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *hint); -/* - * SSL_CTX_set_psk_server_callback - set SSL context PSK server callback function +/** + * @brief set SSL context PSK server callback function * * @param ctx - SSL context point * @param callback - callback function * + * @return none */ void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx, unsigned int (*callback)(SSL *ssl, const char *identity, unsigned char *psk, int max_psk_len)); -/* - * SSL_alert_desc_string - get alert description string +/** + * @brief get alert description string * * @param value - alert value * @@ -1271,8 +1272,8 @@ void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx, */ const char *SSL_alert_desc_string(int value); -/* - * SSL_alert_desc_string - get alert description long string +/** + * @brief get alert description long string * * @param value - alert value * @@ -1280,8 +1281,8 @@ const char *SSL_alert_desc_string(int value); */ const char *SSL_alert_desc_string_long(int value); -/* - * SSL_alert_type_string - get alert type string +/** + * @brief get alert type string * * @param value - alert value * @@ -1289,8 +1290,8 @@ const char *SSL_alert_desc_string_long(int value); */ const char *SSL_alert_type_string(int value); -/* - * SSL_alert_type_string_long - get alert type long string +/** + * @brief get alert type long string * * @param value - alert value * @@ -1298,8 +1299,8 @@ const char *SSL_alert_type_string(int value); */ const char *SSL_alert_type_string_long(int value); -/* - * SSL_get_SSL_CTX - get SSL context of the SSL +/** + * @brief get SSL context of the SSL * * @param ssl - SSL point * @@ -1307,8 +1308,8 @@ const char *SSL_alert_type_string_long(int value); */ SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl); -/* - * SSL_get_app_data - get SSL application data +/** + * @brief get SSL application data * * @param ssl - SSL point * @@ -1316,8 +1317,8 @@ SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl); */ char *SSL_get_app_data(SSL *ssl); -/* - * SSL_get_cipher_bits - get SSL cipher bits +/** + * @brief get SSL cipher bits * * @param ssl - SSL point * @param alg_bits - algorithm bits @@ -1326,8 +1327,8 @@ char *SSL_get_app_data(SSL *ssl); */ int SSL_get_cipher_bits(const SSL *ssl, int *alg_bits); -/* - * SSL_get_cipher_name - get SSL cipher name +/** + * @brief get SSL cipher name * * @param ssl - SSL point * @@ -1335,8 +1336,8 @@ int SSL_get_cipher_bits(const SSL *ssl, int *alg_bits); */ char *SSL_get_cipher_name(const SSL *ssl); -/* - * SSL_get_cipher_version - get SSL cipher version +/** + * @brief get SSL cipher version * * @param ssl - SSL point * @@ -1344,8 +1345,8 @@ char *SSL_get_cipher_name(const SSL *ssl); */ char *SSL_get_cipher_version(const SSL *ssl); -/* - * SSL_get_ex_data - get SSL extra data +/** + * @brief get SSL extra data * * @param ssl - SSL point * @param idx - data index @@ -1354,8 +1355,8 @@ char *SSL_get_cipher_version(const SSL *ssl); */ char *SSL_get_ex_data(const SSL *ssl, int idx); -/* - * SSL_get_ex_data_X509_STORE_CTX_idx - get index of the SSL extra data X509 storage context +/** + * @brief get index of the SSL extra data X509 storage context * * @param none * @@ -1363,8 +1364,8 @@ char *SSL_get_ex_data(const SSL *ssl, int idx); */ int SSL_get_ex_data_X509_STORE_CTX_idx(void); -/* - * SSL_get_peer_cert_chain - get peer certification chain +/** + * @brief get peer certification chain * * @param ssl - SSL point * @@ -1372,8 +1373,8 @@ int SSL_get_ex_data_X509_STORE_CTX_idx(void); */ STACK *SSL_get_peer_cert_chain(const SSL *ssl); -/* - * SSL_get_peer_certificate - get peer certification +/** + * @brief get peer certification * * @param ssl - SSL point * @@ -1381,8 +1382,8 @@ STACK *SSL_get_peer_cert_chain(const SSL *ssl); */ X509 *SSL_get_peer_certificate(const SSL *ssl); -/* - * SSL_get_quiet_shutdown - get SSL quiet shutdown mode +/** + * @brief get SSL quiet shutdown mode * * @param ssl - SSL point * @@ -1390,8 +1391,8 @@ X509 *SSL_get_peer_certificate(const SSL *ssl); */ int SSL_get_quiet_shutdown(const SSL *ssl); -/* - * SSL_get_rbio - get SSL read only IO handle +/** + * @brief get SSL read only IO handle * * @param ssl - SSL point * @@ -1399,19 +1400,19 @@ int SSL_get_quiet_shutdown(const SSL *ssl); */ BIO *SSL_get_rbio(const SSL *ssl); -/* - * SSL_get_shared_ciphers - get SSL shared ciphers +/** + * @brief get SSL shared ciphers * * @param ssl - SSL point * @param buf - buffer to store the ciphers * @param len - buffer len * - * @return shared ciphers or NULL if failed + * @return shared ciphers */ char *SSL_get_shared_ciphers(const SSL *ssl, char *buf, int len); -/* - * SSL_get_shutdown - get SSL shutdown mode +/** + * @brief get SSL shutdown mode * * @param ssl - SSL point * @@ -1419,8 +1420,8 @@ char *SSL_get_shared_ciphers(const SSL *ssl, char *buf, int len); */ int SSL_get_shutdown(const SSL *ssl); -/* - * SSL_get_time - get SSL session time +/** + * @brief get SSL session time * * @param ssl - SSL point * @@ -1428,8 +1429,8 @@ int SSL_get_shutdown(const SSL *ssl); */ long SSL_get_time(const SSL *ssl); -/* - * SSL_get_timeout - get SSL session timeout time +/** + * @brief get SSL session timeout time * * @param ssl - SSL point * @@ -1437,8 +1438,8 @@ long SSL_get_time(const SSL *ssl); */ long SSL_get_timeout(const SSL *ssl); -/* - * SSL_get_verify_mode - get SSL verifying mode +/** + * @brief get SSL verifying mode * * @param ssl - SSL point * @@ -1446,8 +1447,8 @@ long SSL_get_timeout(const SSL *ssl); */ int SSL_get_verify_mode(const SSL *ssl); -/* - * SSL_get_wbio - get SSL write only IO handle +/** + * @brief get SSL write only IO handle * * @param ssl - SSL point * @@ -1455,8 +1456,8 @@ int SSL_get_verify_mode(const SSL *ssl); */ BIO *SSL_get_wbio(const SSL *ssl); -/* - * SSL_load_client_CA_file - load SSL client CA certification file +/** + * @brief load SSL client CA certification file * * @param file - file name * @@ -1464,44 +1465,44 @@ BIO *SSL_get_wbio(const SSL *ssl); */ STACK *SSL_load_client_CA_file(const char *file); -/* - * SSL_up_ref - add SSL reference by '1' +/** + * @brief add SSL reference by '1' * * @param ssl - SSL point * - * @return - * 1 : OK - * 0 : failed + * @return result + * 1 : OK + * 0 : failed */ int SSL_up_ref(SSL *ssl); -/* - * SSL_peek - read and put data into buf, but not clear the SSL low-level storage +/** + * @brief read and put data into buf, but not clear the SSL low-level storage * * @param ssl - SSL point * @param buf - storage buffer point * @param num - data bytes * - * @return - * > 0 : OK, and return read bytes - * = 0 : connect is closed - * < 0 : a error catch + * @return result + * > 0 : OK, and return read bytes + * = 0 : connect is closed + * < 0 : a error catch */ int SSL_peek(SSL *ssl, void *buf, int num); -/* - * SSL_renegotiate - make SSL renegotiate +/** + * @brief make SSL renegotiate * * @param ssl - SSL point * - * @return - * 1 : OK - * 0 : failed + * @return result + * 1 : OK + * 0 : failed */ int SSL_renegotiate(SSL *ssl); -/* - * SSL_rstate_string - get the state string where SSL is reading +/** + * @brief get the state string where SSL is reading * * @param ssl - SSL point * @@ -1509,8 +1510,8 @@ int SSL_renegotiate(SSL *ssl); */ const char *SSL_rstate_string(SSL *ssl); -/* - * SSL_rstate_string_long - get the statement long string where SSL is reading +/** + * @brief get the statement long string where SSL is reading * * @param ssl - SSL point * @@ -1518,8 +1519,8 @@ const char *SSL_rstate_string(SSL *ssl); */ const char *SSL_rstate_string_long(SSL *ssl); -/* - * SSL_set_accept_state - set SSL accept statement +/** + * @brief set SSL accept statement * * @param ssl - SSL point * @@ -1527,8 +1528,8 @@ const char *SSL_rstate_string_long(SSL *ssl); */ void SSL_set_accept_state(SSL *ssl); -/* - * SSL_set_app_data - set SSL application data +/** + * @brief set SSL application data * * @param ssl - SSL point * @param arg - SSL application data point @@ -1537,8 +1538,8 @@ void SSL_set_accept_state(SSL *ssl); */ void SSL_set_app_data(SSL *ssl, char *arg); -/* - * SSL_set_bio - set SSL BIO +/** + * @brief set SSL BIO * * @param ssl - SSL point * @param rbio - read only IO @@ -1548,8 +1549,8 @@ void SSL_set_app_data(SSL *ssl, char *arg); */ void SSL_set_bio(SSL *ssl, BIO *rbio, BIO *wbio); -/* - * SSL_clear_options - clear SSL option +/** + * @brief clear SSL option * * @param ssl - SSL point * @param op - clear option @@ -1558,8 +1559,8 @@ void SSL_set_bio(SSL *ssl, BIO *rbio, BIO *wbio); */ unsigned long SSL_clear_options(SSL *ssl, unsigned long op); -/* - * SSL_clear_options - get SSL option +/** + * @brief get SSL option * * @param ssl - SSL point * @@ -1567,8 +1568,8 @@ unsigned long SSL_clear_options(SSL *ssl, unsigned long op); */ unsigned long SSL_get_options(SSL *ssl); -/* - * SSL_clear_options - clear SSL option +/** + * @brief clear SSL option * * @param ssl - SSL point * @param op - setting option @@ -1577,8 +1578,8 @@ unsigned long SSL_get_options(SSL *ssl); */ unsigned long SSL_set_options(SSL *ssl, unsigned long op); -/* - * SSL_set_quiet_shutdown - set SSL quiet shutdown mode +/** + * @brief set SSL quiet shutdown mode * * @param ssl - SSL point * @param mode - quiet shutdown mode @@ -1587,8 +1588,8 @@ unsigned long SSL_set_options(SSL *ssl, unsigned long op); */ void SSL_set_quiet_shutdown(SSL *ssl, int mode); -/* - * SSL_set_quiet_shutdown - set SSL shutdown mode +/** + * @brief set SSL shutdown mode * * @param ssl - SSL point * @param mode - shutdown mode @@ -1597,8 +1598,8 @@ void SSL_set_quiet_shutdown(SSL *ssl, int mode); */ void SSL_set_shutdown(SSL *ssl, int mode); -/* - * SSL_set_time - set SSL session time +/** + * @brief set SSL session time * * @param ssl - SSL point * @param t - session time @@ -1607,8 +1608,8 @@ void SSL_set_shutdown(SSL *ssl, int mode); */ void SSL_set_time(SSL *ssl, long t); -/* - * SSL_set_time - set SSL session timeout time +/** + * @brief set SSL session timeout time * * @param ssl - SSL point * @param t - session timeout time @@ -1617,8 +1618,8 @@ void SSL_set_time(SSL *ssl, long t); */ void SSL_set_timeout(SSL *ssl, long t); -/* - * SSL_state_string - get SSL statement string +/** + * @brief get SSL statement string * * @param ssl - SSL point * @@ -1626,8 +1627,8 @@ void SSL_set_timeout(SSL *ssl, long t); */ char *SSL_state_string(const SSL *ssl); -/* - * SSL_state_string_long - get SSL statement long string +/** + * @brief get SSL statement long string * * @param ssl - SSL point * @@ -1635,8 +1636,8 @@ char *SSL_state_string(const SSL *ssl); */ char *SSL_state_string_long(const SSL *ssl); -/* - * SSL_total_renegotiations - get SSL renegotiation count +/** + * @brief get SSL renegotiation count * * @param ssl - SSL point * @@ -1644,8 +1645,8 @@ char *SSL_state_string_long(const SSL *ssl); */ long SSL_total_renegotiations(SSL *ssl); -/* - * SSL_version - get SSL version +/** + * @brief get SSL version * * @param ssl - SSL point * @@ -1653,20 +1654,20 @@ long SSL_total_renegotiations(SSL *ssl); */ int SSL_version(const SSL *ssl); -/* - * SSL_use_psk_identity_hint - set SSL PSK identity hint +/** + * @brief set SSL PSK identity hint * * @param ssl - SSL point * @param hint - identity hint * - * @return - * 1 : oK - * 0 : failed + * @return result + * 1 : OK + * 0 : failed */ int SSL_use_psk_identity_hint(SSL *ssl, const char *hint); -/* - * SSL_get_psk_identity_hint - get SSL PSK identity hint +/** + * @brief get SSL PSK identity hint * * @param ssl - SSL point * @@ -1674,8 +1675,8 @@ int SSL_use_psk_identity_hint(SSL *ssl, const char *hint); */ const char *SSL_get_psk_identity_hint(SSL *ssl); -/* - * SSL_get_psk_identity - get SSL PSK identity +/** + * @brief get SSL PSK identity * * @param ssl - SSL point * diff --git a/components/openssl/library/ssl_cert.c b/components/openssl/library/ssl_cert.c index 2d82e62aaa..fd05bc8315 100644 --- a/components/openssl/library/ssl_cert.c +++ b/components/openssl/library/ssl_cert.c @@ -18,12 +18,8 @@ #include "ssl_dbg.h" #include "ssl_port.h" -/* - * ssl_cert_new - create a certification object include private key object - * - * @param none - * - * @return certification object point or NULL if failed +/** + * @brief create a certification object include private key object */ CERT *ssl_cert_new(void) { @@ -51,18 +47,14 @@ failed1: return NULL; } -/* - * ssl_cert_free - free a certification object - * - * @param c - certification object point - * - * @return none +/** + * @brief free a certification object */ -void ssl_cert_free(CERT *c) +void ssl_cert_free(CERT *cert) { - X509_free(c->x509); + X509_free(cert->x509); - EVP_PKEY_free(c->pkey); + EVP_PKEY_free(cert->pkey); - ssl_free(c); + ssl_free(cert); } diff --git a/components/openssl/library/ssl_lib.c b/components/openssl/library/ssl_lib.c index ae517b0a40..a84b89e06c 100644 --- a/components/openssl/library/ssl_lib.c +++ b/components/openssl/library/ssl_lib.c @@ -21,14 +21,8 @@ #define SSL_SEND_DATA_MAX_LENGTH 1460 -/* - * ossl_statem_in_error - Discover whether the current connection is in the error state - * - * @param ssl - SSL point - * - * @return - * 1 : Yes - * 0 : no +/** + * @brief Discover whether the current connection is in the error state */ int ossl_statem_in_error(const SSL *ssl) { @@ -38,81 +32,48 @@ int ossl_statem_in_error(const SSL *ssl) return 0; } -/* - * SSL_want - get the SSL specifical statement - * - * @param ssl - SSL point - * - * @return specifical statement +/** + * @brief get the SSL specifical statement */ int SSL_want(const SSL *ssl) { return ssl->rwstate; } -/* - * SSL_want_nothing - check if SSL want nothing - * - * @param ssl - SSL point - * - * @return - * 1 : yes - * 0 : no +/** + * @brief check if SSL want nothing */ int SSL_want_nothing(const SSL *ssl) { return (SSL_want(ssl) == SSL_NOTHING); } -/* - * SSL_want_read - check if SSL want to read - * - * @param ssl - SSL point - * - * @return - * 1 : yes - * 0 : no +/** + * @brief check if SSL want to read */ int SSL_want_read(const SSL *ssl) { return (SSL_want(ssl) == SSL_READING); } -/* - * SSL_want_read - check if SSL want to write - * - * @param ssl - SSL point - * - * @return - * 1 : yes - * 0 : no +/** + * @brief check if SSL want to write */ int SSL_want_write(const SSL *ssl) { return (SSL_want(ssl) == SSL_WRITING); } -/* - * SSL_want_read - check if SSL want to lookup X509 certification - * - * @param ssl - SSL point - * - * @return - * 1 : yes - * 0 : no +/** + * @brief check if SSL want to lookup X509 certification */ int SSL_want_x509_lookup(const SSL *ssl) { return (SSL_want(ssl) == SSL_WRITING); } -/* - * SSL_get_error - get SSL error code - * - * @param ssl - SSL point - * @param ret_code - SSL return code - * - * @return SSL error number +/** + * @brief get SSL error code */ int SSL_get_error(const SSL *ssl, int ret_code) { @@ -142,12 +103,8 @@ int SSL_get_error(const SSL *ssl, int ret_code) return ret; } -/* - * SSL_get_state - get the SSL state - * - * @param ssl - SSL point - * - * @return SSL state +/** + * @brief get the SSL state */ OSSL_HANDSHAKE_STATE SSL_get_state(const SSL *ssl) { @@ -160,12 +117,8 @@ OSSL_HANDSHAKE_STATE SSL_get_state(const SSL *ssl) return state; } -/* - * SSL_CTX_new - create a SSL context - * - * @param method - the SSL context configuration file - * - * @return the context point, if create failed return NULL +/** + * @brief create a SSL context */ SSL_CTX* SSL_CTX_new(const SSL_METHOD *method) { @@ -203,12 +156,8 @@ go_failed1: return NULL; } -/* - * SSL_CTX_free - free a SSL context - * - * @param method - the SSL context point - * - * @return none +/** + * @brief free a SSL context */ void SSL_CTX_free(SSL_CTX* ctx) { @@ -221,15 +170,8 @@ void SSL_CTX_free(SSL_CTX* ctx) ssl_free(ctx); } -/* - * SSL_CTX_set_ssl_version - set the SSL context version - * - * @param ctx - SSL context point - * @param meth - SSL method point - * - * @return - * 1 : OK - * 0 : failed +/** + * @brief set the SSL context version */ int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth) { @@ -243,12 +185,8 @@ int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth) return 1; } -/* - * SSL_CTX_get_ssl_method - get the SSL context current method - * - * @param ctx - SSL context point - * - * @return the SSL context current method +/** + * @brief get the SSL context current method */ const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx) { @@ -257,12 +195,8 @@ const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx) return ctx->method; } -/* - * SSL_new - create a SSL - * - * @param ctx - the SSL context point - * - * @return the SSL point or NULL if failed +/** + * @brief create a SSL */ SSL *SSL_new(SSL_CTX *ctx) { @@ -300,12 +234,8 @@ failed1: return NULL; } -/* - * SSL_free - free the SSL - * - * @param ssl - the SSL point - * - * @return none +/** + * @brief free the SSL */ void SSL_free(SSL *ssl) { @@ -322,15 +252,8 @@ void SSL_free(SSL *ssl) ssl_free(ssl); } -/* - * SSL_do_handshake - perform the SSL handshake - * - * @param ssl - SSL point - * - * @return - * 1 : OK - * 0 : failed - * -1 : a error catch +/** + * @brief perform the SSL handshake */ int SSL_do_handshake(SSL *ssl) { @@ -343,14 +266,8 @@ int SSL_do_handshake(SSL *ssl) return ret; } -/* - * SSL_connect - connect to the remote SSL server - * - * @param ssl - the SSL point - * - * @return - * 1 : OK - * -1 : failed +/** + * @brief connect to the remote SSL server */ int SSL_connect(SSL *ssl) { @@ -359,14 +276,8 @@ int SSL_connect(SSL *ssl) return SSL_do_handshake(ssl); } -/* - * SSL_accept - accept the remote connection - * - * @param ssl - the SSL point - * - * @return - * 1 : OK - * -1 : failed +/** + * @brief accept the remote connection */ int SSL_accept(SSL *ssl) { @@ -375,15 +286,8 @@ int SSL_accept(SSL *ssl) return SSL_do_handshake(ssl); } -/* - * SSL_shutdown - shutdown the connection - * - * @param ssl - the SSL point - * - * @return - * 1 : OK - * 0 : shutdown is not finished - * -1 : an error catch +/** + * @brief shutdown the connection */ int SSL_shutdown(SSL *ssl) { @@ -398,14 +302,8 @@ int SSL_shutdown(SSL *ssl) return ret; } -/* - * SSL_clear - reset the SSL - * - * @param ssl - SSL point - * - * @return - * 1 : OK - * 0 : failed +/** + * @brief reset the SSL */ int SSL_clear(SSL *ssl) { @@ -429,17 +327,8 @@ go_failed1: return ret; } -/* - * SSL_read - read data from to remote - * - * @param ssl - the SSL point which has been connected - * @param buffer - the received data buffer point - * @param len - the received data length - * - * @return - * > 0 : OK, and return received data bytes - * = 0 : connection is closed - * < 0 : an error catch +/** + * @brief read data from to remote */ int SSL_read(SSL *ssl, void *buffer, int len) { @@ -458,17 +347,8 @@ int SSL_read(SSL *ssl, void *buffer, int len) return ret; } -/* - * SSL_write - send the data to remote - * - * @param ssl - the SSL point which has been connected - * @param buffer - the send data buffer point - * @param len - the send data length - * - * @return - * > 0 : OK, and return sent data bytes - * = 0 : connection is closed - * < 0 : an error catch +/** + * @brief send the data to remote */ int SSL_write(SSL *ssl, const void *buffer, int len) { @@ -511,12 +391,8 @@ int SSL_write(SSL *ssl, const void *buffer, int len) return ret; } -/* - * SSL_get_SSL_CTX - get SSL context of the SSL - * - * @param ssl - SSL point - * - * @return SSL context +/** + * @brief get SSL context of the SSL */ SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl) { @@ -525,12 +401,8 @@ SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl) return ssl->ctx; } -/* - * SSL_CTX_get_ssl_method - get the SSL current method - * - * @param ssl - SSL point - * - * @return the SSL current method +/** + * @brief get the SSL current method */ const SSL_METHOD *SSL_get_ssl_method(SSL *ssl) { @@ -539,15 +411,8 @@ const SSL_METHOD *SSL_get_ssl_method(SSL *ssl) return ssl->method; } -/* - * SSL_set_ssl_method - set the SSL method - * - * @param ssl - SSL point - * @param meth - SSL method point - * - * @return - * 1 : OK - * 0 : failed +/** + * @brief set the SSL method */ int SSL_set_ssl_method(SSL *ssl, const SSL_METHOD *method) { @@ -580,12 +445,8 @@ go_failed1: return ret; } -/* - * SSL_get_shutdown - get SSL shutdown mode - * - * @param ssl - SSL point - * - * @return shutdown mode +/** + * @brief get SSL shutdown mode */ int SSL_get_shutdown(const SSL *ssl) { @@ -594,13 +455,8 @@ int SSL_get_shutdown(const SSL *ssl) return ssl->shutdown; } -/* - * SSL_set_quiet_shutdown - set SSL shutdown mode - * - * @param ssl - SSL point - * @param mode - shutdown mode - * - * @return none +/** + * @brief set SSL shutdown mode */ void SSL_set_shutdown(SSL *ssl, int mode) { @@ -610,12 +466,8 @@ void SSL_set_shutdown(SSL *ssl, int mode) } -/* - * SSL_pending - get the number of the bytes to be read - * - * @param ssl - SSL point - * - * @return number of the bytes +/** + * @brief get the number of the bytes to be read */ int SSL_pending(const SSL *ssl) { @@ -628,14 +480,8 @@ int SSL_pending(const SSL *ssl) return ret; } -/* - * SSL_has_pending - check if some data can be read - * - * @param ssl - SSL point - * - * @return - * 1 : there are bytes to be read - * 0 : no data +/** + * @brief check if some data can be read */ int SSL_has_pending(const SSL *ssl) { @@ -651,52 +497,32 @@ int SSL_has_pending(const SSL *ssl) return ret; } -/* - * SSL_CTX_clear_options - clear the SSL context option bit of "op" - * - * @param ctx - SSL context point - * @param op - option - * - * @return SSL context option +/** + * @brief clear the SSL context option bit of "op" */ unsigned long SSL_CTX_clear_options(SSL_CTX *ctx, unsigned long op) { return ctx->options &= ~op; } -/* - * SSL_CTX_clear_options - get the SSL context option - * - * @param ctx - SSL context point - * @param op - option - * - * @return SSL context option +/** + * @brief get the SSL context option */ unsigned long SSL_CTX_get_options(SSL_CTX *ctx) { return ctx->options; } -/* - * SSL_CTX_set_option - set the option of the SSL context - * - * @param ctx - the SSL context - * - * @return the SSL context option - * +/** + * @brief set the option of the SSL context */ unsigned long SSL_CTX_set_options(SSL_CTX *ctx, unsigned long opt) { return ctx->options |= opt; } -/* - * SSL_clear_options - clear SSL option - * - * @param ssl - SSL point - * @param op - clear option - * - * @return SSL option +/** + * @brief clear SSL option */ unsigned long SSL_clear_options(SSL *ssl, unsigned long op) { @@ -705,12 +531,8 @@ unsigned long SSL_clear_options(SSL *ssl, unsigned long op) return ssl->options & ~op; } -/* - * SSL_clear_options - get SSL option - * - * @param ssl - SSL point - * - * @return SSL option +/** + * @brief get SSL option */ unsigned long SSL_get_options(SSL *ssl) { @@ -719,13 +541,8 @@ unsigned long SSL_get_options(SSL *ssl) return ssl->options; } -/* - * SSL_clear_options - clear SSL option - * - * @param ssl - SSL point - * @param op - setting option - * - * @return SSL option +/** + * @brief clear SSL option */ unsigned long SSL_set_options(SSL *ssl, unsigned long op) { @@ -734,14 +551,8 @@ unsigned long SSL_set_options(SSL *ssl, unsigned long op) return ssl->options |= op; } -/* - * SSL_get_fd - get the socket handle of the SSL - * - * @param ssl - SSL point - * - * @return - * >= 0 : yes, and return socket handle - * < 0 : a error catch +/** + * @brief get the socket handle of the SSL */ int SSL_get_fd(const SSL *ssl) { @@ -754,14 +565,8 @@ int SSL_get_fd(const SSL *ssl) return ret; } -/* - * SSL_get_rfd - get the read only socket handle of the SSL - * - * @param ssl - SSL point - * - * @return - * >= 0 : yes, and return socket handle - * < 0 : a error catch +/** + * @brief get the read only socket handle of the SSL */ int SSL_get_rfd(const SSL *ssl) { @@ -774,14 +579,8 @@ int SSL_get_rfd(const SSL *ssl) return ret; } -/* - * SSL_get_wfd - get the write only socket handle of the SSL - * - * @param ssl - SSL point - * - * @return - * >= 0 : yes, and return socket handle - * < 0 : a error catch +/** + * @brief get the write only socket handle of the SSL */ int SSL_get_wfd(const SSL *ssl) { @@ -794,15 +593,8 @@ int SSL_get_wfd(const SSL *ssl) return ret; } -/* - * SSL_set_fd - bind the socket file description into the SSL - * - * @param ssl - the SSL point - * @param fd - socket handle - * - * @return - * 1 : OK - * 0 : failed +/** + * @brief bind the socket file description into the SSL */ int SSL_set_fd(SSL *ssl, int fd) { @@ -814,15 +606,8 @@ int SSL_set_fd(SSL *ssl, int fd) return 1; } -/* - * SSL_set_fd - bind the read only socket file description into the SSL - * - * @param ssl - the SSL point - * @param fd - socket handle - * - * @return - * 1 : OK - * 0 : failed +/** + * @brief bind the read only socket file description into the SSL */ int SSL_set_rfd(SSL *ssl, int fd) { @@ -834,15 +619,8 @@ int SSL_set_rfd(SSL *ssl, int fd) return 1; } -/* - * SSL_set_fd - bind the write only socket file description into the SSL - * - * @param ssl - the SSL point - * @param fd - socket handle - * - * @return - * 1 : OK - * 0 : failed +/** + * @brief bind the write only socket file description into the SSL */ int SSL_set_wfd(SSL *ssl, int fd) { @@ -854,12 +632,8 @@ int SSL_set_wfd(SSL *ssl, int fd) return 1; } -/* - * SSL_version - get SSL version - * - * @param ssl - SSL point - * - * @return SSL version +/** + * @brief get SSL version */ int SSL_version(const SSL *ssl) { @@ -868,12 +642,8 @@ int SSL_version(const SSL *ssl) return ssl->version; } -/* - * ssl_protocol_to_string - get the SSL version string - * - * @param version - the SSL version - * - * @return the SSL version string +/** + * @brief get the SSL version string */ static const char* ssl_protocol_to_string(int version) { @@ -893,12 +663,8 @@ static const char* ssl_protocol_to_string(int version) return str; } -/* - * SSL_get_version - get the SSL current version - * - * @param ssl - SSL point - * - * @return the version string +/** + * @brief get the SSL current version */ const char *SSL_get_version(const SSL *ssl) { @@ -907,12 +673,8 @@ const char *SSL_get_version(const SSL *ssl) return ssl_protocol_to_string(SSL_version(ssl)); } -/* - * SSL_alert_desc_string - get alert description string - * - * @param value - alert value - * - * @return alert description string +/** + * @brief get alert description string */ const char* SSL_alert_desc_string(int value) { @@ -1018,12 +780,8 @@ const char* SSL_alert_desc_string(int value) return str; } -/* - * SSL_alert_desc_string - get alert description long string - * - * @param value - alert value - * - * @return alert description long string +/** + * @brief get alert description long string */ const char* SSL_alert_desc_string_long(int value) { @@ -1129,12 +887,8 @@ const char* SSL_alert_desc_string_long(int value) return str; } -/* - * SSL_alert_type_string - get alert type string - * - * @param value - alert value - * - * @return alert type string +/** + * @brief get alert type string */ const char *SSL_alert_type_string(int value) { @@ -1156,12 +910,8 @@ const char *SSL_alert_type_string(int value) return str; } -/* - * SSL_alert_type_string_long - get alert type long string - * - * @param value - alert value - * - * @return alert type long string +/** + * @brief get alert type long string */ const char *SSL_alert_type_string_long(int value) { @@ -1183,12 +933,8 @@ const char *SSL_alert_type_string_long(int value) return str; } -/* - * SSL_rstate_string - get the state string where SSL is reading - * - * @param ssl - SSL point - * - * @return state string +/** + * @brief get the state string where SSL is reading */ const char *SSL_rstate_string(SSL *ssl) { @@ -1215,12 +961,8 @@ const char *SSL_rstate_string(SSL *ssl) return str; } -/* - * SSL_rstate_string_long - get the statement long string where SSL is reading - * - * @param ssl - SSL point - * - * @return statement long string +/** + * @brief get the statement long string where SSL is reading */ const char *SSL_rstate_string_long(SSL *ssl) { @@ -1246,12 +988,8 @@ const char *SSL_rstate_string_long(SSL *ssl) return str; } -/* - * SSL_state_string - get SSL statement string - * - * @param ssl - SSL point - * - * @return SSL statement string +/** + * @brief get SSL statement string */ char *SSL_state_string(const SSL *ssl) { @@ -1358,12 +1096,8 @@ char *SSL_state_string(const SSL *ssl) return str; } -/* - * SSL_state_string_long - get SSL statement long string - * - * @param ssl - SSL point - * - * @return SSL statement long string +/** + * @brief get SSL statement long string */ char *SSL_state_string_long(const SSL *ssl) { @@ -1476,13 +1210,8 @@ char *SSL_state_string_long(const SSL *ssl) return str; } -/* - * SSL_CTX_set_default_read_buffer_len - set the SSL context read buffer length - * - * @param ctx - SSL context point - * @param len - read buffer length - * - * @return none +/** + * @brief set the SSL context read buffer length */ void SSL_CTX_set_default_read_buffer_len(SSL_CTX *ctx, size_t len) { @@ -1492,13 +1221,8 @@ void SSL_CTX_set_default_read_buffer_len(SSL_CTX *ctx, size_t len) ctx->read_buffer_len = len; } -/* - * SSL_set_default_read_buffer_len - set the SSL read buffer length - * - * @param ssl - SSL point - * @param len - read buffer length - * - * @return none +/** + * @brief set the SSL read buffer length */ void SSL_set_default_read_buffer_len(SSL *ssl, size_t len) { @@ -1508,13 +1232,8 @@ void SSL_set_default_read_buffer_len(SSL *ssl, size_t len) SSL_METHOD_CALL(set_bufflen, ssl, len); } -/* - * SSL_set_info_callback - set the SSL information callback function - * - * @param ssl - SSL point - * @param cb - information callback function - * - * @return none +/** + * @brief set the SSL information callback function */ void SSL_set_info_callback(SSL *ssl, void (*cb) (const SSL *ssl, int type, int val)) { @@ -1523,32 +1242,23 @@ void SSL_set_info_callback(SSL *ssl, void (*cb) (const SSL *ssl, int type, int v ssl->info_callback = cb; } -/* - * SSL_CTX_up_ref - add SSL context reference count by '1' - * - * @param ctx - SSL context point - * - * @return - * 1 : OK - * 0 : failed +/** + * @brief add SSL context reference count by '1' */ int SSL_CTX_up_ref(SSL_CTX *ctx) { SSL_ASSERT(ctx); - /* no support multi-thread SSL here */ + /** + * no support multi-thread SSL here + */ ctx->references++; return 1; } -/* - * SSL_set_security_level - set the SSL security level - * - * @param ssl - SSL point - * @param level - security level - * - * @return none +/** + * @brief set the SSL security level */ void SSL_set_security_level(SSL *ssl, int level) { @@ -1557,12 +1267,8 @@ void SSL_set_security_level(SSL *ssl, int level) ssl->cert->sec_level = level; } -/* - * SSL_get_security_level - get the SSL security level - * - * @param ssl - SSL point - * - * @return security level +/** + * @brief get the SSL security level */ int SSL_get_security_level(const SSL *ssl) { @@ -1571,12 +1277,8 @@ int SSL_get_security_level(const SSL *ssl) return ssl->cert->sec_level; } -/* - * SSL_CTX_get_verify_mode - get the SSL verifying mode of the SSL context - * - * @param ctx - SSL context point - * - * @return verifying mode +/** + * @brief get the SSL verifying mode of the SSL context */ int SSL_CTX_get_verify_mode(const SSL_CTX *ctx) { @@ -1585,13 +1287,8 @@ int SSL_CTX_get_verify_mode(const SSL_CTX *ctx) return ctx->verify_mode; } -/* - * SSL_CTX_set_timeout - set the session timeout time - * - * @param ctx - SSL context point - * @param t - new session timeout time - * - * @return old session timeout time +/** + * @brief set the session timeout time */ long SSL_CTX_set_timeout(SSL_CTX *ctx, long t) { @@ -1605,12 +1302,8 @@ long SSL_CTX_set_timeout(SSL_CTX *ctx, long t) return l; } -/* - * SSL_CTX_get_timeout - get the session timeout time - * - * @param ctx - SSL context point - * - * @return current session timeout time +/** + * @brief get the session timeout time */ long SSL_CTX_get_timeout(const SSL_CTX *ctx) { @@ -1619,13 +1312,8 @@ long SSL_CTX_get_timeout(const SSL_CTX *ctx) return ctx->session_timeout; } -/* - * SSL_set_read_ahead - set the SSL if we can read as many as data - * - * @param ssl - SSL point - * @param yes - enable the function - * - * @return none +/** + * @brief set the SSL if we can read as many as data */ void SSL_set_read_ahead(SSL *ssl, int yes) { @@ -1634,13 +1322,8 @@ void SSL_set_read_ahead(SSL *ssl, int yes) ssl->rlayer.read_ahead = yes; } -/* - * SSL_set_read_ahead - set the SSL context if we can read as many as data - * - * @param ctx - SSL context point - * @param yes - enable the function - * - * @return none +/** + * @brief set the SSL context if we can read as many as data */ void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes) { @@ -1649,12 +1332,8 @@ void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes) ctx->read_ahead = yes; } -/* - * SSL_set_read_ahead - get the SSL ahead signal if we can read as many as data - * - * @param ssl - SSL point - * - * @return SSL context ahead signal +/** + * @brief get the SSL ahead signal if we can read as many as data */ int SSL_get_read_ahead(const SSL *ssl) { @@ -1663,12 +1342,8 @@ int SSL_get_read_ahead(const SSL *ssl) return ssl->rlayer.read_ahead; } -/* - * SSL_set_read_ahead - get the SSL context ahead signal if we can read as many as data - * - * @param ctx - SSL context point - * - * @return SSL context ahead signal +/** + * @brief get the SSL context ahead signal if we can read as many as data */ long SSL_CTX_get_read_ahead(SSL_CTX *ctx) { @@ -1677,14 +1352,8 @@ long SSL_CTX_get_read_ahead(SSL_CTX *ctx) return ctx->read_ahead; } -/* - * SSL_CTX_get_ciphers - check if the SSL context can read as many as data - * - * @param ctx - SSL context point - * - * @return - * 1 : Yes - * 0 : No +/** + * @brief check if the SSL context can read as many as data */ long SSL_CTX_get_default_read_ahead(SSL_CTX *ctx) { @@ -1693,13 +1362,8 @@ long SSL_CTX_get_default_read_ahead(SSL_CTX *ctx) return ctx->read_ahead; } -/* - * SSL_set_time - set SSL session time - * - * @param ssl - SSL point - * @param t - session time - * - * @return session time +/** + * @brief set SSL session time */ long SSL_set_time(SSL *ssl, long t) { @@ -1710,13 +1374,8 @@ long SSL_set_time(SSL *ssl, long t) return t; } -/* - * SSL_set_time - set SSL session timeout time - * - * @param ssl - SSL point - * @param t - session timeout time - * - * @return session timeout time +/** + * @brief set SSL session timeout time */ long SSL_set_timeout(SSL *ssl, long t) { @@ -1727,12 +1386,8 @@ long SSL_set_timeout(SSL *ssl, long t) return t; } -/* - * SSL_get_verify_result - get the verifying result of the SSL certification - * - * @param ssl - the SSL point - * - * @return the result of verifying +/** + * @brief get the verifying result of the SSL certification */ long SSL_get_verify_result(const SSL *ssl) { @@ -1741,12 +1396,8 @@ long SSL_get_verify_result(const SSL *ssl) return SSL_METHOD_CALL(get_verify_result, ssl); } -/* - * SSL_CTX_get_verify_depth - get the SSL verifying depth of the SSL context - * - * @param ctx - SSL context point - * - * @return verifying depth +/** + * @brief get the SSL verifying depth of the SSL context */ int SSL_CTX_get_verify_depth(const SSL_CTX *ctx) { @@ -1755,13 +1406,8 @@ int SSL_CTX_get_verify_depth(const SSL_CTX *ctx) return ctx->param.depth; } -/* - * SSL_CTX_set_verify_depth - set the SSL verify depth of the SSL context - * - * @param ctx - SSL context point - * @param depth - verifying depth - * - * @return one +/** + * @brief set the SSL verify depth of the SSL context */ void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth) { @@ -1770,12 +1416,8 @@ void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth) ctx->param.depth = depth; } -/* - * SSL_get_verify_depth - get the SSL verifying depth of the SSL - * - * @param ctx - SSL point - * - * @return verifying depth +/** + * @brief get the SSL verifying depth of the SSL */ int SSL_get_verify_depth(const SSL *ssl) { @@ -1784,13 +1426,8 @@ int SSL_get_verify_depth(const SSL *ssl) return ssl->param.depth; } -/* - * SSL_set_verify_depth - set the SSL verify depth of the SSL - * - * @param ctx - SSL point - * @param depth - verifying depth - * - * @return one +/** + * @brief set the SSL verify depth of the SSL */ void SSL_set_verify_depth(SSL *ssl, int depth) { @@ -1799,14 +1436,8 @@ void SSL_set_verify_depth(SSL *ssl, int depth) ssl->param.depth = depth; } -/* - * SSL_CTX_set_verify - set the SSL context verifying of the SSL context - * - * @param ctx - SSL context point - * @param mode - verifying mode - * @param verify_callback - verifying callback function - * - * @return none +/** + * @brief set the SSL context verifying of the SSL context */ void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, int (*verify_callback)(int, X509_STORE_CTX *)) { @@ -1816,14 +1447,8 @@ void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, int (*verify_callback)(int, X509 ctx->default_verify_callback = verify_callback; } -/* - * SSL_set_verify - set the SSL verifying of the SSL context - * - * @param ctx - SSL point - * @param mode - verifying mode - * @param verify_callback - verifying callback function - * - * @return none +/** + * @brief set the SSL verifying of the SSL context */ void SSL_set_verify(SSL *ssl, int mode, int (*verify_callback)(int, X509_STORE_CTX *)) { diff --git a/components/openssl/library/ssl_methods.c b/components/openssl/library/ssl_methods.c index c6fb40e59c..042d670ab9 100644 --- a/components/openssl/library/ssl_methods.c +++ b/components/openssl/library/ssl_methods.c @@ -16,7 +16,7 @@ #include "ssl_methods.h" #include "ssl_pm.h" -/* +/** * TLS method function collection */ IMPLEMENT_TLS_METHOD_FUNC(TLS_method_func, @@ -28,7 +28,7 @@ IMPLEMENT_TLS_METHOD_FUNC(TLS_method_func, ssl_pm_get_verify_result, ssl_pm_get_state); -/* +/** * TLS or SSL client method collection */ IMPLEMENT_TLS_METHOD(TLS_ANY_VERSION, 0, TLS_method_func, TLS_client_method); @@ -41,7 +41,7 @@ IMPLEMENT_TLS_METHOD(TLS1_VERSION, 0, TLS_method_func, TLSv1_client_method); IMPLEMENT_SSL_METHOD(SSL3_VERSION, 0, TLS_method_func, SSLv3_client_method); -/* +/** * TLS or SSL server method collection */ IMPLEMENT_TLS_METHOD(TLS_ANY_VERSION, 1, TLS_method_func, TLS_server_method); @@ -54,7 +54,7 @@ IMPLEMENT_TLS_METHOD(TLS1_VERSION, 0, TLS_method_func, TLSv1_server_method); IMPLEMENT_SSL_METHOD(SSL3_VERSION, 1, TLS_method_func, SSLv3_server_method); -/* +/** * TLS or SSL method collection */ IMPLEMENT_TLS_METHOD(TLS_ANY_VERSION, -1, TLS_method_func, TLS_method); @@ -67,15 +67,15 @@ IMPLEMENT_SSL_METHOD(TLS1_VERSION, -1, TLS_method_func, TLSv1_method); IMPLEMENT_SSL_METHOD(SSL3_VERSION, -1, TLS_method_func, SSLv3_method); -/* - * X509 certification method collection +/** + * @brief get X509 object method */ IMPLEMENT_X509_METHOD(X509_method, x509_pm_new, x509_pm_free, x509_pm_load, x509_pm_unload); -/* - * private key method collection +/** + * @brief get private key object method */ IMPLEMENT_PKEY_METHOD(EVP_PKEY_method, pkey_pm_new, pkey_pm_free, diff --git a/components/openssl/library/ssl_pkey.c b/components/openssl/library/ssl_pkey.c index e13870344f..6f51963eb0 100644 --- a/components/openssl/library/ssl_pkey.c +++ b/components/openssl/library/ssl_pkey.c @@ -19,12 +19,8 @@ #include "ssl_dbg.h" #include "ssl_port.h" -/* - * EVP_PKEY_new - create a private key object - * - * @param none - * - * @return private key object point or NULL if failed +/** + * @brief create a private key object */ EVP_PKEY* EVP_PKEY_new(void) { @@ -49,12 +45,8 @@ failed1: return NULL; } -/* - * EVP_PKEY_free - free a private key object - * - * @param pkey - private key object point - * - * @return none +/** + * @brief free a private key object */ void EVP_PKEY_free(EVP_PKEY *pkey) { @@ -63,16 +55,9 @@ void EVP_PKEY_free(EVP_PKEY *pkey) ssl_free(pkey); } -/* - * d2i_PrivateKey - load a character key context into system context. If '*a' is pointed to the - * private key, then load key into it. Or create a new private key object - * - * @param type - private key type - * @param a - a point pointed to a private key point - * @param pp - a point pointed to the key context memory point - * @param length - key bytes - * - * @return private key object point or NULL if failed +/** + * @brief load a character key context into system context. If '*a' is pointed to the + * private key, then load key into it. Or create a new private key object */ EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, @@ -112,15 +97,8 @@ failed1: return NULL; } -/* - * SSL_CTX_use_certificate - set the SSL context private key - * - * @param ctx - SSL context point - * @param x - private key point - * - * @return - * 1 : OK - * 0 : failed +/** + * @brief set the SSL context private key */ int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) { @@ -135,15 +113,8 @@ int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) return 1; } -/* - * SSL_CTX_use_certificate - set the SSL private key - * - * @param ctx - SSL point - * @param x - private key point - * - * @return - * 1 : OK - * 0 : failed +/** + * @brief set the SSL private key */ int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) { @@ -163,17 +134,8 @@ int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) return 1; } -/* - * SSL_CTX_use_PrivateKey_ASN1 - load private key into the SSL context - * - * @param type - private key type - * @param ctx - SSL context point - * @param d - private key context point - * @param len - private key context bytes - * - * @return - * 1 : OK - * 0 : failed +/** + * @brief load private key into the SSL context */ int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const unsigned char *d, long len) @@ -197,17 +159,8 @@ failed1: return 0; } -/* - * SSL_use_PrivateKey_ASN1 - load private key into the SSL - * - * @param type - private key type - * @param ctx - SSL context point - * @param d - private key context point - * @param len - private key context bytes - * - * @return - * 1 : OK - * 0 : failed +/** + * @brief load private key into the SSL */ int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d, long len) @@ -255,48 +208,24 @@ failed1: return 0; } -/* - * SSL_CTX_use_certificate_file - load the private key file into SSL context - * - * @param ctx - SSL context point - * @param file - private key file name - * @param type - private key encoding type - * - * @return - * 1 : OK - * 0 : failed +/** + * @brief load the private key file into SSL context */ int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) { return 0; } -/* - * SSL_use_PrivateKey_file - load the private key file into SSL - * - * @param ctx - SSL point - * @param file - private key file name - * @param type - private key encoding type - * - * @return - * 1 : OK - * 0 : failed +/** + * @brief load the private key file into SSL */ int SSL_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) { return 0; } -/* - * SSL_CTX_use_certificate_ASN1 - load the RSA ASN1 private key into SSL context - * - * @param ctx - SSL context point - * @param d - data point - * @param len - RSA private key length - * - * @return - * 1 : OK - * 0 : failed +/** + * @brief load the RSA ASN1 private key into SSL context */ int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len) { diff --git a/components/openssl/library/ssl_x509.c b/components/openssl/library/ssl_x509.c index 6eb3c1d461..e96511dc4a 100644 --- a/components/openssl/library/ssl_x509.c +++ b/components/openssl/library/ssl_x509.c @@ -18,12 +18,8 @@ #include "ssl_dbg.h" #include "ssl_port.h" -/* - * sk_X509_NAME_new_null - create a X509 certification object - * - * @param none - * - * @return X509 certification object point or NULL if failed +/** + * @brief create a X509 certification object */ X509* X509_new(void) { @@ -48,12 +44,8 @@ failed1: return NULL; } -/* - * X509_free - free a X509 certification object - * - * @param x - X509 certification object point - * - * @return none +/** + * @brief free a X509 certification object */ void X509_free(X509 *x) { @@ -62,15 +54,9 @@ void X509_free(X509 *x) ssl_free(x); }; -/* - * d2i_X509 - load a character certification context into system context. If '*cert' is pointed to the - * certification, then load certification into it. Or create a new X509 certification object - * - * @param cert - a point pointed to X509 certification - * @param buffer - a point pointed to the certification context memory point - * @param length - certification bytes - * - * @return X509 certification object point or NULL if failed +/** + * @brief load a character certification context into system context. If '*cert' is pointed to the + * certification, then load certification into it. Or create a new X509 certification object */ X509* d2i_X509(X509 **cert, const unsigned char *buffer, long len) { @@ -103,15 +89,8 @@ failed1: return NULL; } -/* - * SSL_CTX_add_client_CA - set SSL context client CA certification - * - * @param ctx - SSL context point - * @param x - client CA certification point - * - * @return - * 1 : OK - * 0 : failed +/** + * @brief set SSL context client CA certification */ int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) { @@ -126,15 +105,8 @@ int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) return 1; } -/* - * SSL_add_client_CA - add CA client certification into the SSL - * - * @param ssl - SSL point - * @param x - CA certification point - * - * @return - * 1 : OK - * 0 : failed +/** + * @brief add CA client certification into the SSL */ int SSL_add_client_CA(SSL *ssl, X509 *x) { @@ -151,15 +123,8 @@ int SSL_add_client_CA(SSL *ssl, X509 *x) return 1; } -/* - * SSL_CTX_use_certificate - set the SSL context certification - * - * @param ctx - SSL context point - * @param x - X509 certification point - * - * @return - * 1 : OK - * 0 : failed +/** + * @brief set the SSL context certification */ int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) { @@ -171,15 +136,8 @@ int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) return 1; } -/* - * SSL_CTX_use_certificate - set the SSL certification - * - * @param ctx - SSL point - * @param x - X509 certification point - * - * @return - * 1 : OK - * 0 : failed +/** + * @brief set the SSL certification */ int SSL_use_certificate(SSL *ssl, X509 *x) { @@ -191,12 +149,8 @@ int SSL_use_certificate(SSL *ssl, X509 *x) return 1; } -/* - * SSL_get_certificate - get the SSL certification point - * - * @param ssl - SSL point - * - * @return SSL certification point +/** + * @brief get the SSL certification point */ X509 *SSL_get_certificate(const SSL *ssl) { @@ -205,16 +159,8 @@ X509 *SSL_get_certificate(const SSL *ssl) return ssl->cert->x509; } -/* - * SSL_CTX_use_certificate_ASN1 - load certification into the SSL context - * - * @param ctx - SSL context point - * @param len - certification context bytes - * @param d - certification context point - * - * @return - * 1 : OK - * 0 : failed +/** + * @brief load certification into the SSL context */ int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d) @@ -238,16 +184,8 @@ failed1: return 0; } -/* - * SSL_use_certificate_ASN1 - load certification into the SSL - * - * @param ctx - SSL point - * @param len - certification context bytes - * @param d - certification context point - * - * @return - * 1 : OK - * 0 : failed +/** + * @brief load certification into the SSL */ int SSL_use_certificate_ASN1(SSL *ssl, int len, const unsigned char *d) @@ -295,44 +233,24 @@ failed1: return 0; } -/* - * SSL_CTX_use_certificate_file - load the certification file into SSL context - * - * @param ctx - SSL context point - * @param file - certification file name - * @param type - certification encoding type - * - * @return - * 1 : OK - * 0 : failed +/** + * @brief load the certification file into SSL context */ int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) { return 0; } -/* - * SSL_use_certificate_file - load the certification file into SSL - * - * @param ctx - SSL point - * @param file - certification file name - * @param type - certification encoding type - * - * @return - * 1 : OK - * 0 : failed +/** + * @brief load the certification file into SSL */ int SSL_use_certificate_file(SSL *ssl, const char *file, int type) { return 0; } -/* - * SSL_get_peer_certificate - get peer certification - * - * @param ssl - SSL point - * - * @return certification +/** + * @brief get peer certification */ X509 *SSL_get_peer_certificate(const SSL *ssl) { diff --git a/components/openssl/platform/ssl_pm.c b/components/openssl/platform/ssl_pm.c index b03aee3e37..9abfc212ec 100644 --- a/components/openssl/platform/ssl_pm.c +++ b/components/openssl/platform/ssl_pm.c @@ -62,6 +62,9 @@ unsigned int max_content_len; /*********************************************************************************************/ /************************************ SSL arch interface *************************************/ +/** + * @brief create SSL low-level object + */ int ssl_pm_new(SSL *ssl) { struct ssl_pm *ssl_pm; @@ -140,6 +143,9 @@ failed1: return -1; } +/** + * @brief free SSL low-level object + */ void ssl_pm_free(SSL *ssl) { struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; @@ -156,6 +162,9 @@ void ssl_pm_free(SSL *ssl) ssl->ssl_pm = NULL; } +/** + * @brief reload SSL low-level certification object + */ static int ssl_pm_reload_crt(SSL *ssl) { int ret; From f9fd5b6c72b6a08579f17317ab997306393516b1 Mon Sep 17 00:00:00 2001 From: dongheng Date: Fri, 23 Sep 2016 14:52:33 +0800 Subject: [PATCH 024/343] components/openssl: add X509 verify result errno --- .../openssl/include/internal/x509_vfy.h | 103 ++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 components/openssl/include/internal/x509_vfy.h diff --git a/components/openssl/include/internal/x509_vfy.h b/components/openssl/include/internal/x509_vfy.h new file mode 100644 index 0000000000..cab110e421 --- /dev/null +++ b/components/openssl/include/internal/x509_vfy.h @@ -0,0 +1,103 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef _X509_VFY_H_ +#define _X509_VFY_H_ + +#define X509_V_OK 0 +#define X509_V_ERR_UNSPECIFIED 1 +#define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT 2 +#define X509_V_ERR_UNABLE_TO_GET_CRL 3 +#define X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE 4 +#define X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE 5 +#define X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY 6 +#define X509_V_ERR_CERT_SIGNATURE_FAILURE 7 +#define X509_V_ERR_CRL_SIGNATURE_FAILURE 8 +#define X509_V_ERR_CERT_NOT_YET_VALID 9 +#define X509_V_ERR_CERT_HAS_EXPIRED 10 +#define X509_V_ERR_CRL_NOT_YET_VALID 11 +#define X509_V_ERR_CRL_HAS_EXPIRED 12 +#define X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD 13 +#define X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD 14 +#define X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD 15 +#define X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD 16 +#define X509_V_ERR_OUT_OF_MEM 17 +#define X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT 18 +#define X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN 19 +#define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY 20 +#define X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE 21 +#define X509_V_ERR_CERT_CHAIN_TOO_LONG 22 +#define X509_V_ERR_CERT_REVOKED 23 +#define X509_V_ERR_INVALID_CA 24 +#define X509_V_ERR_PATH_LENGTH_EXCEEDED 25 +#define X509_V_ERR_INVALID_PURPOSE 26 +#define X509_V_ERR_CERT_UNTRUSTED 27 +#define X509_V_ERR_CERT_REJECTED 28 +/* These are 'informational' when looking for issuer cert */ +#define X509_V_ERR_SUBJECT_ISSUER_MISMATCH 29 +#define X509_V_ERR_AKID_SKID_MISMATCH 30 +#define X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH 31 +#define X509_V_ERR_KEYUSAGE_NO_CERTSIGN 32 +#define X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER 33 +#define X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION 34 +#define X509_V_ERR_KEYUSAGE_NO_CRL_SIGN 35 +#define X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION 36 +#define X509_V_ERR_INVALID_NON_CA 37 +#define X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED 38 +#define X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE 39 +#define X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED 40 +#define X509_V_ERR_INVALID_EXTENSION 41 +#define X509_V_ERR_INVALID_POLICY_EXTENSION 42 +#define X509_V_ERR_NO_EXPLICIT_POLICY 43 +#define X509_V_ERR_DIFFERENT_CRL_SCOPE 44 +#define X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE 45 +#define X509_V_ERR_UNNESTED_RESOURCE 46 +#define X509_V_ERR_PERMITTED_VIOLATION 47 +#define X509_V_ERR_EXCLUDED_VIOLATION 48 +#define X509_V_ERR_SUBTREE_MINMAX 49 +/* The application is not happy */ +#define X509_V_ERR_APPLICATION_VERIFICATION 50 +#define X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE 51 +#define X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX 52 +#define X509_V_ERR_UNSUPPORTED_NAME_SYNTAX 53 +#define X509_V_ERR_CRL_PATH_VALIDATION_ERROR 54 +/* Another issuer check debug option */ +#define X509_V_ERR_PATH_LOOP 55 +/* Suite B mode algorithm violation */ +#define X509_V_ERR_SUITE_B_INVALID_VERSION 56 +#define X509_V_ERR_SUITE_B_INVALID_ALGORITHM 57 +#define X509_V_ERR_SUITE_B_INVALID_CURVE 58 +#define X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM 59 +#define X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED 60 +#define X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 61 +/* Host, email and IP check errors */ +#define X509_V_ERR_HOSTNAME_MISMATCH 62 +#define X509_V_ERR_EMAIL_MISMATCH 63 +#define X509_V_ERR_IP_ADDRESS_MISMATCH 64 +/* DANE TLSA errors */ +#define X509_V_ERR_DANE_NO_MATCH 65 +/* security level errors */ +#define X509_V_ERR_EE_KEY_TOO_SMALL 66 +#define X509_V_ERR_CA_KEY_TOO_SMALL 67 +#define X509_V_ERR_CA_MD_TOO_WEAK 68 +/* Caller error */ +#define X509_V_ERR_INVALID_CALL 69 +/* Issuer lookup error */ +#define X509_V_ERR_STORE_LOOKUP 70 +/* Certificate transparency */ +#define X509_V_ERR_NO_VALID_SCTS 71 + +#define X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION 72 + +#endif From 5c5f7eb7feb16ba2632ad4701d7ef283a3371fec Mon Sep 17 00:00:00 2001 From: dongheng Date: Fri, 23 Sep 2016 14:53:19 +0800 Subject: [PATCH 025/343] components/openssl: add openssl stack object function --- .../openssl/include/internal/ssl_stack.h | 33 +++++++++ components/openssl/library/ssl_stack.c | 70 +++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 components/openssl/include/internal/ssl_stack.h create mode 100644 components/openssl/library/ssl_stack.c diff --git a/components/openssl/include/internal/ssl_stack.h b/components/openssl/include/internal/ssl_stack.h new file mode 100644 index 0000000000..b97015bd95 --- /dev/null +++ b/components/openssl/include/internal/ssl_stack.h @@ -0,0 +1,33 @@ +#ifndef _SSL_STACK_H_ +#define _SSL_STACK_H_ + +#include "ssl_types.h" + +/** + * @brief create a openssl stack object + * + * @param c - stack function + * + * @return openssl stack object point + */ +OPENSSL_STACK* OPENSSL_sk_new(OPENSSL_sk_compfunc c); + +/** + * @brief create a NULL function openssl stack object + * + * @param none + * + * @return openssl stack object point + */ +OPENSSL_STACK *OPENSSL_sk_new_null(void); + +/** + * @brief free openssl stack object + * + * @param openssl stack object point + * + * @return none + */ +void OPENSSL_sk_free(OPENSSL_STACK *stack); + +#endif diff --git a/components/openssl/library/ssl_stack.c b/components/openssl/library/ssl_stack.c new file mode 100644 index 0000000000..46e6f7efd8 --- /dev/null +++ b/components/openssl/library/ssl_stack.c @@ -0,0 +1,70 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "ssl_stack.h" +#include "ssl_dbg.h" +#include "ssl_port.h" + +#ifndef CONFIG_MIN_NODES + #define MIN_NODES 4 +#else + #define MIN_NODES CONFIG_MIN_NODES +#endif + +/** + * @brief create a openssl stack object + */ +OPENSSL_STACK* OPENSSL_sk_new(OPENSSL_sk_compfunc c) +{ + OPENSSL_STACK *stack; + char **data; + + stack = ssl_malloc(sizeof(OPENSSL_STACK)); + if (!stack) + SSL_RET(failed1); + + data = ssl_malloc(sizeof(*data) * MIN_NODES); + if (!data) + SSL_RET(failed2); + + stack->data = data; + stack->num_alloc = MIN_NODES; + stack->c = c; + + return stack; + +failed2: + ssl_free(stack); +failed1: + return NULL; +} + +/** + * @brief create a NULL function openssl stack object + */ +OPENSSL_STACK *OPENSSL_sk_new_null(void) +{ + return OPENSSL_sk_new((OPENSSL_sk_compfunc)NULL); +} + +/** + * @brief free openssl stack object + */ +void OPENSSL_sk_free(OPENSSL_STACK *stack) +{ + SSL_ASSERT(stack); + + ssl_free(stack->data); + ssl_free(stack); +} From 12b72e91afb384d975a5abfe0eeedcec560345b6 Mon Sep 17 00:00:00 2001 From: dongheng Date: Fri, 23 Sep 2016 14:58:14 +0800 Subject: [PATCH 026/343] components/openssl: remove unused variate --- components/openssl/library/ssl_pkey.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/components/openssl/library/ssl_pkey.c b/components/openssl/library/ssl_pkey.c index 6f51963eb0..6891b69eb3 100644 --- a/components/openssl/library/ssl_pkey.c +++ b/components/openssl/library/ssl_pkey.c @@ -118,9 +118,6 @@ int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) */ int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) { - int ret; - int ssl_ret; - SSL_ASSERT(ctx); SSL_ASSERT(pkey); From 83aea6c833c399757d3c740bcd23b0f6ba912859 Mon Sep 17 00:00:00 2001 From: dongheng Date: Fri, 23 Sep 2016 15:18:14 +0800 Subject: [PATCH 027/343] components/openssl: add extern C symbol --- components/openssl/include/internal/ssl3.h | 8 ++++++++ components/openssl/include/internal/ssl_cert.h | 8 ++++++++ components/openssl/include/internal/ssl_code.h | 8 ++++++++ components/openssl/include/internal/ssl_dbg.h | 8 ++++++++ components/openssl/include/internal/ssl_lib.h | 8 ++++++++ components/openssl/include/internal/ssl_methods.h | 8 ++++++++ components/openssl/include/internal/ssl_pkey.h | 8 ++++++++ components/openssl/include/internal/ssl_stack.h | 8 ++++++++ components/openssl/include/internal/ssl_types.h | 8 ++++++++ components/openssl/include/internal/ssl_x509.h | 8 ++++++++ components/openssl/include/internal/tls1.h | 8 ++++++++ components/openssl/include/internal/x509_vfy.h | 8 ++++++++ components/openssl/include/openssl/ssl.h | 7 +++++++ components/openssl/include/platform/ssl_pm.h | 4 ++++ components/openssl/include/platform/ssl_port.h | 4 ++++ 15 files changed, 111 insertions(+) diff --git a/components/openssl/include/internal/ssl3.h b/components/openssl/include/internal/ssl3.h index c90d546df0..007b392f3e 100644 --- a/components/openssl/include/internal/ssl3.h +++ b/components/openssl/include/internal/ssl3.h @@ -15,6 +15,10 @@ #ifndef _SSL3_H_ #define _SSL3_H_ +#ifdef __cplusplus + extern "C" { +#endif + # define SSL3_AD_CLOSE_NOTIFY 0 # define SSL3_AD_UNEXPECTED_MESSAGE 10/* fatal */ # define SSL3_AD_BAD_RECORD_MAC 20/* fatal */ @@ -33,4 +37,8 @@ #define SSL3_VERSION 0x0300 +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/openssl/include/internal/ssl_cert.h b/components/openssl/include/internal/ssl_cert.h index b0bd09d480..6441aaf521 100644 --- a/components/openssl/include/internal/ssl_cert.h +++ b/components/openssl/include/internal/ssl_cert.h @@ -15,6 +15,10 @@ #ifndef _SSL_CERT_H_ #define _SSL_CERT_H_ +#ifdef __cplusplus + extern "C" { +#endif + #include "ssl_types.h" /** @@ -35,4 +39,8 @@ CERT* ssl_cert_new(void); */ void ssl_cert_free(CERT *cert); +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/openssl/include/internal/ssl_code.h b/components/openssl/include/internal/ssl_code.h index 34107d432d..80fdbb20f3 100644 --- a/components/openssl/include/internal/ssl_code.h +++ b/components/openssl/include/internal/ssl_code.h @@ -15,6 +15,10 @@ #ifndef _SSL_CODE_H_ #define _SSL_CODE_H_ +#ifdef __cplusplus + extern "C" { +#endif + #include "ssl3.h" #include "tls1.h" #include "x509_vfy.h" @@ -113,4 +117,8 @@ typedef enum { TLS_ST_SW_FINISHED } OSSL_HANDSHAKE_STATE; +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/openssl/include/internal/ssl_dbg.h b/components/openssl/include/internal/ssl_dbg.h index 745de536ff..27a4bc4db5 100644 --- a/components/openssl/include/internal/ssl_dbg.h +++ b/components/openssl/include/internal/ssl_dbg.h @@ -15,6 +15,10 @@ #ifndef _SSL_DEBUG_H_ #define _SSL_DEBUG_H_ +#ifdef __cplusplus + extern "C" { +#endif + #define SSL_DEBUG_ENBALE 0 #define SSL_DEBUG_LEVEL 0 #define SSL_ASSERT_ENABLE 0 @@ -46,4 +50,8 @@ #define SSL_DEBUG(level, ...) { if (level > SSL_DEBUG_LEVEL) {SSL_PRINT(__VA_ARGS__);} } +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/openssl/include/internal/ssl_lib.h b/components/openssl/include/internal/ssl_lib.h index 6ea547a7c5..bf7de22fdf 100644 --- a/components/openssl/include/internal/ssl_lib.h +++ b/components/openssl/include/internal/ssl_lib.h @@ -15,6 +15,14 @@ #ifndef _SSL_LIB_H_ #define _SSL_LIB_H_ +#ifdef __cplusplus + extern "C" { +#endif + #include "ssl_types.h" +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/openssl/include/internal/ssl_methods.h b/components/openssl/include/internal/ssl_methods.h index 68737b4381..a20b7c768e 100644 --- a/components/openssl/include/internal/ssl_methods.h +++ b/components/openssl/include/internal/ssl_methods.h @@ -15,6 +15,10 @@ #ifndef _SSL_METHODS_H_ #define _SSL_METHODS_H_ +#ifdef __cplusplus + extern "C" { +#endif + /** * TLS method function implement */ @@ -110,4 +114,8 @@ const X509_METHOD* X509_method(void); */ const PKEY_METHOD* EVP_PKEY_method(void); +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/openssl/include/internal/ssl_pkey.h b/components/openssl/include/internal/ssl_pkey.h index d9a22ee02c..5b7f341de9 100644 --- a/components/openssl/include/internal/ssl_pkey.h +++ b/components/openssl/include/internal/ssl_pkey.h @@ -15,6 +15,10 @@ #ifndef _SSL_PKEY_H_ #define _SSL_PKEY_H_ +#ifdef __cplusplus + extern "C" { +#endif + #include "ssl_types.h" /** @@ -51,4 +55,8 @@ EVP_PKEY* d2i_PrivateKey(int type, */ void EVP_PKEY_free(EVP_PKEY *x); +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/openssl/include/internal/ssl_stack.h b/components/openssl/include/internal/ssl_stack.h index b97015bd95..b37c8dffa9 100644 --- a/components/openssl/include/internal/ssl_stack.h +++ b/components/openssl/include/internal/ssl_stack.h @@ -1,6 +1,10 @@ #ifndef _SSL_STACK_H_ #define _SSL_STACK_H_ +#ifdef __cplusplus + extern "C" { +#endif + #include "ssl_types.h" /** @@ -30,4 +34,8 @@ OPENSSL_STACK *OPENSSL_sk_new_null(void); */ void OPENSSL_sk_free(OPENSSL_STACK *stack); +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/openssl/include/internal/ssl_types.h b/components/openssl/include/internal/ssl_types.h index 6da6076148..1dc31f5a53 100644 --- a/components/openssl/include/internal/ssl_types.h +++ b/components/openssl/include/internal/ssl_types.h @@ -15,6 +15,10 @@ #ifndef _SSL_TYPES_H_ #define _SSL_TYPES_H_ +#ifdef __cplusplus + extern "C" { +#endif + #include "ssl_code.h" typedef void SSL_CIPHER; @@ -294,4 +298,8 @@ typedef int (*next_proto_cb)(SSL *ssl, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg); +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/openssl/include/internal/ssl_x509.h b/components/openssl/include/internal/ssl_x509.h index 9359073b69..5dac46137b 100644 --- a/components/openssl/include/internal/ssl_x509.h +++ b/components/openssl/include/internal/ssl_x509.h @@ -15,6 +15,10 @@ #ifndef _SSL_X509_H_ #define _SSL_X509_H_ +#ifdef __cplusplus + extern "C" { +#endif + #include "ssl_types.h" #include "ssl_stack.h" @@ -50,4 +54,8 @@ X509* d2i_X509(X509 **cert, const unsigned char *buffer, long len); */ void X509_free(X509 *x); +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/openssl/include/internal/tls1.h b/components/openssl/include/internal/tls1.h index b2da639194..a9da53e063 100644 --- a/components/openssl/include/internal/tls1.h +++ b/components/openssl/include/internal/tls1.h @@ -15,6 +15,10 @@ #ifndef _TLS1_H_ #define _TLS1_H_ +#ifdef __cplusplus + extern "C" { +#endif + # define TLS1_AD_DECRYPTION_FAILED 21 # define TLS1_AD_RECORD_OVERFLOW 22 # define TLS1_AD_UNKNOWN_CA 48/* fatal */ @@ -44,4 +48,8 @@ #define TLS1_1_VERSION 0x0302 #define TLS1_2_VERSION 0x0303 +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/openssl/include/internal/x509_vfy.h b/components/openssl/include/internal/x509_vfy.h index cab110e421..d5b0d1a213 100644 --- a/components/openssl/include/internal/x509_vfy.h +++ b/components/openssl/include/internal/x509_vfy.h @@ -15,6 +15,10 @@ #ifndef _X509_VFY_H_ #define _X509_VFY_H_ +#ifdef __cplusplus + extern "C" { +#endif + #define X509_V_OK 0 #define X509_V_ERR_UNSPECIFIED 1 #define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT 2 @@ -100,4 +104,8 @@ #define X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION 72 +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/openssl/include/openssl/ssl.h b/components/openssl/include/openssl/ssl.h index 3f92a68d70..3e8e88e67c 100644 --- a/components/openssl/include/openssl/ssl.h +++ b/components/openssl/include/openssl/ssl.h @@ -15,6 +15,10 @@ #ifndef _SSL_H_ #define _SSL_H_ +#ifdef __cplusplus + extern "C" { +#endif + #include "platform/ssl_port.h" #include "internal/ssl_x509.h" @@ -1684,5 +1688,8 @@ const char *SSL_get_psk_identity_hint(SSL *ssl); */ const char *SSL_get_psk_identity(SSL *ssl); +#ifdef __cplusplus +} +#endif #endif diff --git a/components/openssl/include/platform/ssl_pm.h b/components/openssl/include/platform/ssl_pm.h index 3f64a4ae32..47a7331b7e 100644 --- a/components/openssl/include/platform/ssl_pm.h +++ b/components/openssl/include/platform/ssl_pm.h @@ -15,6 +15,10 @@ #ifndef _SSL_PM_H_ #define _SSL_PM_H_ +#ifdef __cplusplus + extern "C" { +#endif + #include "ssl_types.h" #include "ssl_port.h" diff --git a/components/openssl/include/platform/ssl_port.h b/components/openssl/include/platform/ssl_port.h index 23ef5a8757..995d33e0e5 100644 --- a/components/openssl/include/platform/ssl_port.h +++ b/components/openssl/include/platform/ssl_port.h @@ -15,6 +15,10 @@ #ifndef _SSL_PORT_H_ #define _SSL_PORT_H_ +#ifdef __cplusplus + extern "C" { +#endif + #include "esp_types.h" void* ssl_zalloc(size_t size); From d2bc170b869be45772c0889f0c2a8af751222510 Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Fri, 23 Sep 2016 18:13:10 +0800 Subject: [PATCH 028/343] components/openssl: add SSL session function 1. add SSL session new and free function 2. add SSL session peer cert get and free operation 3. above all, change low-level cert object to be object point not object --- .../openssl/include/internal/ssl_types.h | 2 +- components/openssl/library/ssl_lib.c | 46 +++- components/openssl/library/ssl_x509.c | 4 +- components/openssl/platform/ssl_pm.c | 207 ++++++++++-------- 4 files changed, 161 insertions(+), 98 deletions(-) diff --git a/components/openssl/include/internal/ssl_types.h b/components/openssl/include/internal/ssl_types.h index 1dc31f5a53..34249ea054 100644 --- a/components/openssl/include/internal/ssl_types.h +++ b/components/openssl/include/internal/ssl_types.h @@ -213,7 +213,7 @@ struct ssl_st /* where we are */ OSSL_STATEM statem; - SSL_SESSION session; + SSL_SESSION *session; int verify_mode; diff --git a/components/openssl/library/ssl_lib.c b/components/openssl/library/ssl_lib.c index a84b89e06c..ded30a33ac 100644 --- a/components/openssl/library/ssl_lib.c +++ b/components/openssl/library/ssl_lib.c @@ -117,6 +117,38 @@ OSSL_HANDSHAKE_STATE SSL_get_state(const SSL *ssl) return state; } +/** + * @brief create a new SSL session object + */ +SSL_SESSION* SSL_SESSION_new(void) +{ + SSL_SESSION *session; + + session = ssl_zalloc(sizeof(SSL_SESSION)); + if (!session) + SSL_RET(failed1); + + session->peer = X509_new(); + if (!session->peer) + SSL_RET(failed2); + + return session; + +failed2: + ssl_free(session); +failed1: + return NULL; +} + +/** + * @brief free a new SSL session object + */ +void SSL_SESSION_free(SSL_SESSION *session) +{ + X509_free(session->peer); + ssl_free(session); +} + /** * @brief create a SSL context */ @@ -210,6 +242,10 @@ SSL *SSL_new(SSL_CTX *ctx) if (!ssl) SSL_RET(failed1, "ssl_zalloc\n"); + ssl->session = SSL_SESSION_new(); + if (!ssl->session) + SSL_RET(failed2, "ssl_zalloc\n"); + ssl->ctx = ctx; ssl->method = ctx->method; @@ -222,12 +258,14 @@ SSL *SSL_new(SSL_CTX *ctx) ret = SSL_METHOD_CALL(new, ssl); if (ret) - SSL_RET(failed2, "ssl_new\n"); + SSL_RET(failed3, "ssl_new\n"); ssl->rwstate = SSL_NOTHING; return ssl; +failed3: + SSL_SESSION_free(ssl->session); failed2: ssl_free(ssl); failed1: @@ -243,6 +281,8 @@ void SSL_free(SSL *ssl) SSL_METHOD_CALL(free, ssl); + SSL_SESSION_free(ssl->session); + if (ssl->ca_reload) X509_free(ssl->client_CA); @@ -1369,7 +1409,7 @@ long SSL_set_time(SSL *ssl, long t) { SSL_ASSERT(ssl); - ssl->session.time = t; + ssl->session->time = t; return t; } @@ -1381,7 +1421,7 @@ long SSL_set_timeout(SSL *ssl, long t) { SSL_ASSERT(ssl); - ssl->session.timeout = t; + ssl->session->timeout = t; return t; } diff --git a/components/openssl/library/ssl_x509.c b/components/openssl/library/ssl_x509.c index e96511dc4a..c3fa0b307a 100644 --- a/components/openssl/library/ssl_x509.c +++ b/components/openssl/library/ssl_x509.c @@ -32,7 +32,7 @@ X509* X509_new(void) x->method = X509_method(); - ret = x->method->x509_new(x); + ret = X509_METHOD_CALL(new, x); if (ret) SSL_RET(failed2, "x509_new\n"); @@ -256,5 +256,5 @@ X509 *SSL_get_peer_certificate(const SSL *ssl) { SSL_ASSERT(ssl); - return ssl->session.peer; + return ssl->session->peer; } diff --git a/components/openssl/platform/ssl_pm.c b/components/openssl/platform/ssl_pm.c index 9abfc212ec..0cf8f6c0a9 100644 --- a/components/openssl/platform/ssl_pm.c +++ b/components/openssl/platform/ssl_pm.c @@ -43,16 +43,16 @@ struct ssl_pm struct x509_pm { - mbedtls_x509_crt x509_crt; + mbedtls_x509_crt *x509_crt; - int load; + mbedtls_x509_crt *ex_crt; }; struct pkey_pm { - mbedtls_pk_context pkey; + mbedtls_pk_context *pkey; - int load; + mbedtls_pk_context *ex_pkey; }; @@ -78,13 +78,9 @@ int ssl_pm_new(SSL *ssl) const SSL_METHOD *method = ssl->method; - ssl->session.peer = ssl_zalloc(sizeof(X509)); - if (!ssl->session.peer) - SSL_ERR(ret, failed1, "ssl_zalloc\n"); - ssl_pm = ssl_zalloc(sizeof(struct ssl_pm)); if (!ssl_pm) - SSL_ERR(ret, failed2, "ssl_zalloc\n"); + SSL_ERR(ret, failed1, "ssl_zalloc\n"); mbedtls_net_init(&ssl_pm->fd); mbedtls_net_init(&ssl_pm->cl_fd); @@ -96,7 +92,7 @@ int ssl_pm_new(SSL *ssl) ret = mbedtls_ctr_drbg_seed(&ssl_pm->ctr_drbg, mbedtls_entropy_func, &ssl_pm->entropy, pers, pers_len); if (ret) - SSL_ERR(ret, failed3, "mbedtls_ctr_drbg_seed:[-0x%x]\n", -ret); + SSL_ERR(ret, failed2, "mbedtls_ctr_drbg_seed:[-0x%x]\n", -ret); if (method->endpoint) { endpoint = MBEDTLS_SSL_IS_SERVER; @@ -105,7 +101,7 @@ int ssl_pm_new(SSL *ssl) } ret = mbedtls_ssl_config_defaults(&ssl_pm->conf, endpoint, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT); if (ret) - SSL_ERR(ret, failed3, "mbedtls_ssl_config_defaults:[-0x%x]\n", -ret); + SSL_ERR(ret, failed2, "mbedtls_ssl_config_defaults:[-0x%x]\n", -ret); if (TLS1_2_VERSION == ssl->version) version = MBEDTLS_SSL_MINOR_VERSION_3; @@ -124,7 +120,7 @@ int ssl_pm_new(SSL *ssl) ret = mbedtls_ssl_setup(&ssl_pm->ssl, &ssl_pm->conf); if (ret) - SSL_ERR(ret, failed4, "mbedtls_ssl_setup:[-0x%x]\n", -ret); + SSL_ERR(ret, failed3, "mbedtls_ssl_setup:[-0x%x]\n", -ret); mbedtls_ssl_set_bio(&ssl_pm->ssl, &ssl_pm->fd, mbedtls_net_send, mbedtls_net_recv, NULL); @@ -132,13 +128,11 @@ int ssl_pm_new(SSL *ssl) return 0; -failed4: +failed3: mbedtls_ssl_config_free(&ssl_pm->conf); mbedtls_ctr_drbg_free(&ssl_pm->ctr_drbg); -failed3: - mbedtls_entropy_free(&ssl_pm->entropy); failed2: - ssl_free(ssl->session.peer); + mbedtls_entropy_free(&ssl_pm->entropy); failed1: return -1; } @@ -155,9 +149,6 @@ void ssl_pm_free(SSL *ssl) mbedtls_ssl_config_free(&ssl_pm->conf); mbedtls_ssl_free(&ssl_pm->ssl); - ssl_free(ssl->session.peer); - ssl->session.peer = NULL; - ssl_free(ssl_pm); ssl->ssl_pm = NULL; } @@ -186,12 +177,12 @@ static int ssl_pm_reload_crt(SSL *ssl) mbedtls_ssl_conf_authmode(&ssl_pm->conf, mode); - if (ca_pm->load) { - mbedtls_ssl_conf_ca_chain(&ssl_pm->conf, &ca_pm->x509_crt, NULL); + if (ca_pm->x509_crt) { + mbedtls_ssl_conf_ca_chain(&ssl_pm->conf, ca_pm->x509_crt, NULL); } - if (pkey_pm->load) { - ret = mbedtls_ssl_conf_own_cert(&ssl_pm->conf, &crt_pm->x509_crt, &pkey_pm->pkey); + if (crt_pm->x509_crt && pkey_pm->pkey) { + ret = mbedtls_ssl_conf_own_cert(&ssl_pm->conf, crt_pm->x509_crt, pkey_pm->pkey); if (ret) return -1; } @@ -217,9 +208,11 @@ int ssl_pm_handshake(SSL *ssl) ssl_speed_up_exit(); if (!mbed_ret) { + struct x509_pm *x509_pm = (struct x509_pm *)ssl->session->peer->x509_pm; + ret = 1; - ssl->session.peer->x509_pm = (struct x509_pm *)mbedtls_ssl_get_peer_cert(&ssl_pm->ssl); + x509_pm->ex_crt = (mbedtls_x509_crt *)mbedtls_ssl_get_peer_cert(&ssl_pm->ssl); } else { ret = 0; SSL_DEBUG(1, "mbedtls_ssl_handshake [-0x%x]\n", -mbed_ret); @@ -234,8 +227,13 @@ int ssl_pm_shutdown(SSL *ssl) struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; mbed_ret = mbedtls_ssl_close_notify(&ssl_pm->ssl); - if (!mbed_ret) + if (!mbed_ret) { + struct x509_pm *x509_pm = (struct x509_pm *)ssl->session->peer->x509_pm; + ret = 0; + + x509_pm->ex_crt = NULL; + } else ret = -1; @@ -365,51 +363,26 @@ int x509_pm_new(X509 *x) x509_pm = ssl_zalloc(sizeof(struct x509_pm)); if (!x509_pm) - return -1; + SSL_RET(failed1); x->x509_pm = x509_pm; return 0; + +failed1: + return -1; } void x509_pm_unload(X509 *x) { struct x509_pm *x509_pm = (struct x509_pm *)x->x509_pm; - if (x509_pm->load) - mbedtls_x509_crt_free(&x509_pm->x509_crt); + if (x509_pm->x509_crt) { + mbedtls_x509_crt_free(x509_pm->x509_crt); - x509_pm->load = 0; -} - -int x509_pm_load(X509 *x, const unsigned char *buffer, int len) -{ - int ret; - unsigned char *load_buf; - struct x509_pm *x509_pm = (struct x509_pm *)x->x509_pm; - - load_buf = ssl_malloc(len + 1); - if (!load_buf) - SSL_RET(failed1); - - ssl_memcpy(load_buf, buffer, len); - load_buf[len] = '\0'; - - x509_pm_unload(x); - - mbedtls_x509_crt_init(&x509_pm->x509_crt); - ret = mbedtls_x509_crt_parse(&x509_pm->x509_crt, load_buf, len); - ssl_free(load_buf); - - if (ret) - SSL_RET(failed1, ""); - - x509_pm->load = 1; - - return 0; - -failed1: - return -1; + ssl_free(x509_pm->x509_crt); + x509_pm->x509_crt = NULL; + } } void x509_pm_free(X509 *x) @@ -420,6 +393,44 @@ void x509_pm_free(X509 *x) x->x509_pm = NULL; } +int x509_pm_load(X509 *x, const unsigned char *buffer, int len) +{ + int ret; + unsigned char *load_buf; + struct x509_pm *x509_pm = (struct x509_pm *)x->x509_pm; + + if (!x509_pm->x509_crt) { + x509_pm->x509_crt = ssl_malloc(sizeof(mbedtls_x509_crt)); + if (!x509_pm->x509_crt) + SSL_RET(failed1); + } + + load_buf = ssl_malloc(len + 1); + if (!load_buf) + SSL_RET(failed2); + + ssl_memcpy(load_buf, buffer, len); + load_buf[len] = '\0'; + + if (x509_pm->x509_crt) + mbedtls_x509_crt_free(x509_pm->x509_crt); + + mbedtls_x509_crt_init(x509_pm->x509_crt); + ret = mbedtls_x509_crt_parse(x509_pm->x509_crt, load_buf, len); + ssl_free(load_buf); + + if (ret) + SSL_RET(failed2); + + return 0; + +failed2: + ssl_free(x509_pm->x509_crt); + x509_pm->x509_crt = NULL; +failed1: + return -1; +} + int pkey_pm_new(EVP_PKEY *pkey) { struct pkey_pm *pkey_pm; @@ -437,40 +448,12 @@ void pkey_pm_unload(EVP_PKEY *pkey) { struct pkey_pm *pkey_pm = (struct pkey_pm *)pkey->pkey_pm; - if (pkey_pm->load) - mbedtls_pk_free(&pkey_pm->pkey); + if (pkey_pm->pkey) { + mbedtls_pk_free(pkey_pm->pkey); - pkey_pm->load = 0; -} - -int pkey_pm_load(EVP_PKEY *pkey, const unsigned char *buffer, int len) -{ - int ret; - unsigned char *load_buf; - struct pkey_pm *pkey_pm = (struct pkey_pm *)pkey->pkey_pm; - - load_buf = ssl_malloc(len + 1); - if (!load_buf) - SSL_RET(failed1); - - ssl_memcpy(load_buf, buffer, len); - load_buf[len] = '\0'; - - pkey_pm_unload(pkey); - - mbedtls_pk_init(&pkey_pm->pkey); - ret = mbedtls_pk_parse_key(&pkey_pm->pkey, load_buf, len, NULL, 0); - ssl_free(load_buf); - - if (ret) - SSL_RET(failed1, ""); - - pkey_pm->load = 1; - - return 0; - -failed1: - return -1; + ssl_free(pkey_pm->pkey); + pkey_pm->pkey = NULL; + } } void pkey_pm_free(EVP_PKEY *pkey) @@ -481,6 +464,46 @@ void pkey_pm_free(EVP_PKEY *pkey) pkey->pkey_pm = NULL; } +int pkey_pm_load(EVP_PKEY *pkey, const unsigned char *buffer, int len) +{ + int ret; + unsigned char *load_buf; + struct pkey_pm *pkey_pm = (struct pkey_pm *)pkey->pkey_pm; + + if (!pkey_pm->pkey) { + pkey_pm->pkey = ssl_malloc(sizeof(mbedtls_pk_context)); + if (!pkey_pm->pkey) + SSL_RET(failed1); + } + + load_buf = ssl_malloc(len + 1); + if (!load_buf) + SSL_RET(failed2); + + ssl_memcpy(load_buf, buffer, len); + load_buf[len] = '\0'; + + if (pkey_pm->pkey) + mbedtls_pk_free(pkey_pm->pkey); + + mbedtls_pk_init(pkey_pm->pkey); + ret = mbedtls_pk_parse_key(pkey_pm->pkey, load_buf, len, NULL, 0); + ssl_free(load_buf); + + if (ret) + SSL_RET(failed2); + + return 0; + +failed2: + ssl_free(pkey_pm->pkey); + pkey_pm->pkey = NULL; +failed1: + return -1; +} + + + void ssl_pm_set_bufflen(SSL *ssl, int len) { max_content_len = len; From e1c4a4bfa3e9a929c42e40238878c1bce83db76a Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Fri, 23 Sep 2016 18:47:09 +0800 Subject: [PATCH 029/343] components/openssl: add cert and pkey extra object point the point is pointed to its father's object and should not free just set NULL if not use --- components/openssl/library/ssl_lib.c | 26 +++++++++++++++++--------- components/openssl/platform/ssl_pm.c | 23 +++++++++++++++++++++-- 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/components/openssl/library/ssl_lib.c b/components/openssl/library/ssl_lib.c index ded30a33ac..06bbe270c5 100644 --- a/components/openssl/library/ssl_lib.c +++ b/components/openssl/library/ssl_lib.c @@ -246,24 +246,34 @@ SSL *SSL_new(SSL_CTX *ctx) if (!ssl->session) SSL_RET(failed2, "ssl_zalloc\n"); + ssl->cert = ssl_cert_new(); + if (!ssl->cert) + SSL_RET(failed3, "ssl_cert_new\n"); + + ssl->client_CA = X509_new(); + if (!ssl->client_CA) + SSL_RET(failed4, "ssl_cert_new\n"); + ssl->ctx = ctx; ssl->method = ctx->method; ssl->version = ctx->version; ssl->options = ctx->options; - ssl->cert = ctx->cert; - ssl->client_CA = ctx->client_CA; ssl->verify_mode = ctx->verify_mode; ret = SSL_METHOD_CALL(new, ssl); if (ret) - SSL_RET(failed3, "ssl_new\n"); + SSL_RET(failed5, "ssl_new\n"); ssl->rwstate = SSL_NOTHING; return ssl; +failed5: + X509_free(ssl->client_CA); +failed4: + ssl_cert_free(ssl->cert); failed3: SSL_SESSION_free(ssl->session); failed2: @@ -281,14 +291,12 @@ void SSL_free(SSL *ssl) SSL_METHOD_CALL(free, ssl); + X509_free(ssl->client_CA); + + ssl_cert_free(ssl->cert); + SSL_SESSION_free(ssl->session); - if (ssl->ca_reload) - X509_free(ssl->client_CA); - - if (ssl->crt_reload) - ssl_cert_free(ssl->cert); - ssl_free(ssl); } diff --git a/components/openssl/platform/ssl_pm.c b/components/openssl/platform/ssl_pm.c index 0cf8f6c0a9..311c3a4b6f 100644 --- a/components/openssl/platform/ssl_pm.c +++ b/components/openssl/platform/ssl_pm.c @@ -78,6 +78,14 @@ int ssl_pm_new(SSL *ssl) const SSL_METHOD *method = ssl->method; + struct x509_pm *ctx_ca = (struct x509_pm *)ssl->ctx->client_CA->x509_pm; + struct x509_pm *ctx_crt = (struct x509_pm *)ssl->ctx->cert->x509->x509_pm; + struct pkey_pm *ctx_pkey = (struct pkey_pm *)ssl->ctx->cert->pkey->pkey_pm; + + struct x509_pm *ssl_ca = (struct x509_pm *)ssl->client_CA->x509_pm; + struct x509_pm *ssl_crt = (struct x509_pm *)ssl->cert->x509->x509_pm; + struct pkey_pm *ssl_pkey = (struct pkey_pm *)ssl->cert->pkey->pkey_pm; + ssl_pm = ssl_zalloc(sizeof(struct ssl_pm)); if (!ssl_pm) SSL_ERR(ret, failed1, "ssl_zalloc\n"); @@ -126,6 +134,10 @@ int ssl_pm_new(SSL *ssl) ssl->ssl_pm = ssl_pm; + ssl_ca->ex_crt = ctx_ca->x509_crt; + ssl_crt->ex_crt = ctx_crt->x509_crt; + ssl_pkey->ex_pkey = ctx_pkey->pkey; + return 0; failed3: @@ -179,14 +191,21 @@ static int ssl_pm_reload_crt(SSL *ssl) if (ca_pm->x509_crt) { mbedtls_ssl_conf_ca_chain(&ssl_pm->conf, ca_pm->x509_crt, NULL); + } else if (ca_pm->ex_crt) { + mbedtls_ssl_conf_ca_chain(&ssl_pm->conf, ca_pm->x509_crt, NULL); } if (crt_pm->x509_crt && pkey_pm->pkey) { ret = mbedtls_ssl_conf_own_cert(&ssl_pm->conf, crt_pm->x509_crt, pkey_pm->pkey); - if (ret) - return -1; + } else if (crt_pm->ex_crt && pkey_pm->ex_pkey) { + ret = mbedtls_ssl_conf_own_cert(&ssl_pm->conf, crt_pm->ex_crt, pkey_pm->ex_pkey); + } else { + ret = 0; } + if (ret) + return -1; + return 0; } From cf4aaf639714f4d479dd38ea396ff0a66d5a5981 Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Mon, 26 Sep 2016 11:14:19 +0800 Subject: [PATCH 030/343] components/openssl: optimize the SSL certification and private key function 1. add inheritance function 2. remove low-level platform unload cert & pkey function 3. optimize the cert load and free function --- .../openssl/include/internal/ssl_cert.h | 9 ++ .../openssl/include/internal/ssl_methods.h | 12 +-- .../openssl/include/internal/ssl_pkey.h | 9 ++ .../openssl/include/internal/ssl_types.h | 12 +-- .../openssl/include/internal/ssl_x509.h | 9 ++ components/openssl/include/platform/ssl_pm.h | 11 +-- components/openssl/library/ssl_cert.c | 33 +++++-- components/openssl/library/ssl_lib.c | 16 ++-- components/openssl/library/ssl_methods.c | 4 +- components/openssl/library/ssl_pkey.c | 82 ++++++++--------- components/openssl/library/ssl_x509.c | 89 ++++++++++--------- components/openssl/platform/ssl_pm.c | 56 +++++------- 12 files changed, 178 insertions(+), 164 deletions(-) diff --git a/components/openssl/include/internal/ssl_cert.h b/components/openssl/include/internal/ssl_cert.h index 6441aaf521..86cf31ad51 100644 --- a/components/openssl/include/internal/ssl_cert.h +++ b/components/openssl/include/internal/ssl_cert.h @@ -21,6 +21,15 @@ #include "ssl_types.h" +/** + * @brief create a certification object include private key object according to input certification + * + * @param ic - input certification point + * + * @return certification object point + */ +CERT *__ssl_cert_new(CERT *ic); + /** * @brief create a certification object include private key object * diff --git a/components/openssl/include/internal/ssl_methods.h b/components/openssl/include/internal/ssl_methods.h index a20b7c768e..9fd9ce9068 100644 --- a/components/openssl/include/internal/ssl_methods.h +++ b/components/openssl/include/internal/ssl_methods.h @@ -69,14 +69,12 @@ #define IMPLEMENT_X509_METHOD(func_name, \ new, \ free, \ - load, \ - unload) \ + load) \ const X509_METHOD* func_name(void) { \ static const X509_METHOD func_name##_data LOCAL_ATRR = { \ new, \ free, \ - load, \ - unload, \ + load \ }; \ return &func_name##_data; \ } @@ -84,14 +82,12 @@ #define IMPLEMENT_PKEY_METHOD(func_name, \ new, \ free, \ - load, \ - unload) \ + load) \ const PKEY_METHOD* func_name(void) { \ static const PKEY_METHOD func_name##_data LOCAL_ATRR = { \ new, \ free, \ - load, \ - unload, \ + load \ }; \ return &func_name##_data; \ } diff --git a/components/openssl/include/internal/ssl_pkey.h b/components/openssl/include/internal/ssl_pkey.h index 5b7f341de9..f4da041681 100644 --- a/components/openssl/include/internal/ssl_pkey.h +++ b/components/openssl/include/internal/ssl_pkey.h @@ -21,6 +21,15 @@ #include "ssl_types.h" +/** + * @brief create a private key object according to input private key + * + * @param ipk - input private key point + * + * @return new private key object point + */ +EVP_PKEY* __EVP_PKEY_new(EVP_PKEY *ipk); + /** * @brief create a private key object * diff --git a/components/openssl/include/internal/ssl_types.h b/components/openssl/include/internal/ssl_types.h index 34249ea054..c571865c1e 100644 --- a/components/openssl/include/internal/ssl_types.h +++ b/components/openssl/include/internal/ssl_types.h @@ -196,12 +196,8 @@ struct ssl_st /* shut things down(0x01 : sent, 0x02 : received) */ int shutdown; - int crt_reload; - CERT *cert; - int ca_reload; - X509 *client_CA; SSL_CTX *ctx; @@ -274,24 +270,20 @@ struct ssl_method_func_st { struct x509_method_st { - int (*x509_new)(X509 *x); + int (*x509_new)(X509 *x, X509 *m_x); void (*x509_free)(X509 *x); int (*x509_load)(X509 *x, const unsigned char *buf, int len); - - void (*x509_unload)(X509 *x); }; struct pkey_method_st { - int (*pkey_new)(EVP_PKEY *pkey); + int (*pkey_new)(EVP_PKEY *pkey, EVP_PKEY *m_pkey); void (*pkey_free)(EVP_PKEY *pkey); int (*pkey_load)(EVP_PKEY *pkey, const unsigned char *buf, int len); - - void (*pkey_unload)(EVP_PKEY *pkey); }; typedef int (*next_proto_cb)(SSL *ssl, unsigned char **out, diff --git a/components/openssl/include/internal/ssl_x509.h b/components/openssl/include/internal/ssl_x509.h index 5dac46137b..2c72980b07 100644 --- a/components/openssl/include/internal/ssl_x509.h +++ b/components/openssl/include/internal/ssl_x509.h @@ -24,6 +24,15 @@ DEFINE_STACK_OF(X509_NAME) +/** + * @brief create a X509 certification object according to input X509 certification + * + * @param ix - input X509 certification point + * + * @return new X509 certification object point + */ +X509* __X509_new(X509 *ix); + /** * @brief create a X509 certification object * diff --git a/components/openssl/include/platform/ssl_pm.h b/components/openssl/include/platform/ssl_pm.h index 47a7331b7e..cf1d213799 100644 --- a/components/openssl/include/platform/ssl_pm.h +++ b/components/openssl/include/platform/ssl_pm.h @@ -42,16 +42,13 @@ OSSL_HANDSHAKE_STATE ssl_pm_get_state(const SSL *ssl); void ssl_pm_set_bufflen(SSL *ssl, int len); -int x509_pm_new(X509 *x); +int x509_pm_new(X509 *x, X509 *m_x); void x509_pm_free(X509 *x); int x509_pm_load(X509 *x, const unsigned char *buffer, int len); -void x509_pm_unload(X509 *x); -void x509_pm_start_ca(X509 *x); -int pkey_pm_new(EVP_PKEY *pkey); -void pkey_pm_free(EVP_PKEY *pkey); -int pkey_pm_load(EVP_PKEY *pkey, const unsigned char *buffer, int len); -void pkey_pm_unload(EVP_PKEY *pkey); +int pkey_pm_new(EVP_PKEY *pk, EVP_PKEY *m_pk); +void pkey_pm_free(EVP_PKEY *pk); +int pkey_pm_load(EVP_PKEY *pk, const unsigned char *buffer, int len); long ssl_pm_get_verify_result(const SSL *ssl); diff --git a/components/openssl/library/ssl_cert.c b/components/openssl/library/ssl_cert.c index fd05bc8315..e4fd4d7785 100644 --- a/components/openssl/library/ssl_cert.c +++ b/components/openssl/library/ssl_cert.c @@ -19,23 +19,34 @@ #include "ssl_port.h" /** - * @brief create a certification object include private key object + * @brief create a certification object according to input certification */ -CERT *ssl_cert_new(void) +CERT *__ssl_cert_new(CERT *ic) { CERT *cert; + X509 *ix; + EVP_PKEY *ipk; + cert = ssl_zalloc(sizeof(CERT)); if (!cert) SSL_RET(failed1, "ssl_zalloc\n"); - cert->pkey = EVP_PKEY_new(); - if (!cert->pkey) - SSL_RET(failed2, "EVP_PKEY_new\n"); + if (ic) { + ipk = ic->pkey; + ix = ic->x509; + } else { + ipk = NULL; + ix = NULL; + } - cert->x509 = X509_new(); + cert->pkey = __EVP_PKEY_new(ipk); + if (!cert->pkey) + SSL_RET(failed2, "__EVP_PKEY_new\n"); + + cert->x509 = __X509_new(ix); if (!cert->x509) - SSL_RET(failed3, "X509_new\n"); + SSL_RET(failed3, "__X509_new\n"); return cert; @@ -47,6 +58,14 @@ failed1: return NULL; } +/** + * @brief create a certification object include private key object + */ +CERT *ssl_cert_new(void) +{ + return __ssl_cert_new(NULL); +} + /** * @brief free a certification object */ diff --git a/components/openssl/library/ssl_lib.c b/components/openssl/library/ssl_lib.c index 06bbe270c5..b82d54cd26 100644 --- a/components/openssl/library/ssl_lib.c +++ b/components/openssl/library/ssl_lib.c @@ -158,11 +158,11 @@ SSL_CTX* SSL_CTX_new(const SSL_METHOD *method) CERT *cert; X509 *client_ca; - if (!method) SSL_RET(go_failed1, "method\n"); + if (!method) SSL_RET(go_failed1, "method:NULL\n"); client_ca = X509_new(); if (!client_ca) - SSL_RET(go_failed1, "sk_X509_NAME_new_null\n"); + SSL_RET(go_failed1, "X509_new\n"); cert = ssl_cert_new(); if (!cert) @@ -170,7 +170,7 @@ SSL_CTX* SSL_CTX_new(const SSL_METHOD *method) ctx = (SSL_CTX *)ssl_zalloc(sizeof(SSL_CTX)); if (!ctx) - SSL_RET(go_failed3, "ssl_ctx_new:ctx\n"); + SSL_RET(go_failed3, "ssl_zalloc:ctx\n"); ctx->method = method; ctx->client_CA = client_ca; @@ -244,15 +244,15 @@ SSL *SSL_new(SSL_CTX *ctx) ssl->session = SSL_SESSION_new(); if (!ssl->session) - SSL_RET(failed2, "ssl_zalloc\n"); + SSL_RET(failed2, "SSL_SESSION_new\n"); - ssl->cert = ssl_cert_new(); + ssl->cert = __ssl_cert_new(ctx->cert); if (!ssl->cert) - SSL_RET(failed3, "ssl_cert_new\n"); + SSL_RET(failed3, "__ssl_cert_new\n"); - ssl->client_CA = X509_new(); + ssl->client_CA = __X509_new(ctx->client_CA); if (!ssl->client_CA) - SSL_RET(failed4, "ssl_cert_new\n"); + SSL_RET(failed4, "__X509_new\n"); ssl->ctx = ctx; ssl->method = ctx->method; diff --git a/components/openssl/library/ssl_methods.c b/components/openssl/library/ssl_methods.c index 042d670ab9..e363b5e46d 100644 --- a/components/openssl/library/ssl_methods.c +++ b/components/openssl/library/ssl_methods.c @@ -72,11 +72,11 @@ IMPLEMENT_SSL_METHOD(SSL3_VERSION, -1, TLS_method_func, SSLv3_method); */ IMPLEMENT_X509_METHOD(X509_method, x509_pm_new, x509_pm_free, - x509_pm_load, x509_pm_unload); + x509_pm_load); /** * @brief get private key object method */ IMPLEMENT_PKEY_METHOD(EVP_PKEY_method, pkey_pm_new, pkey_pm_free, - pkey_pm_load, pkey_pm_unload); + pkey_pm_load); diff --git a/components/openssl/library/ssl_pkey.c b/components/openssl/library/ssl_pkey.c index 6891b69eb3..573b1f2e8f 100644 --- a/components/openssl/library/ssl_pkey.c +++ b/components/openssl/library/ssl_pkey.c @@ -20,20 +20,24 @@ #include "ssl_port.h" /** - * @brief create a private key object + * @brief create a private key object according to input private key */ -EVP_PKEY* EVP_PKEY_new(void) +EVP_PKEY* __EVP_PKEY_new(EVP_PKEY *ipk) { int ret; EVP_PKEY *pkey; pkey = ssl_zalloc(sizeof(EVP_PKEY)); if (!pkey) - SSL_RET(failed1, "ssl_malloc\n"); + SSL_RET(failed1, "ssl_zalloc\n"); - pkey->method = EVP_PKEY_method(); + if (ipk) { + pkey->method = ipk->method; + } else { + pkey->method = EVP_PKEY_method(); + } - ret = EVP_PKEY_METHOD_CALL(new, pkey); + ret = EVP_PKEY_METHOD_CALL(new, pkey, ipk); if (ret) SSL_RET(failed2, "EVP_PKEY_METHOD_CALL\n"); @@ -45,6 +49,14 @@ failed1: return NULL; } +/** + * @brief create a private key object + */ +EVP_PKEY* EVP_PKEY_new(void) +{ + return __EVP_PKEY_new(NULL); +} + /** * @brief free a private key object */ @@ -105,6 +117,9 @@ int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) SSL_ASSERT(ctx); SSL_ASSERT(pkey); + if (ctx->cert->pkey == pkey) + return 1; + if (ctx->cert->pkey) EVP_PKEY_free(ctx->cert->pkey); @@ -118,12 +133,13 @@ int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) */ int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) { - SSL_ASSERT(ctx); + SSL_ASSERT(ssl); SSL_ASSERT(pkey); - if (!ssl->ca_reload) - ssl->ca_reload = 1; - else + if (ssl->cert->pkey == pkey) + return 1; + + if (ssl->cert->pkey) EVP_PKEY_free(ssl->cert->pkey); ssl->cert->pkey = pkey; @@ -138,20 +154,20 @@ int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const unsigned char *d, long len) { int ret; - EVP_PKEY *pkey; + EVP_PKEY *pk; - pkey = d2i_PrivateKey(0, &ctx->cert->pkey, &d, len); - if (!pkey) + pk = d2i_PrivateKey(0, NULL, &d, len); + if (!pk) SSL_RET(failed1, "d2i_PrivateKey\n"); - ret = SSL_CTX_use_PrivateKey(ctx, pkey); + ret = SSL_CTX_use_PrivateKey(ctx, pk); if (!ret) SSL_RET(failed2, "SSL_CTX_use_PrivateKey\n"); return 1; failed2: - EVP_PKEY_free(pkey); + EVP_PKEY_free(pk); failed1: return 0; } @@ -163,44 +179,20 @@ int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d, long len) { int ret; - int reload; - EVP_PKEY *pkey; - CERT *cert; - CERT *old_cert; + EVP_PKEY *pk; - if (!ssl->crt_reload) { - cert = ssl_cert_new(); - if (!cert) - SSL_RET(failed1, "ssl_cert_new\n"); + pk = d2i_PrivateKey(0, NULL, &d, len); + if (!pk) + SSL_RET(failed1, "d2i_PrivateKey\n"); - old_cert = ssl->cert ; - ssl->cert = cert; - - ssl->crt_reload = 1; - - reload = 1; - } else { - reload = 0; - } - - pkey = d2i_PrivateKey(0, &ssl->cert->pkey, &d, len); - if (!pkey) - SSL_RET(failed2, "d2i_PrivateKey\n"); - - ret = SSL_use_PrivateKey(ssl, pkey); + ret = SSL_use_PrivateKey(ssl, pk); if (!ret) - SSL_RET(failed3, "SSL_use_PrivateKey\n"); + SSL_RET(failed2, "SSL_use_PrivateKey\n"); return 1; -failed3: - EVP_PKEY_free(pkey); failed2: - if (reload) { - ssl->cert = old_cert; - ssl_cert_free(cert); - ssl->crt_reload = 0; - } + EVP_PKEY_free(pk); failed1: return 0; } diff --git a/components/openssl/library/ssl_x509.c b/components/openssl/library/ssl_x509.c index c3fa0b307a..b57cc0dfb9 100644 --- a/components/openssl/library/ssl_x509.c +++ b/components/openssl/library/ssl_x509.c @@ -19,9 +19,9 @@ #include "ssl_port.h" /** - * @brief create a X509 certification object + * @brief create a X509 certification object according to input X509 certification */ -X509* X509_new(void) +X509* __X509_new(X509 *ix) { int ret; X509 *x; @@ -30,9 +30,12 @@ X509* X509_new(void) if (!x) SSL_RET(failed1, "ssl_malloc\n"); - x->method = X509_method(); + if (ix) + x->method = ix->method; + else + x->method = X509_method(); - ret = X509_METHOD_CALL(new, x); + ret = X509_METHOD_CALL(new, x, ix); if (ret) SSL_RET(failed2, "x509_new\n"); @@ -44,6 +47,14 @@ failed1: return NULL; } +/** + * @brief create a X509 certification object + */ +X509* X509_new(void) +{ + return __X509_new(NULL); +} + /** * @brief free a X509 certification object */ @@ -78,7 +89,7 @@ X509* d2i_X509(X509 **cert, const unsigned char *buffer, long len) ret = X509_METHOD_CALL(load, x, buffer, len); if (ret) - SSL_RET(failed2, "X509_METHOD_CALL\n"); + SSL_RET(failed2, "x509_load\n"); return x; @@ -97,8 +108,10 @@ int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) SSL_ASSERT(ctx); SSL_ASSERT(x); - if (ctx->client_CA) - X509_free(ctx->client_CA); + if (ctx->client_CA == x) + return 1; + + X509_free(ctx->client_CA); ctx->client_CA = x; @@ -113,10 +126,10 @@ int SSL_add_client_CA(SSL *ssl, X509 *x) SSL_ASSERT(ssl); SSL_ASSERT(x); - if (!ssl->ca_reload) - ssl->ca_reload = 1; - else - X509_free(ssl->client_CA); + if (ssl->client_CA == x) + return 1; + + X509_free(ssl->client_CA); ssl->client_CA = x; @@ -131,6 +144,11 @@ int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) SSL_ASSERT(ctx); SSL_ASSERT(x); + if (ctx->cert->x509 == x) + return 1; + + X509_free(ctx->cert->x509); + ctx->cert->x509 = x; return 1; @@ -141,9 +159,14 @@ int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) */ int SSL_use_certificate(SSL *ssl, X509 *x) { - SSL_ASSERT(ctx); + SSL_ASSERT(ssl); SSL_ASSERT(x); + if (ssl->cert->x509 == x) + return 1; + + X509_free(ssl->cert->x509); + ssl->cert->x509 = x; return 1; @@ -166,20 +189,20 @@ int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d) { int ret; - X509 *cert; + X509 *x; - cert = d2i_X509(&ctx->cert->x509, d, len); - if (!cert) + x = d2i_X509(NULL, d, len); + if (!x) SSL_RET(failed1, "d2i_X509\n"); - ret = SSL_CTX_use_certificate(ctx, cert); + ret = SSL_CTX_use_certificate(ctx, x); if (!ret) SSL_RET(failed2, "SSL_CTX_use_certificate\n"); return 1; failed2: - X509_free(cert); + X509_free(x); failed1: return 0; } @@ -193,42 +216,20 @@ int SSL_use_certificate_ASN1(SSL *ssl, int len, int ret; int reload; X509 *x; - CERT *cert; - CERT *old_cert; + int m = 0; - if (!ssl->crt_reload) { - cert = ssl_cert_new(); - if (!cert) - SSL_RET(failed1, "ssl_cert_new\n"); - - old_cert = ssl->cert ; - ssl->cert = cert; - - ssl->crt_reload = 1; - - reload = 1; - } else { - reload = 0; - } - - x = d2i_X509(&ssl->cert->x509, d, len); + x = d2i_X509(NULL, d, len); if (!x) - SSL_RET(failed2, "d2i_X509\n"); + SSL_RET(failed1, "d2i_X509\n"); ret = SSL_use_certificate(ssl, x); if (!ret) - SSL_RET(failed3, "SSL_use_certificate\n"); + SSL_RET(failed2, "SSL_use_certificate\n"); return 1; -failed3: - X509_free(x); failed2: - if (reload) { - ssl->cert = old_cert; - ssl_cert_free(cert); - ssl->crt_reload = 0; - } + X509_free(x); failed1: return 0; } diff --git a/components/openssl/platform/ssl_pm.c b/components/openssl/platform/ssl_pm.c index 311c3a4b6f..9f5290cc52 100644 --- a/components/openssl/platform/ssl_pm.c +++ b/components/openssl/platform/ssl_pm.c @@ -78,14 +78,6 @@ int ssl_pm_new(SSL *ssl) const SSL_METHOD *method = ssl->method; - struct x509_pm *ctx_ca = (struct x509_pm *)ssl->ctx->client_CA->x509_pm; - struct x509_pm *ctx_crt = (struct x509_pm *)ssl->ctx->cert->x509->x509_pm; - struct pkey_pm *ctx_pkey = (struct pkey_pm *)ssl->ctx->cert->pkey->pkey_pm; - - struct x509_pm *ssl_ca = (struct x509_pm *)ssl->client_CA->x509_pm; - struct x509_pm *ssl_crt = (struct x509_pm *)ssl->cert->x509->x509_pm; - struct pkey_pm *ssl_pkey = (struct pkey_pm *)ssl->cert->pkey->pkey_pm; - ssl_pm = ssl_zalloc(sizeof(struct ssl_pm)); if (!ssl_pm) SSL_ERR(ret, failed1, "ssl_zalloc\n"); @@ -134,10 +126,6 @@ int ssl_pm_new(SSL *ssl) ssl->ssl_pm = ssl_pm; - ssl_ca->ex_crt = ctx_ca->x509_crt; - ssl_crt->ex_crt = ctx_crt->x509_crt; - ssl_pkey->ex_pkey = ctx_pkey->pkey; - return 0; failed3: @@ -376,7 +364,7 @@ OSSL_HANDSHAKE_STATE ssl_pm_get_state(const SSL *ssl) return state; } -int x509_pm_new(X509 *x) +int x509_pm_new(X509 *x, X509 *m_x) { struct x509_pm *x509_pm; @@ -386,13 +374,19 @@ int x509_pm_new(X509 *x) x->x509_pm = x509_pm; + if (m_x) { + struct x509_pm *m_x509_pm = (struct x509_pm *)m_x->x509_pm; + + x509_pm->ex_crt = m_x509_pm->x509_crt; + } + return 0; failed1: return -1; } -void x509_pm_unload(X509 *x) +void x509_pm_free(X509 *x) { struct x509_pm *x509_pm = (struct x509_pm *)x->x509_pm; @@ -402,11 +396,6 @@ void x509_pm_unload(X509 *x) ssl_free(x509_pm->x509_crt); x509_pm->x509_crt = NULL; } -} - -void x509_pm_free(X509 *x) -{ - x509_pm_unload(x); ssl_free(x->x509_pm); x->x509_pm = NULL; @@ -450,7 +439,7 @@ failed1: return -1; } -int pkey_pm_new(EVP_PKEY *pkey) +int pkey_pm_new(EVP_PKEY *pk, EVP_PKEY *m_pkey) { struct pkey_pm *pkey_pm; @@ -458,14 +447,20 @@ int pkey_pm_new(EVP_PKEY *pkey) if (!pkey_pm) return -1; - pkey->pkey_pm = pkey_pm; + pk->pkey_pm = pkey_pm; + + if (m_pkey) { + struct pkey_pm *m_pkey_pm = (struct pkey_pm *)m_pkey->pkey_pm; + + pkey_pm->ex_pkey = m_pkey_pm->pkey; + } return 0; } -void pkey_pm_unload(EVP_PKEY *pkey) +void pkey_pm_free(EVP_PKEY *pk) { - struct pkey_pm *pkey_pm = (struct pkey_pm *)pkey->pkey_pm; + struct pkey_pm *pkey_pm = (struct pkey_pm *)pk->pkey_pm; if (pkey_pm->pkey) { mbedtls_pk_free(pkey_pm->pkey); @@ -473,21 +468,16 @@ void pkey_pm_unload(EVP_PKEY *pkey) ssl_free(pkey_pm->pkey); pkey_pm->pkey = NULL; } + + ssl_free(pk->pkey_pm); + pk->pkey_pm = NULL; } -void pkey_pm_free(EVP_PKEY *pkey) -{ - pkey_pm_unload(pkey); - - ssl_free(pkey->pkey_pm); - pkey->pkey_pm = NULL; -} - -int pkey_pm_load(EVP_PKEY *pkey, const unsigned char *buffer, int len) +int pkey_pm_load(EVP_PKEY *pk, const unsigned char *buffer, int len) { int ret; unsigned char *load_buf; - struct pkey_pm *pkey_pm = (struct pkey_pm *)pkey->pkey_pm; + struct pkey_pm *pkey_pm = (struct pkey_pm *)pk->pkey_pm; if (!pkey_pm->pkey) { pkey_pm->pkey = ssl_malloc(sizeof(mbedtls_pk_context)); From 3882937427e7cd3fe60ee78ff7b5d583cfb84fec Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Tue, 27 Sep 2016 10:06:24 +0800 Subject: [PATCH 031/343] components/openssl: add debug message and change verifying mode --- components/openssl/include/internal/ssl_dbg.h | 6 ++-- .../openssl/include/internal/ssl_methods.h | 2 ++ .../openssl/include/internal/ssl_x509.h | 24 ++++++++++++++++ components/openssl/library/ssl_lib.c | 6 ++-- components/openssl/library/ssl_methods.c | 1 - components/openssl/library/ssl_pkey.c | 2 -- components/openssl/library/ssl_stack.c | 8 +++--- components/openssl/library/ssl_x509.c | 3 -- components/openssl/platform/ssl_pm.c | 28 ++++++++++--------- 9 files changed, 51 insertions(+), 29 deletions(-) diff --git a/components/openssl/include/internal/ssl_dbg.h b/components/openssl/include/internal/ssl_dbg.h index 27a4bc4db5..d6ae47499e 100644 --- a/components/openssl/include/internal/ssl_dbg.h +++ b/components/openssl/include/internal/ssl_dbg.h @@ -19,10 +19,10 @@ extern "C" { #endif -#define SSL_DEBUG_ENBALE 0 +#define SSL_DEBUG_ENBALE 1 #define SSL_DEBUG_LEVEL 0 -#define SSL_ASSERT_ENABLE 0 -#define SSL_DEBUG_LOCATION_ENABLE 0 +#define SSL_ASSERT_ENABLE 1 +#define SSL_DEBUG_LOCATION_ENABLE 1 #if SSL_DEBUG_ENBALE extern int ets_printf(const char *fmt, ...); diff --git a/components/openssl/include/internal/ssl_methods.h b/components/openssl/include/internal/ssl_methods.h index 9fd9ce9068..7a63b9e949 100644 --- a/components/openssl/include/internal/ssl_methods.h +++ b/components/openssl/include/internal/ssl_methods.h @@ -15,6 +15,8 @@ #ifndef _SSL_METHODS_H_ #define _SSL_METHODS_H_ +#include "ssl_types.h" + #ifdef __cplusplus extern "C" { #endif diff --git a/components/openssl/include/internal/ssl_x509.h b/components/openssl/include/internal/ssl_x509.h index 2c72980b07..b5fea34f1a 100644 --- a/components/openssl/include/internal/ssl_x509.h +++ b/components/openssl/include/internal/ssl_x509.h @@ -63,6 +63,30 @@ X509* d2i_X509(X509 **cert, const unsigned char *buffer, long len); */ void X509_free(X509 *x); +/** + * @brief set SSL context client CA certification + * + * @param ctx - SSL context point + * @param x - X509 certification point + * + * @return result + * 0 : failed + * 1 : OK + */ +int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x); + +/** + * @brief add CA client certification into the SSL + * + * @param ssl - SSL point + * @param x - X509 certification point + * + * @return result + * 0 : failed + * 1 : OK + */ +int SSL_add_client_CA(SSL *ssl, X509 *x); + #ifdef __cplusplus } #endif diff --git a/components/openssl/library/ssl_lib.c b/components/openssl/library/ssl_lib.c index b82d54cd26..267d23f25f 100644 --- a/components/openssl/library/ssl_lib.c +++ b/components/openssl/library/ssl_lib.c @@ -126,11 +126,11 @@ SSL_SESSION* SSL_SESSION_new(void) session = ssl_zalloc(sizeof(SSL_SESSION)); if (!session) - SSL_RET(failed1); + SSL_RET(failed1, "ssl_zalloc\n"); session->peer = X509_new(); if (!session->peer) - SSL_RET(failed2); + SSL_RET(failed2, "X509_new\n"); return session; @@ -1500,7 +1500,7 @@ void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, int (*verify_callback)(int, X509 */ void SSL_set_verify(SSL *ssl, int mode, int (*verify_callback)(int, X509_STORE_CTX *)) { - SSL_ASSERT(ctx); + SSL_ASSERT(ssl); ssl->verify_mode = mode; ssl->verify_callback = verify_callback; diff --git a/components/openssl/library/ssl_methods.c b/components/openssl/library/ssl_methods.c index e363b5e46d..8159511c49 100644 --- a/components/openssl/library/ssl_methods.c +++ b/components/openssl/library/ssl_methods.c @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "ssl_lib.h" #include "ssl_methods.h" #include "ssl_pm.h" diff --git a/components/openssl/library/ssl_pkey.c b/components/openssl/library/ssl_pkey.c index 573b1f2e8f..20debfbcfc 100644 --- a/components/openssl/library/ssl_pkey.c +++ b/components/openssl/library/ssl_pkey.c @@ -12,9 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "ssl_lib.h" #include "ssl_pkey.h" -#include "ssl_cert.h" #include "ssl_methods.h" #include "ssl_dbg.h" #include "ssl_port.h" diff --git a/components/openssl/library/ssl_stack.c b/components/openssl/library/ssl_stack.c index 46e6f7efd8..4ea40e7259 100644 --- a/components/openssl/library/ssl_stack.c +++ b/components/openssl/library/ssl_stack.c @@ -30,13 +30,13 @@ OPENSSL_STACK* OPENSSL_sk_new(OPENSSL_sk_compfunc c) OPENSSL_STACK *stack; char **data; - stack = ssl_malloc(sizeof(OPENSSL_STACK)); + stack = ssl_zalloc(sizeof(OPENSSL_STACK)); if (!stack) - SSL_RET(failed1); + SSL_RET(failed1, "ssl_zalloc\n"); - data = ssl_malloc(sizeof(*data) * MIN_NODES); + data = ssl_zalloc(sizeof(*data) * MIN_NODES); if (!data) - SSL_RET(failed2); + SSL_RET(failed2, "ssl_zalloc\n"); stack->data = data; stack->num_alloc = MIN_NODES; diff --git a/components/openssl/library/ssl_x509.c b/components/openssl/library/ssl_x509.c index b57cc0dfb9..d060419e6a 100644 --- a/components/openssl/library/ssl_x509.c +++ b/components/openssl/library/ssl_x509.c @@ -13,7 +13,6 @@ // limitations under the License. #include "ssl_x509.h" -#include "ssl_cert.h" #include "ssl_methods.h" #include "ssl_dbg.h" #include "ssl_port.h" @@ -214,9 +213,7 @@ int SSL_use_certificate_ASN1(SSL *ssl, int len, const unsigned char *d) { int ret; - int reload; X509 *x; - int m = 0; x = d2i_X509(NULL, d, len); if (!x) diff --git a/components/openssl/platform/ssl_pm.c b/components/openssl/platform/ssl_pm.c index 9f5290cc52..151adbaf81 100644 --- a/components/openssl/platform/ssl_pm.c +++ b/components/openssl/platform/ssl_pm.c @@ -112,7 +112,7 @@ int ssl_pm_new(SSL *ssl) else version = MBEDTLS_SSL_MINOR_VERSION_0; - mbedtls_ssl_conf_max_version(&ssl_pm->conf, MBEDTLS_SSL_MAJOR_VERSION_3, version); + //mbedtls_ssl_conf_max_version(&ssl_pm->conf, MBEDTLS_SSL_MAJOR_VERSION_3, version); mbedtls_ssl_conf_rng(&ssl_pm->conf, mbedtls_ctr_drbg_random, &ssl_pm->ctr_drbg); @@ -169,7 +169,7 @@ static int ssl_pm_reload_crt(SSL *ssl) if (ssl->verify_mode == SSL_VERIFY_PEER) mode = MBEDTLS_SSL_VERIFY_REQUIRED; else if (ssl->verify_mode == SSL_VERIFY_FAIL_IF_NO_PEER_CERT) - mode = MBEDTLS_SSL_VERIFY_NONE; + mode = MBEDTLS_SSL_VERIFY_OPTIONAL; else if (ssl->verify_mode == SSL_VERIFY_CLIENT_ONCE) mode = MBEDTLS_SSL_VERIFY_UNSET; else @@ -370,7 +370,7 @@ int x509_pm_new(X509 *x, X509 *m_x) x509_pm = ssl_zalloc(sizeof(struct x509_pm)); if (!x509_pm) - SSL_RET(failed1); + SSL_RET(failed1, "ssl_zalloc\n"); x->x509_pm = x509_pm; @@ -408,27 +408,28 @@ int x509_pm_load(X509 *x, const unsigned char *buffer, int len) struct x509_pm *x509_pm = (struct x509_pm *)x->x509_pm; if (!x509_pm->x509_crt) { - x509_pm->x509_crt = ssl_malloc(sizeof(mbedtls_x509_crt)); + x509_pm->x509_crt = ssl_zalloc(sizeof(mbedtls_x509_crt)); if (!x509_pm->x509_crt) - SSL_RET(failed1); + SSL_RET(failed1, "ssl_zalloc\n"); } load_buf = ssl_malloc(len + 1); if (!load_buf) - SSL_RET(failed2); + SSL_RET(failed2, "ssl_malloc\n"); ssl_memcpy(load_buf, buffer, len); load_buf[len] = '\0'; + mbedtls_x509_crt_init(x509_pm->x509_crt); + if (x509_pm->x509_crt) mbedtls_x509_crt_free(x509_pm->x509_crt); - mbedtls_x509_crt_init(x509_pm->x509_crt); ret = mbedtls_x509_crt_parse(x509_pm->x509_crt, load_buf, len); ssl_free(load_buf); if (ret) - SSL_RET(failed2); + SSL_RET(failed2, "mbedtls_x509_crt_parse, return [-0x%x]\n", -ret); return 0; @@ -480,27 +481,28 @@ int pkey_pm_load(EVP_PKEY *pk, const unsigned char *buffer, int len) struct pkey_pm *pkey_pm = (struct pkey_pm *)pk->pkey_pm; if (!pkey_pm->pkey) { - pkey_pm->pkey = ssl_malloc(sizeof(mbedtls_pk_context)); + pkey_pm->pkey = ssl_zalloc(sizeof(mbedtls_pk_context)); if (!pkey_pm->pkey) - SSL_RET(failed1); + SSL_RET(failed1, "ssl_zalloc\n"); } load_buf = ssl_malloc(len + 1); if (!load_buf) - SSL_RET(failed2); + SSL_RET(failed2, "ssl_malloc\n"); ssl_memcpy(load_buf, buffer, len); load_buf[len] = '\0'; + mbedtls_pk_init(pkey_pm->pkey); + if (pkey_pm->pkey) mbedtls_pk_free(pkey_pm->pkey); - mbedtls_pk_init(pkey_pm->pkey); ret = mbedtls_pk_parse_key(pkey_pm->pkey, load_buf, len, NULL, 0); ssl_free(load_buf); if (ret) - SSL_RET(failed2); + SSL_RET(failed2, "mbedtls_pk_parse_key, return [-0x%x]\n", -ret); return 0; From 652ddae44f7fe78ab45f7efc524204f2e6ad5ee8 Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Tue, 27 Sep 2016 14:28:39 +0800 Subject: [PATCH 032/343] components/openssl: change low-level certification loading sequence --- components/openssl/platform/ssl_pm.c | 34 ++++++++++++++++++---------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/components/openssl/platform/ssl_pm.c b/components/openssl/platform/ssl_pm.c index 151adbaf81..9df8b6481e 100644 --- a/components/openssl/platform/ssl_pm.c +++ b/components/openssl/platform/ssl_pm.c @@ -25,6 +25,12 @@ #include "mbedtls/error.h" #include "mbedtls/certs.h" +#if 0 + #define DEBUG_LOAD_BUF_STRING(str) SSL_DEBUG(1, "%s\n", str) +#else + #define DEBUG_LOAD_BUF_STRING(str) +#endif + struct ssl_pm { /* local socket file description */ @@ -407,10 +413,13 @@ int x509_pm_load(X509 *x, const unsigned char *buffer, int len) unsigned char *load_buf; struct x509_pm *x509_pm = (struct x509_pm *)x->x509_pm; + if (x509_pm->x509_crt) + mbedtls_x509_crt_free(x509_pm->x509_crt); + if (!x509_pm->x509_crt) { - x509_pm->x509_crt = ssl_zalloc(sizeof(mbedtls_x509_crt)); + x509_pm->x509_crt = ssl_malloc(sizeof(mbedtls_x509_crt)); if (!x509_pm->x509_crt) - SSL_RET(failed1, "ssl_zalloc\n"); + SSL_RET(failed1, "ssl_malloc\n"); } load_buf = ssl_malloc(len + 1); @@ -420,12 +429,11 @@ int x509_pm_load(X509 *x, const unsigned char *buffer, int len) ssl_memcpy(load_buf, buffer, len); load_buf[len] = '\0'; - mbedtls_x509_crt_init(x509_pm->x509_crt); + DEBUG_LOAD_BUF_STRING(load_buf); - if (x509_pm->x509_crt) - mbedtls_x509_crt_free(x509_pm->x509_crt); + mbedtls_x509_crt_init(x509_pm->x509_crt); - ret = mbedtls_x509_crt_parse(x509_pm->x509_crt, load_buf, len); + ret = mbedtls_x509_crt_parse(x509_pm->x509_crt, load_buf, len + 1); ssl_free(load_buf); if (ret) @@ -480,10 +488,13 @@ int pkey_pm_load(EVP_PKEY *pk, const unsigned char *buffer, int len) unsigned char *load_buf; struct pkey_pm *pkey_pm = (struct pkey_pm *)pk->pkey_pm; + if (pkey_pm->pkey) + mbedtls_pk_free(pkey_pm->pkey); + if (!pkey_pm->pkey) { - pkey_pm->pkey = ssl_zalloc(sizeof(mbedtls_pk_context)); + pkey_pm->pkey = ssl_malloc(sizeof(mbedtls_pk_context)); if (!pkey_pm->pkey) - SSL_RET(failed1, "ssl_zalloc\n"); + SSL_RET(failed1, "ssl_malloc\n"); } load_buf = ssl_malloc(len + 1); @@ -493,12 +504,11 @@ int pkey_pm_load(EVP_PKEY *pk, const unsigned char *buffer, int len) ssl_memcpy(load_buf, buffer, len); load_buf[len] = '\0'; + DEBUG_LOAD_BUF_STRING(load_buf); + mbedtls_pk_init(pkey_pm->pkey); - if (pkey_pm->pkey) - mbedtls_pk_free(pkey_pm->pkey); - - ret = mbedtls_pk_parse_key(pkey_pm->pkey, load_buf, len, NULL, 0); + ret = mbedtls_pk_parse_key(pkey_pm->pkey, load_buf, len + 1, NULL, 0); ssl_free(load_buf); if (ret) From 877adaab7a0365ab2a85f9df8073332a38fd9232 Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Tue, 27 Sep 2016 18:50:57 +0800 Subject: [PATCH 033/343] components/openssl: add some function description --- .../openssl/include/internal/ssl_pkey.h | 15 +++++++++++++ .../openssl/include/internal/ssl_x509.h | 14 +++++++++++++ components/openssl/include/openssl/ssl.h | 21 +++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/components/openssl/include/internal/ssl_pkey.h b/components/openssl/include/internal/ssl_pkey.h index f4da041681..e790fcc995 100644 --- a/components/openssl/include/internal/ssl_pkey.h +++ b/components/openssl/include/internal/ssl_pkey.h @@ -64,6 +64,21 @@ EVP_PKEY* d2i_PrivateKey(int type, */ void EVP_PKEY_free(EVP_PKEY *x); +/** + * @brief load private key into the SSL + * + * @param type - private key type + * @param ssl - SSL point + * @param len - data bytes + * @param d - data point + * + * @return result + * 0 : failed + * 1 : OK + */ + int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d, long len); + + #ifdef __cplusplus } #endif diff --git a/components/openssl/include/internal/ssl_x509.h b/components/openssl/include/internal/ssl_x509.h index b5fea34f1a..840fbf1ec1 100644 --- a/components/openssl/include/internal/ssl_x509.h +++ b/components/openssl/include/internal/ssl_x509.h @@ -87,6 +87,20 @@ int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x); */ int SSL_add_client_CA(SSL *ssl, X509 *x); +/** + * @brief load certification into the SSL + * + * @param ssl - SSL point + * @param len - data bytes + * @param d - data point + * + * @return result + * 0 : failed + * 1 : OK + * + */ +int SSL_use_certificate_ASN1(SSL *ssl, int len, const unsigned char *d); + #ifdef __cplusplus } #endif diff --git a/components/openssl/include/openssl/ssl.h b/components/openssl/include/openssl/ssl.h index 3e8e88e67c..1d115214fd 100644 --- a/components/openssl/include/openssl/ssl.h +++ b/components/openssl/include/openssl/ssl.h @@ -21,6 +21,7 @@ #include "platform/ssl_port.h" #include "internal/ssl_x509.h" +#include "internal/ssl_pkey.h" /* { @@ -426,6 +427,26 @@ const char *SSL_get_version(const SSL *ssl); */ int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth); +/** + * @brief get the bytes numbers which are to be read + * + * @param ssl - SSL point + * + * @return bytes number + */ +int SSL_pending(const SSL *ssl); + +/** + * @brief check if SSL want nothing + * + * @param ssl - SSL point + * + * @return result + * 0 : false + * 1 : true + */ +int SSL_want_nothing(const SSL *ssl); + /** * @brief get the SSL context current method * From 6941b5871a73086786191a9d73a21d8c64dbec82 Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Tue, 27 Sep 2016 18:52:31 +0800 Subject: [PATCH 034/343] components/openssl: add OpenSSL APIs description --- components/openssl/OpenSSL_APIs.rst | 688 ++++++++++++++++++++++++++++ 1 file changed, 688 insertions(+) create mode 100644 components/openssl/OpenSSL_APIs.rst diff --git a/components/openssl/OpenSSL_APIs.rst b/components/openssl/OpenSSL_APIs.rst new file mode 100644 index 0000000000..e130d8398b --- /dev/null +++ b/components/openssl/OpenSSL_APIs.rst @@ -0,0 +1,688 @@ +OpenSSL APIs +====================== + +/** + * @brief create the target SSL context client method + * + * @param none + * + * @return the SSLV2.3 version SSL context client method + */ +const SSL_METHOD* SSLv23_client_method(void); + + +/** + * @brief create the target SSL context client method + * + * @param none + * + * @return the TLSV1.0 version SSL context client method + */ +const SSL_METHOD* TLSv1_client_method(void); + + +/** + * @brief create the target SSL context client method + * + * @param none + * + * @return the SSLV1.0 version SSL context client method + */ +const SSL_METHOD* SSLv3_client_method(void); + + +/** + * @brief create the target SSL context client method + * + * @param none + * + * @return the TLSV1.1 version SSL context client method + */ +const SSL_METHOD* TLSv1_1_client_method(void); + + +/** + * @brief create the target SSL context client method + * + * @param none + * + * @return the TLSV1.2 version SSL context client method + */ +const SSL_METHOD* TLSv1_2_client_method(void); + + +/** + * @brief create the target SSL context server method + * + * @param none + * + * @return the SSLV2.3 version SSL context server method + */ +const SSL_METHOD* SSLv23_server_method(void); + +/** + * @brief create the target SSL context server method + * + * @param none + * + * @return the TLSV1.1 version SSL context server method + */ +const SSL_METHOD* TLSv1_1_server_method(void); + +/** + * @brief create the target SSL context server method + * + * @param none + * + * @return the TLSV1.2 version SSL context server method + */ +const SSL_METHOD* TLSv1_2_server_method(void); + +/** + * @brief create the target SSL context server method + * + * @param none + * + * @return the TLSV1.0 version SSL context server method + */ +const SSL_METHOD* TLSv1_server_method(void); + +/** + * @brief create the target SSL context server method + * + * @param none + * + * @return the SSLV3.0 version SSL context server method + */ +const SSL_METHOD* SSLv3_server_method(void); + +/** + * @brief create a SSL context + * + * @param method - the SSL context method point + * + * @return the context point + */ +SSL_CTX* SSL_CTX_new(const SSL_METHOD *method); + +/** + * @brief free a SSL context + * + * @param method - the SSL context point + * + * @return none + */ +void SSL_CTX_free(SSL_CTX *ctx); + +/** + * @brief set the SSL context version + * + * @param ctx - SSL context point + * @param meth - SSL method point + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth); + +/** + * @brief get the SSL context current method + * + * @param ctx - SSL context point + * + * @return the SSL context current method + */ +const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx); + +/** + * @brief create a SSL + * + * @param ctx - the SSL context point + * + * @return the SSL point + */ +SSL* SSL_new(SSL_CTX *ctx); + +/** + * @brief free the SSL + * + * @param ssl - the SSL point + * + * @return none + */ +void SSL_free(SSL *ssl); + +/** + * @brief perform the SSL handshake + * + * @param ssl - SSL point + * + * @return result + * 1 : OK + * 0 : failed + * -1 : a error catch + */ +int SSL_do_handshake(SSL *ssl); + +/** + * @brief connect to the remote SSL server + * + * @param ssl - the SSL point + * + * @return result + * 1 : OK + * -1 : failed + */ +int SSL_connect(SSL *ssl); + +/** + * @brief accept the remote connection + * + * @param ssl - the SSL point + * + * @return result + * 1 : OK + * -1 : failed + */ +int SSL_accept(SSL *ssl); + +/** + * @brief shutdown the connection + * + * @param ssl - the SSL point + * + * @return result + * 1 : OK + * 0 : shutdown is not finished + * -1 : an error catch + */ +int SSL_shutdown(SSL *ssl); + +/** + * @brief reset the SSL + * + * @param ssl - SSL point + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_clear(SSL *ssl); + +/** + * @brief read data from to remote + * + * @param ssl - the SSL point which has been connected + * @param buffer - the received data buffer point + * @param len - the received data length + * + * @return result + * > 0 : OK, and return received data bytes + * = 0 : connection is closed + * < 0 : an error catch + */ +int SSL_read(SSL *ssl, void *buffer, int len); + +/** + * @brief send the data to remote + * + * @param ssl - the SSL point which has been connected + * @param buffer - the send data buffer point + * @param len - the send data length + * + * @return result + * > 0 : OK, and return sent data bytes + * = 0 : connection is closed + * < 0 : an error catch + */ +int SSL_write(SSL *ssl, const void *buffer, int len); + +/** + * @brief get SSL context of the SSL + * + * @param ssl - SSL point + * + * @return SSL context + */ +SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl); + +/** + * @brief get SSL shutdown mode + * + * @param ssl - SSL point + * + * @return shutdown mode + */ +int SSL_get_shutdown(const SSL *ssl); + +/** + * @brief set SSL shutdown mode + * + * @param ssl - SSL point + * @param mode - shutdown mode + * + * @return none + */ +void SSL_set_shutdown(SSL *ssl, int mode); + +/** + * @brief get the SSL current method + * + * @param ssl - SSL point + * + * @return the SSL current method + */ +const SSL_METHOD *SSL_get_ssl_method(SSL *ssl); + +/** + * @brief set the SSL method + * + * @param ssl - SSL point + * @param meth - SSL method point + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_set_ssl_method(SSL *ssl, const SSL_METHOD *method); + +/** + * @brief get the bytes numbers which are to be read + * + * @param ssl - SSL point + * + * @return bytes number + */ +int SSL_pending(const SSL *ssl); + +/** + * @brief check if some data can be read + * + * @param ssl - SSL point + * + * @return + * 1 : there are bytes to be read + * 0 : no data + */ +int SSL_has_pending(const SSL *ssl); + +/** + * @brief get the socket handle of the SSL + * + * @param ssl - SSL point + * + * @return result + * >= 0 : yes, and return socket handle + * < 0 : a error catch + */ +int SSL_get_fd(const SSL *ssl); + +/** + * @brief get the read only socket handle of the SSL + * + * @param ssl - SSL point + * + * @return result + * >= 0 : yes, and return socket handle + * < 0 : a error catch + */ +int SSL_get_rfd(const SSL *ssl); + +/** + * @brief get the write only socket handle of the SSL + * + * @param ssl - SSL point + * + * @return result + * >= 0 : yes, and return socket handle + * < 0 : a error catch + */ +int SSL_get_wfd(const SSL *ssl); + +/** + * @brief bind the socket file description into the SSL + * + * @param ssl - the SSL point + * @param fd - socket handle + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_set_fd(SSL *ssl, int fd); + +/** + * @brief bind the read only socket file description into the SSL + * + * @param ssl - the SSL point + * @param fd - socket handle + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_set_rfd(SSL *ssl, int fd); + +/** + * @brief bind the write only socket file description into the SSL + * + * @param ssl - the SSL point + * @param fd - socket handle + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_set_wfd(SSL *ssl, int fd); + +/** + * @brief get SSL version + * + * @param ssl - SSL point + * + * @return SSL version + */ +int SSL_version(const SSL *ssl); + +/** + * @brief get the SSL current version + * + * @param ssl - SSL point + * + * @return the version string + */ +const char *SSL_get_version(const SSL *ssl); + +/** + * @brief get the SSL state + * + * @param ssl - SSL point + * + * @return SSL state + */ +OSSL_HANDSHAKE_STATE SSL_get_state(const SSL *ssl); + +/** + * @brief get alert description string + * + * @param value - alert value + * + * @return alert description string + */ +const char *SSL_alert_desc_string(int value); + +/** + * @brief get alert description long string + * + * @param value - alert value + * + * @return alert description long string + */ +const char *SSL_alert_desc_string_long(int value); + +/** + * @brief get alert type string + * + * @param value - alert value + * + * @return alert type string + */ +const char *SSL_alert_type_string(int value); + +/** + * @brief get alert type long string + * + * @param value - alert value + * + * @return alert type long string + */ +const char *SSL_alert_type_string_long(int value); + +/** + * @brief get the state string where SSL is reading + * + * @param ssl - SSL point + * + * @return state string + */ +const char *SSL_rstate_string(SSL *ssl); + +/** + * @brief get the statement long string where SSL is reading + * + * @param ssl - SSL point + * + * @return statement long string + */ +const char *SSL_rstate_string_long(SSL *ssl); + +/** + * @brief get SSL statement string + * + * @param ssl - SSL point + * + * @return SSL statement string + */ +char *SSL_state_string(const SSL *ssl); + +/** + * @brief get SSL statement long string + * + * @param ssl - SSL point + * + * @return SSL statement long string + */ +char *SSL_state_string_long(const SSL *ssl); + +/** + * @brief get SSL error code + * + * @param ssl - SSL point + * @param ret_code - SSL return code + * + * @return SSL error number + */ +int SSL_get_error(const SSL *ssl, int ret_code); + +/** + * @brief load a character certification context into system context. If '*cert' is pointed to the + * certification, then load certification into it. Or create a new X509 certification object + * + * @param cert - a point pointed to X509 certification + * @param buffer - a point pointed to the certification context memory point + * @param length - certification bytes + * + * @return X509 certification object point + */ +X509* d2i_X509(X509 **cert, const unsigned char *buffer, long len); + +/** + * @brief add CA client certification into the SSL + * + * @param ssl - SSL point + * @param x - CA certification point + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_add_client_CA(SSL *ssl, X509 *x); + +/** + * @brief add CA client certification into the SSL context + * + * @param ctx - SSL context point + * @param x - CA certification point + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x); + +/** + * @brief get the SSL certification point + * + * @param ssl - SSL point + * + * @return SSL certification point + */ +X509 *SSL_get_certificate(const SSL *ssl); + +/** + * @brief get the verifying result of the SSL certification + * + * @param ssl - the SSL point + * + * @return the result of verifying + */ +long SSL_get_verify_result(const SSL *ssl); + +/** + * @brief These functions load the certification into the SSL_CTX or SSL object + * + * @param ctx - the SSL context point + * @param pkey - certification object point + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x); + +/** + * @brief load the ASN1 certification into SSL context + * + * @param ctx - SSL context point + * @param len - certification length + * @param d - data point + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d); + +/** + * @brief These functions load the private key into the SSL_CTX or SSL object + * + * @param ctx - the SSL context point + * @param pkey - private key object point + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey); + +/** + * @brief load the ASN1 private key into SSL context + * + * @param ctx - SSL context point + * @param d - data point + * @param len - private key length + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, const unsigned char *d, long len); + +/** + * @brief load the RSA ASN1 private key into SSL context + * + * @param ctx - SSL context point + * @param d - data point + * @param len - RSA private key length + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len); + +/** + * @brief load certification into the SSL + * + * @param ssl - SSL point + * @param len - data bytes + * @param d - data point + * + * @return result + * 0 : failed + * 1 : OK + * + */ +int SSL_use_certificate_ASN1(SSL *ssl, int len, const unsigned char *d); + +/** + * @brief get peer certification + * + * @param ssl - SSL point + * + * @return certification + */ +X509 *SSL_get_peer_certificate(const SSL *ssl); + +/** + * @brief set the SSL context read buffer length + * + * @param ctx - SSL context point + * @param len - read buffer length + * + * @return none + */ +void SSL_CTX_set_default_read_buffer_len(SSL_CTX *ctx, size_t len); + +/** + * @brief set the SSL read buffer length + * + * @param ssl - SSL point + * @param len - read buffer length + * + * @return none + */ +void SSL_set_default_read_buffer_len(SSL *ssl, size_t len); + +/** + * @brief get the SSL specifical statement + * + * @param ssl - SSL point + * + * @return specifical statement + */ +int SSL_want(const SSL *ssl); + +/** + * @brief check if SSL want nothing + * + * @param ssl - SSL point + * + * @return result + * 0 : false + * 1 : true + */ +int SSL_want_nothing(const SSL *ssl); + +/** + * @brief check if SSL want to read + * + * @param ssl - SSL point + * + * @return result + * 0 : false + * 1 : true + */ +int SSL_want_read(const SSL *ssl); + +/** + * @brief check if SSL want to write + * + * @param ssl - SSL point + * + * @return result + * 0 : false + * 1 : true + */ +int SSL_want_write(const SSL *ssl); From 9e20d31f898ef561c908d3db14887a8e68dd9bb4 Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Tue, 27 Sep 2016 19:06:07 +0800 Subject: [PATCH 035/343] components/openssl: fix extra certification loading --- components/openssl/platform/ssl_pm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/openssl/platform/ssl_pm.c b/components/openssl/platform/ssl_pm.c index 9df8b6481e..4bc631382f 100644 --- a/components/openssl/platform/ssl_pm.c +++ b/components/openssl/platform/ssl_pm.c @@ -186,7 +186,7 @@ static int ssl_pm_reload_crt(SSL *ssl) if (ca_pm->x509_crt) { mbedtls_ssl_conf_ca_chain(&ssl_pm->conf, ca_pm->x509_crt, NULL); } else if (ca_pm->ex_crt) { - mbedtls_ssl_conf_ca_chain(&ssl_pm->conf, ca_pm->x509_crt, NULL); + mbedtls_ssl_conf_ca_chain(&ssl_pm->conf, ca_pm->ex_crt, NULL); } if (crt_pm->x509_crt && pkey_pm->pkey) { From 9c4e43a3a5becc441642edbbbf06b90a06bfa5eb Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Wed, 28 Sep 2016 16:46:27 +0800 Subject: [PATCH 036/343] components/openssl: optimize the OpenSSL APIs brief document 1. change document name 2. change function introduction template --- components/openssl/OpenSSL-APIs.rst | 1478 +++++++++++++++++++++++++++ components/openssl/OpenSSL_APIs.rst | 688 ------------- 2 files changed, 1478 insertions(+), 688 deletions(-) create mode 100644 components/openssl/OpenSSL-APIs.rst delete mode 100644 components/openssl/OpenSSL_APIs.rst diff --git a/components/openssl/OpenSSL-APIs.rst b/components/openssl/OpenSSL-APIs.rst new file mode 100644 index 0000000000..ff91d2ebb7 --- /dev/null +++ b/components/openssl/OpenSSL-APIs.rst @@ -0,0 +1,1478 @@ +OpenSSL-APIs +====================== + +Chapter 1. SSL Context Method Create +Chapter 2. SSL Context Fucntion +Chapter 3. SSL Fucntion +Chapter 4. SSL X509 Certification and Private Key Function + +====================== +Chapter 1. SSL Context Method Create + +1.1 const SSL_METHOD* SSLv23_client_method(void); + + Arguments : none + + Return : SSLV2 and 3 version SSL context client method point + + Description : create the target SSL context method + + Example : + + void example(void) + { + const SSL_METHOD *method = SSLv23_client_method(); + + ... + } + + +1.2 const SSL_METHOD* TLSv1_client_method(void); + + Arguments : none + + Return : TLSV1.0 version SSL context client method point + + Description : create the target SSL context method + + Example : + + void example(void) + { + const SSL_METHOD *method = TLSv1_client_method(); + + ... + } + + +1.3 const SSL_METHOD* SSLv3_client_method(void); + + Arguments : none + + Return : SSLV3.0 version SSL context client method point + + Description : create the target SSL context method + + Example : + + void example(void) + { + const SSL_METHOD *method = SSLv3_client_method(); + + ... + } + + +1.4 const SSL_METHOD* TLSv1_1_client_method(void); + + Arguments : none + + Return : TLSV1.1 version SSL context client method point + + Description : create the target SSL context method + + Example : + + void example(void) + { + const SSL_METHOD *method = TLSv1_1_client_method(); + + ... + } + + +1.5 const SSL_METHOD* TLSv1_2_client_method(void); + + Arguments : none + + Return : TLSV1.2 version SSL context client method point + + Description : create the target SSL context method + + Example : + + void example(void) + { + const SSL_METHOD *method = TLSv1_2_client_method(); + + ... + } + + +1.6 const SSL_METHOD* SSLv23_server_method(void); + + Arguments : none + + Return : SSLV2 and 3 version SSL context server method point + + Description : create the target SSL context method + + Example : + + void example(void) + { + const SSL_METHOD *method = SSLv23_server_method(); + + ... + } + + +1.7 const SSL_METHOD* TLSv1_1_server_method(void); + + Arguments : none + + Return : TLSV1.1 version SSL context server method point + + Description : create the target SSL context method + + Example : + + void example(void) + { + const SSL_METHOD *method = TLSv1_1_server_method(); + + ... + } + + +1.8 const SSL_METHOD* TLSv1_2_server_method(void); + + Arguments : none + + Return : TLSV1.2 version SSL context server method point + + Description : create the target SSL context method + + Example : + + void example(void) + { + const SSL_METHOD *method = TLSv1_2_server_method(); + + ... + } + + +1.9 const SSL_METHOD* TLSv1_server_method(void); + + Arguments : none + + Return : TLSV1.0 version SSL context server method point + + Description : create the target SSL context method + + Example : + + void example(void) + { + const SSL_METHOD *method = TLSv1_server_method(); + + ... + } + + +1.10 const SSL_METHOD* SSLv3_server_method(void); + + Arguments : none + + Return : SSLV3.0 version SSL context server method point + + Description : create the target SSL context method + + Example : + + void example(void) + { + const SSL_METHOD *method = SSLv3_server_method(); + + ... + } + + +====================== +Chapter 2. SSL Context Fucntion + +2.1 SSL_CTX* SSL_CTX_new(const SSL_METHOD *method); + + Arguments : method - the SSL context method point + + Return : context point + + Description : create a SSL context + + Example : + + void example(void) + { + SSL_CTX *ctx = SSL_CTX_new(SSLv3_server_method()); + + ... + } + + +2.2 void SSL_CTX_free(SSL_CTX *ctx); + + Arguments : ctx - the SSL context point + + Return : none + + Description : free a SSL context + + Example : + + void example(void) + { + SSL_CTX *ctx; + + ... ... + + SSL_CTX_free(ctx); + } + + +2.3 int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth); + + Arguments : ctx - SSL context point + meth - SSL method point + + Return : result + 1 : OK + 0 : failed + + Description : set the SSL context version + + Example : + + void example(void) + { + SSL_CTX *ctx; + const SSL_METHOD *meth; + + ... ... + + SSL_CTX_set_ssl_version(ctx, meth); + } + + +2.4 const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx); + + Arguments : ctx - SSL context point + + Return : SSL context method + + Description : get the SSL context method + + Example : + + void example(void) + { + const SSL_METHOD *method; + SSL_CTX *ctx; + + ... ... + + method = SSL_CTX_get_ssl_method(ctx); + } + + +====================== +Chapter 3. SSL Fucntion + +3.1 SSL* SSL_new(SSL_CTX *ctx); + + Arguments : ctx - SSL context point + + Return : SSL method + + Description : create a SSL + + Example : + + void example(void) + { + SSL *ssl; + SSL_CTX *ctx; + + ... ... + + ssl = SSL_new(ctx); + } + + +3.2 void SSL_free(SSL *ssl); + + Arguments : ssl - SSL point + + Return : none + + Description : free SSL + + Example : + + void example(void) + { + SSL *ssl; + + ... ... + + SSL_free(ssl); + } + + +3.3 int SSL_do_handshake(SSL *ssl); + + Arguments : ssl - SSL point + + Return : result + 1 : OK + 0 : failed, connect is close by remote + -1 : a error catch + + Description : perform the SSL handshake + + Example : + + void example(void) + { + SSL *ssl; + int ret; + + ... ... + + ret = SSL_do_handshake(ssl); + } + + +3.4 int SSL_connect(SSL *ssl); + + Arguments : ssl - SSL point + + Return : result + 1 : OK + 0 : failed, connect is close by remote + -1 : a error catch + + Description : connect to the remote SSL server + + Example : + + void example(void) + { + SSL *ssl; + int ret; + + ... ... + + ret = SSL_connect(ssl); + } + + +3.5 int SSL_accept(SSL *ssl); + + Arguments : ssl - SSL point + + Return : result + 1 : OK + 0 : failed, connect is close by remote + -1 : a error catch + + Description : accept the remote connection + + Example : + + void example(void) + { + SSL *ssl; + int ret; + + ... ... + + ret = SSL_accept(ssl); + } + + +3.6 int SSL_shutdown(SSL *ssl); + + Arguments : ssl - SSL point + + Return : result + 1 : OK + 0 : failed, connect is close by remote + -1 : a error catch + + Description : shutdown the connection + + Example : + + void example(void) + { + SSL *ssl; + int ret; + + ... ... + + ret = SSL_shutdown(ssl); + } + + +3.7 int SSL_clear(SSL *ssl); + + Arguments : ssl - SSL point + + Return : result + 1 : OK + 0 : failed + + Description : shutdown the connection + + Example : + + void example(void) + { + SSL *ssl; + int ret; + + ... ... + + ret = SSL_clear(ssl); + } + + +3.8 int SSL_read(SSL *ssl, void *buffer, int len); + + Arguments : ssl - point + buffer - data buffer point + len - data length + + Return : result + > 0 : OK, and return received data bytes + = 0 : no data received or connection is closed + < 0 : an error catch + + Description : read data from remote + + Example : + + void example(void) + { + SSL *ssl; + char *buf; + int len; + int ret; + + ... ... + + ret = SSL_read(ssl, buf, len); + } + +3.9 int SSL_write(SSL *ssl, const void *buffer, int len); + + Arguments : ssl - SSL point + buffer - data buffer point + len - data length + + Return : result + > 0 : OK, and return received data bytes + = 0 : no data sent or connection is closed + < 0 : an error catch + + Description : send the data to remote + + Example : + + void example(void) + { + SSL *ssl; + char *buf; + int len; + int ret; + + ... ... + + ret = SSL_write(ssl, buf, len); + } + + +3.10 SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl); + + Arguments : ssl - SSL point + + Return : SSL context + + Description : get SSL context of the SSL + + Example : + + void example(void) + { + SSL *ssl; + SSL_CTX *ctx; + + ... ... + + ctx = SSL_get_SSL_CTX(ssl); + } + + +3.11 int SSL_get_shutdown(const SSL *ssl); + + Arguments : ssl - SSL point + + Return : shutdown mode + + Description : get SSL shutdown mode + + Example : + + void example(void) + { + SSL *ssl; + int mode; + + ... ... + + mode = SSL_get_SSL_CTX(ssl); + } + + +3.12 void SSL_set_shutdown(SSL *ssl, int mode); + + Arguments : ssl - SSL point + + Return : shutdown mode + + Description : set SSL shutdown mode + + Example : + + void example(void) + { + SSL *ssl; + int mode = 0; + + ... ... + + SSL_set_shutdown(ssl, mode); + } + + +3.13 const SSL_METHOD *SSL_get_ssl_method(SSL *ssl); + + Arguments : ssl - SSL point + + Return : SSL method + + Description : set SSL shutdown mode + + Example : + + void example(void) + { + SSL *ssl; + const SSL_METHOD *method; + + ... ... + + method = SSL_get_ssl_method(ssl); + } + + +3.14 int SSL_set_ssl_method(SSL *ssl, const SSL_METHOD *method); + + Arguments : ssl - SSL point + meth - SSL method point + + Return : result + 1 : OK + 0 : failed + + Description : set the SSL method + + Example : + + void example(void) + { + int ret; + SSL *ssl; + const SSL_METHOD *method; + + ... ... + + ret = SSL_set_ssl_method(ssl, method); + } + + +3.15 int SSL_pending(const SSL *ssl); + + Arguments : ssl - SSL point + + Return : data bytes + + Description : get received data bytes + + Example : + + void example(void) + { + int ret; + SSL *ssl; + + ... ... + + ret = SSL_pending(ssl); + } + + +3.16 int SSL_has_pending(const SSL *ssl); + + Arguments : ssl - SSL point + + Return : result + 1 : Yes + 0 : No + + Description : check if data is received + + Example : + + void example(void) + { + int ret; + SSL *ssl; + + ... ... + + ret = SSL_has_pending(ssl); + } + + +3.17 int SSL_get_fd(const SSL *ssl); + + Arguments : ssl - SSL point + + Return : result + >= 0 : socket id + < 0 : a error catch + + Description : get the socket of the SSL + + Example : + + void example(void) + { + int ret; + SSL *ssl; + + ... ... + + ret = SSL_get_fd(ssl); + } + + +3.18 int SSL_get_rfd(const SSL *ssl); + + Arguments : ssl - SSL point + + Return : result + >= 0 : socket id + < 0 : a error catch + + Description : get the read only socket of the SSL + + Example : + + void example(void) + { + int ret; + SSL *ssl; + + ... ... + + ret = SSL_get_rfd(ssl); + } + + +3.19 int SSL_get_wfd(const SSL *ssl); + + Arguments : ssl - SSL point + + Return : result + >= 0 : socket id + < 0 : a error catch + + Description : get the write only socket of the SSL + + Example : + + void example(void) + { + int ret; + SSL *ssl; + + ... ... + + ret = SSL_get_wfd(ssl); + } + + +3.20 int SSL_set_fd(SSL *ssl, int fd); + + Arguments : ssl - SSL point + fd - socket id + + Return : result + 1 : OK + 0 : failed + + Description : set socket to SSL + + Example : + + void example(void) + { + int ret; + SSL *ssl; + int socket; + + ... ... + + ret = SSL_set_fd(ssl, socket); + } + + +3.21 int SSL_set_rfd(SSL *ssl, int fd); + + Arguments : ssl - SSL point + fd - socket id + + Return : result + 1 : OK + 0 : failed + + Description : set read only socket to SSL + + Example : + + void example(void) + { + int ret; + SSL *ssl; + int socket; + + ... ... + + ret = SSL_set_rfd(ssl, socket); + } + + +3.22 int SSL_set_wfd(SSL *ssl, int fd); + + Arguments : ssl - SSL point + fd - socket id + + Return : result + 1 : OK + 0 : failed + + Description : set write only socket to SSL + + Example : + + void example(void) + { + int ret; + SSL *ssl; + int socket; + + ... ... + + ret = SSL_set_wfd(ssl, socket); + } + + +3.23 int SSL_version(const SSL *ssl); + + Arguments : ssl - SSL point + + Return : SSL version + + Description : get SSL version + + Example : + + void example(void) + { + int version; + SSL *ssl; + + ... ... + + version = SSL_version(ssl); + } + + +3.24 const char *SSL_get_version(const SSL *ssl); + + Arguments : ssl - SSL point + + Return : SSL version string + + Description : get the SSL current version string + + Example : + + void example(void) + { + char *version; + SSL *ssl; + + ... ... + + version = SSL_get_version(ssl); + } + + +3.25 OSSL_HANDSHAKE_STATE SSL_get_state(const SSL *ssl); + + Arguments : ssl - SSL point + + Return : SSL state + + Description : get the SSL state + + Example : + + void example(void) + { + OSSL_HANDSHAKE_STATE state; + SSL *ssl; + + ... ... + + state = SSL_get_state(ssl); + } + + +3.26 const char *SSL_alert_desc_string(int value); + + Arguments : value - SSL description + + Return : alert value string + + Description : get alert description string + + Example : + + void example(void) + { + int val; + char *str; + + ... ... + + str = SSL_alert_desc_string(val); + } + + +3.27 const char *SSL_alert_desc_string_long(int value); + + Arguments : value - SSL description + + Return : alert value long string + + Description : get alert description long string + + Example : + + void example(void) + { + int val; + char *str; + + ... ... + + str = SSL_alert_desc_string_long(val); + } + + +3.28 const char *SSL_alert_type_string(int value); + + Arguments : value - SSL type description + + Return : alert type string + + Description : get alert type string + + Example : + + void example(void) + { + int val; + char *str; + + ... ... + + str = SSL_alert_type_string(val); + } + + +3.29 const char *SSL_alert_type_string_long(int value); + + Arguments : value - SSL type description + + Return : alert type long string + + Description : get alert type long string + + Example : + + void example(void) + { + int val; + char *str; + + ... ... + + str = SSL_alert_type_string_long(val); + } + +3.30 const char *SSL_rstate_string(SSL *ssl); + + Arguments : ssl - SSL point + + Return : state string + + Description : get the state string where SSL is reading + + Example : + + void example(void) + { + SSL *ssl; + char *str; + + ... ... + + str = SSL_rstate_string(ssl); + } + + +3.31 const char *SSL_rstate_string_long(SSL *ssl); + + Arguments : ssl - SSL point + + Return : state long string + + Description : get the state long string where SSL is reading + + Example : + + void example(void) + { + SSL *ssl; + char *str; + + ... ... + + str = SSL_rstate_string_long(ssl); + } + + +3.32 char *SSL_state_string(const SSL *ssl); + + Arguments : ssl - SSL point + + Return : state string + + Description : get the state string + + Example : + + void example(void) + { + SSL *ssl; + char *str; + + ... ... + + str = SSL_state_string(ssl); + } + + +3.33 char *SSL_state_string_long(const SSL *ssl); + + Arguments : ssl - SSL point + + Return : state long string + + Description : get the state long string + + Example : + + void example(void) + { + SSL *ssl; + char *str; + + ... ... + + str = SSL_state_string(ssl); + } + + +3.34 int SSL_get_error(const SSL *ssl, int ret_code); + + Arguments : ssl - SSL point + ret_code - SSL return code + + Return : SSL error number + + Description : get SSL error code + + Example : + + void example(void) + { + SSL *ssl; + int ret; + int err; + + ... ... + + err = SSL_get_error(ssl, ret); + } + +3.35 void SSL_CTX_set_default_read_buffer_len(SSL_CTX *ctx, size_t len); + + Arguments : ctx - SSL context point + len - read buffer length + + Return : none + + Description : set the SSL context read buffer length + + Example : + + void example(void) + { + SSL_CTX *ctx; + size_t len; + + ... ... + + SSL_CTX_set_default_read_buffer_len(ctx, len); + } + + +3.36 void SSL_set_default_read_buffer_len(SSL *ssl, size_t len); + + Arguments : ssl - SSL point + len - read buffer length + + Return : none + + Description : set the SSL read buffer length + + Example : + + void example(void) + { + SSL *ssl; + size_t len; + + ... ... + + SSL_set_default_read_buffer_len(ctx, len); + } + + +3.37 int SSL_want(const SSL *ssl); + + Arguments : ssl - SSL point + + Return : specifical statement + + Description : get the SSL specifical statement + + Example : + + void example(void) + { + SSL *ssl; + int state; + + ... ... + + state = SSL_want(ssl); + } + + +3.38 int SSL_want_nothing(const SSL *ssl); + + Arguments : ssl - SSL point + + Return : result + 0 : false + 1 : true + + Description : check if SSL want nothing + + Example : + + void example(void) + { + SSL *ssl; + int ret; + + ... ... + + ret = SSL_want(ssl); + } + + +3.39 int SSL_want_read(const SSL *ssl); + + Arguments : ssl - SSL point + + Return : result + 0 : false + 1 : true + + Description : check if SSL want to read + + Example : + + void example(void) + { + SSL *ssl; + int ret; + + ... ... + + ret = SSL_want_read(ssl); + } + + +3.40 int SSL_want_write(const SSL *ssl); + + Arguments : ssl - SSL point + + Return : result + 0 : false + 1 : true + + Description : check if SSL want to write + + Example : + + void example(void) + { + SSL *ssl; + int ret; + + ... ... + + ret = SSL_want_write(ssl); + } + +====================== +Chapter 4. SSL X509 Certification and Private Key Function + +4.1 X509* d2i_X509(X509 **cert, const unsigned char *buffer, long len); + + Arguments : cert - a point pointed to X509 certification + buffer - a point pointed to the certification context memory point + length - certification bytes + + Return : X509 certification object point + + Description : load a character certification context into system context. If '*cert' is pointed to the + certification, then load certification into it. Or create a new X509 certification object + + Example : + + void example(void) + { + X509 *new; + X509 *cert; + unsigned char *buffer; + long len; + ... ... + + new = d2i_X509(&cert, buffer, len); + } + + +4.2 int SSL_add_client_CA(SSL *ssl, X509 *x); + + Arguments : ssl - SSL point + x - CA certification point + + Return : result + 1 : OK + 0 : failed + + Description : add CA client certification into the SSL + + Example : + + void example(void) + { + int ret; + SSL *ssl; + X509 *new; + + ... ... + + ret = SSL_add_client_CA(ssl, new); + } + + +4.3 int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x); + + Arguments : ctx - SSL context point + x - CA certification point + + Return : result + 1 : OK + 0 : failed + + Description : add CA client certification into the SSL context + + Example : + + void example(void) + { + int ret; + SSL_CTX *ctx; + X509 *new; + + ... ... + + ret = SSL_add_clSSL_CTX_add_client_CAient_CA(ctx, new); + } + + +4.4 X509 *SSL_get_certificate(const SSL *ssl); + + Arguments : ssl - SSL point + + Return : SSL certification point + + Description : get the SSL certification point + + Example : + + void example(void) + { + SSL *ssl; + X509 *cert; + + ... ... + + cert = SSL_get_certificate(ssl); + } + + +4.5 long SSL_get_verify_result(const SSL *ssl); + + Arguments : ssl - SSL point + + Return : the result of verifying + + Description : get the verifying result of the SSL certification + + Example : + + void example(void) + { + SSL *ssl; + long ret; + + ... ... + + ret = SSL_get_verify_result(ssl); + } + + +4.6 int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x); + + Arguments : ctx - the SSL context point + pkey - certification object point + + Return : result + 1 : OK + 0 : failed + + Description : load the certification into the SSL_CTX or SSL object + + Example : + + void example(void) + { + int ret; + SSL_CTX *ctx + X509 *new; + + ... ... + + ret = SSL_CTX_use_certificate(ctx, new); + } + + +4.7 int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d); + + Arguments : ctx - SSL context point + len - certification length + d - data point + + Return : result + 1 : OK + 0 : failed + + Description : load the ASN1 certification into SSL context + + Example : + + void example(void) + { + int ret; + SSL_CTX *ctx; + const unsigned char *buf; + int len; + + ... ... + + ret = SSL_CTX_use_certificate_ASN1(ctx, len, buf); + } + + +4.8 int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey); + + Arguments : ctx - SSL context point + pkey - private key object point + + Return : result + 1 : OK + 0 : failed + + Description : load the private key into the context object + + Example : + + void example(void) + { + int ret; + SSL_CTX *ctx; + EVP_PKEY *pkey; + + ... ... + + ret = SSL_CTX_use_PrivateKey(ctx, pkey); + } + + +4.9 int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, const unsigned char *d, long len); + + Arguments : ctx - SSL context point + d - data point + len - private key length + + Return : result + 1 : OK + 0 : failed + + Description : load the ASN1 private key into SSL context + + Example : + + void example(void) + { + int ret; + int pk; + SSL_CTX *ctx; + const unsigned char *buf; + long len; + + ... ... + + ret = SSL_CTX_use_PrivateKey_ASN1(pk, ctx, buf, len); + } + + +4.10 int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len); + + Arguments : ctx - SSL context point + d - data point + len - private key length + + Return : result + 1 : OK + 0 : failed + + Description : load the RSA ASN1 private key into SSL context + + Example : + + void example(void) + { + int ret; + SSL_CTX *ctx; + const unsigned char *buf; + long len; + + ... ... + + ret = SSL_CTX_use_RSAPrivateKey_ASN1(ctx, buf, len); + } + + +4.11 int SSL_use_certificate_ASN1(SSL *ssl, int len, const unsigned char *d); + + Arguments : ssl - SSL point + len - data bytes + d - data point + + Return : result + 1 : OK + 0 : failed + + Description : load certification into the SSL + + Example : + + void example(void) + { + int ret; + SSL *ssl; + const unsigned char *buf; + long len; + + ... ... + + ret = SSL_use_certificate_ASN1(ssl, len, buf); + } + + +4.12 X509 *SSL_get_peer_certificate(const SSL *ssl); + + Arguments : ssl - SSL point + + Return : peer certification + + Description : get peer certification + + Example : + + void example(void) + { + SSL *ssl; + X509 *peer; + + ... ... + + peer = SSL_get_peer_certificate(ssl); + } + +====================== +END \ No newline at end of file diff --git a/components/openssl/OpenSSL_APIs.rst b/components/openssl/OpenSSL_APIs.rst deleted file mode 100644 index e130d8398b..0000000000 --- a/components/openssl/OpenSSL_APIs.rst +++ /dev/null @@ -1,688 +0,0 @@ -OpenSSL APIs -====================== - -/** - * @brief create the target SSL context client method - * - * @param none - * - * @return the SSLV2.3 version SSL context client method - */ -const SSL_METHOD* SSLv23_client_method(void); - - -/** - * @brief create the target SSL context client method - * - * @param none - * - * @return the TLSV1.0 version SSL context client method - */ -const SSL_METHOD* TLSv1_client_method(void); - - -/** - * @brief create the target SSL context client method - * - * @param none - * - * @return the SSLV1.0 version SSL context client method - */ -const SSL_METHOD* SSLv3_client_method(void); - - -/** - * @brief create the target SSL context client method - * - * @param none - * - * @return the TLSV1.1 version SSL context client method - */ -const SSL_METHOD* TLSv1_1_client_method(void); - - -/** - * @brief create the target SSL context client method - * - * @param none - * - * @return the TLSV1.2 version SSL context client method - */ -const SSL_METHOD* TLSv1_2_client_method(void); - - -/** - * @brief create the target SSL context server method - * - * @param none - * - * @return the SSLV2.3 version SSL context server method - */ -const SSL_METHOD* SSLv23_server_method(void); - -/** - * @brief create the target SSL context server method - * - * @param none - * - * @return the TLSV1.1 version SSL context server method - */ -const SSL_METHOD* TLSv1_1_server_method(void); - -/** - * @brief create the target SSL context server method - * - * @param none - * - * @return the TLSV1.2 version SSL context server method - */ -const SSL_METHOD* TLSv1_2_server_method(void); - -/** - * @brief create the target SSL context server method - * - * @param none - * - * @return the TLSV1.0 version SSL context server method - */ -const SSL_METHOD* TLSv1_server_method(void); - -/** - * @brief create the target SSL context server method - * - * @param none - * - * @return the SSLV3.0 version SSL context server method - */ -const SSL_METHOD* SSLv3_server_method(void); - -/** - * @brief create a SSL context - * - * @param method - the SSL context method point - * - * @return the context point - */ -SSL_CTX* SSL_CTX_new(const SSL_METHOD *method); - -/** - * @brief free a SSL context - * - * @param method - the SSL context point - * - * @return none - */ -void SSL_CTX_free(SSL_CTX *ctx); - -/** - * @brief set the SSL context version - * - * @param ctx - SSL context point - * @param meth - SSL method point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth); - -/** - * @brief get the SSL context current method - * - * @param ctx - SSL context point - * - * @return the SSL context current method - */ -const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx); - -/** - * @brief create a SSL - * - * @param ctx - the SSL context point - * - * @return the SSL point - */ -SSL* SSL_new(SSL_CTX *ctx); - -/** - * @brief free the SSL - * - * @param ssl - the SSL point - * - * @return none - */ -void SSL_free(SSL *ssl); - -/** - * @brief perform the SSL handshake - * - * @param ssl - SSL point - * - * @return result - * 1 : OK - * 0 : failed - * -1 : a error catch - */ -int SSL_do_handshake(SSL *ssl); - -/** - * @brief connect to the remote SSL server - * - * @param ssl - the SSL point - * - * @return result - * 1 : OK - * -1 : failed - */ -int SSL_connect(SSL *ssl); - -/** - * @brief accept the remote connection - * - * @param ssl - the SSL point - * - * @return result - * 1 : OK - * -1 : failed - */ -int SSL_accept(SSL *ssl); - -/** - * @brief shutdown the connection - * - * @param ssl - the SSL point - * - * @return result - * 1 : OK - * 0 : shutdown is not finished - * -1 : an error catch - */ -int SSL_shutdown(SSL *ssl); - -/** - * @brief reset the SSL - * - * @param ssl - SSL point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_clear(SSL *ssl); - -/** - * @brief read data from to remote - * - * @param ssl - the SSL point which has been connected - * @param buffer - the received data buffer point - * @param len - the received data length - * - * @return result - * > 0 : OK, and return received data bytes - * = 0 : connection is closed - * < 0 : an error catch - */ -int SSL_read(SSL *ssl, void *buffer, int len); - -/** - * @brief send the data to remote - * - * @param ssl - the SSL point which has been connected - * @param buffer - the send data buffer point - * @param len - the send data length - * - * @return result - * > 0 : OK, and return sent data bytes - * = 0 : connection is closed - * < 0 : an error catch - */ -int SSL_write(SSL *ssl, const void *buffer, int len); - -/** - * @brief get SSL context of the SSL - * - * @param ssl - SSL point - * - * @return SSL context - */ -SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl); - -/** - * @brief get SSL shutdown mode - * - * @param ssl - SSL point - * - * @return shutdown mode - */ -int SSL_get_shutdown(const SSL *ssl); - -/** - * @brief set SSL shutdown mode - * - * @param ssl - SSL point - * @param mode - shutdown mode - * - * @return none - */ -void SSL_set_shutdown(SSL *ssl, int mode); - -/** - * @brief get the SSL current method - * - * @param ssl - SSL point - * - * @return the SSL current method - */ -const SSL_METHOD *SSL_get_ssl_method(SSL *ssl); - -/** - * @brief set the SSL method - * - * @param ssl - SSL point - * @param meth - SSL method point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_set_ssl_method(SSL *ssl, const SSL_METHOD *method); - -/** - * @brief get the bytes numbers which are to be read - * - * @param ssl - SSL point - * - * @return bytes number - */ -int SSL_pending(const SSL *ssl); - -/** - * @brief check if some data can be read - * - * @param ssl - SSL point - * - * @return - * 1 : there are bytes to be read - * 0 : no data - */ -int SSL_has_pending(const SSL *ssl); - -/** - * @brief get the socket handle of the SSL - * - * @param ssl - SSL point - * - * @return result - * >= 0 : yes, and return socket handle - * < 0 : a error catch - */ -int SSL_get_fd(const SSL *ssl); - -/** - * @brief get the read only socket handle of the SSL - * - * @param ssl - SSL point - * - * @return result - * >= 0 : yes, and return socket handle - * < 0 : a error catch - */ -int SSL_get_rfd(const SSL *ssl); - -/** - * @brief get the write only socket handle of the SSL - * - * @param ssl - SSL point - * - * @return result - * >= 0 : yes, and return socket handle - * < 0 : a error catch - */ -int SSL_get_wfd(const SSL *ssl); - -/** - * @brief bind the socket file description into the SSL - * - * @param ssl - the SSL point - * @param fd - socket handle - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_set_fd(SSL *ssl, int fd); - -/** - * @brief bind the read only socket file description into the SSL - * - * @param ssl - the SSL point - * @param fd - socket handle - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_set_rfd(SSL *ssl, int fd); - -/** - * @brief bind the write only socket file description into the SSL - * - * @param ssl - the SSL point - * @param fd - socket handle - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_set_wfd(SSL *ssl, int fd); - -/** - * @brief get SSL version - * - * @param ssl - SSL point - * - * @return SSL version - */ -int SSL_version(const SSL *ssl); - -/** - * @brief get the SSL current version - * - * @param ssl - SSL point - * - * @return the version string - */ -const char *SSL_get_version(const SSL *ssl); - -/** - * @brief get the SSL state - * - * @param ssl - SSL point - * - * @return SSL state - */ -OSSL_HANDSHAKE_STATE SSL_get_state(const SSL *ssl); - -/** - * @brief get alert description string - * - * @param value - alert value - * - * @return alert description string - */ -const char *SSL_alert_desc_string(int value); - -/** - * @brief get alert description long string - * - * @param value - alert value - * - * @return alert description long string - */ -const char *SSL_alert_desc_string_long(int value); - -/** - * @brief get alert type string - * - * @param value - alert value - * - * @return alert type string - */ -const char *SSL_alert_type_string(int value); - -/** - * @brief get alert type long string - * - * @param value - alert value - * - * @return alert type long string - */ -const char *SSL_alert_type_string_long(int value); - -/** - * @brief get the state string where SSL is reading - * - * @param ssl - SSL point - * - * @return state string - */ -const char *SSL_rstate_string(SSL *ssl); - -/** - * @brief get the statement long string where SSL is reading - * - * @param ssl - SSL point - * - * @return statement long string - */ -const char *SSL_rstate_string_long(SSL *ssl); - -/** - * @brief get SSL statement string - * - * @param ssl - SSL point - * - * @return SSL statement string - */ -char *SSL_state_string(const SSL *ssl); - -/** - * @brief get SSL statement long string - * - * @param ssl - SSL point - * - * @return SSL statement long string - */ -char *SSL_state_string_long(const SSL *ssl); - -/** - * @brief get SSL error code - * - * @param ssl - SSL point - * @param ret_code - SSL return code - * - * @return SSL error number - */ -int SSL_get_error(const SSL *ssl, int ret_code); - -/** - * @brief load a character certification context into system context. If '*cert' is pointed to the - * certification, then load certification into it. Or create a new X509 certification object - * - * @param cert - a point pointed to X509 certification - * @param buffer - a point pointed to the certification context memory point - * @param length - certification bytes - * - * @return X509 certification object point - */ -X509* d2i_X509(X509 **cert, const unsigned char *buffer, long len); - -/** - * @brief add CA client certification into the SSL - * - * @param ssl - SSL point - * @param x - CA certification point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_add_client_CA(SSL *ssl, X509 *x); - -/** - * @brief add CA client certification into the SSL context - * - * @param ctx - SSL context point - * @param x - CA certification point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x); - -/** - * @brief get the SSL certification point - * - * @param ssl - SSL point - * - * @return SSL certification point - */ -X509 *SSL_get_certificate(const SSL *ssl); - -/** - * @brief get the verifying result of the SSL certification - * - * @param ssl - the SSL point - * - * @return the result of verifying - */ -long SSL_get_verify_result(const SSL *ssl); - -/** - * @brief These functions load the certification into the SSL_CTX or SSL object - * - * @param ctx - the SSL context point - * @param pkey - certification object point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x); - -/** - * @brief load the ASN1 certification into SSL context - * - * @param ctx - SSL context point - * @param len - certification length - * @param d - data point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d); - -/** - * @brief These functions load the private key into the SSL_CTX or SSL object - * - * @param ctx - the SSL context point - * @param pkey - private key object point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey); - -/** - * @brief load the ASN1 private key into SSL context - * - * @param ctx - SSL context point - * @param d - data point - * @param len - private key length - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, const unsigned char *d, long len); - -/** - * @brief load the RSA ASN1 private key into SSL context - * - * @param ctx - SSL context point - * @param d - data point - * @param len - RSA private key length - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len); - -/** - * @brief load certification into the SSL - * - * @param ssl - SSL point - * @param len - data bytes - * @param d - data point - * - * @return result - * 0 : failed - * 1 : OK - * - */ -int SSL_use_certificate_ASN1(SSL *ssl, int len, const unsigned char *d); - -/** - * @brief get peer certification - * - * @param ssl - SSL point - * - * @return certification - */ -X509 *SSL_get_peer_certificate(const SSL *ssl); - -/** - * @brief set the SSL context read buffer length - * - * @param ctx - SSL context point - * @param len - read buffer length - * - * @return none - */ -void SSL_CTX_set_default_read_buffer_len(SSL_CTX *ctx, size_t len); - -/** - * @brief set the SSL read buffer length - * - * @param ssl - SSL point - * @param len - read buffer length - * - * @return none - */ -void SSL_set_default_read_buffer_len(SSL *ssl, size_t len); - -/** - * @brief get the SSL specifical statement - * - * @param ssl - SSL point - * - * @return specifical statement - */ -int SSL_want(const SSL *ssl); - -/** - * @brief check if SSL want nothing - * - * @param ssl - SSL point - * - * @return result - * 0 : false - * 1 : true - */ -int SSL_want_nothing(const SSL *ssl); - -/** - * @brief check if SSL want to read - * - * @param ssl - SSL point - * - * @return result - * 0 : false - * 1 : true - */ -int SSL_want_read(const SSL *ssl); - -/** - * @brief check if SSL want to write - * - * @param ssl - SSL point - * - * @return result - * 0 : false - * 1 : true - */ -int SSL_want_write(const SSL *ssl); From 1bcc5438ec51e3755b4fe98e18891e96335e1a57 Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Wed, 28 Sep 2016 19:40:05 +0800 Subject: [PATCH 037/343] components/openssl: fix .rst file encoding type --- components/openssl/OpenSSL-APIs.rst | 2965 ++++++++++++++------------- 1 file changed, 1487 insertions(+), 1478 deletions(-) diff --git a/components/openssl/OpenSSL-APIs.rst b/components/openssl/OpenSSL-APIs.rst index ff91d2ebb7..5a44794cd2 100644 --- a/components/openssl/OpenSSL-APIs.rst +++ b/components/openssl/OpenSSL-APIs.rst @@ -1,1478 +1,1487 @@ -OpenSSL-APIs -====================== - -Chapter 1. SSL Context Method Create -Chapter 2. SSL Context Fucntion -Chapter 3. SSL Fucntion -Chapter 4. SSL X509 Certification and Private Key Function - -====================== -Chapter 1. SSL Context Method Create - -1.1 const SSL_METHOD* SSLv23_client_method(void); - - Arguments : none - - Return : SSLV2 and 3 version SSL context client method point - - Description : create the target SSL context method - - Example : - - void example(void) - { - const SSL_METHOD *method = SSLv23_client_method(); - - ... - } - - -1.2 const SSL_METHOD* TLSv1_client_method(void); - - Arguments : none - - Return : TLSV1.0 version SSL context client method point - - Description : create the target SSL context method - - Example : - - void example(void) - { - const SSL_METHOD *method = TLSv1_client_method(); - - ... - } - - -1.3 const SSL_METHOD* SSLv3_client_method(void); - - Arguments : none - - Return : SSLV3.0 version SSL context client method point - - Description : create the target SSL context method - - Example : - - void example(void) - { - const SSL_METHOD *method = SSLv3_client_method(); - - ... - } - - -1.4 const SSL_METHOD* TLSv1_1_client_method(void); - - Arguments : none - - Return : TLSV1.1 version SSL context client method point - - Description : create the target SSL context method - - Example : - - void example(void) - { - const SSL_METHOD *method = TLSv1_1_client_method(); - - ... - } - - -1.5 const SSL_METHOD* TLSv1_2_client_method(void); - - Arguments : none - - Return : TLSV1.2 version SSL context client method point - - Description : create the target SSL context method - - Example : - - void example(void) - { - const SSL_METHOD *method = TLSv1_2_client_method(); - - ... - } - - -1.6 const SSL_METHOD* SSLv23_server_method(void); - - Arguments : none - - Return : SSLV2 and 3 version SSL context server method point - - Description : create the target SSL context method - - Example : - - void example(void) - { - const SSL_METHOD *method = SSLv23_server_method(); - - ... - } - - -1.7 const SSL_METHOD* TLSv1_1_server_method(void); - - Arguments : none - - Return : TLSV1.1 version SSL context server method point - - Description : create the target SSL context method - - Example : - - void example(void) - { - const SSL_METHOD *method = TLSv1_1_server_method(); - - ... - } - - -1.8 const SSL_METHOD* TLSv1_2_server_method(void); - - Arguments : none - - Return : TLSV1.2 version SSL context server method point - - Description : create the target SSL context method - - Example : - - void example(void) - { - const SSL_METHOD *method = TLSv1_2_server_method(); - - ... - } - - -1.9 const SSL_METHOD* TLSv1_server_method(void); - - Arguments : none - - Return : TLSV1.0 version SSL context server method point - - Description : create the target SSL context method - - Example : - - void example(void) - { - const SSL_METHOD *method = TLSv1_server_method(); - - ... - } - - -1.10 const SSL_METHOD* SSLv3_server_method(void); - - Arguments : none - - Return : SSLV3.0 version SSL context server method point - - Description : create the target SSL context method - - Example : - - void example(void) - { - const SSL_METHOD *method = SSLv3_server_method(); - - ... - } - - -====================== -Chapter 2. SSL Context Fucntion - -2.1 SSL_CTX* SSL_CTX_new(const SSL_METHOD *method); - - Arguments : method - the SSL context method point - - Return : context point - - Description : create a SSL context - - Example : - - void example(void) - { - SSL_CTX *ctx = SSL_CTX_new(SSLv3_server_method()); - - ... - } - - -2.2 void SSL_CTX_free(SSL_CTX *ctx); - - Arguments : ctx - the SSL context point - - Return : none - - Description : free a SSL context - - Example : - - void example(void) - { - SSL_CTX *ctx; - - ... ... - - SSL_CTX_free(ctx); - } - - -2.3 int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth); - - Arguments : ctx - SSL context point - meth - SSL method point - - Return : result - 1 : OK - 0 : failed - - Description : set the SSL context version - - Example : - - void example(void) - { - SSL_CTX *ctx; - const SSL_METHOD *meth; - - ... ... - - SSL_CTX_set_ssl_version(ctx, meth); - } - - -2.4 const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx); - - Arguments : ctx - SSL context point - - Return : SSL context method - - Description : get the SSL context method - - Example : - - void example(void) - { - const SSL_METHOD *method; - SSL_CTX *ctx; - - ... ... - - method = SSL_CTX_get_ssl_method(ctx); - } - - -====================== -Chapter 3. SSL Fucntion - -3.1 SSL* SSL_new(SSL_CTX *ctx); - - Arguments : ctx - SSL context point - - Return : SSL method - - Description : create a SSL - - Example : - - void example(void) - { - SSL *ssl; - SSL_CTX *ctx; - - ... ... - - ssl = SSL_new(ctx); - } - - -3.2 void SSL_free(SSL *ssl); - - Arguments : ssl - SSL point - - Return : none - - Description : free SSL - - Example : - - void example(void) - { - SSL *ssl; - - ... ... - - SSL_free(ssl); - } - - -3.3 int SSL_do_handshake(SSL *ssl); - - Arguments : ssl - SSL point - - Return : result - 1 : OK - 0 : failed, connect is close by remote - -1 : a error catch - - Description : perform the SSL handshake - - Example : - - void example(void) - { - SSL *ssl; - int ret; - - ... ... - - ret = SSL_do_handshake(ssl); - } - - -3.4 int SSL_connect(SSL *ssl); - - Arguments : ssl - SSL point - - Return : result - 1 : OK - 0 : failed, connect is close by remote - -1 : a error catch - - Description : connect to the remote SSL server - - Example : - - void example(void) - { - SSL *ssl; - int ret; - - ... ... - - ret = SSL_connect(ssl); - } - - -3.5 int SSL_accept(SSL *ssl); - - Arguments : ssl - SSL point - - Return : result - 1 : OK - 0 : failed, connect is close by remote - -1 : a error catch - - Description : accept the remote connection - - Example : - - void example(void) - { - SSL *ssl; - int ret; - - ... ... - - ret = SSL_accept(ssl); - } - - -3.6 int SSL_shutdown(SSL *ssl); - - Arguments : ssl - SSL point - - Return : result - 1 : OK - 0 : failed, connect is close by remote - -1 : a error catch - - Description : shutdown the connection - - Example : - - void example(void) - { - SSL *ssl; - int ret; - - ... ... - - ret = SSL_shutdown(ssl); - } - - -3.7 int SSL_clear(SSL *ssl); - - Arguments : ssl - SSL point - - Return : result - 1 : OK - 0 : failed - - Description : shutdown the connection - - Example : - - void example(void) - { - SSL *ssl; - int ret; - - ... ... - - ret = SSL_clear(ssl); - } - - -3.8 int SSL_read(SSL *ssl, void *buffer, int len); - - Arguments : ssl - point - buffer - data buffer point - len - data length - - Return : result - > 0 : OK, and return received data bytes - = 0 : no data received or connection is closed - < 0 : an error catch - - Description : read data from remote - - Example : - - void example(void) - { - SSL *ssl; - char *buf; - int len; - int ret; - - ... ... - - ret = SSL_read(ssl, buf, len); - } - -3.9 int SSL_write(SSL *ssl, const void *buffer, int len); - - Arguments : ssl - SSL point - buffer - data buffer point - len - data length - - Return : result - > 0 : OK, and return received data bytes - = 0 : no data sent or connection is closed - < 0 : an error catch - - Description : send the data to remote - - Example : - - void example(void) - { - SSL *ssl; - char *buf; - int len; - int ret; - - ... ... - - ret = SSL_write(ssl, buf, len); - } - - -3.10 SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl); - - Arguments : ssl - SSL point - - Return : SSL context - - Description : get SSL context of the SSL - - Example : - - void example(void) - { - SSL *ssl; - SSL_CTX *ctx; - - ... ... - - ctx = SSL_get_SSL_CTX(ssl); - } - - -3.11 int SSL_get_shutdown(const SSL *ssl); - - Arguments : ssl - SSL point - - Return : shutdown mode - - Description : get SSL shutdown mode - - Example : - - void example(void) - { - SSL *ssl; - int mode; - - ... ... - - mode = SSL_get_SSL_CTX(ssl); - } - - -3.12 void SSL_set_shutdown(SSL *ssl, int mode); - - Arguments : ssl - SSL point - - Return : shutdown mode - - Description : set SSL shutdown mode - - Example : - - void example(void) - { - SSL *ssl; - int mode = 0; - - ... ... - - SSL_set_shutdown(ssl, mode); - } - - -3.13 const SSL_METHOD *SSL_get_ssl_method(SSL *ssl); - - Arguments : ssl - SSL point - - Return : SSL method - - Description : set SSL shutdown mode - - Example : - - void example(void) - { - SSL *ssl; - const SSL_METHOD *method; - - ... ... - - method = SSL_get_ssl_method(ssl); - } - - -3.14 int SSL_set_ssl_method(SSL *ssl, const SSL_METHOD *method); - - Arguments : ssl - SSL point - meth - SSL method point - - Return : result - 1 : OK - 0 : failed - - Description : set the SSL method - - Example : - - void example(void) - { - int ret; - SSL *ssl; - const SSL_METHOD *method; - - ... ... - - ret = SSL_set_ssl_method(ssl, method); - } - - -3.15 int SSL_pending(const SSL *ssl); - - Arguments : ssl - SSL point - - Return : data bytes - - Description : get received data bytes - - Example : - - void example(void) - { - int ret; - SSL *ssl; - - ... ... - - ret = SSL_pending(ssl); - } - - -3.16 int SSL_has_pending(const SSL *ssl); - - Arguments : ssl - SSL point - - Return : result - 1 : Yes - 0 : No - - Description : check if data is received - - Example : - - void example(void) - { - int ret; - SSL *ssl; - - ... ... - - ret = SSL_has_pending(ssl); - } - - -3.17 int SSL_get_fd(const SSL *ssl); - - Arguments : ssl - SSL point - - Return : result - >= 0 : socket id - < 0 : a error catch - - Description : get the socket of the SSL - - Example : - - void example(void) - { - int ret; - SSL *ssl; - - ... ... - - ret = SSL_get_fd(ssl); - } - - -3.18 int SSL_get_rfd(const SSL *ssl); - - Arguments : ssl - SSL point - - Return : result - >= 0 : socket id - < 0 : a error catch - - Description : get the read only socket of the SSL - - Example : - - void example(void) - { - int ret; - SSL *ssl; - - ... ... - - ret = SSL_get_rfd(ssl); - } - - -3.19 int SSL_get_wfd(const SSL *ssl); - - Arguments : ssl - SSL point - - Return : result - >= 0 : socket id - < 0 : a error catch - - Description : get the write only socket of the SSL - - Example : - - void example(void) - { - int ret; - SSL *ssl; - - ... ... - - ret = SSL_get_wfd(ssl); - } - - -3.20 int SSL_set_fd(SSL *ssl, int fd); - - Arguments : ssl - SSL point - fd - socket id - - Return : result - 1 : OK - 0 : failed - - Description : set socket to SSL - - Example : - - void example(void) - { - int ret; - SSL *ssl; - int socket; - - ... ... - - ret = SSL_set_fd(ssl, socket); - } - - -3.21 int SSL_set_rfd(SSL *ssl, int fd); - - Arguments : ssl - SSL point - fd - socket id - - Return : result - 1 : OK - 0 : failed - - Description : set read only socket to SSL - - Example : - - void example(void) - { - int ret; - SSL *ssl; - int socket; - - ... ... - - ret = SSL_set_rfd(ssl, socket); - } - - -3.22 int SSL_set_wfd(SSL *ssl, int fd); - - Arguments : ssl - SSL point - fd - socket id - - Return : result - 1 : OK - 0 : failed - - Description : set write only socket to SSL - - Example : - - void example(void) - { - int ret; - SSL *ssl; - int socket; - - ... ... - - ret = SSL_set_wfd(ssl, socket); - } - - -3.23 int SSL_version(const SSL *ssl); - - Arguments : ssl - SSL point - - Return : SSL version - - Description : get SSL version - - Example : - - void example(void) - { - int version; - SSL *ssl; - - ... ... - - version = SSL_version(ssl); - } - - -3.24 const char *SSL_get_version(const SSL *ssl); - - Arguments : ssl - SSL point - - Return : SSL version string - - Description : get the SSL current version string - - Example : - - void example(void) - { - char *version; - SSL *ssl; - - ... ... - - version = SSL_get_version(ssl); - } - - -3.25 OSSL_HANDSHAKE_STATE SSL_get_state(const SSL *ssl); - - Arguments : ssl - SSL point - - Return : SSL state - - Description : get the SSL state - - Example : - - void example(void) - { - OSSL_HANDSHAKE_STATE state; - SSL *ssl; - - ... ... - - state = SSL_get_state(ssl); - } - - -3.26 const char *SSL_alert_desc_string(int value); - - Arguments : value - SSL description - - Return : alert value string - - Description : get alert description string - - Example : - - void example(void) - { - int val; - char *str; - - ... ... - - str = SSL_alert_desc_string(val); - } - - -3.27 const char *SSL_alert_desc_string_long(int value); - - Arguments : value - SSL description - - Return : alert value long string - - Description : get alert description long string - - Example : - - void example(void) - { - int val; - char *str; - - ... ... - - str = SSL_alert_desc_string_long(val); - } - - -3.28 const char *SSL_alert_type_string(int value); - - Arguments : value - SSL type description - - Return : alert type string - - Description : get alert type string - - Example : - - void example(void) - { - int val; - char *str; - - ... ... - - str = SSL_alert_type_string(val); - } - - -3.29 const char *SSL_alert_type_string_long(int value); - - Arguments : value - SSL type description - - Return : alert type long string - - Description : get alert type long string - - Example : - - void example(void) - { - int val; - char *str; - - ... ... - - str = SSL_alert_type_string_long(val); - } - -3.30 const char *SSL_rstate_string(SSL *ssl); - - Arguments : ssl - SSL point - - Return : state string - - Description : get the state string where SSL is reading - - Example : - - void example(void) - { - SSL *ssl; - char *str; - - ... ... - - str = SSL_rstate_string(ssl); - } - - -3.31 const char *SSL_rstate_string_long(SSL *ssl); - - Arguments : ssl - SSL point - - Return : state long string - - Description : get the state long string where SSL is reading - - Example : - - void example(void) - { - SSL *ssl; - char *str; - - ... ... - - str = SSL_rstate_string_long(ssl); - } - - -3.32 char *SSL_state_string(const SSL *ssl); - - Arguments : ssl - SSL point - - Return : state string - - Description : get the state string - - Example : - - void example(void) - { - SSL *ssl; - char *str; - - ... ... - - str = SSL_state_string(ssl); - } - - -3.33 char *SSL_state_string_long(const SSL *ssl); - - Arguments : ssl - SSL point - - Return : state long string - - Description : get the state long string - - Example : - - void example(void) - { - SSL *ssl; - char *str; - - ... ... - - str = SSL_state_string(ssl); - } - - -3.34 int SSL_get_error(const SSL *ssl, int ret_code); - - Arguments : ssl - SSL point - ret_code - SSL return code - - Return : SSL error number - - Description : get SSL error code - - Example : - - void example(void) - { - SSL *ssl; - int ret; - int err; - - ... ... - - err = SSL_get_error(ssl, ret); - } - -3.35 void SSL_CTX_set_default_read_buffer_len(SSL_CTX *ctx, size_t len); - - Arguments : ctx - SSL context point - len - read buffer length - - Return : none - - Description : set the SSL context read buffer length - - Example : - - void example(void) - { - SSL_CTX *ctx; - size_t len; - - ... ... - - SSL_CTX_set_default_read_buffer_len(ctx, len); - } - - -3.36 void SSL_set_default_read_buffer_len(SSL *ssl, size_t len); - - Arguments : ssl - SSL point - len - read buffer length - - Return : none - - Description : set the SSL read buffer length - - Example : - - void example(void) - { - SSL *ssl; - size_t len; - - ... ... - - SSL_set_default_read_buffer_len(ctx, len); - } - - -3.37 int SSL_want(const SSL *ssl); - - Arguments : ssl - SSL point - - Return : specifical statement - - Description : get the SSL specifical statement - - Example : - - void example(void) - { - SSL *ssl; - int state; - - ... ... - - state = SSL_want(ssl); - } - - -3.38 int SSL_want_nothing(const SSL *ssl); - - Arguments : ssl - SSL point - - Return : result - 0 : false - 1 : true - - Description : check if SSL want nothing - - Example : - - void example(void) - { - SSL *ssl; - int ret; - - ... ... - - ret = SSL_want(ssl); - } - - -3.39 int SSL_want_read(const SSL *ssl); - - Arguments : ssl - SSL point - - Return : result - 0 : false - 1 : true - - Description : check if SSL want to read - - Example : - - void example(void) - { - SSL *ssl; - int ret; - - ... ... - - ret = SSL_want_read(ssl); - } - - -3.40 int SSL_want_write(const SSL *ssl); - - Arguments : ssl - SSL point - - Return : result - 0 : false - 1 : true - - Description : check if SSL want to write - - Example : - - void example(void) - { - SSL *ssl; - int ret; - - ... ... - - ret = SSL_want_write(ssl); - } - -====================== -Chapter 4. SSL X509 Certification and Private Key Function - -4.1 X509* d2i_X509(X509 **cert, const unsigned char *buffer, long len); - - Arguments : cert - a point pointed to X509 certification - buffer - a point pointed to the certification context memory point - length - certification bytes - - Return : X509 certification object point - - Description : load a character certification context into system context. If '*cert' is pointed to the - certification, then load certification into it. Or create a new X509 certification object - - Example : - - void example(void) - { - X509 *new; - X509 *cert; - unsigned char *buffer; - long len; - ... ... - - new = d2i_X509(&cert, buffer, len); - } - - -4.2 int SSL_add_client_CA(SSL *ssl, X509 *x); - - Arguments : ssl - SSL point - x - CA certification point - - Return : result - 1 : OK - 0 : failed - - Description : add CA client certification into the SSL - - Example : - - void example(void) - { - int ret; - SSL *ssl; - X509 *new; - - ... ... - - ret = SSL_add_client_CA(ssl, new); - } - - -4.3 int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x); - - Arguments : ctx - SSL context point - x - CA certification point - - Return : result - 1 : OK - 0 : failed - - Description : add CA client certification into the SSL context - - Example : - - void example(void) - { - int ret; - SSL_CTX *ctx; - X509 *new; - - ... ... - - ret = SSL_add_clSSL_CTX_add_client_CAient_CA(ctx, new); - } - - -4.4 X509 *SSL_get_certificate(const SSL *ssl); - - Arguments : ssl - SSL point - - Return : SSL certification point - - Description : get the SSL certification point - - Example : - - void example(void) - { - SSL *ssl; - X509 *cert; - - ... ... - - cert = SSL_get_certificate(ssl); - } - - -4.5 long SSL_get_verify_result(const SSL *ssl); - - Arguments : ssl - SSL point - - Return : the result of verifying - - Description : get the verifying result of the SSL certification - - Example : - - void example(void) - { - SSL *ssl; - long ret; - - ... ... - - ret = SSL_get_verify_result(ssl); - } - - -4.6 int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x); - - Arguments : ctx - the SSL context point - pkey - certification object point - - Return : result - 1 : OK - 0 : failed - - Description : load the certification into the SSL_CTX or SSL object - - Example : - - void example(void) - { - int ret; - SSL_CTX *ctx - X509 *new; - - ... ... - - ret = SSL_CTX_use_certificate(ctx, new); - } - - -4.7 int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d); - - Arguments : ctx - SSL context point - len - certification length - d - data point - - Return : result - 1 : OK - 0 : failed - - Description : load the ASN1 certification into SSL context - - Example : - - void example(void) - { - int ret; - SSL_CTX *ctx; - const unsigned char *buf; - int len; - - ... ... - - ret = SSL_CTX_use_certificate_ASN1(ctx, len, buf); - } - - -4.8 int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey); - - Arguments : ctx - SSL context point - pkey - private key object point - - Return : result - 1 : OK - 0 : failed - - Description : load the private key into the context object - - Example : - - void example(void) - { - int ret; - SSL_CTX *ctx; - EVP_PKEY *pkey; - - ... ... - - ret = SSL_CTX_use_PrivateKey(ctx, pkey); - } - - -4.9 int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, const unsigned char *d, long len); - - Arguments : ctx - SSL context point - d - data point - len - private key length - - Return : result - 1 : OK - 0 : failed - - Description : load the ASN1 private key into SSL context - - Example : - - void example(void) - { - int ret; - int pk; - SSL_CTX *ctx; - const unsigned char *buf; - long len; - - ... ... - - ret = SSL_CTX_use_PrivateKey_ASN1(pk, ctx, buf, len); - } - - -4.10 int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len); - - Arguments : ctx - SSL context point - d - data point - len - private key length - - Return : result - 1 : OK - 0 : failed - - Description : load the RSA ASN1 private key into SSL context - - Example : - - void example(void) - { - int ret; - SSL_CTX *ctx; - const unsigned char *buf; - long len; - - ... ... - - ret = SSL_CTX_use_RSAPrivateKey_ASN1(ctx, buf, len); - } - - -4.11 int SSL_use_certificate_ASN1(SSL *ssl, int len, const unsigned char *d); - - Arguments : ssl - SSL point - len - data bytes - d - data point - - Return : result - 1 : OK - 0 : failed - - Description : load certification into the SSL - - Example : - - void example(void) - { - int ret; - SSL *ssl; - const unsigned char *buf; - long len; - - ... ... - - ret = SSL_use_certificate_ASN1(ssl, len, buf); - } - - -4.12 X509 *SSL_get_peer_certificate(const SSL *ssl); - - Arguments : ssl - SSL point - - Return : peer certification - - Description : get peer certification - - Example : - - void example(void) - { - SSL *ssl; - X509 *peer; - - ... ... - - peer = SSL_get_peer_certificate(ssl); - } - -====================== -END \ No newline at end of file +OpenSSL-APIs +============ + +All original source code in this repository is Copyright (C) 2015-2016 +Espressif Systems. This source code is licensed under the Apache +License 2.0 as described in the file LICENSE. + +Chapter Introduction +==================== + +Chapter 1. SSL Context Method Create +Chapter 2. SSL Context Fucntion +Chapter 3. SSL Fucntion +Chapter 4. SSL X509 Certification and Private Key Function + + +Chapter 1. SSL Context Method Create +==================================== + +1.1 const SSL_METHOD* SSLv23_client_method(void); + + Arguments : none + + Return : SSLV2 and 3 version SSL context client method point + + Description : create the target SSL context method + + Example : + + void example(void) + { + const SSL_METHOD *method = SSLv23_client_method(); + + ... + } + + +1.2 const SSL_METHOD* TLSv1_client_method(void); + + Arguments : none + + Return : TLSV1.0 version SSL context client method point + + Description : create the target SSL context method + + Example : + + void example(void) + { + const SSL_METHOD *method = TLSv1_client_method(); + + ... + } + + +1.3 const SSL_METHOD* SSLv3_client_method(void); + + Arguments : none + + Return : SSLV3.0 version SSL context client method point + + Description : create the target SSL context method + + Example : + + void example(void) + { + const SSL_METHOD *method = SSLv3_client_method(); + + ... + } + + +1.4 const SSL_METHOD* TLSv1_1_client_method(void); + + Arguments : none + + Return : TLSV1.1 version SSL context client method point + + Description : create the target SSL context method + + Example : + + void example(void) + { + const SSL_METHOD *method = TLSv1_1_client_method(); + + ... + } + + +1.5 const SSL_METHOD* TLSv1_2_client_method(void); + + Arguments : none + + Return : TLSV1.2 version SSL context client method point + + Description : create the target SSL context method + + Example : + + void example(void) + { + const SSL_METHOD *method = TLSv1_2_client_method(); + + ... + } + + +1.6 const SSL_METHOD* SSLv23_server_method(void); + + Arguments : none + + Return : SSLV2 and 3 version SSL context server method point + + Description : create the target SSL context method + + Example : + + void example(void) + { + const SSL_METHOD *method = SSLv23_server_method(); + + ... + } + + +1.7 const SSL_METHOD* TLSv1_1_server_method(void); + + Arguments : none + + Return : TLSV1.1 version SSL context server method point + + Description : create the target SSL context method + + Example : + + void example(void) + { + const SSL_METHOD *method = TLSv1_1_server_method(); + + ... + } + + +1.8 const SSL_METHOD* TLSv1_2_server_method(void); + + Arguments : none + + Return : TLSV1.2 version SSL context server method point + + Description : create the target SSL context method + + Example : + + void example(void) + { + const SSL_METHOD *method = TLSv1_2_server_method(); + + ... + } + + +1.9 const SSL_METHOD* TLSv1_server_method(void); + + Arguments : none + + Return : TLSV1.0 version SSL context server method point + + Description : create the target SSL context method + + Example : + + void example(void) + { + const SSL_METHOD *method = TLSv1_server_method(); + + ... + } + + +1.10 const SSL_METHOD* SSLv3_server_method(void); + + Arguments : none + + Return : SSLV3.0 version SSL context server method point + + Description : create the target SSL context method + + Example : + + void example(void) + { + const SSL_METHOD *method = SSLv3_server_method(); + + ... + } + + + +Chapter 2. SSL Context Fucntion +=============================== + +2.1 SSL_CTX* SSL_CTX_new(const SSL_METHOD *method); + + Arguments : method - the SSL context method point + + Return : context point + + Description : create a SSL context + + Example : + + void example(void) + { + SSL_CTX *ctx = SSL_CTX_new(SSLv3_server_method()); + + ... + } + + +2.2 void SSL_CTX_free(SSL_CTX *ctx); + + Arguments : ctx - the SSL context point + + Return : none + + Description : free a SSL context + + Example : + + void example(void) + { + SSL_CTX *ctx; + + ... ... + + SSL_CTX_free(ctx); + } + + +2.3 int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth); + + Arguments : ctx - SSL context point + meth - SSL method point + + Return : result + 1 : OK + 0 : failed + + Description : set the SSL context version + + Example : + + void example(void) + { + SSL_CTX *ctx; + const SSL_METHOD *meth; + + ... ... + + SSL_CTX_set_ssl_version(ctx, meth); + } + + +2.4 const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx); + + Arguments : ctx - SSL context point + + Return : SSL context method + + Description : get the SSL context method + + Example : + + void example(void) + { + const SSL_METHOD *method; + SSL_CTX *ctx; + + ... ... + + method = SSL_CTX_get_ssl_method(ctx); + } + + + +Chapter 3. SSL Fucntion +======================= + +3.1 SSL* SSL_new(SSL_CTX *ctx); + + Arguments : ctx - SSL context point + + Return : SSL method + + Description : create a SSL + + Example : + + void example(void) + { + SSL *ssl; + SSL_CTX *ctx; + + ... ... + + ssl = SSL_new(ctx); + } + + +3.2 void SSL_free(SSL *ssl); + + Arguments : ssl - SSL point + + Return : none + + Description : free SSL + + Example : + + void example(void) + { + SSL *ssl; + + ... ... + + SSL_free(ssl); + } + + +3.3 int SSL_do_handshake(SSL *ssl); + + Arguments : ssl - SSL point + + Return : result + 1 : OK + 0 : failed, connect is close by remote + -1 : a error catch + + Description : perform the SSL handshake + + Example : + + void example(void) + { + SSL *ssl; + int ret; + + ... ... + + ret = SSL_do_handshake(ssl); + } + + +3.4 int SSL_connect(SSL *ssl); + + Arguments : ssl - SSL point + + Return : result + 1 : OK + 0 : failed, connect is close by remote + -1 : a error catch + + Description : connect to the remote SSL server + + Example : + + void example(void) + { + SSL *ssl; + int ret; + + ... ... + + ret = SSL_connect(ssl); + } + + +3.5 int SSL_accept(SSL *ssl); + + Arguments : ssl - SSL point + + Return : result + 1 : OK + 0 : failed, connect is close by remote + -1 : a error catch + + Description : accept the remote connection + + Example : + + void example(void) + { + SSL *ssl; + int ret; + + ... ... + + ret = SSL_accept(ssl); + } + + +3.6 int SSL_shutdown(SSL *ssl); + + Arguments : ssl - SSL point + + Return : result + 1 : OK + 0 : failed, connect is close by remote + -1 : a error catch + + Description : shutdown the connection + + Example : + + void example(void) + { + SSL *ssl; + int ret; + + ... ... + + ret = SSL_shutdown(ssl); + } + + +3.7 int SSL_clear(SSL *ssl); + + Arguments : ssl - SSL point + + Return : result + 1 : OK + 0 : failed + + Description : shutdown the connection + + Example : + + void example(void) + { + SSL *ssl; + int ret; + + ... ... + + ret = SSL_clear(ssl); + } + + +3.8 int SSL_read(SSL *ssl, void *buffer, int len); + + Arguments : ssl - point + buffer - data buffer point + len - data length + + Return : result + > 0 : OK, and return received data bytes + = 0 : no data received or connection is closed + < 0 : an error catch + + Description : read data from remote + + Example : + + void example(void) + { + SSL *ssl; + char *buf; + int len; + int ret; + + ... ... + + ret = SSL_read(ssl, buf, len); + } + +3.9 int SSL_write(SSL *ssl, const void *buffer, int len); + + Arguments : ssl - SSL point + buffer - data buffer point + len - data length + + Return : result + > 0 : OK, and return received data bytes + = 0 : no data sent or connection is closed + < 0 : an error catch + + Description : send the data to remote + + Example : + + void example(void) + { + SSL *ssl; + char *buf; + int len; + int ret; + + ... ... + + ret = SSL_write(ssl, buf, len); + } + + +3.10 SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl); + + Arguments : ssl - SSL point + + Return : SSL context + + Description : get SSL context of the SSL + + Example : + + void example(void) + { + SSL *ssl; + SSL_CTX *ctx; + + ... ... + + ctx = SSL_get_SSL_CTX(ssl); + } + + +3.11 int SSL_get_shutdown(const SSL *ssl); + + Arguments : ssl - SSL point + + Return : shutdown mode + + Description : get SSL shutdown mode + + Example : + + void example(void) + { + SSL *ssl; + int mode; + + ... ... + + mode = SSL_get_SSL_CTX(ssl); + } + + +3.12 void SSL_set_shutdown(SSL *ssl, int mode); + + Arguments : ssl - SSL point + + Return : shutdown mode + + Description : set SSL shutdown mode + + Example : + + void example(void) + { + SSL *ssl; + int mode = 0; + + ... ... + + SSL_set_shutdown(ssl, mode); + } + + +3.13 const SSL_METHOD *SSL_get_ssl_method(SSL *ssl); + + Arguments : ssl - SSL point + + Return : SSL method + + Description : set SSL shutdown mode + + Example : + + void example(void) + { + SSL *ssl; + const SSL_METHOD *method; + + ... ... + + method = SSL_get_ssl_method(ssl); + } + + +3.14 int SSL_set_ssl_method(SSL *ssl, const SSL_METHOD *method); + + Arguments : ssl - SSL point + meth - SSL method point + + Return : result + 1 : OK + 0 : failed + + Description : set the SSL method + + Example : + + void example(void) + { + int ret; + SSL *ssl; + const SSL_METHOD *method; + + ... ... + + ret = SSL_set_ssl_method(ssl, method); + } + + +3.15 int SSL_pending(const SSL *ssl); + + Arguments : ssl - SSL point + + Return : data bytes + + Description : get received data bytes + + Example : + + void example(void) + { + int ret; + SSL *ssl; + + ... ... + + ret = SSL_pending(ssl); + } + + +3.16 int SSL_has_pending(const SSL *ssl); + + Arguments : ssl - SSL point + + Return : result + 1 : Yes + 0 : No + + Description : check if data is received + + Example : + + void example(void) + { + int ret; + SSL *ssl; + + ... ... + + ret = SSL_has_pending(ssl); + } + + +3.17 int SSL_get_fd(const SSL *ssl); + + Arguments : ssl - SSL point + + Return : result + >= 0 : socket id + < 0 : a error catch + + Description : get the socket of the SSL + + Example : + + void example(void) + { + int ret; + SSL *ssl; + + ... ... + + ret = SSL_get_fd(ssl); + } + + +3.18 int SSL_get_rfd(const SSL *ssl); + + Arguments : ssl - SSL point + + Return : result + >= 0 : socket id + < 0 : a error catch + + Description : get the read only socket of the SSL + + Example : + + void example(void) + { + int ret; + SSL *ssl; + + ... ... + + ret = SSL_get_rfd(ssl); + } + + +3.19 int SSL_get_wfd(const SSL *ssl); + + Arguments : ssl - SSL point + + Return : result + >= 0 : socket id + < 0 : a error catch + + Description : get the write only socket of the SSL + + Example : + + void example(void) + { + int ret; + SSL *ssl; + + ... ... + + ret = SSL_get_wfd(ssl); + } + + +3.20 int SSL_set_fd(SSL *ssl, int fd); + + Arguments : ssl - SSL point + fd - socket id + + Return : result + 1 : OK + 0 : failed + + Description : set socket to SSL + + Example : + + void example(void) + { + int ret; + SSL *ssl; + int socket; + + ... ... + + ret = SSL_set_fd(ssl, socket); + } + + +3.21 int SSL_set_rfd(SSL *ssl, int fd); + + Arguments : ssl - SSL point + fd - socket id + + Return : result + 1 : OK + 0 : failed + + Description : set read only socket to SSL + + Example : + + void example(void) + { + int ret; + SSL *ssl; + int socket; + + ... ... + + ret = SSL_set_rfd(ssl, socket); + } + + +3.22 int SSL_set_wfd(SSL *ssl, int fd); + + Arguments : ssl - SSL point + fd - socket id + + Return : result + 1 : OK + 0 : failed + + Description : set write only socket to SSL + + Example : + + void example(void) + { + int ret; + SSL *ssl; + int socket; + + ... ... + + ret = SSL_set_wfd(ssl, socket); + } + + +3.23 int SSL_version(const SSL *ssl); + + Arguments : ssl - SSL point + + Return : SSL version + + Description : get SSL version + + Example : + + void example(void) + { + int version; + SSL *ssl; + + ... ... + + version = SSL_version(ssl); + } + + +3.24 const char *SSL_get_version(const SSL *ssl); + + Arguments : ssl - SSL point + + Return : SSL version string + + Description : get the SSL current version string + + Example : + + void example(void) + { + char *version; + SSL *ssl; + + ... ... + + version = SSL_get_version(ssl); + } + + +3.25 OSSL_HANDSHAKE_STATE SSL_get_state(const SSL *ssl); + + Arguments : ssl - SSL point + + Return : SSL state + + Description : get the SSL state + + Example : + + void example(void) + { + OSSL_HANDSHAKE_STATE state; + SSL *ssl; + + ... ... + + state = SSL_get_state(ssl); + } + + +3.26 const char *SSL_alert_desc_string(int value); + + Arguments : value - SSL description + + Return : alert value string + + Description : get alert description string + + Example : + + void example(void) + { + int val; + char *str; + + ... ... + + str = SSL_alert_desc_string(val); + } + + +3.27 const char *SSL_alert_desc_string_long(int value); + + Arguments : value - SSL description + + Return : alert value long string + + Description : get alert description long string + + Example : + + void example(void) + { + int val; + char *str; + + ... ... + + str = SSL_alert_desc_string_long(val); + } + + +3.28 const char *SSL_alert_type_string(int value); + + Arguments : value - SSL type description + + Return : alert type string + + Description : get alert type string + + Example : + + void example(void) + { + int val; + char *str; + + ... ... + + str = SSL_alert_type_string(val); + } + + +3.29 const char *SSL_alert_type_string_long(int value); + + Arguments : value - SSL type description + + Return : alert type long string + + Description : get alert type long string + + Example : + + void example(void) + { + int val; + char *str; + + ... ... + + str = SSL_alert_type_string_long(val); + } + +3.30 const char *SSL_rstate_string(SSL *ssl); + + Arguments : ssl - SSL point + + Return : state string + + Description : get the state string where SSL is reading + + Example : + + void example(void) + { + SSL *ssl; + char *str; + + ... ... + + str = SSL_rstate_string(ssl); + } + + +3.31 const char *SSL_rstate_string_long(SSL *ssl); + + Arguments : ssl - SSL point + + Return : state long string + + Description : get the state long string where SSL is reading + + Example : + + void example(void) + { + SSL *ssl; + char *str; + + ... ... + + str = SSL_rstate_string_long(ssl); + } + + +3.32 char *SSL_state_string(const SSL *ssl); + + Arguments : ssl - SSL point + + Return : state string + + Description : get the state string + + Example : + + void example(void) + { + SSL *ssl; + char *str; + + ... ... + + str = SSL_state_string(ssl); + } + + +3.33 char *SSL_state_string_long(const SSL *ssl); + + Arguments : ssl - SSL point + + Return : state long string + + Description : get the state long string + + Example : + + void example(void) + { + SSL *ssl; + char *str; + + ... ... + + str = SSL_state_string(ssl); + } + + +3.34 int SSL_get_error(const SSL *ssl, int ret_code); + + Arguments : ssl - SSL point + ret_code - SSL return code + + Return : SSL error number + + Description : get SSL error code + + Example : + + void example(void) + { + SSL *ssl; + int ret; + int err; + + ... ... + + err = SSL_get_error(ssl, ret); + } + +3.35 void SSL_CTX_set_default_read_buffer_len(SSL_CTX *ctx, size_t len); + + Arguments : ctx - SSL context point + len - read buffer length + + Return : none + + Description : set the SSL context read buffer length + + Example : + + void example(void) + { + SSL_CTX *ctx; + size_t len; + + ... ... + + SSL_CTX_set_default_read_buffer_len(ctx, len); + } + + +3.36 void SSL_set_default_read_buffer_len(SSL *ssl, size_t len); + + Arguments : ssl - SSL point + len - read buffer length + + Return : none + + Description : set the SSL read buffer length + + Example : + + void example(void) + { + SSL *ssl; + size_t len; + + ... ... + + SSL_set_default_read_buffer_len(ctx, len); + } + + +3.37 int SSL_want(const SSL *ssl); + + Arguments : ssl - SSL point + + Return : specifical statement + + Description : get the SSL specifical statement + + Example : + + void example(void) + { + SSL *ssl; + int state; + + ... ... + + state = SSL_want(ssl); + } + + +3.38 int SSL_want_nothing(const SSL *ssl); + + Arguments : ssl - SSL point + + Return : result + 0 : false + 1 : true + + Description : check if SSL want nothing + + Example : + + void example(void) + { + SSL *ssl; + int ret; + + ... ... + + ret = SSL_want(ssl); + } + + +3.39 int SSL_want_read(const SSL *ssl); + + Arguments : ssl - SSL point + + Return : result + 0 : false + 1 : true + + Description : check if SSL want to read + + Example : + + void example(void) + { + SSL *ssl; + int ret; + + ... ... + + ret = SSL_want_read(ssl); + } + + +3.40 int SSL_want_write(const SSL *ssl); + + Arguments : ssl - SSL point + + Return : result + 0 : false + 1 : true + + Description : check if SSL want to write + + Example : + + void example(void) + { + SSL *ssl; + int ret; + + ... ... + + ret = SSL_want_write(ssl); + } + + +Chapter 4. SSL X509 Certification and Private Key Function +========================================================== + +4.1 X509* d2i_X509(X509 **cert, const unsigned char *buffer, long len); + + Arguments : cert - a point pointed to X509 certification + buffer - a point pointed to the certification context memory point + length - certification bytes + + Return : X509 certification object point + + Description : load a character certification context into system context. If '*cert' is pointed to the + certification, then load certification into it. Or create a new X509 certification object + + Example : + + void example(void) + { + X509 *new; + X509 *cert; + unsigned char *buffer; + long len; + ... ... + + new = d2i_X509(&cert, buffer, len); + } + + +4.2 int SSL_add_client_CA(SSL *ssl, X509 *x); + + Arguments : ssl - SSL point + x - CA certification point + + Return : result + 1 : OK + 0 : failed + + Description : add CA client certification into the SSL + + Example : + + void example(void) + { + int ret; + SSL *ssl; + X509 *new; + + ... ... + + ret = SSL_add_client_CA(ssl, new); + } + + +4.3 int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x); + + Arguments : ctx - SSL context point + x - CA certification point + + Return : result + 1 : OK + 0 : failed + + Description : add CA client certification into the SSL context + + Example : + + void example(void) + { + int ret; + SSL_CTX *ctx; + X509 *new; + + ... ... + + ret = SSL_add_clSSL_CTX_add_client_CAient_CA(ctx, new); + } + + +4.4 X509 *SSL_get_certificate(const SSL *ssl); + + Arguments : ssl - SSL point + + Return : SSL certification point + + Description : get the SSL certification point + + Example : + + void example(void) + { + SSL *ssl; + X509 *cert; + + ... ... + + cert = SSL_get_certificate(ssl); + } + + +4.5 long SSL_get_verify_result(const SSL *ssl); + + Arguments : ssl - SSL point + + Return : the result of verifying + + Description : get the verifying result of the SSL certification + + Example : + + void example(void) + { + SSL *ssl; + long ret; + + ... ... + + ret = SSL_get_verify_result(ssl); + } + + +4.6 int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x); + + Arguments : ctx - the SSL context point + pkey - certification object point + + Return : result + 1 : OK + 0 : failed + + Description : load the certification into the SSL_CTX or SSL object + + Example : + + void example(void) + { + int ret; + SSL_CTX *ctx + X509 *new; + + ... ... + + ret = SSL_CTX_use_certificate(ctx, new); + } + + +4.7 int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d); + + Arguments : ctx - SSL context point + len - certification length + d - data point + + Return : result + 1 : OK + 0 : failed + + Description : load the ASN1 certification into SSL context + + Example : + + void example(void) + { + int ret; + SSL_CTX *ctx; + const unsigned char *buf; + int len; + + ... ... + + ret = SSL_CTX_use_certificate_ASN1(ctx, len, buf); + } + + +4.8 int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey); + + Arguments : ctx - SSL context point + pkey - private key object point + + Return : result + 1 : OK + 0 : failed + + Description : load the private key into the context object + + Example : + + void example(void) + { + int ret; + SSL_CTX *ctx; + EVP_PKEY *pkey; + + ... ... + + ret = SSL_CTX_use_PrivateKey(ctx, pkey); + } + + +4.9 int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, const unsigned char *d, long len); + + Arguments : ctx - SSL context point + d - data point + len - private key length + + Return : result + 1 : OK + 0 : failed + + Description : load the ASN1 private key into SSL context + + Example : + + void example(void) + { + int ret; + int pk; + SSL_CTX *ctx; + const unsigned char *buf; + long len; + + ... ... + + ret = SSL_CTX_use_PrivateKey_ASN1(pk, ctx, buf, len); + } + + +4.10 int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len); + + Arguments : ctx - SSL context point + d - data point + len - private key length + + Return : result + 1 : OK + 0 : failed + + Description : load the RSA ASN1 private key into SSL context + + Example : + + void example(void) + { + int ret; + SSL_CTX *ctx; + const unsigned char *buf; + long len; + + ... ... + + ret = SSL_CTX_use_RSAPrivateKey_ASN1(ctx, buf, len); + } + + +4.11 int SSL_use_certificate_ASN1(SSL *ssl, int len, const unsigned char *d); + + Arguments : ssl - SSL point + len - data bytes + d - data point + + Return : result + 1 : OK + 0 : failed + + Description : load certification into the SSL + + Example : + + void example(void) + { + int ret; + SSL *ssl; + const unsigned char *buf; + long len; + + ... ... + + ret = SSL_use_certificate_ASN1(ssl, len, buf); + } + + +4.12 X509 *SSL_get_peer_certificate(const SSL *ssl); + + Arguments : ssl - SSL point + + Return : peer certification + + Description : get peer certification + + Example : + + void example(void) + { + SSL *ssl; + X509 *peer; + + ... ... + + peer = SSL_get_peer_certificate(ssl); + } + From b97c00f2c1b367fb5d6e2602ccc21392282378ff Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Wed, 28 Sep 2016 20:41:11 +0800 Subject: [PATCH 038/343] components/openssl: add more .rst encoding type --- components/openssl/OpenSSL-APIs.rst | 1123 ++++++++++++++++++--------- 1 file changed, 748 insertions(+), 375 deletions(-) diff --git a/components/openssl/OpenSSL-APIs.rst b/components/openssl/OpenSSL-APIs.rst index 5a44794cd2..cb90a23c93 100644 --- a/components/openssl/OpenSSL-APIs.rst +++ b/components/openssl/OpenSSL-APIs.rst @@ -8,24 +8,31 @@ License 2.0 as described in the file LICENSE. Chapter Introduction ==================== -Chapter 1. SSL Context Method Create -Chapter 2. SSL Context Fucntion -Chapter 3. SSL Fucntion -Chapter 4. SSL X509 Certification and Private Key Function +- Chapter 1. SSL Context Method Create +- Chapter 2. SSL Context Fucntion +- Chapter 3. SSL Fucntion +- Chapter 4. SSL X509 Certification and Private Key Function Chapter 1. SSL Context Method Create ==================================== -1.1 const SSL_METHOD* SSLv23_client_method(void); - Arguments : none +1.1 const SSL_METHOD* ``SSLv23_client_method``(void) + + Arguments:: - Return : SSLV2 and 3 version SSL context client method point + none - Description : create the target SSL context method + Return:: - Example : + SSLV2 and 3 version SSL context client method point + + Description:: + + create the target SSL context method + + Example:: void example(void) { @@ -35,15 +42,21 @@ Chapter 1. SSL Context Method Create } -1.2 const SSL_METHOD* TLSv1_client_method(void); +1.2 const SSL_METHOD* ``TLSv1_client_method``(void) - Arguments : none + Arguments:: - Return : TLSV1.0 version SSL context client method point + none - Description : create the target SSL context method + Return:: - Example : + TLSV1.0 version SSL context client method point + + Description:: + + create the target SSL context method + + Example:: void example(void) { @@ -53,15 +66,21 @@ Chapter 1. SSL Context Method Create } -1.3 const SSL_METHOD* SSLv3_client_method(void); +1.3 const SSL_METHOD* ``SSLv3_client_method``(void) - Arguments : none + Arguments:: - Return : SSLV3.0 version SSL context client method point + none - Description : create the target SSL context method + Return:: - Example : + SSLV3.0 version SSL context client method point + + Description:: + + create the target SSL context method + + Example:: void example(void) { @@ -71,15 +90,21 @@ Chapter 1. SSL Context Method Create } -1.4 const SSL_METHOD* TLSv1_1_client_method(void); +1.4 const SSL_METHOD* ``TLSv1_1_client_method``(void) - Arguments : none + Arguments:: - Return : TLSV1.1 version SSL context client method point + none - Description : create the target SSL context method + Return:: - Example : + TLSV1.1 version SSL context client method point + + Description:: + + create the target SSL context method + + Example:: void example(void) { @@ -89,15 +114,21 @@ Chapter 1. SSL Context Method Create } -1.5 const SSL_METHOD* TLSv1_2_client_method(void); +1.5 const SSL_METHOD* ``TLSv1_2_client_method``(void) - Arguments : none + Arguments:: - Return : TLSV1.2 version SSL context client method point + none - Description : create the target SSL context method + Return:: - Example : + TLSV1.2 version SSL context client method point + + Description:: + + create the target SSL context method + + Example:: void example(void) { @@ -107,15 +138,21 @@ Chapter 1. SSL Context Method Create } -1.6 const SSL_METHOD* SSLv23_server_method(void); +1.6 const SSL_METHOD* ``SSLv23_server_method``(void) - Arguments : none + Arguments:: - Return : SSLV2 and 3 version SSL context server method point + none - Description : create the target SSL context method + Return:: - Example : + SSLV2 and 3 version SSL context server method point + + Description:: + + create the target SSL context method + + Example:: void example(void) { @@ -125,13 +162,19 @@ Chapter 1. SSL Context Method Create } -1.7 const SSL_METHOD* TLSv1_1_server_method(void); +1.7 const SSL_METHOD* ``TLSv1_1_server_method``(void) - Arguments : none + Arguments:: - Return : TLSV1.1 version SSL context server method point + none - Description : create the target SSL context method + Return:: + + TLSV1.1 version SSL context server method point + + Description:: + + create the target SSL context method Example : @@ -143,15 +186,21 @@ Chapter 1. SSL Context Method Create } -1.8 const SSL_METHOD* TLSv1_2_server_method(void); +1.8 const SSL_METHOD* ``TLSv1_2_server_method``(void) - Arguments : none + Arguments:: - Return : TLSV1.2 version SSL context server method point + none - Description : create the target SSL context method + Return:: - Example : + TLSV1.2 version SSL context server method point + + Description:: + + create the target SSL context method + + Example:: void example(void) { @@ -161,15 +210,21 @@ Chapter 1. SSL Context Method Create } -1.9 const SSL_METHOD* TLSv1_server_method(void); +1.9 const SSL_METHOD* ``TLSv1_server_method``(void) - Arguments : none + Arguments:: - Return : TLSV1.0 version SSL context server method point + none - Description : create the target SSL context method + Return:: - Example : + TLSV1.0 version SSL context server method point + + Description:: + + create the target SSL context method + + Example:: void example(void) { @@ -179,15 +234,21 @@ Chapter 1. SSL Context Method Create } -1.10 const SSL_METHOD* SSLv3_server_method(void); +1.10 const SSL_METHOD* ``SSLv3_server_method``(void) - Arguments : none + Arguments:: - Return : SSLV3.0 version SSL context server method point + none - Description : create the target SSL context method + Return:: - Example : + SSLV3.0 version SSL context server method point + + Description:: + + create the target SSL context method + + Example:: void example(void) { @@ -201,15 +262,22 @@ Chapter 1. SSL Context Method Create Chapter 2. SSL Context Fucntion =============================== -2.1 SSL_CTX* SSL_CTX_new(const SSL_METHOD *method); - Arguments : method - the SSL context method point +2.1 SSL_CTX* ``SSL_CTX_new``(const SSL_METHOD *method) + + Arguments:: - Return : context point + method - the SSL context method point - Description : create a SSL context + Return:: - Example : + context point + + Description:: + + create a SSL context + + Example:: void example(void) { @@ -219,15 +287,21 @@ Chapter 2. SSL Context Fucntion } -2.2 void SSL_CTX_free(SSL_CTX *ctx); +2.2 ``void SSL_CTX_free``(SSL_CTX *ctx) - Arguments : ctx - the SSL context point + Arguments:: - Return : none + ctx - the SSL context point - Description : free a SSL context + Return:: - Example : + none + + Description:: + + free a SSL context + + Example:: void example(void) { @@ -239,18 +313,23 @@ Chapter 2. SSL Context Fucntion } -2.3 int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth); +2.3 ``int SSL_CTX_set_ssl_version``(SSL_CTX *ctx, const SSL_METHOD *meth) - Arguments : ctx - SSL context point - meth - SSL method point + Arguments:: + + ctx - SSL context point + meth - SSL method point + + Return:: - Return : result 1 : OK 0 : failed - Description : set the SSL context version + Description:: - Example : + set the SSL context version + + Example:: void example(void) { @@ -263,15 +342,21 @@ Chapter 2. SSL Context Fucntion } -2.4 const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx); +2.4 const SSL_METHOD* ``SSL_CTX_get_ssl_method``(SSL_CTX *ctx) - Arguments : ctx - SSL context point + Arguments:: - Return : SSL context method + ctx - SSL context point - Description : get the SSL context method + Return:: - Example : + SSL context method + + Description:: + + get the SSL context method + + Example:: void example(void) { @@ -288,15 +373,22 @@ Chapter 2. SSL Context Fucntion Chapter 3. SSL Fucntion ======================= -3.1 SSL* SSL_new(SSL_CTX *ctx); - Arguments : ctx - SSL context point +3.1 SSL* ``SSL_new``(SSL_CTX *ctx) + + Arguments:: - Return : SSL method + ctx - SSL context point - Description : create a SSL + Return:: - Example : + SSL method + + Description:: + + create a SSL + + Example:: void example(void) { @@ -309,15 +401,21 @@ Chapter 3. SSL Fucntion } -3.2 void SSL_free(SSL *ssl); +3.2 void ``SSL_free``(SSL *ssl) - Arguments : ssl - SSL point + Arguments:: - Return : none + ssl - SSL point - Description : free SSL + Return:: - Example : + none + + Description:: + + free SSL + + Example:: void example(void) { @@ -329,18 +427,23 @@ Chapter 3. SSL Fucntion } -3.3 int SSL_do_handshake(SSL *ssl); +3.3 int ``SSL_do_handshake``(SSL *ssl) - Arguments : ssl - SSL point + Arguments:: + + ssl - SSL point + + Return:: - Return : result 1 : OK 0 : failed, connect is close by remote -1 : a error catch - Description : perform the SSL handshake + Description:: - Example : + perform the SSL handshake + + Example:: void example(void) { @@ -353,18 +456,23 @@ Chapter 3. SSL Fucntion } -3.4 int SSL_connect(SSL *ssl); +3.4 int ``SSL_connect``(SSL *ssl) - Arguments : ssl - SSL point + Arguments:: + + ssl - SSL point + + Return:: - Return : result 1 : OK 0 : failed, connect is close by remote -1 : a error catch - Description : connect to the remote SSL server + Description:: - Example : + connect to the remote SSL server + + Example:: void example(void) { @@ -377,18 +485,23 @@ Chapter 3. SSL Fucntion } -3.5 int SSL_accept(SSL *ssl); +3.5 int ``SSL_accept``(SSL *ssl) - Arguments : ssl - SSL point + Arguments:: + + ssl - SSL point + + Return:: - Return : result 1 : OK 0 : failed, connect is close by remote -1 : a error catch - Description : accept the remote connection + Description:: - Example : + accept the remote connection + + Example:: void example(void) { @@ -401,18 +514,23 @@ Chapter 3. SSL Fucntion } -3.6 int SSL_shutdown(SSL *ssl); +3.6 int ``SSL_shutdown``(SSL *ssl) - Arguments : ssl - SSL point + Arguments:: + + ssl - SSL point + + Return:: - Return : result 1 : OK 0 : failed, connect is close by remote -1 : a error catch - Description : shutdown the connection + Description:: - Example : + shutdown the connection + + Example:: void example(void) { @@ -425,17 +543,22 @@ Chapter 3. SSL Fucntion } -3.7 int SSL_clear(SSL *ssl); +3.7 int ``SSL_clear``(SSL *ssl) - Arguments : ssl - SSL point + Arguments:: + + ssl - SSL point + + Return:: - Return : result 1 : OK 0 : failed - Description : shutdown the connection + Description:: - Example : + shutdown the connection + + Example:: void example(void) { @@ -448,20 +571,25 @@ Chapter 3. SSL Fucntion } -3.8 int SSL_read(SSL *ssl, void *buffer, int len); +3.8 int ``SSL_read``(SSL *ssl, void *buffer, int len) - Arguments : ssl - point - buffer - data buffer point - len - data length + Arguments:: + + ssl - point + buffer - data buffer point + len - data length + + Return:: - Return : result > 0 : OK, and return received data bytes = 0 : no data received or connection is closed < 0 : an error catch - Description : read data from remote + Description:: - Example : + read data from remote + + Example:: void example(void) { @@ -475,20 +603,25 @@ Chapter 3. SSL Fucntion ret = SSL_read(ssl, buf, len); } -3.9 int SSL_write(SSL *ssl, const void *buffer, int len); +3.9 int ``SSL_write``(SSL *ssl, const void *buffer, int len) - Arguments : ssl - SSL point - buffer - data buffer point - len - data length + Arguments:: + + ssl - SSL point + buffer - data buffer point + len - data length + + Return:: - Return : result > 0 : OK, and return received data bytes = 0 : no data sent or connection is closed < 0 : an error catch - Description : send the data to remote + Description:: - Example : + send the data to remote + + Example:: void example(void) { @@ -503,15 +636,21 @@ Chapter 3. SSL Fucntion } -3.10 SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl); +3.10 ``SSL_CTX *SSL_get_SSL_CTX``(const SSL *ssl) - Arguments : ssl - SSL point + Arguments:: - Return : SSL context + ssl - SSL point + + Return:: + + SSL context - Description : get SSL context of the SSL + Description:: - Example : + get SSL context of the SSL + + Example:: void example(void) { @@ -524,15 +663,21 @@ Chapter 3. SSL Fucntion } -3.11 int SSL_get_shutdown(const SSL *ssl); +3.11 int ``SSL_get_shutdown``(const SSL *ssl) - Arguments : ssl - SSL point + Arguments:: - Return : shutdown mode + ssl - SSL point + + Return:: + + shutdown mode - Description : get SSL shutdown mode + Description:: - Example : + get SSL shutdown mode + + Example:: void example(void) { @@ -545,15 +690,21 @@ Chapter 3. SSL Fucntion } -3.12 void SSL_set_shutdown(SSL *ssl, int mode); +3.12 void ``SSL_set_shutdown``(SSL *ssl, int mode) - Arguments : ssl - SSL point + Arguments:: - Return : shutdown mode + ssl - SSL point + + Return:: + + shutdown mode - Description : set SSL shutdown mode + Description:: - Example : + set SSL shutdown mode + + Example:: void example(void) { @@ -566,15 +717,21 @@ Chapter 3. SSL Fucntion } -3.13 const SSL_METHOD *SSL_get_ssl_method(SSL *ssl); +3.13 const SSL_METHOD* ``SSL_get_ssl_method``(SSL *ssl) - Arguments : ssl - SSL point + Arguments:: - Return : SSL method + ssl - SSL point + + Return:: + + SSL method - Description : set SSL shutdown mode + Description:: - Example : + set SSL shutdown mode + + Example:: void example(void) { @@ -587,18 +744,23 @@ Chapter 3. SSL Fucntion } -3.14 int SSL_set_ssl_method(SSL *ssl, const SSL_METHOD *method); +3.14 int ``SSL_set_ssl_method``(SSL *ssl, const SSL_METHOD *method) - Arguments : ssl - SSL point - meth - SSL method point + Arguments:: + + ssl - SSL point + meth - SSL method point + + Return:: - Return : result 1 : OK 0 : failed - Description : set the SSL method + Description:: - Example : + set the SSL method + + Example:: void example(void) { @@ -612,15 +774,21 @@ Chapter 3. SSL Fucntion } -3.15 int SSL_pending(const SSL *ssl); +3.15 int ``SSL_pending``(const SSL *ssl) - Arguments : ssl - SSL point + Arguments:: - Return : data bytes + ssl - SSL point + + Return:: + + data bytes - Description : get received data bytes + Description:: - Example : + get received data bytes + + Example:: void example(void) { @@ -633,17 +801,22 @@ Chapter 3. SSL Fucntion } -3.16 int SSL_has_pending(const SSL *ssl); +3.16 int ``SSL_has_pending``(const SSL *ssl) - Arguments : ssl - SSL point + Arguments:: + + ssl - SSL point + + Return:: - Return : result 1 : Yes 0 : No - Description : check if data is received + Description:: - Example : + check if data is received + + Example:: void example(void) { @@ -656,17 +829,22 @@ Chapter 3. SSL Fucntion } -3.17 int SSL_get_fd(const SSL *ssl); +3.17 int ``SSL_get_fd``(const SSL *ssl) - Arguments : ssl - SSL point + Arguments:: + + ssl - SSL point + + Return:: - Return : result >= 0 : socket id < 0 : a error catch - Description : get the socket of the SSL + Description:: - Example : + get the socket of the SSL + + Example:: void example(void) { @@ -679,17 +857,22 @@ Chapter 3. SSL Fucntion } -3.18 int SSL_get_rfd(const SSL *ssl); +3.18 int ``SSL_get_rfd``(const SSL *ssl) - Arguments : ssl - SSL point + Arguments:: + + ssl - SSL point + + Return:: - Return : result >= 0 : socket id < 0 : a error catch - Description : get the read only socket of the SSL + Description:: - Example : + get the read only socket of the SSL + + Example:: void example(void) { @@ -702,17 +885,22 @@ Chapter 3. SSL Fucntion } -3.19 int SSL_get_wfd(const SSL *ssl); +3.19 int ``SSL_get_wfd``(const SSL *ssl) - Arguments : ssl - SSL point + Arguments:: + + ssl - SSL point + + Return:: - Return : result >= 0 : socket id < 0 : a error catch - Description : get the write only socket of the SSL + Description:: - Example : + get the write only socket of the SSL + + Example:: void example(void) { @@ -725,18 +913,23 @@ Chapter 3. SSL Fucntion } -3.20 int SSL_set_fd(SSL *ssl, int fd); +3.20 int ``SSL_set_fd``(SSL *ssl, int fd) - Arguments : ssl - SSL point - fd - socket id + Arguments:: + + ssl - SSL point + fd - socket id + + Return:: - Return : result 1 : OK 0 : failed - Description : set socket to SSL + Description:: - Example : + set socket to SSL + + Example:: void example(void) { @@ -750,18 +943,23 @@ Chapter 3. SSL Fucntion } -3.21 int SSL_set_rfd(SSL *ssl, int fd); +3.21 int ``SSL_set_rfd``(SSL *ssl, int fd) - Arguments : ssl - SSL point - fd - socket id + Arguments:: + + ssl - SSL point + fd - socket id + + Return:: - Return : result 1 : OK 0 : failed - Description : set read only socket to SSL + Description:: - Example : + set read only socket to SSL + + Example:: void example(void) { @@ -775,18 +973,23 @@ Chapter 3. SSL Fucntion } -3.22 int SSL_set_wfd(SSL *ssl, int fd); +3.22 int ``SSL_set_wfd``(SSL *ssl, int fd) - Arguments : ssl - SSL point - fd - socket id + Arguments:: + + ssl - SSL point + fd - socket id + + Return:: - Return : result 1 : OK 0 : failed - Description : set write only socket to SSL + Description:: - Example : + set write only socket to SSL + + Example:: void example(void) { @@ -800,15 +1003,21 @@ Chapter 3. SSL Fucntion } -3.23 int SSL_version(const SSL *ssl); +3.23 int ``SSL_version``(const SSL *ssl) - Arguments : ssl - SSL point + Arguments:: - Return : SSL version + ssl - SSL point + + Return:: + + SSL version - Description : get SSL version + Description:: - Example : + get SSL version + + Example:: void example(void) { @@ -821,15 +1030,21 @@ Chapter 3. SSL Fucntion } -3.24 const char *SSL_get_version(const SSL *ssl); +3.24 const char* ``SSL_get_version``(const SSL *ssl) - Arguments : ssl - SSL point + Arguments:: - Return : SSL version string + ssl - SSL point + + Return:: + + SSL version string - Description : get the SSL current version string + Description:: - Example : + get the SSL current version string + + Example:: void example(void) { @@ -842,15 +1057,21 @@ Chapter 3. SSL Fucntion } -3.25 OSSL_HANDSHAKE_STATE SSL_get_state(const SSL *ssl); +3.25 OSSL_HANDSHAKE_STATE ``SSL_get_state``(const SSL *ssl) - Arguments : ssl - SSL point + Arguments:: - Return : SSL state + ssl - SSL point + + Return:: + + SSL state - Description : get the SSL state + Description:: - Example : + get the SSL state + + Example:: void example(void) { @@ -863,15 +1084,21 @@ Chapter 3. SSL Fucntion } -3.26 const char *SSL_alert_desc_string(int value); +3.26 const char* ``SSL_alert_desc_string``(int value) - Arguments : value - SSL description + Arguments:: - Return : alert value string + value - SSL description + + Return:: + + alert value string - Description : get alert description string + Description:: - Example : + get alert description string + + Example:: void example(void) { @@ -884,15 +1111,21 @@ Chapter 3. SSL Fucntion } -3.27 const char *SSL_alert_desc_string_long(int value); +3.27 const char* ``SSL_alert_desc_string_long``(int value) - Arguments : value - SSL description + Arguments:: - Return : alert value long string + value - SSL description + + Return:: + + alert value long string - Description : get alert description long string + Description:: - Example : + get alert description long string + + Example:: void example(void) { @@ -905,15 +1138,21 @@ Chapter 3. SSL Fucntion } -3.28 const char *SSL_alert_type_string(int value); +3.28 const char* ``SSL_alert_type_string``(int value) - Arguments : value - SSL type description + Arguments:: - Return : alert type string + value - SSL type description + + Return:: + + alert type string - Description : get alert type string + Description:: - Example : + get alert type string + + Example:: void example(void) { @@ -926,15 +1165,21 @@ Chapter 3. SSL Fucntion } -3.29 const char *SSL_alert_type_string_long(int value); +3.29 const char* ``SSL_alert_type_string_long``(int value) - Arguments : value - SSL type description + Arguments:: - Return : alert type long string + value - SSL type description + + Return:: + + alert type long string - Description : get alert type long string + Description:: - Example : + get alert type long string + + Example:: void example(void) { @@ -946,15 +1191,21 @@ Chapter 3. SSL Fucntion str = SSL_alert_type_string_long(val); } -3.30 const char *SSL_rstate_string(SSL *ssl); +3.30 const char* ``SSL_rstate_string``(SSL *ssl) - Arguments : ssl - SSL point + Arguments:: - Return : state string + ssl - SSL point + + Return:: + + state string - Description : get the state string where SSL is reading + Description:: - Example : + get the state string where SSL is reading + + Example:: void example(void) { @@ -967,15 +1218,21 @@ Chapter 3. SSL Fucntion } -3.31 const char *SSL_rstate_string_long(SSL *ssl); +3.31 const char* ``SSL_rstate_string_long``(SSL *ssl) - Arguments : ssl - SSL point + Arguments:: - Return : state long string + ssl - SSL point + + Return:: + + state long string - Description : get the state long string where SSL is reading + Description:: - Example : + get the state long string where SSL is reading + + Example:: void example(void) { @@ -988,15 +1245,48 @@ Chapter 3. SSL Fucntion } -3.32 char *SSL_state_string(const SSL *ssl); +3.32 const char* ``SSL_state_string``(const SSL *ssl) - Arguments : ssl - SSL point + Arguments:: - Return : state string + ssl - SSL point + + Return:: + + state string - Description : get the state string + Description:: - Example : + get the state string + + Example:: + + void example(void) + { + SSL *ssl; + const char *str; + + ... ... + + str = SSL_state_string(ssl); + } + + +3.33 char* ``SSL_state_string_long``(const SSL *ssl) + + Arguments:: + + ssl - SSL point + + Return:: + + state long string + + Description:: + + get the state long string + + Example:: void example(void) { @@ -1009,37 +1299,22 @@ Chapter 3. SSL Fucntion } -3.33 char *SSL_state_string_long(const SSL *ssl); +3.34 int ``SSL_get_error``(const SSL *ssl, int ret_code) - Arguments : ssl - SSL point + Arguments:: - Return : state long string + ssl - SSL point + ret_code - SSL return code + + Return:: + + SSL error number - Description : get the state long string + Description:: - Example : + get SSL error code - void example(void) - { - SSL *ssl; - char *str; - - ... ... - - str = SSL_state_string(ssl); - } - - -3.34 int SSL_get_error(const SSL *ssl, int ret_code); - - Arguments : ssl - SSL point - ret_code - SSL return code - - Return : SSL error number - - Description : get SSL error code - - Example : + Example:: void example(void) { @@ -1052,16 +1327,22 @@ Chapter 3. SSL Fucntion err = SSL_get_error(ssl, ret); } -3.35 void SSL_CTX_set_default_read_buffer_len(SSL_CTX *ctx, size_t len); +3.35 void ``SSL_CTX_set_default_read_buffer_len``(SSL_CTX *ctx, size_t len) - Arguments : ctx - SSL context point - len - read buffer length + Arguments:: - Return : none + ctx - SSL context point + len - read buffer length + + Return:: + + none - Description : set the SSL context read buffer length + Description:: - Example : + set the SSL context read buffer length + + Example:: void example(void) { @@ -1074,16 +1355,22 @@ Chapter 3. SSL Fucntion } -3.36 void SSL_set_default_read_buffer_len(SSL *ssl, size_t len); +3.36 void ``SSL_set_default_read_buffer_len``(SSL *ssl, size_t len) - Arguments : ssl - SSL point - len - read buffer length + Arguments:: - Return : none + ssl - SSL point + len - read buffer length + + Return:: + + none - Description : set the SSL read buffer length + Description:: - Example : + set the SSL read buffer length + + Example:: void example(void) { @@ -1096,15 +1383,21 @@ Chapter 3. SSL Fucntion } -3.37 int SSL_want(const SSL *ssl); +3.37 int ``SSL_want``(const SSL *ssl) - Arguments : ssl - SSL point + Arguments:: - Return : specifical statement + ssl - SSL point + + Return:: + + specifical statement - Description : get the SSL specifical statement + Description:: - Example : + get the SSL specifical statement + + Example:: void example(void) { @@ -1117,17 +1410,22 @@ Chapter 3. SSL Fucntion } -3.38 int SSL_want_nothing(const SSL *ssl); +3.38 int ``SSL_want_nothing``(const SSL *ssl) - Arguments : ssl - SSL point + Arguments:: + + ssl - SSL point + + Return:: - Return : result 0 : false 1 : true - Description : check if SSL want nothing + Description:: - Example : + check if SSL want nothing + + Example:: void example(void) { @@ -1140,17 +1438,22 @@ Chapter 3. SSL Fucntion } -3.39 int SSL_want_read(const SSL *ssl); +3.39 int ``SSL_want_read``(const SSL *ssl) - Arguments : ssl - SSL point + Arguments:: + + ssl - SSL point + + Return:: - Return : result 0 : false 1 : true - Description : check if SSL want to read + Description:: - Example : + check if SSL want to read + + Example:: void example(void) { @@ -1163,17 +1466,22 @@ Chapter 3. SSL Fucntion } -3.40 int SSL_want_write(const SSL *ssl); +3.40 int ``SSL_want_write``(const SSL *ssl) - Arguments : ssl - SSL point + Arguments:: + + ssl - SSL point + + Return:: - Return : result 0 : false 1 : true - Description : check if SSL want to write + Description:: - Example : + check if SSL want to write + + Example:: void example(void) { @@ -1189,18 +1497,25 @@ Chapter 3. SSL Fucntion Chapter 4. SSL X509 Certification and Private Key Function ========================================================== -4.1 X509* d2i_X509(X509 **cert, const unsigned char *buffer, long len); - Arguments : cert - a point pointed to X509 certification - buffer - a point pointed to the certification context memory point - length - certification bytes +4.1 X509* ``d2i_X509``(X509 **cert, const unsigned char *buffer, long len) + + Arguments:: - Return : X509 certification object point + cert - a point pointed to X509 certification + buffer - a point pointed to the certification context memory point + length - certification bytes + + Return:: + + X509 certification object point - Description : load a character certification context into system context. If '*cert' is pointed to the - certification, then load certification into it. Or create a new X509 certification object + Description:: - Example : + load a character certification context into system context. If '*cert' is pointed to the + certification, then load certification into it. Or create a new X509 certification object + + Example:: void example(void) { @@ -1214,18 +1529,23 @@ Chapter 4. SSL X509 Certification and Private Key Function } -4.2 int SSL_add_client_CA(SSL *ssl, X509 *x); +4.2 int ``SSL_add_client_CA``(SSL *ssl, X509 *x) - Arguments : ssl - SSL point - x - CA certification point + Arguments:: - Return : result + ssl - SSL point + x - CA certification point + + Return:: + 1 : OK 0 : failed - Description : add CA client certification into the SSL + Description:: - Example : + add CA client certification into the SSL + + Example:: void example(void) { @@ -1239,18 +1559,23 @@ Chapter 4. SSL X509 Certification and Private Key Function } -4.3 int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x); +4.3 int ``SSL_CTX_add_client_CA``(SSL_CTX *ctx, X509 *x) - Arguments : ctx - SSL context point - x - CA certification point + Arguments:: - Return : result + ctx - SSL context point + x - CA certification point + + Return:: + 1 : OK 0 : failed - Description : add CA client certification into the SSL context + Description:: - Example : + add CA client certification into the SSL context + + Example:: void example(void) { @@ -1264,15 +1589,21 @@ Chapter 4. SSL X509 Certification and Private Key Function } -4.4 X509 *SSL_get_certificate(const SSL *ssl); +4.4 X509* ``SSL_get_certificate``(const SSL *ssl) - Arguments : ssl - SSL point + Arguments:: - Return : SSL certification point + ssl - SSL point + + Return:: + + SSL certification point - Description : get the SSL certification point + Description:: - Example : + get the SSL certification point + + Example:: void example(void) { @@ -1285,15 +1616,21 @@ Chapter 4. SSL X509 Certification and Private Key Function } -4.5 long SSL_get_verify_result(const SSL *ssl); +4.5 long ``SSL_get_verify_result``(const SSL *ssl) - Arguments : ssl - SSL point + Arguments:: - Return : the result of verifying + ssl - SSL point + + Return:: + + the result of verifying - Description : get the verifying result of the SSL certification + Description:: - Example : + get the verifying result of the SSL certification + + Example:: void example(void) { @@ -1306,18 +1643,23 @@ Chapter 4. SSL X509 Certification and Private Key Function } -4.6 int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x); +4.6 int ``SSL_CTX_use_certificate``(SSL_CTX *ctx, X509 *x) - Arguments : ctx - the SSL context point - pkey - certification object point + Arguments:: + + ctx - the SSL context point + pkey - certification object point + + Return:: - Return : result 1 : OK 0 : failed - Description : load the certification into the SSL_CTX or SSL object + Description:: - Example : + load the certification into the SSL_CTX or SSL object + + Example:: void example(void) { @@ -1331,19 +1673,24 @@ Chapter 4. SSL X509 Certification and Private Key Function } -4.7 int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d); +4.7 int ``SSL_CTX_use_certificate_ASN1``(SSL_CTX *ctx, int len, const unsigned char *d) - Arguments : ctx - SSL context point - len - certification length - d - data point + Arguments:: - Return : result + ctx - SSL context point + len - certification length + d - data point + + Return:: + 1 : OK 0 : failed - Description : load the ASN1 certification into SSL context + Description:: - Example : + load the ASN1 certification into SSL context + + Example:: void example(void) { @@ -1358,18 +1705,23 @@ Chapter 4. SSL X509 Certification and Private Key Function } -4.8 int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey); +4.8 int ``SSL_CTX_use_PrivateKey``(SSL_CTX *ctx, EVP_PKEY *pkey) - Arguments : ctx - SSL context point - pkey - private key object point + Arguments:: - Return : result + ctx - SSL context point + pkey - private key object point + + Return:: + 1 : OK 0 : failed - Description : load the private key into the context object + Description:: - Example : + load the private key into the context object + + Example:: void example(void) { @@ -1383,19 +1735,24 @@ Chapter 4. SSL X509 Certification and Private Key Function } -4.9 int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, const unsigned char *d, long len); +4.9 int ``SSL_CTX_use_PrivateKey_ASN1``(int pk, SSL_CTX *ctx, const unsigned char *d, long len) - Arguments : ctx - SSL context point - d - data point - len - private key length + Arguments:: + + ctx - SSL context point + d - data point + len - private key length + + Return:: - Return : result 1 : OK 0 : failed - Description : load the ASN1 private key into SSL context + Description:: - Example : + load the ASN1 private key into SSL context + + Example:: void example(void) { @@ -1411,19 +1768,24 @@ Chapter 4. SSL X509 Certification and Private Key Function } -4.10 int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len); +4.10 int ``SSL_CTX_use_RSAPrivateKey_ASN1``(SSL_CTX *ctx, const unsigned char *d, long len) - Arguments : ctx - SSL context point - d - data point - len - private key length + Arguments:: + + ctx - SSL context point + d - data point + len - private key length + + Return:: - Return : result 1 : OK 0 : failed - Description : load the RSA ASN1 private key into SSL context + Description:: - Example : + load the RSA ASN1 private key into SSL context + + Example:: void example(void) { @@ -1438,19 +1800,24 @@ Chapter 4. SSL X509 Certification and Private Key Function } -4.11 int SSL_use_certificate_ASN1(SSL *ssl, int len, const unsigned char *d); +4.11 int ``SSL_use_certificate_ASN1``(SSL *ssl, int len, const unsigned char *d) - Arguments : ssl - SSL point - len - data bytes - d - data point + Arguments:: + + ssl - SSL point + len - data bytes + d - data point + + Return:: - Return : result 1 : OK 0 : failed - Description : load certification into the SSL + Description:: - Example : + load certification into the SSL + + Example:: void example(void) { @@ -1465,15 +1832,21 @@ Chapter 4. SSL X509 Certification and Private Key Function } -4.12 X509 *SSL_get_peer_certificate(const SSL *ssl); +4.12 X509* ``SSL_get_peer_certificate``(const SSL *ssl) - Arguments : ssl - SSL point + Arguments:: - Return : peer certification + ssl - SSL point + + Return:: + + peer certification - Description : get peer certification + Description:: - Example : + get peer certification + + Example:: void example(void) { From de587a2e0d1418d45c9b7880ed07a68237975f3d Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Wed, 28 Sep 2016 20:46:45 +0800 Subject: [PATCH 039/343] components/openssl: fix .rst file encoding error --- components/openssl/OpenSSL-APIs.rst | 132 ++++++++++++++-------------- 1 file changed, 66 insertions(+), 66 deletions(-) diff --git a/components/openssl/OpenSSL-APIs.rst b/components/openssl/OpenSSL-APIs.rst index cb90a23c93..6a8a68c1ff 100644 --- a/components/openssl/OpenSSL-APIs.rst +++ b/components/openssl/OpenSSL-APIs.rst @@ -18,7 +18,7 @@ Chapter 1. SSL Context Method Create ==================================== -1.1 const SSL_METHOD* ``SSLv23_client_method``(void) +1.1 const SSL_METHOD* ``SSLv23_client_method`` (void) Arguments:: @@ -42,7 +42,7 @@ Chapter 1. SSL Context Method Create } -1.2 const SSL_METHOD* ``TLSv1_client_method``(void) +1.2 const SSL_METHOD* ``TLSv1_client_method`` (void) Arguments:: @@ -66,7 +66,7 @@ Chapter 1. SSL Context Method Create } -1.3 const SSL_METHOD* ``SSLv3_client_method``(void) +1.3 const SSL_METHOD* ``SSLv3_client_method`` (void) Arguments:: @@ -90,7 +90,7 @@ Chapter 1. SSL Context Method Create } -1.4 const SSL_METHOD* ``TLSv1_1_client_method``(void) +1.4 const SSL_METHOD* ``TLSv1_1_client_method`` (void) Arguments:: @@ -114,7 +114,7 @@ Chapter 1. SSL Context Method Create } -1.5 const SSL_METHOD* ``TLSv1_2_client_method``(void) +1.5 const SSL_METHOD* ``TLSv1_2_client_method`` (void) Arguments:: @@ -138,7 +138,7 @@ Chapter 1. SSL Context Method Create } -1.6 const SSL_METHOD* ``SSLv23_server_method``(void) +1.6 const SSL_METHOD* ``SSLv23_server_method`` (void) Arguments:: @@ -162,7 +162,7 @@ Chapter 1. SSL Context Method Create } -1.7 const SSL_METHOD* ``TLSv1_1_server_method``(void) +1.7 const SSL_METHOD* ``TLSv1_1_server_method`` (void) Arguments:: @@ -186,7 +186,7 @@ Chapter 1. SSL Context Method Create } -1.8 const SSL_METHOD* ``TLSv1_2_server_method``(void) +1.8 const SSL_METHOD* ``TLSv1_2_server_method`` (void) Arguments:: @@ -210,7 +210,7 @@ Chapter 1. SSL Context Method Create } -1.9 const SSL_METHOD* ``TLSv1_server_method``(void) +1.9 const SSL_METHOD* ``TLSv1_server_method`` (void) Arguments:: @@ -234,7 +234,7 @@ Chapter 1. SSL Context Method Create } -1.10 const SSL_METHOD* ``SSLv3_server_method``(void) +1.10 const SSL_METHOD* ``SSLv3_server_method`` (void) Arguments:: @@ -263,7 +263,7 @@ Chapter 2. SSL Context Fucntion =============================== -2.1 SSL_CTX* ``SSL_CTX_new``(const SSL_METHOD *method) +2.1 SSL_CTX* ``SSL_CTX_new`` (const SSL_METHOD *method) Arguments:: @@ -287,7 +287,7 @@ Chapter 2. SSL Context Fucntion } -2.2 ``void SSL_CTX_free``(SSL_CTX *ctx) +2.2 ``void SSL_CTX_free`` (SSL_CTX *ctx) Arguments:: @@ -313,7 +313,7 @@ Chapter 2. SSL Context Fucntion } -2.3 ``int SSL_CTX_set_ssl_version``(SSL_CTX *ctx, const SSL_METHOD *meth) +2.3 ``int SSL_CTX_set_ssl_version`` (SSL_CTX *ctx, const SSL_METHOD *meth) Arguments:: @@ -342,7 +342,7 @@ Chapter 2. SSL Context Fucntion } -2.4 const SSL_METHOD* ``SSL_CTX_get_ssl_method``(SSL_CTX *ctx) +2.4 const SSL_METHOD* ``SSL_CTX_get_ssl_method`` (SSL_CTX *ctx) Arguments:: @@ -374,7 +374,7 @@ Chapter 3. SSL Fucntion ======================= -3.1 SSL* ``SSL_new``(SSL_CTX *ctx) +3.1 SSL* ``SSL_new`` (SSL_CTX *ctx) Arguments:: @@ -401,7 +401,7 @@ Chapter 3. SSL Fucntion } -3.2 void ``SSL_free``(SSL *ssl) +3.2 void ``SSL_free`` (SSL *ssl) Arguments:: @@ -427,7 +427,7 @@ Chapter 3. SSL Fucntion } -3.3 int ``SSL_do_handshake``(SSL *ssl) +3.3 int ``SSL_do_handshake`` (SSL *ssl) Arguments:: @@ -456,7 +456,7 @@ Chapter 3. SSL Fucntion } -3.4 int ``SSL_connect``(SSL *ssl) +3.4 int ``SSL_connect`` (SSL *ssl) Arguments:: @@ -485,7 +485,7 @@ Chapter 3. SSL Fucntion } -3.5 int ``SSL_accept``(SSL *ssl) +3.5 int ``SSL_accept`` (SSL *ssl) Arguments:: @@ -514,7 +514,7 @@ Chapter 3. SSL Fucntion } -3.6 int ``SSL_shutdown``(SSL *ssl) +3.6 int ``SSL_shutdown`` (SSL *ssl) Arguments:: @@ -543,7 +543,7 @@ Chapter 3. SSL Fucntion } -3.7 int ``SSL_clear``(SSL *ssl) +3.7 int ``SSL_clear`` (SSL *ssl) Arguments:: @@ -571,7 +571,7 @@ Chapter 3. SSL Fucntion } -3.8 int ``SSL_read``(SSL *ssl, void *buffer, int len) +3.8 int ``SSL_read`` (SSL *ssl, void *buffer, int len) Arguments:: @@ -603,7 +603,7 @@ Chapter 3. SSL Fucntion ret = SSL_read(ssl, buf, len); } -3.9 int ``SSL_write``(SSL *ssl, const void *buffer, int len) +3.9 int ``SSL_write`` (SSL *ssl, const void *buffer, int len) Arguments:: @@ -636,7 +636,7 @@ Chapter 3. SSL Fucntion } -3.10 ``SSL_CTX *SSL_get_SSL_CTX``(const SSL *ssl) +3.10 ``SSL_CTX *SSL_get_SSL_CTX`` (const SSL *ssl) Arguments:: @@ -663,7 +663,7 @@ Chapter 3. SSL Fucntion } -3.11 int ``SSL_get_shutdown``(const SSL *ssl) +3.11 int ``SSL_get_shutdown`` (const SSL *ssl) Arguments:: @@ -690,7 +690,7 @@ Chapter 3. SSL Fucntion } -3.12 void ``SSL_set_shutdown``(SSL *ssl, int mode) +3.12 void ``SSL_set_shutdown`` (SSL *ssl, int mode) Arguments:: @@ -717,7 +717,7 @@ Chapter 3. SSL Fucntion } -3.13 const SSL_METHOD* ``SSL_get_ssl_method``(SSL *ssl) +3.13 const SSL_METHOD* ``SSL_get_ssl_method`` (SSL *ssl) Arguments:: @@ -744,7 +744,7 @@ Chapter 3. SSL Fucntion } -3.14 int ``SSL_set_ssl_method``(SSL *ssl, const SSL_METHOD *method) +3.14 int ``SSL_set_ssl_method`` (SSL *ssl, const SSL_METHOD *method) Arguments:: @@ -774,7 +774,7 @@ Chapter 3. SSL Fucntion } -3.15 int ``SSL_pending``(const SSL *ssl) +3.15 int ``SSL_pending`` (const SSL *ssl) Arguments:: @@ -801,7 +801,7 @@ Chapter 3. SSL Fucntion } -3.16 int ``SSL_has_pending``(const SSL *ssl) +3.16 int ``SSL_has_pending`` (const SSL *ssl) Arguments:: @@ -829,7 +829,7 @@ Chapter 3. SSL Fucntion } -3.17 int ``SSL_get_fd``(const SSL *ssl) +3.17 int ``SSL_get_fd`` (const SSL *ssl) Arguments:: @@ -857,7 +857,7 @@ Chapter 3. SSL Fucntion } -3.18 int ``SSL_get_rfd``(const SSL *ssl) +3.18 int ``SSL_get_rfd`` (const SSL *ssl) Arguments:: @@ -885,7 +885,7 @@ Chapter 3. SSL Fucntion } -3.19 int ``SSL_get_wfd``(const SSL *ssl) +3.19 int ``SSL_get_wfd`` (const SSL *ssl) Arguments:: @@ -913,7 +913,7 @@ Chapter 3. SSL Fucntion } -3.20 int ``SSL_set_fd``(SSL *ssl, int fd) +3.20 int ``SSL_set_fd`` (SSL *ssl, int fd) Arguments:: @@ -943,7 +943,7 @@ Chapter 3. SSL Fucntion } -3.21 int ``SSL_set_rfd``(SSL *ssl, int fd) +3.21 int ``SSL_set_rfd`` (SSL *ssl, int fd) Arguments:: @@ -973,7 +973,7 @@ Chapter 3. SSL Fucntion } -3.22 int ``SSL_set_wfd``(SSL *ssl, int fd) +3.22 int ``SSL_set_wfd`` (SSL *ssl, int fd) Arguments:: @@ -1003,7 +1003,7 @@ Chapter 3. SSL Fucntion } -3.23 int ``SSL_version``(const SSL *ssl) +3.23 int ``SSL_version`` (const SSL *ssl) Arguments:: @@ -1030,7 +1030,7 @@ Chapter 3. SSL Fucntion } -3.24 const char* ``SSL_get_version``(const SSL *ssl) +3.24 const char* ``SSL_get_version`` (const SSL *ssl) Arguments:: @@ -1057,7 +1057,7 @@ Chapter 3. SSL Fucntion } -3.25 OSSL_HANDSHAKE_STATE ``SSL_get_state``(const SSL *ssl) +3.25 OSSL_HANDSHAKE_STATE ``SSL_get_state`` (const SSL *ssl) Arguments:: @@ -1084,7 +1084,7 @@ Chapter 3. SSL Fucntion } -3.26 const char* ``SSL_alert_desc_string``(int value) +3.26 const char* ``SSL_alert_desc_string`` (int value) Arguments:: @@ -1111,7 +1111,7 @@ Chapter 3. SSL Fucntion } -3.27 const char* ``SSL_alert_desc_string_long``(int value) +3.27 const char* ``SSL_alert_desc_string_long`` (int value) Arguments:: @@ -1138,7 +1138,7 @@ Chapter 3. SSL Fucntion } -3.28 const char* ``SSL_alert_type_string``(int value) +3.28 const char* ``SSL_alert_type_string`` (int value) Arguments:: @@ -1165,7 +1165,7 @@ Chapter 3. SSL Fucntion } -3.29 const char* ``SSL_alert_type_string_long``(int value) +3.29 const char* ``SSL_alert_type_string_long`` (int value) Arguments:: @@ -1191,7 +1191,7 @@ Chapter 3. SSL Fucntion str = SSL_alert_type_string_long(val); } -3.30 const char* ``SSL_rstate_string``(SSL *ssl) +3.30 const char* ``SSL_rstate_string`` (SSL *ssl) Arguments:: @@ -1218,7 +1218,7 @@ Chapter 3. SSL Fucntion } -3.31 const char* ``SSL_rstate_string_long``(SSL *ssl) +3.31 const char* ``SSL_rstate_string_long`` (SSL *ssl) Arguments:: @@ -1245,7 +1245,7 @@ Chapter 3. SSL Fucntion } -3.32 const char* ``SSL_state_string``(const SSL *ssl) +3.32 const char* ``SSL_state_string`` (const SSL *ssl) Arguments:: @@ -1272,7 +1272,7 @@ Chapter 3. SSL Fucntion } -3.33 char* ``SSL_state_string_long``(const SSL *ssl) +3.33 char* ``SSL_state_string_long`` (const SSL *ssl) Arguments:: @@ -1299,7 +1299,7 @@ Chapter 3. SSL Fucntion } -3.34 int ``SSL_get_error``(const SSL *ssl, int ret_code) +3.34 int ``SSL_get_error`` (const SSL *ssl, int ret_code) Arguments:: @@ -1327,7 +1327,7 @@ Chapter 3. SSL Fucntion err = SSL_get_error(ssl, ret); } -3.35 void ``SSL_CTX_set_default_read_buffer_len``(SSL_CTX *ctx, size_t len) +3.35 void ``SSL_CTX_set_default_read_buffer_len`` (SSL_CTX *ctx, size_t len) Arguments:: @@ -1355,7 +1355,7 @@ Chapter 3. SSL Fucntion } -3.36 void ``SSL_set_default_read_buffer_len``(SSL *ssl, size_t len) +3.36 void ``SSL_set_default_read_buffer_len`` (SSL *ssl, size_t len) Arguments:: @@ -1383,7 +1383,7 @@ Chapter 3. SSL Fucntion } -3.37 int ``SSL_want``(const SSL *ssl) +3.37 int ``SSL_want`` (const SSL *ssl) Arguments:: @@ -1410,7 +1410,7 @@ Chapter 3. SSL Fucntion } -3.38 int ``SSL_want_nothing``(const SSL *ssl) +3.38 int ``SSL_want_nothing`` (const SSL *ssl) Arguments:: @@ -1438,7 +1438,7 @@ Chapter 3. SSL Fucntion } -3.39 int ``SSL_want_read``(const SSL *ssl) +3.39 int ``SSL_want_read`` (const SSL *ssl) Arguments:: @@ -1466,7 +1466,7 @@ Chapter 3. SSL Fucntion } -3.40 int ``SSL_want_write``(const SSL *ssl) +3.40 int ``SSL_want_write`` (const SSL *ssl) Arguments:: @@ -1498,7 +1498,7 @@ Chapter 4. SSL X509 Certification and Private Key Function ========================================================== -4.1 X509* ``d2i_X509``(X509 **cert, const unsigned char *buffer, long len) +4.1 X509* ``d2i_X509`` (X509 **cert, const unsigned char *buffer, long len) Arguments:: @@ -1529,7 +1529,7 @@ Chapter 4. SSL X509 Certification and Private Key Function } -4.2 int ``SSL_add_client_CA``(SSL *ssl, X509 *x) +4.2 int ``SSL_add_client_CA`` (SSL *ssl, X509 *x) Arguments:: @@ -1559,7 +1559,7 @@ Chapter 4. SSL X509 Certification and Private Key Function } -4.3 int ``SSL_CTX_add_client_CA``(SSL_CTX *ctx, X509 *x) +4.3 int ``SSL_CTX_add_client_CA`` (SSL_CTX *ctx, X509 *x) Arguments:: @@ -1589,7 +1589,7 @@ Chapter 4. SSL X509 Certification and Private Key Function } -4.4 X509* ``SSL_get_certificate``(const SSL *ssl) +4.4 X509* ``SSL_get_certificate`` (const SSL *ssl) Arguments:: @@ -1616,7 +1616,7 @@ Chapter 4. SSL X509 Certification and Private Key Function } -4.5 long ``SSL_get_verify_result``(const SSL *ssl) +4.5 long ``SSL_get_verify_result`` (const SSL *ssl) Arguments:: @@ -1643,7 +1643,7 @@ Chapter 4. SSL X509 Certification and Private Key Function } -4.6 int ``SSL_CTX_use_certificate``(SSL_CTX *ctx, X509 *x) +4.6 int ``SSL_CTX_use_certificate`` (SSL_CTX *ctx, X509 *x) Arguments:: @@ -1673,7 +1673,7 @@ Chapter 4. SSL X509 Certification and Private Key Function } -4.7 int ``SSL_CTX_use_certificate_ASN1``(SSL_CTX *ctx, int len, const unsigned char *d) +4.7 int ``SSL_CTX_use_certificate_ASN1`` (SSL_CTX *ctx, int len, const unsigned char *d) Arguments:: @@ -1705,7 +1705,7 @@ Chapter 4. SSL X509 Certification and Private Key Function } -4.8 int ``SSL_CTX_use_PrivateKey``(SSL_CTX *ctx, EVP_PKEY *pkey) +4.8 int ``SSL_CTX_use_PrivateKey`` (SSL_CTX *ctx, EVP_PKEY *pkey) Arguments:: @@ -1735,7 +1735,7 @@ Chapter 4. SSL X509 Certification and Private Key Function } -4.9 int ``SSL_CTX_use_PrivateKey_ASN1``(int pk, SSL_CTX *ctx, const unsigned char *d, long len) +4.9 int ``SSL_CTX_use_PrivateKey_ASN1`` (int pk, SSL_CTX *ctx, const unsigned char *d, long len) Arguments:: @@ -1768,7 +1768,7 @@ Chapter 4. SSL X509 Certification and Private Key Function } -4.10 int ``SSL_CTX_use_RSAPrivateKey_ASN1``(SSL_CTX *ctx, const unsigned char *d, long len) +4.10 int ``SSL_CTX_use_RSAPrivateKey_ASN1`` (SSL_CTX *ctx, const unsigned char *d, long len) Arguments:: @@ -1800,7 +1800,7 @@ Chapter 4. SSL X509 Certification and Private Key Function } -4.11 int ``SSL_use_certificate_ASN1``(SSL *ssl, int len, const unsigned char *d) +4.11 int ``SSL_use_certificate_ASN1`` (SSL *ssl, int len, const unsigned char *d) Arguments:: @@ -1832,7 +1832,7 @@ Chapter 4. SSL X509 Certification and Private Key Function } -4.12 X509* ``SSL_get_peer_certificate``(const SSL *ssl) +4.12 X509* ``SSL_get_peer_certificate`` (const SSL *ssl) Arguments:: From 9c0cd10d4885a03d4cb97a323c88ca7dd96555eb Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 4 Oct 2016 12:37:10 +1100 Subject: [PATCH 040/343] Build system tests: Add test cases for out-of-tree builds (currently failing) See github #38 --- make/test_build_system.sh | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/make/test_build_system.sh b/make/test_build_system.sh index 5be1504e3d..b6aaa9e58f 100755 --- a/make/test_build_system.sh +++ b/make/test_build_system.sh @@ -62,7 +62,7 @@ function run_tests() print_status "Partition CSV file rebuilds partitions" take_build_snapshot touch ${IDF_PATH}/components/partition_table/partitions_singleapp.csv - make partition_table + make partition_table || failure "Failed to build partition table" assert_rebuilt partitions_singleapp.bin assert_not_rebuilt app-template.bin app-template.elf ${BOOTLOADER_BINS} @@ -70,18 +70,31 @@ function run_tests() take_build_snapshot # verify no build files are refreshed by a partial make ALL_BUILD_FILES=$(find ${BUILD} -type f | sed "s@${BUILD}/@@") - make + make || failure "Partial build failed" assert_not_rebuilt ${ALL_BUILD_FILES} print_status "Cleaning should remove all files from build" - make clean + make clean || failure "Failed to make clean" ALL_BUILD_FILES=$(find ${BUILD} -type f) if [ -n "${ALL_BUILD_FILES}" ]; then failure "Files weren't cleaned: ${ALL_BUILD_FILES}" fi + print_status "Moving BUILD_DIR_BASE out of tree should still build OK" + rm -rf --preserve-root ${BUILD}/* + OUTOFTREE_BUILD=${TESTDIR}/alt_build + make BUILD_DIR_BASE=${OUTOFTREE_BUILD} || failure "Failed to build with BUILD_DIR_BASE overriden" + NEW_BUILD_FILES=$(find ${OUTOFREE_BUILD} -type f) + if [ -z "${NEW_BUILD_FILES}" ]; then + failure "No files found in new build directory!" + fi + DEFAULT_BUILD_FILES=$(find ${BUILD} -mindepth 1) + if [ -n "${DEFAULT_BUILD_FILES}" ]; then + failure "Some files were incorrectly put into the default build directory: ${DEFAULT_BUILD_FILES}" + fi + print_status "Can still clean build if all text files are CRLFs" - make clean + make clean || failure "Unexpected failure to make clean" find . -exec unix2dos {} \; # CRLFify template dir # make a copy of esp-idf and CRLFify it CRLF_ESPIDF=${TESTDIR}/esp-idf-crlf @@ -89,12 +102,11 @@ function run_tests() cp -rv ${IDF_PATH}/* ${CRLF_ESPIDF} # don't CRLFify executable files, as Linux will fail to execute them find ${CRLF_ESPIDF} -type f ! -perm 755 -exec unix2dos {} \; - make IDF_PATH=${CRLF_ESPIDF} + make IDF_PATH=${CRLF_ESPIDF} || failure "Failed to build with CRLFs in source" # do the same checks we do for the clean build assert_built ${APP_BINS} ${BOOTLOADER_BINS} partitions_singleapp.bin [ -f ${BUILD}/partition*.bin ] || failure "A partition table should have been built in CRLF mode" - # NOTE: If adding new tests, add them above this CRLF test... print_status "All tests completed" if [ -n "${FAILURES}" ]; then From 66882347e86e142ba0c72c8c3e6fe1a946a25a78 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 4 Oct 2016 15:03:48 +1100 Subject: [PATCH 041/343] build system: Fix out-of-tree building via BUILD_DIR_BASE Closes #38 --- components/bootloader/Makefile.projbuild | 16 +++++----- components/esp32/component.mk | 4 ++- make/common.mk | 2 +- make/project.mk | 3 +- make/project_config.mk | 38 ++++++++++-------------- 5 files changed, 31 insertions(+), 32 deletions(-) diff --git a/components/bootloader/Makefile.projbuild b/components/bootloader/Makefile.projbuild index d45cf144e7..7c5cde3b8c 100644 --- a/components/bootloader/Makefile.projbuild +++ b/components/bootloader/Makefile.projbuild @@ -14,17 +14,18 @@ BOOTLOADER_COMPONENT_PATH := $(COMPONENT_PATH) BOOTLOADER_BUILD_DIR=$(BUILD_DIR_BASE)/bootloader BOOTLOADER_BIN=$(BOOTLOADER_BUILD_DIR)/bootloader.bin +# Custom recursive make for bootloader sub-project +BOOTLOADER_MAKE=$(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src \ + MAKEFLAGS= V=$(V) \ + BUILD_DIR_BASE=$(BOOTLOADER_BUILD_DIR) \ + .PHONY: bootloader-clean bootloader-flash bootloader $(BOOTLOADER_BIN) $(BOOTLOADER_BIN): $(COMPONENT_PATH)/src/sdkconfig - $(Q) PROJECT_PATH= \ - BUILD_DIR_BASE=$(BOOTLOADER_BUILD_DIR) \ - $(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src MAKEFLAGS= V=$(V) TARGET_BIN_LAYOUT="$(BOOTLOADER_TARGET_BIN_LAYOUT)" $(BOOTLOADER_BIN) + $(Q) $(BOOTLOADER_MAKE) $@ bootloader-clean: - $(Q) PROJECT_PATH= \ - BUILD_DIR_BASE=$(BOOTLOADER_BUILD_DIR) \ - $(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src app-clean MAKEFLAGS= V=$(V) + $(Q) $(BOOTLOADER_MAKE) app-clean clean: bootloader-clean @@ -43,7 +44,8 @@ $(COMPONENT_PATH)/src/sdkconfig: $(PROJECT_PATH)/sdkconfig # bootloader-flash calls flash in the bootloader dummy project bootloader-flash: $(BOOTLOADER_BIN) - $(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src flash MAKEFLAGS= V=$(V) + $(BOOTLOADER_MAKE) flash + else CFLAGS += -D BOOTLOADER_BUILD=1 -I $(IDF_PATH)/components/esp32/include diff --git a/components/esp32/component.mk b/components/esp32/component.mk index 6eac77afd3..85040d77a0 100644 --- a/components/esp32/component.mk +++ b/components/esp32/component.mk @@ -6,7 +6,7 @@ # lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable, # please read the esp-idf build system document if you need to do this. # --include $(PROJECT_PATH)/build/include/config/auto.conf +-include $(BUILD_DIR_BASE)/include/config/auto.conf COMPONENT_SRCDIRS := . hwcrypto @@ -44,6 +44,8 @@ $(COMPONENT_LIBRARY): $(ALL_LIB_FILES) # saves us from having to add the target to a Makefile.projbuild $(COMPONENT_LIBRARY): esp32_out.ld +# .. is BUILD_DIR_BASE here, as component makefiles +# are evaluated with CWD=component build dir esp32_out.ld: $(COMPONENT_PATH)/ld/esp32.ld ../include/sdkconfig.h $(CC) -I ../include -C -P -x c -E $< -o $@ diff --git a/make/common.mk b/make/common.mk index a515584a9b..b2917d5c96 100644 --- a/make/common.mk +++ b/make/common.mk @@ -6,7 +6,7 @@ # # (Note that we only rebuild auto.conf automatically for some targets, # see project_config.mk for details.) --include $(PROJECT_PATH)/build/include/config/auto.conf +-include $(BUILD_DIR_BASE)/include/config/auto.conf #Handling of V=1/VERBOSE=1 flag # diff --git a/make/project.mk b/make/project.mk index 35dccaf248..74943334a6 100644 --- a/make/project.mk +++ b/make/project.mk @@ -50,6 +50,7 @@ endif #The directory where we put all objects/libraries/binaries. The project Makefile can #configure this if needed. BUILD_DIR_BASE ?= $(PROJECT_PATH)/build +export BUILD_DIR_BASE #Component directories. These directories are searched for components. #The project Makefile can override these component dirs, or define extra component directories. @@ -105,7 +106,7 @@ COMPONENT_INCLUDES := $(abspath $(foreach comp,$(COMPONENT_PATHS_BUILDABLE),$(ad $(call GetVariable,$(comp),COMPONENT_ADD_INCLUDEDIRS)))) #Also add project include path, for sdk includes -COMPONENT_INCLUDES += $(PROJECT_PATH)/build/include/ +COMPONENT_INCLUDES += $(BUILD_DIR_BASE)/include/ export COMPONENT_INCLUDES #COMPONENT_LDFLAGS has a list of all flags that are needed to link the components together. It's collected diff --git a/make/project_config.mk b/make/project_config.mk index d2909bb308..92937e8bfe 100644 --- a/make/project_config.mk +++ b/make/project_config.mk @@ -13,13 +13,15 @@ $(KCONFIG_TOOL_DIR)/mconf $(KCONFIG_TOOL_DIR)/conf: CC=$(HOSTCC) LD=$(HOSTLD) \ $(MAKE) -C $(KCONFIG_TOOL_DIR) -menuconfig: $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig $(BUILD_DIR_BASE) - $(summary) MENUCONFIG - $(Q) KCONFIG_AUTOHEADER=$(PROJECT_PATH)/build/include/sdkconfig.h \ +# use a wrapper environment for where we run Kconfig tools +KCONFIG_TOOL_ENV=KCONFIG_AUTOHEADER=$(BUILD_DIR_BASE)/include/sdkconfig.h \ KCONFIG_CONFIG=$(PROJECT_PATH)/sdkconfig \ COMPONENT_KCONFIGS="$(COMPONENT_KCONFIGS)" \ - COMPONENT_KCONFIGS_PROJBUILD="$(COMPONENT_KCONFIGS_PROJBUILD)" \ - $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig + COMPONENT_KCONFIGS_PROJBUILD="$(COMPONENT_KCONFIGS_PROJBUILD)" + +menuconfig: $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig $(BUILD_DIR_BASE) + $(summary) MENUCONFIG + $(Q) $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig ifeq ("$(wildcard $(PROJECT_PATH)/sdkconfig)","") #No sdkconfig found. Need to run menuconfig to make this if we need it. @@ -28,17 +30,13 @@ endif defconfig: $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig $(BUILD_DIR_BASE) $(summary) DEFCONFIG - $(Q) mkdir -p $(PROJECT_PATH)/build/include/config - $(Q) KCONFIG_AUTOHEADER=$(PROJECT_PATH)/build/include/sdkconfig.h \ - KCONFIG_CONFIG=$(PROJECT_PATH)/sdkconfig \ - COMPONENT_KCONFIGS="$(COMPONENT_KCONFIGS)" \ - COMPONENT_KCONFIGS_PROJBUILD="$(COMPONENT_KCONFIGS_PROJBUILD)" \ - $(KCONFIG_TOOL_DIR)/conf --olddefconfig $(IDF_PATH)/Kconfig + $(Q) mkdir -p $(BUILD_DIR_BASE)/include/config + $(Q) $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/conf --olddefconfig $(IDF_PATH)/Kconfig # Work out of whether we have to build the Kconfig makefile # (auto.conf), or if we're in a situation where we don't need it NON_CONFIG_TARGETS := clean %-clean get_variable help menuconfig defconfig -AUTO_CONF_REGEN_TARGET := $(PROJECT_PATH)/build/include/config/auto.conf +AUTO_CONF_REGEN_TARGET := $(BUILD_DIR_BASE)/include/config/auto.conf # disable AUTO_CONF_REGEN_TARGET if all targets are non-config targets # (and not building default target) @@ -46,19 +44,15 @@ ifneq ("$(MAKECMDGOALS)","") ifeq ($(filter $(NON_CONFIG_TARGETS), $(MAKECMDGOALS)),$(MAKECMDGOALS)) AUTO_CONF_REGEN_TARGET := # dummy target -$(PROJECT_PATH)/build/include/config/auto.conf: +$(BUILD_DIR_BASE)/include/config/auto.conf: endif endif -$(AUTO_CONF_REGEN_TARGET) $(PROJECT_PATH)/build/include/sdkconfig.h: $(PROJECT_PATH)/sdkconfig $(KCONFIG_TOOL_DIR)/conf $(COMPONENT_KCONFIGS) $(COMPONENT_KCONFIGS_PROJBUILD) +$(AUTO_CONF_REGEN_TARGET) $(BUILD_DIR_BASE)/include/sdkconfig.h: $(PROJECT_PATH)/sdkconfig $(KCONFIG_TOOL_DIR)/conf $(COMPONENT_KCONFIGS) $(COMPONENT_KCONFIGS_PROJBUILD) $(summary) GENCONFIG - $(Q) mkdir -p $(PROJECT_PATH)/build/include/config - $(Q) cd build; KCONFIG_AUTOHEADER="$(PROJECT_PATH)/build/include/sdkconfig.h" \ - KCONFIG_CONFIG=$(PROJECT_PATH)/sdkconfig \ - COMPONENT_KCONFIGS="$(COMPONENT_KCONFIGS)" \ - COMPONENT_KCONFIGS_PROJBUILD="$(COMPONENT_KCONFIGS_PROJBUILD)" \ - $(KCONFIG_TOOL_DIR)/conf --silentoldconfig $(IDF_PATH)/Kconfig - $(Q) touch $(AUTO_CONF_REGEN_TARGET) $(PROJECT_PATH)/build/include/sdkconfig.h + $(Q) mkdir -p $(BUILD_DIR_BASE)/include/config + $(Q) cd $(BUILD_DIR_BASE); $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/conf --silentoldconfig $(IDF_PATH)/Kconfig + $(Q) touch $(AUTO_CONF_REGEN_TARGET) $(BUILD_DIR_BASE)/include/sdkconfig.h # touch to ensure both output files are newer - as 'conf' can also update sdkconfig (a dependency). Without this, # sometimes you can get an infinite make loop on Windows where sdkconfig always gets regenerated newer # than the target(!) @@ -68,4 +62,4 @@ clean: config-clean config-clean: $(summary RM CONFIG) $(MAKE) -C $(KCONFIG_TOOL_DIR) clean - $(Q) rm -rf $(PROJECT_PATH)/build/include/config $(PROJECT_PATH)/build/include/sdkconfig.h + $(Q) rm -rf $(BUILD_DIR_BASE)/include/config $(BUILD_DIR_BASE)/include/sdkconfig.h From 477d71e589a18af96472199caf918097c22ed0bc Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 4 Oct 2016 15:38:20 +1100 Subject: [PATCH 042/343] config system: Fix configuration when BUILD_DIR_BASE out-of-tree Ref #38. Also no longer generates bootloader sdkconfig in source tree. --- .gitignore | 3 --- components/bootloader/Makefile.projbuild | 20 ++++++++++++-------- make/project_config.mk | 13 ++++++++----- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/.gitignore b/.gitignore index 85027773b6..5ec57a167f 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,3 @@ GPATH examples/*/sdkconfig examples/*/sdkconfig.old examples/*/build - -# Bootloader files -components/bootloader/src/sdkconfig.old \ No newline at end of file diff --git a/components/bootloader/Makefile.projbuild b/components/bootloader/Makefile.projbuild index 7c5cde3b8c..559769957c 100644 --- a/components/bootloader/Makefile.projbuild +++ b/components/bootloader/Makefile.projbuild @@ -13,19 +13,21 @@ ifeq ("$(IS_BOOTLOADER_BUILD)","") BOOTLOADER_COMPONENT_PATH := $(COMPONENT_PATH) BOOTLOADER_BUILD_DIR=$(BUILD_DIR_BASE)/bootloader BOOTLOADER_BIN=$(BOOTLOADER_BUILD_DIR)/bootloader.bin +BOOTLOADER_SDKCONFIG=$(BOOTLOADER_BUILD_DIR)/sdkconfig # Custom recursive make for bootloader sub-project BOOTLOADER_MAKE=$(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src \ - MAKEFLAGS= V=$(V) \ + MAKEFLAGS= V=$(V) SDKCONFIG=$(BOOTLOADER_SDKCONFIG) \ BUILD_DIR_BASE=$(BOOTLOADER_BUILD_DIR) \ .PHONY: bootloader-clean bootloader-flash bootloader $(BOOTLOADER_BIN) -$(BOOTLOADER_BIN): $(COMPONENT_PATH)/src/sdkconfig +$(BOOTLOADER_BIN): | $(BOOTLOADER_BUILD_DIR)/sdkconfig $(Q) $(BOOTLOADER_MAKE) $@ bootloader-clean: - $(Q) $(BOOTLOADER_MAKE) app-clean + $(Q) $(BOOTLOADER_MAKE) app-clean config-clean + $(Q) rm -f $(BOOTLOADER_SDKCONFIG) $(BOOTLOADER_SDKCONFIG).old clean: bootloader-clean @@ -37,15 +39,17 @@ all_binaries: $(BOOTLOADER_BIN) ESPTOOL_ALL_FLASH_ARGS += 0x1000 $(BOOTLOADER_BIN) -# synchronise the project level config to the component's -# config -$(COMPONENT_PATH)/src/sdkconfig: $(PROJECT_PATH)/sdkconfig - $(Q) cp $< $@ - # bootloader-flash calls flash in the bootloader dummy project bootloader-flash: $(BOOTLOADER_BIN) $(BOOTLOADER_MAKE) flash +# synchronise the project level config to the bootloader's +# config +$(BOOTLOADER_SDKCONFIG): $(PROJECT_PATH)/sdkconfig | $(BOOTLOADER_BUILD_DIR) + $(Q) cp $< $@ + +$(BOOTLOADER_BUILD_DIR): + $(Q) mkdir -p $@ else CFLAGS += -D BOOTLOADER_BUILD=1 -I $(IDF_PATH)/components/esp32/include diff --git a/make/project_config.mk b/make/project_config.mk index 92937e8bfe..40f51ff8ff 100644 --- a/make/project_config.mk +++ b/make/project_config.mk @@ -7,6 +7,10 @@ COMPONENT_KCONFIGS_PROJBUILD := $(foreach component,$(COMPONENT_PATHS),$(wildcar #For doing make menuconfig etc KCONFIG_TOOL_DIR=$(IDF_PATH)/tools/kconfig +# set SDKCONFIG to the project's sdkconfig, +# unless it's overriden (happens for bootloader) +SDKCONFIG ?= $(PROJECT_PATH)/sdkconfig + # clear MAKEFLAGS as the menuconfig makefile uses implicit compile rules $(KCONFIG_TOOL_DIR)/mconf $(KCONFIG_TOOL_DIR)/conf: MAKEFLAGS="" \ @@ -15,17 +19,16 @@ $(KCONFIG_TOOL_DIR)/mconf $(KCONFIG_TOOL_DIR)/conf: # use a wrapper environment for where we run Kconfig tools KCONFIG_TOOL_ENV=KCONFIG_AUTOHEADER=$(BUILD_DIR_BASE)/include/sdkconfig.h \ - KCONFIG_CONFIG=$(PROJECT_PATH)/sdkconfig \ - COMPONENT_KCONFIGS="$(COMPONENT_KCONFIGS)" \ + COMPONENT_KCONFIGS="$(COMPONENT_KCONFIGS)" KCONFIG_CONFIG=$(SDKCONFIG) \ COMPONENT_KCONFIGS_PROJBUILD="$(COMPONENT_KCONFIGS_PROJBUILD)" menuconfig: $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig $(BUILD_DIR_BASE) $(summary) MENUCONFIG $(Q) $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig -ifeq ("$(wildcard $(PROJECT_PATH)/sdkconfig)","") +ifeq ("$(wildcard $(SDKCONFIG))","") #No sdkconfig found. Need to run menuconfig to make this if we need it. -$(PROJECT_PATH)/sdkconfig: menuconfig +$(SDKCONFIG): menuconfig endif defconfig: $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig $(BUILD_DIR_BASE) @@ -48,7 +51,7 @@ $(BUILD_DIR_BASE)/include/config/auto.conf: endif endif -$(AUTO_CONF_REGEN_TARGET) $(BUILD_DIR_BASE)/include/sdkconfig.h: $(PROJECT_PATH)/sdkconfig $(KCONFIG_TOOL_DIR)/conf $(COMPONENT_KCONFIGS) $(COMPONENT_KCONFIGS_PROJBUILD) +$(AUTO_CONF_REGEN_TARGET) $(BUILD_DIR_BASE)/include/sdkconfig.h: $(SDKCONFIG) $(KCONFIG_TOOL_DIR)/conf $(COMPONENT_KCONFIGS) $(COMPONENT_KCONFIGS_PROJBUILD) $(summary) GENCONFIG $(Q) mkdir -p $(BUILD_DIR_BASE)/include/config $(Q) cd $(BUILD_DIR_BASE); $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/conf --silentoldconfig $(IDF_PATH)/Kconfig From eccf54b93969396d991012e453fa187cb8684c15 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 4 Oct 2016 15:54:27 +1100 Subject: [PATCH 043/343] build system tests: Add some more notes about test internals --- make/test_build_system.sh | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/make/test_build_system.sh b/make/test_build_system.sh index b6aaa9e58f..401c8376cb 100755 --- a/make/test_build_system.sh +++ b/make/test_build_system.sh @@ -2,7 +2,7 @@ # # Test the build system for basic consistency # -# Just a bash script that tests some likely make failure scenarios in a row +# A bash script that tests some likely make failure scenarios in a row # Creates its own test build directory under TMP and cleans it up when done. # # Environment variables: @@ -11,6 +11,17 @@ # ESP_IDF_TEMPLATE_GIT - Can override git clone source for template app. Otherwise github. # NOCLEANUP - Set to '1' if you want the script to leave its temporary directory when done, for post-mortem. # +# +# Internals: +# * The tests run in sequence & the system keeps track of all failures to print at the end. +# * BUILD directory is set to default BUILD_DIR_BASE +# * The "print_status" function both prints a status line to the log and keeps track of which test is running. +# * Calling the "failure" function prints a failure message to the log and also adds to the list of failures to print at the end. +# * The function "assert_built" tests for a file relative to the BUILD directory. +# * The function "take_build_snapshot" can be paired with the functions "assert_rebuilt" and "assert_not_rebuilt" to compare file timestamps and verify if they were rebuilt or not since the snapshot was taken. +# +# To add a new test case, add it to the end of the run_tests function. Note that not all test cases do comprehensive cleanup +# (although very invasive ones like appending CRLFs to all files take a copy of the esp-idf tree.) # Set up some variables # From f720e82d403a8a09cf94a176067aea71263c307f Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 6 Oct 2016 18:05:51 +1100 Subject: [PATCH 044/343] build system: Allow BUILD_DIR_BASE to be a relative directory (see github #38) --- components/bootloader/Makefile.projbuild | 2 +- components/esp32/component.mk | 2 +- make/project.mk | 2 +- make/project_config.mk | 2 +- make/test_build_system.sh | 10 +++++++++- 5 files changed, 13 insertions(+), 5 deletions(-) diff --git a/components/bootloader/Makefile.projbuild b/components/bootloader/Makefile.projbuild index 559769957c..02135e1c64 100644 --- a/components/bootloader/Makefile.projbuild +++ b/components/bootloader/Makefile.projbuild @@ -11,7 +11,7 @@ ifeq ("$(IS_BOOTLOADER_BUILD)","") BOOTLOADER_COMPONENT_PATH := $(COMPONENT_PATH) -BOOTLOADER_BUILD_DIR=$(BUILD_DIR_BASE)/bootloader +BOOTLOADER_BUILD_DIR=$(abspath $(BUILD_DIR_BASE)/bootloader) BOOTLOADER_BIN=$(BOOTLOADER_BUILD_DIR)/bootloader.bin BOOTLOADER_SDKCONFIG=$(BOOTLOADER_BUILD_DIR)/sdkconfig diff --git a/components/esp32/component.mk b/components/esp32/component.mk index 85040d77a0..b3d95f1b19 100644 --- a/components/esp32/component.mk +++ b/components/esp32/component.mk @@ -6,7 +6,7 @@ # lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable, # please read the esp-idf build system document if you need to do this. # --include $(BUILD_DIR_BASE)/include/config/auto.conf +-include include/config/auto.conf COMPONENT_SRCDIRS := . hwcrypto diff --git a/make/project.mk b/make/project.mk index 74943334a6..c4bf68db63 100644 --- a/make/project.mk +++ b/make/project.mk @@ -106,7 +106,7 @@ COMPONENT_INCLUDES := $(abspath $(foreach comp,$(COMPONENT_PATHS_BUILDABLE),$(ad $(call GetVariable,$(comp),COMPONENT_ADD_INCLUDEDIRS)))) #Also add project include path, for sdk includes -COMPONENT_INCLUDES += $(BUILD_DIR_BASE)/include/ +COMPONENT_INCLUDES += $(abspath $(BUILD_DIR_BASE)/include/) export COMPONENT_INCLUDES #COMPONENT_LDFLAGS has a list of all flags that are needed to link the components together. It's collected diff --git a/make/project_config.mk b/make/project_config.mk index 40f51ff8ff..00452dda4d 100644 --- a/make/project_config.mk +++ b/make/project_config.mk @@ -18,7 +18,7 @@ $(KCONFIG_TOOL_DIR)/mconf $(KCONFIG_TOOL_DIR)/conf: $(MAKE) -C $(KCONFIG_TOOL_DIR) # use a wrapper environment for where we run Kconfig tools -KCONFIG_TOOL_ENV=KCONFIG_AUTOHEADER=$(BUILD_DIR_BASE)/include/sdkconfig.h \ +KCONFIG_TOOL_ENV=KCONFIG_AUTOHEADER=$(abspath $(BUILD_DIR_BASE)/include/sdkconfig.h) \ COMPONENT_KCONFIGS="$(COMPONENT_KCONFIGS)" KCONFIG_CONFIG=$(SDKCONFIG) \ COMPONENT_KCONFIGS_PROJBUILD="$(COMPONENT_KCONFIGS_PROJBUILD)" diff --git a/make/test_build_system.sh b/make/test_build_system.sh index 401c8376cb..b7004eece1 100755 --- a/make/test_build_system.sh +++ b/make/test_build_system.sh @@ -91,7 +91,7 @@ function run_tests() failure "Files weren't cleaned: ${ALL_BUILD_FILES}" fi - print_status "Moving BUILD_DIR_BASE out of tree should still build OK" + print_status "Moving BUILD_DIR_BASE out of tree" rm -rf --preserve-root ${BUILD}/* OUTOFTREE_BUILD=${TESTDIR}/alt_build make BUILD_DIR_BASE=${OUTOFTREE_BUILD} || failure "Failed to build with BUILD_DIR_BASE overriden" @@ -104,6 +104,14 @@ function run_tests() failure "Some files were incorrectly put into the default build directory: ${DEFAULT_BUILD_FILES}" fi + print_status "BUILD_DIR_BASE inside default build directory" + rm -rf --preserve-root ${BUILD}/* + make BUILD_DIR_BASE=build/subdirectory || failure "Failed to build with BUILD_DIR_BASE as subdir" + NEW_BUILD_FILES=$(find ${BUILD}/subdirectory -type f) + if [ -z "${NEW_BUILD_FILES}" ]; then + failure "No files found in new build directory!" + fi + print_status "Can still clean build if all text files are CRLFs" make clean || failure "Unexpected failure to make clean" find . -exec unix2dos {} \; # CRLFify template dir From 6a890e6c49d1b4b00080fe9544f730b4b517331e Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 6 Oct 2016 18:06:52 +1100 Subject: [PATCH 045/343] build system tests: Untabify shell script --- make/test_build_system.sh | 260 +++++++++++++++++++------------------- 1 file changed, 130 insertions(+), 130 deletions(-) diff --git a/make/test_build_system.sh b/make/test_build_system.sh index b7004eece1..f721588383 100755 --- a/make/test_build_system.sh +++ b/make/test_build_system.sh @@ -32,123 +32,123 @@ export V=1 function run_tests() { - FAILURES= - STATUS="Starting" - print_status "Checking prerequisites" - [ -z ${IDF_PATH} ] && echo "IDF_PATH is not set. Need path to esp-idf installation." && exit 2 + FAILURES= + STATUS="Starting" + print_status "Checking prerequisites" + [ -z ${IDF_PATH} ] && echo "IDF_PATH is not set. Need path to esp-idf installation." && exit 2 - print_status "Cloning template from ${ESP_IDF_TEMPLATE_GIT}..." - git clone ${ESP_IDF_TEMPLATE_GIT} template - cd template - git checkout ${CI_BUILD_REF_NAME} || echo "Using esp-idf-template default branch..." + print_status "Cloning template from ${ESP_IDF_TEMPLATE_GIT}..." + git clone ${ESP_IDF_TEMPLATE_GIT} template + cd template + git checkout ${CI_BUILD_REF_NAME} || echo "Using esp-idf-template default branch..." - print_status "Updating template config..." - make defconfig || exit $? + print_status "Updating template config..." + make defconfig || exit $? - BOOTLOADER_BINS="bootloader/bootloader.elf bootloader/bootloader.bin" - APP_BINS="app-template.elf app-template.bin" + BOOTLOADER_BINS="bootloader/bootloader.elf bootloader/bootloader.bin" + APP_BINS="app-template.elf app-template.bin" - print_status "Initial clean build" - # if make fails here, everything fails - make || exit $? - # check all the expected build artifacts from the clean build - assert_built ${APP_BINS} ${BOOTLOADER_BINS} partitions_singleapp.bin - [ -f ${BUILD}/partition*.bin ] || failure "A partition table should have been built" + print_status "Initial clean build" + # if make fails here, everything fails + make || exit $? + # check all the expected build artifacts from the clean build + assert_built ${APP_BINS} ${BOOTLOADER_BINS} partitions_singleapp.bin + [ -f ${BUILD}/partition*.bin ] || failure "A partition table should have been built" - print_status "Updating component source file rebuilds component" - # touch a file & do a build - take_build_snapshot - touch ${IDF_PATH}/components/esp32/syscalls.c - make || failure "Failed to partial build" - assert_rebuilt ${APP_BINS} esp32/libesp32.a esp32/syscalls.o - assert_not_rebuilt lwip/liblwip.a freertos/libfreertos.a ${BOOTLOADER_BINS} partitions_singleapp.bin + print_status "Updating component source file rebuilds component" + # touch a file & do a build + take_build_snapshot + touch ${IDF_PATH}/components/esp32/syscalls.c + make || failure "Failed to partial build" + assert_rebuilt ${APP_BINS} esp32/libesp32.a esp32/syscalls.o + assert_not_rebuilt lwip/liblwip.a freertos/libfreertos.a ${BOOTLOADER_BINS} partitions_singleapp.bin - print_status "Bootloader source file rebuilds bootloader" - take_build_snapshot - touch ${IDF_PATH}/components/bootloader/src/main/bootloader_start.c - make bootloader || failure "Failed to partial build bootloader" - assert_rebuilt ${BOOTLOADER_BINS} bootloader/main/bootloader_start.o - assert_not_rebuilt ${APP_BINS} partitions_singleapp.bin + print_status "Bootloader source file rebuilds bootloader" + take_build_snapshot + touch ${IDF_PATH}/components/bootloader/src/main/bootloader_start.c + make bootloader || failure "Failed to partial build bootloader" + assert_rebuilt ${BOOTLOADER_BINS} bootloader/main/bootloader_start.o + assert_not_rebuilt ${APP_BINS} partitions_singleapp.bin - print_status "Partition CSV file rebuilds partitions" - take_build_snapshot - touch ${IDF_PATH}/components/partition_table/partitions_singleapp.csv - make partition_table || failure "Failed to build partition table" - assert_rebuilt partitions_singleapp.bin - assert_not_rebuilt app-template.bin app-template.elf ${BOOTLOADER_BINS} + print_status "Partition CSV file rebuilds partitions" + take_build_snapshot + touch ${IDF_PATH}/components/partition_table/partitions_singleapp.csv + make partition_table || failure "Failed to build partition table" + assert_rebuilt partitions_singleapp.bin + assert_not_rebuilt app-template.bin app-template.elf ${BOOTLOADER_BINS} - print_status "Partial build doesn't compile anything by default" - take_build_snapshot - # verify no build files are refreshed by a partial make - ALL_BUILD_FILES=$(find ${BUILD} -type f | sed "s@${BUILD}/@@") - make || failure "Partial build failed" - assert_not_rebuilt ${ALL_BUILD_FILES} + print_status "Partial build doesn't compile anything by default" + take_build_snapshot + # verify no build files are refreshed by a partial make + ALL_BUILD_FILES=$(find ${BUILD} -type f | sed "s@${BUILD}/@@") + make || failure "Partial build failed" + assert_not_rebuilt ${ALL_BUILD_FILES} - print_status "Cleaning should remove all files from build" - make clean || failure "Failed to make clean" - ALL_BUILD_FILES=$(find ${BUILD} -type f) - if [ -n "${ALL_BUILD_FILES}" ]; then - failure "Files weren't cleaned: ${ALL_BUILD_FILES}" - fi + print_status "Cleaning should remove all files from build" + make clean || failure "Failed to make clean" + ALL_BUILD_FILES=$(find ${BUILD} -type f) + if [ -n "${ALL_BUILD_FILES}" ]; then + failure "Files weren't cleaned: ${ALL_BUILD_FILES}" + fi - print_status "Moving BUILD_DIR_BASE out of tree" - rm -rf --preserve-root ${BUILD}/* - OUTOFTREE_BUILD=${TESTDIR}/alt_build - make BUILD_DIR_BASE=${OUTOFTREE_BUILD} || failure "Failed to build with BUILD_DIR_BASE overriden" - NEW_BUILD_FILES=$(find ${OUTOFREE_BUILD} -type f) - if [ -z "${NEW_BUILD_FILES}" ]; then - failure "No files found in new build directory!" - fi - DEFAULT_BUILD_FILES=$(find ${BUILD} -mindepth 1) - if [ -n "${DEFAULT_BUILD_FILES}" ]; then - failure "Some files were incorrectly put into the default build directory: ${DEFAULT_BUILD_FILES}" - fi + print_status "Moving BUILD_DIR_BASE out of tree" + rm -rf --preserve-root ${BUILD}/* + OUTOFTREE_BUILD=${TESTDIR}/alt_build + make BUILD_DIR_BASE=${OUTOFTREE_BUILD} || failure "Failed to build with BUILD_DIR_BASE overriden" + NEW_BUILD_FILES=$(find ${OUTOFREE_BUILD} -type f) + if [ -z "${NEW_BUILD_FILES}" ]; then + failure "No files found in new build directory!" + fi + DEFAULT_BUILD_FILES=$(find ${BUILD} -mindepth 1) + if [ -n "${DEFAULT_BUILD_FILES}" ]; then + failure "Some files were incorrectly put into the default build directory: ${DEFAULT_BUILD_FILES}" + fi - print_status "BUILD_DIR_BASE inside default build directory" - rm -rf --preserve-root ${BUILD}/* - make BUILD_DIR_BASE=build/subdirectory || failure "Failed to build with BUILD_DIR_BASE as subdir" - NEW_BUILD_FILES=$(find ${BUILD}/subdirectory -type f) - if [ -z "${NEW_BUILD_FILES}" ]; then - failure "No files found in new build directory!" - fi + print_status "BUILD_DIR_BASE inside default build directory" + rm -rf --preserve-root ${BUILD}/* + make BUILD_DIR_BASE=build/subdirectory || failure "Failed to build with BUILD_DIR_BASE as subdir" + NEW_BUILD_FILES=$(find ${BUILD}/subdirectory -type f) + if [ -z "${NEW_BUILD_FILES}" ]; then + failure "No files found in new build directory!" + fi - print_status "Can still clean build if all text files are CRLFs" - make clean || failure "Unexpected failure to make clean" - find . -exec unix2dos {} \; # CRLFify template dir - # make a copy of esp-idf and CRLFify it - CRLF_ESPIDF=${TESTDIR}/esp-idf-crlf - mkdir -p ${CRLF_ESPIDF} - cp -rv ${IDF_PATH}/* ${CRLF_ESPIDF} - # don't CRLFify executable files, as Linux will fail to execute them - find ${CRLF_ESPIDF} -type f ! -perm 755 -exec unix2dos {} \; - make IDF_PATH=${CRLF_ESPIDF} || failure "Failed to build with CRLFs in source" - # do the same checks we do for the clean build - assert_built ${APP_BINS} ${BOOTLOADER_BINS} partitions_singleapp.bin - [ -f ${BUILD}/partition*.bin ] || failure "A partition table should have been built in CRLF mode" + print_status "Can still clean build if all text files are CRLFs" + make clean || failure "Unexpected failure to make clean" + find . -exec unix2dos {} \; # CRLFify template dir + # make a copy of esp-idf and CRLFify it + CRLF_ESPIDF=${TESTDIR}/esp-idf-crlf + mkdir -p ${CRLF_ESPIDF} + cp -rv ${IDF_PATH}/* ${CRLF_ESPIDF} + # don't CRLFify executable files, as Linux will fail to execute them + find ${CRLF_ESPIDF} -type f ! -perm 755 -exec unix2dos {} \; + make IDF_PATH=${CRLF_ESPIDF} || failure "Failed to build with CRLFs in source" + # do the same checks we do for the clean build + assert_built ${APP_BINS} ${BOOTLOADER_BINS} partitions_singleapp.bin + [ -f ${BUILD}/partition*.bin ] || failure "A partition table should have been built in CRLF mode" - print_status "All tests completed" - if [ -n "${FAILURES}" ]; then - echo "Some failures were detected:" - echo -e "${FAILURES}" - exit 1 - else - echo "Build tests passed." - fi + print_status "All tests completed" + if [ -n "${FAILURES}" ]; then + echo "Some failures were detected:" + echo -e "${FAILURES}" + exit 1 + else + echo "Build tests passed." + fi } function print_status() { - echo "******** $1" - STATUS="$1" + echo "******** $1" + STATUS="$1" } function failure() { - echo "!!!!!!!!!!!!!!!!!!!" - echo "FAILURE: $1" - echo "!!!!!!!!!!!!!!!!!!!" - FAILURES="${FAILURES}${STATUS} :: $1\n" + echo "!!!!!!!!!!!!!!!!!!!" + echo "FAILURE: $1" + echo "!!!!!!!!!!!!!!!!!!!" + FAILURES="${FAILURES}${STATUS} :: $1\n" } TESTDIR=${TMP}/build_system_tests_$$ @@ -164,62 +164,62 @@ BUILD=${TESTDIR}/template/build # copy all the build output to a snapshot directory function take_build_snapshot() { - rm -rf ${SNAPSHOT} - cp -ap ${TESTDIR}/template/build ${SNAPSHOT} + rm -rf ${SNAPSHOT} + cp -ap ${TESTDIR}/template/build ${SNAPSHOT} } # verify that all the arguments are present in the build output directory function assert_built() { - until [ -z "$1" ]; do - if [ ! -f "${BUILD}/$1" ]; then - failure "File $1 should be in the build output directory" - fi - shift - done + until [ -z "$1" ]; do + if [ ! -f "${BUILD}/$1" ]; then + failure "File $1 should be in the build output directory" + fi + shift + done } # Test if a file has been rebuilt. function file_was_rebuilt() { - # can't use [ a -ot b ] here as -ot only gives second resolution - # but stat -c %y seems to be microsecond at least for tmpfs, ext4.. - if [ "$(stat -c %y ${SNAPSHOT}/$1)" != "$(stat -c %y ${BUILD}/$1)" ]; then - return 0 - else - return 1 - fi + # can't use [ a -ot b ] here as -ot only gives second resolution + # but stat -c %y seems to be microsecond at least for tmpfs, ext4.. + if [ "$(stat -c %y ${SNAPSHOT}/$1)" != "$(stat -c %y ${BUILD}/$1)" ]; then + return 0 + else + return 1 + fi } # verify all the arguments passed in were rebuilt relative to the snapshot function assert_rebuilt() { - until [ -z "$1" ]; do - assert_built "$1" - if [ ! -f "${SNAPSHOT}/$1" ]; then - failure "File $1 should have been original build snapshot" - fi - if ! file_was_rebuilt "$1"; then - failure "File $1 should have been rebuilt" - fi - shift - done + until [ -z "$1" ]; do + assert_built "$1" + if [ ! -f "${SNAPSHOT}/$1" ]; then + failure "File $1 should have been original build snapshot" + fi + if ! file_was_rebuilt "$1"; then + failure "File $1 should have been rebuilt" + fi + shift + done } # verify all the arguments are in the build directory & snapshot, # but were not rebuilt function assert_not_rebuilt() { - until [ -z "$1" ]; do - assert_built "$1" - if [ ! -f "${SNAPSHOT}/$1" ]; then - failure "File $1 should be in snapshot build directory" - fi - if file_was_rebuilt "$1"; then - failure "File $1 should not have been rebuilt" - fi - shift - done + until [ -z "$1" ]; do + assert_built "$1" + if [ ! -f "${SNAPSHOT}/$1" ]; then + failure "File $1 should be in snapshot build directory" + fi + if file_was_rebuilt "$1"; then + failure "File $1 should not have been rebuilt" + fi + shift + done } cd ${TESTDIR} From 305bc9fd9c532286a23a281231c23e4673566a23 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 6 Oct 2016 18:29:34 +1100 Subject: [PATCH 046/343] build system: Run parallel builds without warnings Ref github #38 --- components/bootloader/Makefile.projbuild | 4 ++-- make/project.mk | 3 ++- make/project_config.mk | 5 ++--- make/test_build_system.sh | 17 +++++++++++++++-- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/components/bootloader/Makefile.projbuild b/components/bootloader/Makefile.projbuild index 02135e1c64..91be3a6d6e 100644 --- a/components/bootloader/Makefile.projbuild +++ b/components/bootloader/Makefile.projbuild @@ -16,8 +16,8 @@ BOOTLOADER_BIN=$(BOOTLOADER_BUILD_DIR)/bootloader.bin BOOTLOADER_SDKCONFIG=$(BOOTLOADER_BUILD_DIR)/sdkconfig # Custom recursive make for bootloader sub-project -BOOTLOADER_MAKE=$(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src \ - MAKEFLAGS= V=$(V) SDKCONFIG=$(BOOTLOADER_SDKCONFIG) \ +BOOTLOADER_MAKE=+$(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src \ + V=$(V) SDKCONFIG=$(BOOTLOADER_SDKCONFIG) \ BUILD_DIR_BASE=$(BOOTLOADER_BUILD_DIR) \ .PHONY: bootloader-clean bootloader-flash bootloader $(BOOTLOADER_BIN) diff --git a/make/project.mk b/make/project.mk index c4bf68db63..5797889868 100644 --- a/make/project.mk +++ b/make/project.mk @@ -37,6 +37,7 @@ help: @echo "'make partition_table', etc, etc." # disable built-in make rules, makes debugging saner +MAKEFLAGS_OLD := $(MAKEFLAGS) MAKEFLAGS +=-rR # Figure out PROJECT_PATH if not set @@ -231,7 +232,7 @@ define GenerateComponentPhonyTarget # $(2) - target to generate (build, clean) .PHONY: $(notdir $(1))-$(2) $(notdir $(1))-$(2): | $(BUILD_DIR_BASE)/$(notdir $(1)) - @+$(MAKE) -C $(BUILD_DIR_BASE)/$(notdir $(1)) -f $(1)/component.mk COMPONENT_BUILD_DIR=$(BUILD_DIR_BASE)/$(notdir $(1)) $(2) + $(Q) +$(MAKE) -C $(BUILD_DIR_BASE)/$(notdir $(1)) -f $(1)/component.mk COMPONENT_BUILD_DIR=$(BUILD_DIR_BASE)/$(notdir $(1)) $(2) endef define GenerateComponentTargets diff --git a/make/project_config.mk b/make/project_config.mk index 00452dda4d..7ca83ce5af 100644 --- a/make/project_config.mk +++ b/make/project_config.mk @@ -11,10 +11,9 @@ KCONFIG_TOOL_DIR=$(IDF_PATH)/tools/kconfig # unless it's overriden (happens for bootloader) SDKCONFIG ?= $(PROJECT_PATH)/sdkconfig -# clear MAKEFLAGS as the menuconfig makefile uses implicit compile rules +# reset MAKEFLAGS as the menuconfig makefile uses implicit compile rules $(KCONFIG_TOOL_DIR)/mconf $(KCONFIG_TOOL_DIR)/conf: - MAKEFLAGS="" \ - CC=$(HOSTCC) LD=$(HOSTLD) \ + MAKEFLAGS=$(ORIGINAL_MAKEFLAGS) CC=$(HOSTCC) LD=$(HOSTLD) \ $(MAKE) -C $(KCONFIG_TOOL_DIR) # use a wrapper environment for where we run Kconfig tools diff --git a/make/test_build_system.sh b/make/test_build_system.sh index f721588383..c6e54d9222 100755 --- a/make/test_build_system.sh +++ b/make/test_build_system.sh @@ -92,7 +92,7 @@ function run_tests() fi print_status "Moving BUILD_DIR_BASE out of tree" - rm -rf --preserve-root ${BUILD}/* + clean_build_dir OUTOFTREE_BUILD=${TESTDIR}/alt_build make BUILD_DIR_BASE=${OUTOFTREE_BUILD} || failure "Failed to build with BUILD_DIR_BASE overriden" NEW_BUILD_FILES=$(find ${OUTOFREE_BUILD} -type f) @@ -105,13 +105,20 @@ function run_tests() fi print_status "BUILD_DIR_BASE inside default build directory" - rm -rf --preserve-root ${BUILD}/* + clean_build_dir make BUILD_DIR_BASE=build/subdirectory || failure "Failed to build with BUILD_DIR_BASE as subdir" NEW_BUILD_FILES=$(find ${BUILD}/subdirectory -type f) if [ -z "${NEW_BUILD_FILES}" ]; then failure "No files found in new build directory!" fi + print_status "Parallel builds should work OK" + clean_build_dir + (make -j5 2>&1 | tee ${TESTDIR}/parallel_build.log) || failure "Failed to build in parallel" + if grep -q "warning: jobserver unavailable" ${TESTDIR}/parallel_build.log; then + failure "Parallel build prints 'warning: jobserver unavailable' errors" + fi + print_status "Can still clean build if all text files are CRLFs" make clean || failure "Unexpected failure to make clean" find . -exec unix2dos {} \; # CRLFify template dir @@ -222,5 +229,11 @@ function assert_not_rebuilt() done } +# do a "clean" that doesn't depend on 'make clean' +function clean_build_dir() +{ + rm -rf --preserve-root ${BUILD}/* +} + cd ${TESTDIR} run_tests From a03e75d34ccc977ef1d3aa7efb944beee4b6748a Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Sat, 8 Oct 2016 14:11:34 +0800 Subject: [PATCH 047/343] Move heap_alloc_caps.h to a location where it can be included by components --- components/esp32/{ => include}/heap_alloc_caps.h | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename components/esp32/{ => include}/heap_alloc_caps.h (100%) diff --git a/components/esp32/heap_alloc_caps.h b/components/esp32/include/heap_alloc_caps.h similarity index 100% rename from components/esp32/heap_alloc_caps.h rename to components/esp32/include/heap_alloc_caps.h From 82df5f9aa0c6131cd9b167d5a2501d4f941959b3 Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Sat, 8 Oct 2016 14:12:55 +0800 Subject: [PATCH 048/343] Convert Windows -> Unix line ends in gpio.c --- components/driver/gpio.c | 736 +++++++++++++++++++-------------------- 1 file changed, 368 insertions(+), 368 deletions(-) diff --git a/components/driver/gpio.c b/components/driver/gpio.c index 320533e8d4..14dfc00b43 100644 --- a/components/driver/gpio.c +++ b/components/driver/gpio.c @@ -1,368 +1,368 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#include -#include "esp_err.h" -#include "esp_intr.h" -#include "freertos/FreeRTOS.h" -#include "freertos/xtensa_api.h" -#include "driver/gpio.h" -#include "soc/soc.h" - -//TODO: move debug options to menuconfig -#define GPIO_DBG_ENABLE (0) -#define GPIO_WARNING_ENABLE (0) -#define GPIO_ERROR_ENABLE (0) -#define GPIO_INFO_ENABLE (0) -//DBG INFOR -#if GPIO_INFO_ENABLE -#define GPIO_INFO ets_printf -#else -#define GPIO_INFO(...) -#endif -#if GPIO_WARNING_ENABLE -#define GPIO_WARNING(format,...) do{\ - ets_printf("[waring][%s#%u]",__FUNCTION__,__LINE__);\ - ets_printf(format,##__VA_ARGS__);\ -}while(0) -#else -#define GPIO_WARNING(...) -#endif -#if GPIO_ERROR_ENABLE -#define GPIO_ERROR(format,...) do{\ - ets_printf("[error][%s#%u]",__FUNCTION__,__LINE__);\ - ets_printf(format,##__VA_ARGS__);\ -}while(0) -#else -#define GPIO_ERROR(...) -#endif - -const uint32_t GPIO_PIN_MUX_REG[GPIO_PIN_COUNT] = { - GPIO_PIN_REG_0, - GPIO_PIN_REG_1, - GPIO_PIN_REG_2, - GPIO_PIN_REG_3, - GPIO_PIN_REG_4, - GPIO_PIN_REG_5, - GPIO_PIN_REG_6, - GPIO_PIN_REG_7, - GPIO_PIN_REG_8, - GPIO_PIN_REG_9, - GPIO_PIN_REG_10, - GPIO_PIN_REG_11, - GPIO_PIN_REG_12, - GPIO_PIN_REG_13, - GPIO_PIN_REG_14, - GPIO_PIN_REG_15, - GPIO_PIN_REG_16, - GPIO_PIN_REG_17, - GPIO_PIN_REG_18, - GPIO_PIN_REG_19, - 0, - GPIO_PIN_REG_21, - GPIO_PIN_REG_22, - GPIO_PIN_REG_23, - 0, - GPIO_PIN_REG_25, - GPIO_PIN_REG_26, - GPIO_PIN_REG_27, - 0, - 0, - 0, - 0, - GPIO_PIN_REG_32, - GPIO_PIN_REG_33, - GPIO_PIN_REG_34, - GPIO_PIN_REG_35, - GPIO_PIN_REG_36, - GPIO_PIN_REG_37, - GPIO_PIN_REG_38, - GPIO_PIN_REG_39 -}; - -static int is_valid_gpio(int gpio_num) -{ - if(gpio_num >= GPIO_PIN_COUNT || GPIO_PIN_MUX_REG[gpio_num] == 0) { - GPIO_ERROR("GPIO io_num=%d does not exist\n",gpio_num); - return 0; - } - return 1; -} - -esp_err_t gpio_set_intr_type(gpio_num_t gpio_num, gpio_int_type_t intr_type) -{ - if(!is_valid_gpio(gpio_num)) { - return ESP_ERR_INVALID_ARG; - } - if(intr_type >= GPIO_INTR_MAX) { - GPIO_ERROR("Unknown GPIO intr:%u\n",intr_type); - return ESP_ERR_INVALID_ARG; - } - GPIO.pin[gpio_num].int_type = intr_type; - return ESP_OK; -} - -esp_err_t gpio_intr_enable(gpio_num_t gpio_num) -{ - if(!is_valid_gpio(gpio_num)) { - return ESP_ERR_INVALID_ARG; - } - if(xPortGetCoreID() == 0) { - GPIO.pin[gpio_num].int_ena = GPIO_PRO_CPU_INTR_ENA; //enable pro cpu intr - } else { - GPIO.pin[gpio_num].int_ena = GPIO_APP_CPU_INTR_ENA; //enable pro cpu intr - } - return ESP_OK; -} - -esp_err_t gpio_intr_disable(gpio_num_t gpio_num) -{ - if(!is_valid_gpio(gpio_num)) { - return ESP_ERR_INVALID_ARG; - } - GPIO.pin[gpio_num].int_ena = 0; //disable GPIO intr - return ESP_OK; -} - -static esp_err_t gpio_output_disable(gpio_num_t gpio_num) -{ - if(!is_valid_gpio(gpio_num)) { - return ESP_ERR_INVALID_ARG; - } - if(gpio_num < 32) { - GPIO.enable_w1tc = (0x1 << gpio_num); - } else { - GPIO.enable1_w1tc.data = (0x1 << (gpio_num - 32)); - } - return ESP_OK; -} - -static esp_err_t gpio_output_enable(gpio_num_t gpio_num) -{ - if(gpio_num >= 34) { - GPIO_ERROR("io_num=%d can only be input\n",gpio_num); - return ESP_ERR_INVALID_ARG; - } - if(!is_valid_gpio(gpio_num)) { - return ESP_ERR_INVALID_ARG; - } - if(gpio_num < 32) { - GPIO.enable_w1ts = (0x1 << gpio_num); - } else { - GPIO.enable1_w1ts.data = (0x1 << (gpio_num - 32)); - } - return ESP_OK; -} - -esp_err_t gpio_set_level(gpio_num_t gpio_num, uint32_t level) -{ - if(!GPIO_IS_VALID_GPIO(gpio_num)) { - return ESP_ERR_INVALID_ARG; - } - if(level) { - if(gpio_num < 32) { - GPIO.out_w1ts = (1 << gpio_num); - } else { - GPIO.out1_w1ts.data = (1 << (gpio_num - 32)); - } - } else { - if(gpio_num < 32) { - GPIO.out_w1tc = (1 << gpio_num); - } else { - GPIO.out1_w1tc.data = (1 << (gpio_num - 32)); - } - } - return ESP_OK; -} - -int gpio_get_level(gpio_num_t gpio_num) -{ - if(gpio_num < 32) { - return (GPIO.in >> gpio_num) & 0x1; - } else { - return (GPIO.in1.data >> (gpio_num - 32)) & 0x1; - } -} - -esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull) -{ - if(!is_valid_gpio(gpio_num)) { - return ESP_ERR_INVALID_ARG; - } - esp_err_t ret = ESP_OK; - switch(pull) { - case GPIO_PULLUP_ONLY: - PIN_PULLUP_EN(GPIO_PIN_MUX_REG[gpio_num]); - PIN_PULLDWN_DIS(GPIO_PIN_MUX_REG[gpio_num]); - break; - case GPIO_PULLDOWN_ONLY: - PIN_PULLUP_DIS(GPIO_PIN_MUX_REG[gpio_num]); - PIN_PULLDWN_EN(GPIO_PIN_MUX_REG[gpio_num]); - break; - case GPIO_PULLUP_PULLDOWN: - PIN_PULLUP_EN(GPIO_PIN_MUX_REG[gpio_num]); - PIN_PULLDWN_EN(GPIO_PIN_MUX_REG[gpio_num]); - break; - case GPIO_FLOATING: - PIN_PULLUP_DIS(GPIO_PIN_MUX_REG[gpio_num]); - PIN_PULLDWN_DIS(GPIO_PIN_MUX_REG[gpio_num]); - break; - default: - GPIO_ERROR("Unknown pull up/down mode,gpio_num=%u,pull=%u\n",gpio_num,pull); - ret = ESP_ERR_INVALID_ARG; - break; - } - return ret; -} - -esp_err_t gpio_set_direction(gpio_num_t gpio_num, gpio_mode_t mode) -{ - if(!is_valid_gpio(gpio_num)) { - return ESP_ERR_INVALID_ARG; - } - if(gpio_num >= 34 && (mode & (GPIO_MODE_DEF_OUTPUT))) { - GPIO_ERROR("io_num=%d can only be input\n",gpio_num); - return ESP_ERR_INVALID_ARG; - } - esp_err_t ret = ESP_OK; - if(mode & GPIO_MODE_DEF_INPUT) { - PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[gpio_num]); - } else { - PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[gpio_num]); - } - if(mode & GPIO_MODE_DEF_OUTPUT) { - if(gpio_num < 32) { - GPIO.enable_w1ts = (0x1 << gpio_num); - } else { - GPIO.enable1_w1ts.data = (0x1 << (gpio_num - 32)); - } - } else { - if(gpio_num < 32) { - GPIO.enable_w1tc = (0x1 << gpio_num); - } else { - GPIO.enable1_w1tc.data = (0x1 << (gpio_num - 32)); - } - } - if(mode & GPIO_MODE_DEF_OD) { - GPIO.pin[gpio_num].pad_driver = 1; - } else { - GPIO.pin[gpio_num].pad_driver = 0; - } - return ret; -} - -esp_err_t gpio_config(gpio_config_t *pGPIOConfig) -{ - uint64_t gpio_pin_mask = (pGPIOConfig->pin_bit_mask); - uint32_t io_reg = 0; - uint32_t io_num = 0; - uint64_t bit_valid = 0; - if(pGPIOConfig->pin_bit_mask == 0 || pGPIOConfig->pin_bit_mask >= (((uint64_t) 1) << GPIO_PIN_COUNT)) { - GPIO_ERROR("GPIO_PIN mask error \n"); - return ESP_ERR_INVALID_ARG; - } - if((pGPIOConfig->mode) & (GPIO_MODE_DEF_OUTPUT)) { - //GPIO 34/35/36/37/38/39 can only be used as input mode; - if((gpio_pin_mask & ( GPIO_SEL_34 | GPIO_SEL_35 | GPIO_SEL_36 | GPIO_SEL_37 | GPIO_SEL_38 | GPIO_SEL_39))) { - GPIO_ERROR("GPIO34-39 can only be used as input mode\n"); - return ESP_ERR_INVALID_ARG; - } - } - do { - io_reg = GPIO_PIN_MUX_REG[io_num]; - if(((gpio_pin_mask >> io_num) & BIT(0)) && io_reg) { - GPIO_INFO("Gpio%02d |Mode:",io_num); - if((pGPIOConfig->mode) & GPIO_MODE_DEF_INPUT) { - GPIO_INFO("INPUT "); - PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[io_num]); - } else { - PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[io_num]); - } - if((pGPIOConfig->mode) & GPIO_MODE_DEF_OD) { - GPIO_INFO("OD "); - GPIO.pin[io_num].pad_driver = 1; /*0x01 Open-drain */ - } else { - GPIO.pin[io_num].pad_driver = 0; /*0x00 Normal gpio output */ - } - if((pGPIOConfig->mode) & GPIO_MODE_DEF_OUTPUT) { - GPIO_INFO("OUTPUT "); - gpio_output_enable(io_num); - } else { - gpio_output_disable(io_num); - } - GPIO_INFO("|"); - if(pGPIOConfig->pull_up_en) { - GPIO_INFO("PU "); - PIN_PULLUP_EN(io_reg); - } else { - PIN_PULLUP_DIS(io_reg); - } - if(pGPIOConfig->pull_down_en) { - GPIO_INFO("PD "); - PIN_PULLDWN_EN(io_reg); - } else { - PIN_PULLDWN_DIS(io_reg); - } - GPIO_INFO("Intr:%d |\n",pGPIOConfig->intr_type); - gpio_set_intr_type(io_num, pGPIOConfig->intr_type); - if(pGPIOConfig->intr_type) { - gpio_intr_enable(io_num); - } else { - gpio_intr_disable(io_num); - } - PIN_FUNC_SELECT(io_reg, PIN_FUNC_GPIO); /*function number 2 is GPIO_FUNC for each pin */ - } else if(bit_valid && (io_reg == 0)) { - GPIO_WARNING("io_num=%d does not exist\n",io_num); - } - io_num++; - } while(io_num < GPIO_PIN_COUNT); - return ESP_OK; -} - -esp_err_t gpio_isr_register(uint32_t gpio_intr_num, void (*fn)(void*), void * arg) -{ - if(fn == NULL) { - return ESP_ERR_INVALID_ARG; - } - ESP_INTR_DISABLE(gpio_intr_num); - intr_matrix_set(xPortGetCoreID(), ETS_GPIO_INTR_SOURCE, gpio_intr_num); - xt_set_interrupt_handler(gpio_intr_num, fn, arg); - ESP_INTR_ENABLE(gpio_intr_num); - return ESP_OK; -} - -/*only level interrupt can be used for wake-up function*/ -esp_err_t gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type) -{ - if(!is_valid_gpio(gpio_num)) { - return ESP_ERR_INVALID_ARG; - } - esp_err_t ret = ESP_OK; - if((intr_type == GPIO_INTR_LOW_LEVEL) || (intr_type == GPIO_INTR_HIGH_LEVEL)) { - GPIO.pin[gpio_num].int_type = intr_type; - GPIO.pin[gpio_num].wakeup_enable = 0x1; - } else { - GPIO_ERROR("GPIO wakeup only support Level mode,but edge mode set. gpio_num:%u\n",gpio_num); - ret = ESP_ERR_INVALID_ARG; - } - return ret; -} - -esp_err_t gpio_wakeup_disable(gpio_num_t gpio_num) -{ - if(!is_valid_gpio(gpio_num)) { - return ESP_ERR_INVALID_ARG; - } - GPIO.pin[gpio_num].wakeup_enable = 0; - return ESP_OK; -} +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include +#include "esp_err.h" +#include "esp_intr.h" +#include "freertos/FreeRTOS.h" +#include "freertos/xtensa_api.h" +#include "driver/gpio.h" +#include "soc/soc.h" + +//TODO: move debug options to menuconfig +#define GPIO_DBG_ENABLE (0) +#define GPIO_WARNING_ENABLE (0) +#define GPIO_ERROR_ENABLE (0) +#define GPIO_INFO_ENABLE (0) +//DBG INFOR +#if GPIO_INFO_ENABLE +#define GPIO_INFO ets_printf +#else +#define GPIO_INFO(...) +#endif +#if GPIO_WARNING_ENABLE +#define GPIO_WARNING(format,...) do{\ + ets_printf("[waring][%s#%u]",__FUNCTION__,__LINE__);\ + ets_printf(format,##__VA_ARGS__);\ +}while(0) +#else +#define GPIO_WARNING(...) +#endif +#if GPIO_ERROR_ENABLE +#define GPIO_ERROR(format,...) do{\ + ets_printf("[error][%s#%u]",__FUNCTION__,__LINE__);\ + ets_printf(format,##__VA_ARGS__);\ +}while(0) +#else +#define GPIO_ERROR(...) +#endif + +const uint32_t GPIO_PIN_MUX_REG[GPIO_PIN_COUNT] = { + GPIO_PIN_REG_0, + GPIO_PIN_REG_1, + GPIO_PIN_REG_2, + GPIO_PIN_REG_3, + GPIO_PIN_REG_4, + GPIO_PIN_REG_5, + GPIO_PIN_REG_6, + GPIO_PIN_REG_7, + GPIO_PIN_REG_8, + GPIO_PIN_REG_9, + GPIO_PIN_REG_10, + GPIO_PIN_REG_11, + GPIO_PIN_REG_12, + GPIO_PIN_REG_13, + GPIO_PIN_REG_14, + GPIO_PIN_REG_15, + GPIO_PIN_REG_16, + GPIO_PIN_REG_17, + GPIO_PIN_REG_18, + GPIO_PIN_REG_19, + 0, + GPIO_PIN_REG_21, + GPIO_PIN_REG_22, + GPIO_PIN_REG_23, + 0, + GPIO_PIN_REG_25, + GPIO_PIN_REG_26, + GPIO_PIN_REG_27, + 0, + 0, + 0, + 0, + GPIO_PIN_REG_32, + GPIO_PIN_REG_33, + GPIO_PIN_REG_34, + GPIO_PIN_REG_35, + GPIO_PIN_REG_36, + GPIO_PIN_REG_37, + GPIO_PIN_REG_38, + GPIO_PIN_REG_39 +}; + +static int is_valid_gpio(int gpio_num) +{ + if(gpio_num >= GPIO_PIN_COUNT || GPIO_PIN_MUX_REG[gpio_num] == 0) { + GPIO_ERROR("GPIO io_num=%d does not exist\n",gpio_num); + return 0; + } + return 1; +} + +esp_err_t gpio_set_intr_type(gpio_num_t gpio_num, gpio_int_type_t intr_type) +{ + if(!is_valid_gpio(gpio_num)) { + return ESP_ERR_INVALID_ARG; + } + if(intr_type >= GPIO_INTR_MAX) { + GPIO_ERROR("Unknown GPIO intr:%u\n",intr_type); + return ESP_ERR_INVALID_ARG; + } + GPIO.pin[gpio_num].int_type = intr_type; + return ESP_OK; +} + +esp_err_t gpio_intr_enable(gpio_num_t gpio_num) +{ + if(!is_valid_gpio(gpio_num)) { + return ESP_ERR_INVALID_ARG; + } + if(xPortGetCoreID() == 0) { + GPIO.pin[gpio_num].int_ena = GPIO_PRO_CPU_INTR_ENA; //enable pro cpu intr + } else { + GPIO.pin[gpio_num].int_ena = GPIO_APP_CPU_INTR_ENA; //enable pro cpu intr + } + return ESP_OK; +} + +esp_err_t gpio_intr_disable(gpio_num_t gpio_num) +{ + if(!is_valid_gpio(gpio_num)) { + return ESP_ERR_INVALID_ARG; + } + GPIO.pin[gpio_num].int_ena = 0; //disable GPIO intr + return ESP_OK; +} + +static esp_err_t gpio_output_disable(gpio_num_t gpio_num) +{ + if(!is_valid_gpio(gpio_num)) { + return ESP_ERR_INVALID_ARG; + } + if(gpio_num < 32) { + GPIO.enable_w1tc = (0x1 << gpio_num); + } else { + GPIO.enable1_w1tc.data = (0x1 << (gpio_num - 32)); + } + return ESP_OK; +} + +static esp_err_t gpio_output_enable(gpio_num_t gpio_num) +{ + if(gpio_num >= 34) { + GPIO_ERROR("io_num=%d can only be input\n",gpio_num); + return ESP_ERR_INVALID_ARG; + } + if(!is_valid_gpio(gpio_num)) { + return ESP_ERR_INVALID_ARG; + } + if(gpio_num < 32) { + GPIO.enable_w1ts = (0x1 << gpio_num); + } else { + GPIO.enable1_w1ts.data = (0x1 << (gpio_num - 32)); + } + return ESP_OK; +} + +esp_err_t gpio_set_level(gpio_num_t gpio_num, uint32_t level) +{ + if(!GPIO_IS_VALID_GPIO(gpio_num)) { + return ESP_ERR_INVALID_ARG; + } + if(level) { + if(gpio_num < 32) { + GPIO.out_w1ts = (1 << gpio_num); + } else { + GPIO.out1_w1ts.data = (1 << (gpio_num - 32)); + } + } else { + if(gpio_num < 32) { + GPIO.out_w1tc = (1 << gpio_num); + } else { + GPIO.out1_w1tc.data = (1 << (gpio_num - 32)); + } + } + return ESP_OK; +} + +int gpio_get_level(gpio_num_t gpio_num) +{ + if(gpio_num < 32) { + return (GPIO.in >> gpio_num) & 0x1; + } else { + return (GPIO.in1.data >> (gpio_num - 32)) & 0x1; + } +} + +esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull) +{ + if(!is_valid_gpio(gpio_num)) { + return ESP_ERR_INVALID_ARG; + } + esp_err_t ret = ESP_OK; + switch(pull) { + case GPIO_PULLUP_ONLY: + PIN_PULLUP_EN(GPIO_PIN_MUX_REG[gpio_num]); + PIN_PULLDWN_DIS(GPIO_PIN_MUX_REG[gpio_num]); + break; + case GPIO_PULLDOWN_ONLY: + PIN_PULLUP_DIS(GPIO_PIN_MUX_REG[gpio_num]); + PIN_PULLDWN_EN(GPIO_PIN_MUX_REG[gpio_num]); + break; + case GPIO_PULLUP_PULLDOWN: + PIN_PULLUP_EN(GPIO_PIN_MUX_REG[gpio_num]); + PIN_PULLDWN_EN(GPIO_PIN_MUX_REG[gpio_num]); + break; + case GPIO_FLOATING: + PIN_PULLUP_DIS(GPIO_PIN_MUX_REG[gpio_num]); + PIN_PULLDWN_DIS(GPIO_PIN_MUX_REG[gpio_num]); + break; + default: + GPIO_ERROR("Unknown pull up/down mode,gpio_num=%u,pull=%u\n",gpio_num,pull); + ret = ESP_ERR_INVALID_ARG; + break; + } + return ret; +} + +esp_err_t gpio_set_direction(gpio_num_t gpio_num, gpio_mode_t mode) +{ + if(!is_valid_gpio(gpio_num)) { + return ESP_ERR_INVALID_ARG; + } + if(gpio_num >= 34 && (mode & (GPIO_MODE_DEF_OUTPUT))) { + GPIO_ERROR("io_num=%d can only be input\n",gpio_num); + return ESP_ERR_INVALID_ARG; + } + esp_err_t ret = ESP_OK; + if(mode & GPIO_MODE_DEF_INPUT) { + PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[gpio_num]); + } else { + PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[gpio_num]); + } + if(mode & GPIO_MODE_DEF_OUTPUT) { + if(gpio_num < 32) { + GPIO.enable_w1ts = (0x1 << gpio_num); + } else { + GPIO.enable1_w1ts.data = (0x1 << (gpio_num - 32)); + } + } else { + if(gpio_num < 32) { + GPIO.enable_w1tc = (0x1 << gpio_num); + } else { + GPIO.enable1_w1tc.data = (0x1 << (gpio_num - 32)); + } + } + if(mode & GPIO_MODE_DEF_OD) { + GPIO.pin[gpio_num].pad_driver = 1; + } else { + GPIO.pin[gpio_num].pad_driver = 0; + } + return ret; +} + +esp_err_t gpio_config(gpio_config_t *pGPIOConfig) +{ + uint64_t gpio_pin_mask = (pGPIOConfig->pin_bit_mask); + uint32_t io_reg = 0; + uint32_t io_num = 0; + uint64_t bit_valid = 0; + if(pGPIOConfig->pin_bit_mask == 0 || pGPIOConfig->pin_bit_mask >= (((uint64_t) 1) << GPIO_PIN_COUNT)) { + GPIO_ERROR("GPIO_PIN mask error \n"); + return ESP_ERR_INVALID_ARG; + } + if((pGPIOConfig->mode) & (GPIO_MODE_DEF_OUTPUT)) { + //GPIO 34/35/36/37/38/39 can only be used as input mode; + if((gpio_pin_mask & ( GPIO_SEL_34 | GPIO_SEL_35 | GPIO_SEL_36 | GPIO_SEL_37 | GPIO_SEL_38 | GPIO_SEL_39))) { + GPIO_ERROR("GPIO34-39 can only be used as input mode\n"); + return ESP_ERR_INVALID_ARG; + } + } + do { + io_reg = GPIO_PIN_MUX_REG[io_num]; + if(((gpio_pin_mask >> io_num) & BIT(0)) && io_reg) { + GPIO_INFO("Gpio%02d |Mode:",io_num); + if((pGPIOConfig->mode) & GPIO_MODE_DEF_INPUT) { + GPIO_INFO("INPUT "); + PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[io_num]); + } else { + PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[io_num]); + } + if((pGPIOConfig->mode) & GPIO_MODE_DEF_OD) { + GPIO_INFO("OD "); + GPIO.pin[io_num].pad_driver = 1; /*0x01 Open-drain */ + } else { + GPIO.pin[io_num].pad_driver = 0; /*0x00 Normal gpio output */ + } + if((pGPIOConfig->mode) & GPIO_MODE_DEF_OUTPUT) { + GPIO_INFO("OUTPUT "); + gpio_output_enable(io_num); + } else { + gpio_output_disable(io_num); + } + GPIO_INFO("|"); + if(pGPIOConfig->pull_up_en) { + GPIO_INFO("PU "); + PIN_PULLUP_EN(io_reg); + } else { + PIN_PULLUP_DIS(io_reg); + } + if(pGPIOConfig->pull_down_en) { + GPIO_INFO("PD "); + PIN_PULLDWN_EN(io_reg); + } else { + PIN_PULLDWN_DIS(io_reg); + } + GPIO_INFO("Intr:%d |\n",pGPIOConfig->intr_type); + gpio_set_intr_type(io_num, pGPIOConfig->intr_type); + if(pGPIOConfig->intr_type) { + gpio_intr_enable(io_num); + } else { + gpio_intr_disable(io_num); + } + PIN_FUNC_SELECT(io_reg, PIN_FUNC_GPIO); /*function number 2 is GPIO_FUNC for each pin */ + } else if(bit_valid && (io_reg == 0)) { + GPIO_WARNING("io_num=%d does not exist\n",io_num); + } + io_num++; + } while(io_num < GPIO_PIN_COUNT); + return ESP_OK; +} + +esp_err_t gpio_isr_register(uint32_t gpio_intr_num, void (*fn)(void*), void * arg) +{ + if(fn == NULL) { + return ESP_ERR_INVALID_ARG; + } + ESP_INTR_DISABLE(gpio_intr_num); + intr_matrix_set(xPortGetCoreID(), ETS_GPIO_INTR_SOURCE, gpio_intr_num); + xt_set_interrupt_handler(gpio_intr_num, fn, arg); + ESP_INTR_ENABLE(gpio_intr_num); + return ESP_OK; +} + +/*only level interrupt can be used for wake-up function*/ +esp_err_t gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type) +{ + if(!is_valid_gpio(gpio_num)) { + return ESP_ERR_INVALID_ARG; + } + esp_err_t ret = ESP_OK; + if((intr_type == GPIO_INTR_LOW_LEVEL) || (intr_type == GPIO_INTR_HIGH_LEVEL)) { + GPIO.pin[gpio_num].int_type = intr_type; + GPIO.pin[gpio_num].wakeup_enable = 0x1; + } else { + GPIO_ERROR("GPIO wakeup only support Level mode,but edge mode set. gpio_num:%u\n",gpio_num); + ret = ESP_ERR_INVALID_ARG; + } + return ret; +} + +esp_err_t gpio_wakeup_disable(gpio_num_t gpio_num) +{ + if(!is_valid_gpio(gpio_num)) { + return ESP_ERR_INVALID_ARG; + } + GPIO.pin[gpio_num].wakeup_enable = 0; + return ESP_OK; +} From df31bb8dfc2d6967a7bfbe122d6024b935802b2b Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Sun, 9 Oct 2016 15:32:08 +0800 Subject: [PATCH 049/343] Rename include, use spaces instead of tabs --- components/esp32/heap_alloc_caps.c | 294 +++++++++--------- .../esp32/include/esp_heap_alloc_caps.h | 34 ++ components/freertos/tasks.c | 1 - 3 files changed, 181 insertions(+), 148 deletions(-) create mode 100644 components/esp32/include/esp_heap_alloc_caps.h diff --git a/components/esp32/heap_alloc_caps.c b/components/esp32/heap_alloc_caps.c index 5b3ec33dba..46b1125ccb 100644 --- a/components/esp32/heap_alloc_caps.c +++ b/components/esp32/heap_alloc_caps.c @@ -15,7 +15,7 @@ #include -#include "heap_alloc_caps.h" +#include "esp_heap_alloc_caps.h" #include "spiram.h" #include "esp_log.h" @@ -40,23 +40,23 @@ Tag descriptors. These describe the capabilities of a bit of memory that's tagge Each tag contains NO_PRIOS entries; later entries are only taken if earlier ones can't fulfill the memory request. */ static const uint32_t tagDesc[][NO_PRIOS]={ - { MALLOC_CAP_DMA|MALLOC_CAP_8BIT, MALLOC_CAP_32BIT, 0 }, //Tag 0: Plain ole D-port RAM - { 0, MALLOC_CAP_DMA|MALLOC_CAP_8BIT, MALLOC_CAP_32BIT|MALLOC_CAP_EXEC }, //Tag 1: Plain ole D-port RAM which has an alias on the I-port - { MALLOC_CAP_EXEC|MALLOC_CAP_32BIT, 0, 0 }, //Tag 2: IRAM - { MALLOC_CAP_PID2, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, //Tag 3-8: PID 2-7 IRAM - { MALLOC_CAP_PID3, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, // - { MALLOC_CAP_PID4, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, // - { MALLOC_CAP_PID5, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, // - { MALLOC_CAP_PID6, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, // - { MALLOC_CAP_PID7, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, // - { MALLOC_CAP_PID2, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT }, //Tag 9-14: PID 2-7 DRAM - { MALLOC_CAP_PID3, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT }, // - { MALLOC_CAP_PID4, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT }, // - { MALLOC_CAP_PID5, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT }, // - { MALLOC_CAP_PID6, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT }, // - { MALLOC_CAP_PID7, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT }, // - { MALLOC_CAP_SPISRAM, 0, MALLOC_CAP_DMA|MALLOC_CAP_8BIT|MALLOC_CAP_32BIT}, //Tag 15: SPI SRAM data - { MALLOC_CAP_INVALID, MALLOC_CAP_INVALID, MALLOC_CAP_INVALID } //End + { MALLOC_CAP_DMA|MALLOC_CAP_8BIT, MALLOC_CAP_32BIT, 0 }, //Tag 0: Plain ole D-port RAM + { 0, MALLOC_CAP_DMA|MALLOC_CAP_8BIT, MALLOC_CAP_32BIT|MALLOC_CAP_EXEC }, //Tag 1: Plain ole D-port RAM which has an alias on the I-port + { MALLOC_CAP_EXEC|MALLOC_CAP_32BIT, 0, 0 }, //Tag 2: IRAM + { MALLOC_CAP_PID2, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, //Tag 3-8: PID 2-7 IRAM + { MALLOC_CAP_PID3, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, // + { MALLOC_CAP_PID4, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, // + { MALLOC_CAP_PID5, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, // + { MALLOC_CAP_PID6, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, // + { MALLOC_CAP_PID7, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, // + { MALLOC_CAP_PID2, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT }, //Tag 9-14: PID 2-7 DRAM + { MALLOC_CAP_PID3, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT }, // + { MALLOC_CAP_PID4, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT }, // + { MALLOC_CAP_PID5, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT }, // + { MALLOC_CAP_PID6, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT }, // + { MALLOC_CAP_PID7, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT }, // + { MALLOC_CAP_SPISRAM, 0, MALLOC_CAP_DMA|MALLOC_CAP_8BIT|MALLOC_CAP_32BIT}, //Tag 15: SPI SRAM data + { MALLOC_CAP_INVALID, MALLOC_CAP_INVALID, MALLOC_CAP_INVALID } //End }; /* @@ -79,81 +79,81 @@ be sorted from low to high start address. This array is *NOT* const because it gets modified depending on what pools are/aren't available. */ static HeapRegionTagged_t regions[]={ - { (uint8_t *)0x3F800000, 0x20000, 15, 0}, //SPI SRAM, if available - { (uint8_t *)0x3FFAE000, 0x2000, 0, 0}, //pool 16 <- used for rom code - { (uint8_t *)0x3FFB0000, 0x8000, 0, 0}, //pool 15 <- can be used for BT - { (uint8_t *)0x3FFB8000, 0x8000, 0, 0}, //pool 14 <- can be used for BT - { (uint8_t *)0x3FFC0000, 0x2000, 0, 0}, //pool 10-13, mmu page 0 - { (uint8_t *)0x3FFC2000, 0x2000, 0, 0}, //pool 10-13, mmu page 1 - { (uint8_t *)0x3FFC4000, 0x2000, 0, 0}, //pool 10-13, mmu page 2 - { (uint8_t *)0x3FFC6000, 0x2000, 0, 0}, //pool 10-13, mmu page 3 - { (uint8_t *)0x3FFC8000, 0x2000, 0, 0}, //pool 10-13, mmu page 4 - { (uint8_t *)0x3FFCA000, 0x2000, 0, 0}, //pool 10-13, mmu page 5 - { (uint8_t *)0x3FFCC000, 0x2000, 0, 0}, //pool 10-13, mmu page 6 - { (uint8_t *)0x3FFCE000, 0x2000, 0, 0}, //pool 10-13, mmu page 7 - { (uint8_t *)0x3FFD0000, 0x2000, 0, 0}, //pool 10-13, mmu page 8 - { (uint8_t *)0x3FFD2000, 0x2000, 0, 0}, //pool 10-13, mmu page 9 - { (uint8_t *)0x3FFD4000, 0x2000, 0, 0}, //pool 10-13, mmu page 10 - { (uint8_t *)0x3FFD6000, 0x2000, 0, 0}, //pool 10-13, mmu page 11 - { (uint8_t *)0x3FFD8000, 0x2000, 0, 0}, //pool 10-13, mmu page 12 - { (uint8_t *)0x3FFDA000, 0x2000, 0, 0}, //pool 10-13, mmu page 13 - { (uint8_t *)0x3FFDC000, 0x2000, 0, 0}, //pool 10-13, mmu page 14 - { (uint8_t *)0x3FFDE000, 0x2000, 0, 0}, //pool 10-13, mmu page 15 - { (uint8_t *)0x3FFE0000, 0x4000, 1, 0x400BC000}, //pool 9 blk 1 - { (uint8_t *)0x3FFE4000, 0x4000, 1, 0x400B8000}, //pool 9 blk 0 - { (uint8_t *)0x3FFE8000, 0x8000, 1, 0x400B0000}, //pool 8 <- can be remapped to ROM, used for MAC dump - { (uint8_t *)0x3FFF0000, 0x8000, 1, 0x400A8000}, //pool 7 <- can be used for MAC dump - { (uint8_t *)0x3FFF8000, 0x4000, 1, 0x400A4000}, //pool 6 blk 1 <- can be used as trace memory - { (uint8_t *)0x3FFFC000, 0x4000, 1, 0x400A0000}, //pool 6 blk 0 <- can be used as trace memory - { (uint8_t *)0x40070000, 0x8000, 2, 0}, //pool 0 - { (uint8_t *)0x40078000, 0x8000, 2, 0}, //pool 1 - { (uint8_t *)0x40080000, 0x2000, 2, 0}, //pool 2-5, mmu page 0 - { (uint8_t *)0x40082000, 0x2000, 2, 0}, //pool 2-5, mmu page 1 - { (uint8_t *)0x40084000, 0x2000, 2, 0}, //pool 2-5, mmu page 2 - { (uint8_t *)0x40086000, 0x2000, 2, 0}, //pool 2-5, mmu page 3 - { (uint8_t *)0x40088000, 0x2000, 2, 0}, //pool 2-5, mmu page 4 - { (uint8_t *)0x4008A000, 0x2000, 2, 0}, //pool 2-5, mmu page 5 - { (uint8_t *)0x4008C000, 0x2000, 2, 0}, //pool 2-5, mmu page 6 - { (uint8_t *)0x4008E000, 0x2000, 2, 0}, //pool 2-5, mmu page 7 - { (uint8_t *)0x40090000, 0x2000, 2, 0}, //pool 2-5, mmu page 8 - { (uint8_t *)0x40092000, 0x2000, 2, 0}, //pool 2-5, mmu page 9 - { (uint8_t *)0x40094000, 0x2000, 2, 0}, //pool 2-5, mmu page 10 - { (uint8_t *)0x40096000, 0x2000, 2, 0}, //pool 2-5, mmu page 11 - { (uint8_t *)0x40098000, 0x2000, 2, 0}, //pool 2-5, mmu page 12 - { (uint8_t *)0x4009A000, 0x2000, 2, 0}, //pool 2-5, mmu page 13 - { (uint8_t *)0x4009C000, 0x2000, 2, 0}, //pool 2-5, mmu page 14 - { (uint8_t *)0x4009E000, 0x2000, 2, 0}, //pool 2-5, mmu page 15 - { NULL, 0, 0, 0} //end + { (uint8_t *)0x3F800000, 0x20000, 15, 0}, //SPI SRAM, if available + { (uint8_t *)0x3FFAE000, 0x2000, 0, 0}, //pool 16 <- used for rom code + { (uint8_t *)0x3FFB0000, 0x8000, 0, 0}, //pool 15 <- can be used for BT + { (uint8_t *)0x3FFB8000, 0x8000, 0, 0}, //pool 14 <- can be used for BT + { (uint8_t *)0x3FFC0000, 0x2000, 0, 0}, //pool 10-13, mmu page 0 + { (uint8_t *)0x3FFC2000, 0x2000, 0, 0}, //pool 10-13, mmu page 1 + { (uint8_t *)0x3FFC4000, 0x2000, 0, 0}, //pool 10-13, mmu page 2 + { (uint8_t *)0x3FFC6000, 0x2000, 0, 0}, //pool 10-13, mmu page 3 + { (uint8_t *)0x3FFC8000, 0x2000, 0, 0}, //pool 10-13, mmu page 4 + { (uint8_t *)0x3FFCA000, 0x2000, 0, 0}, //pool 10-13, mmu page 5 + { (uint8_t *)0x3FFCC000, 0x2000, 0, 0}, //pool 10-13, mmu page 6 + { (uint8_t *)0x3FFCE000, 0x2000, 0, 0}, //pool 10-13, mmu page 7 + { (uint8_t *)0x3FFD0000, 0x2000, 0, 0}, //pool 10-13, mmu page 8 + { (uint8_t *)0x3FFD2000, 0x2000, 0, 0}, //pool 10-13, mmu page 9 + { (uint8_t *)0x3FFD4000, 0x2000, 0, 0}, //pool 10-13, mmu page 10 + { (uint8_t *)0x3FFD6000, 0x2000, 0, 0}, //pool 10-13, mmu page 11 + { (uint8_t *)0x3FFD8000, 0x2000, 0, 0}, //pool 10-13, mmu page 12 + { (uint8_t *)0x3FFDA000, 0x2000, 0, 0}, //pool 10-13, mmu page 13 + { (uint8_t *)0x3FFDC000, 0x2000, 0, 0}, //pool 10-13, mmu page 14 + { (uint8_t *)0x3FFDE000, 0x2000, 0, 0}, //pool 10-13, mmu page 15 + { (uint8_t *)0x3FFE0000, 0x4000, 1, 0x400BC000}, //pool 9 blk 1 + { (uint8_t *)0x3FFE4000, 0x4000, 1, 0x400B8000}, //pool 9 blk 0 + { (uint8_t *)0x3FFE8000, 0x8000, 1, 0x400B0000}, //pool 8 <- can be remapped to ROM, used for MAC dump + { (uint8_t *)0x3FFF0000, 0x8000, 1, 0x400A8000}, //pool 7 <- can be used for MAC dump + { (uint8_t *)0x3FFF8000, 0x4000, 1, 0x400A4000}, //pool 6 blk 1 <- can be used as trace memory + { (uint8_t *)0x3FFFC000, 0x4000, 1, 0x400A0000}, //pool 6 blk 0 <- can be used as trace memory + { (uint8_t *)0x40070000, 0x8000, 2, 0}, //pool 0 + { (uint8_t *)0x40078000, 0x8000, 2, 0}, //pool 1 + { (uint8_t *)0x40080000, 0x2000, 2, 0}, //pool 2-5, mmu page 0 + { (uint8_t *)0x40082000, 0x2000, 2, 0}, //pool 2-5, mmu page 1 + { (uint8_t *)0x40084000, 0x2000, 2, 0}, //pool 2-5, mmu page 2 + { (uint8_t *)0x40086000, 0x2000, 2, 0}, //pool 2-5, mmu page 3 + { (uint8_t *)0x40088000, 0x2000, 2, 0}, //pool 2-5, mmu page 4 + { (uint8_t *)0x4008A000, 0x2000, 2, 0}, //pool 2-5, mmu page 5 + { (uint8_t *)0x4008C000, 0x2000, 2, 0}, //pool 2-5, mmu page 6 + { (uint8_t *)0x4008E000, 0x2000, 2, 0}, //pool 2-5, mmu page 7 + { (uint8_t *)0x40090000, 0x2000, 2, 0}, //pool 2-5, mmu page 8 + { (uint8_t *)0x40092000, 0x2000, 2, 0}, //pool 2-5, mmu page 9 + { (uint8_t *)0x40094000, 0x2000, 2, 0}, //pool 2-5, mmu page 10 + { (uint8_t *)0x40096000, 0x2000, 2, 0}, //pool 2-5, mmu page 11 + { (uint8_t *)0x40098000, 0x2000, 2, 0}, //pool 2-5, mmu page 12 + { (uint8_t *)0x4009A000, 0x2000, 2, 0}, //pool 2-5, mmu page 13 + { (uint8_t *)0x4009C000, 0x2000, 2, 0}, //pool 2-5, mmu page 14 + { (uint8_t *)0x4009E000, 0x2000, 2, 0}, //pool 2-5, mmu page 15 + { NULL, 0, 0, 0} //end }; //Modify regions array to disable the given range of memory. static void disable_mem_region(void *from, void *to) { - int i; - //Align from and to on word boundaries - from=(void*)((uint32_t)from&~3); - to=(void*)(((uint32_t)to+3)&~3); - for (i=0; regions[i].xSizeInBytes!=0; i++) { - void *regStart=regions[i].pucStartAddress; - void *regEnd=regions[i].pucStartAddress+regions[i].xSizeInBytes; - if (regStart>=from && regEnd<=to) { - //Entire region falls in the range. Disable entirely. - regions[i].xTag=-1; - } else if (regStart>=from && regEnd>to && regStartfrom && regEnd<=to) { - //End of the region falls in the range. Modify length. - regions[i].xSizeInBytes-=(uint8_t *)regEnd-(uint8_t *)from; - } else if (regStartto) { - //Range punches a hole in the region! We do not support this. - ESP_EARLY_LOGE(TAG, "region %d: hole punching is not supported!", i); - regions[i].xTag=-1; //Just disable memory region. That'll teach them! - } - } + int i; + //Align from and to on word boundaries + from=(void*)((uint32_t)from&~3); + to=(void*)(((uint32_t)to+3)&~3); + for (i=0; regions[i].xSizeInBytes!=0; i++) { + void *regStart=regions[i].pucStartAddress; + void *regEnd=regions[i].pucStartAddress+regions[i].xSizeInBytes; + if (regStart>=from && regEnd<=to) { + //Entire region falls in the range. Disable entirely. + regions[i].xTag=-1; + } else if (regStart>=from && regEnd>to && regStartfrom && regEnd<=to) { + //End of the region falls in the range. Modify length. + regions[i].xSizeInBytes-=(uint8_t *)regEnd-(uint8_t *)from; + } else if (regStartto) { + //Range punches a hole in the region! We do not support this. + ESP_EARLY_LOGE(TAG, "region %d: hole punching is not supported!", i); + regions[i].xTag=-1; //Just disable memory region. That'll teach them! + } + } } @@ -170,52 +170,52 @@ ToDo: The regions are different when stuff like trace memory, BT, ... is used. M Same with loading of apps. Same with using SPI RAM. */ void heap_alloc_caps_init() { - int i; - //Disable the bits of memory where this code is loaded. - disable_mem_region(&_bss_start, &_heap_start); - disable_mem_region((void*)0x3ffae000, (void*)0x3ffb0000); //knock out ROM data region - disable_mem_region((void*)0x40070000, (void*)0x40078000); //CPU0 cache region - disable_mem_region((void*)0x40078000, (void*)0x40080000); //CPU1 cache region - disable_mem_region((void*)0x40080000, (void*)0x400a0000); //pool 2-5 + int i; + //Disable the bits of memory where this code is loaded. + disable_mem_region(&_bss_start, &_heap_start); + disable_mem_region((void*)0x3ffae000, (void*)0x3ffb0000); //knock out ROM data region + disable_mem_region((void*)0x40070000, (void*)0x40078000); //CPU0 cache region + disable_mem_region((void*)0x40078000, (void*)0x40080000); //CPU1 cache region + disable_mem_region((void*)0x40080000, (void*)0x400a0000); //pool 2-5 - // TODO: this region should be checked, since we don't need to knock out all region finally - disable_mem_region((void*)0x3ffe0000, (void*)0x3ffe8000); //knock out ROM data region + // TODO: this region should be checked, since we don't need to knock out all region finally + disable_mem_region((void*)0x3ffe0000, (void*)0x3ffe8000); //knock out ROM data region #if CONFIG_MEMMAP_BT - disable_mem_region((void*)0x3ffb0000, (void*)0x3ffc0000); //knock out BT data region + disable_mem_region((void*)0x3ffb0000, (void*)0x3ffc0000); //knock out BT data region #endif #if CONFIG_MEMMAP_TRACEMEM - disable_mem_region((void*)0x3fff8000, (void*)0x40000000); //knock out trace mem region + disable_mem_region((void*)0x3fff8000, (void*)0x40000000); //knock out trace mem region #endif #if 0 - enable_spi_sram(); + enable_spi_sram(); #else - disable_mem_region((void*)0x3f800000, (void*)0x3f820000); //SPI SRAM not installed + disable_mem_region((void*)0x3f800000, (void*)0x3f820000); //SPI SRAM not installed #endif - //The heap allocator will treat every region given to it as separate. In order to get bigger ranges of contiguous memory, - //it's useful to coalesce adjacent regions that have the same tag. + //The heap allocator will treat every region given to it as separate. In order to get bigger ranges of contiguous memory, + //it's useful to coalesce adjacent regions that have the same tag. - for (i=1; regions[i].xSizeInBytes!=0; i++) { - if (regions[i].pucStartAddress == (regions[i-1].pucStartAddress + regions[i-1].xSizeInBytes) && - regions[i].xTag == regions[i-1].xTag ) { - regions[i-1].xTag=-1; - regions[i].pucStartAddress=regions[i-1].pucStartAddress; - regions[i].xSizeInBytes+=regions[i-1].xSizeInBytes; - } - } + for (i=1; regions[i].xSizeInBytes!=0; i++) { + if (regions[i].pucStartAddress == (regions[i-1].pucStartAddress + regions[i-1].xSizeInBytes) && + regions[i].xTag == regions[i-1].xTag ) { + regions[i-1].xTag=-1; + regions[i].pucStartAddress=regions[i-1].pucStartAddress; + regions[i].xSizeInBytes+=regions[i-1].xSizeInBytes; + } + } - ESP_EARLY_LOGI(TAG, "Initializing heap allocator:"); - for (i=0; regions[i].xSizeInBytes!=0; i++) { - if (regions[i].xTag != -1) { - ESP_EARLY_LOGI(TAG, "Region %02d: %08X len %08X tag %d", i, - (int)regions[i].pucStartAddress, regions[i].xSizeInBytes, regions[i].xTag); - } - } - //Initialize the malloc implementation. - vPortDefineHeapRegionsTagged( regions ); + ESP_EARLY_LOGI(TAG, "Initializing heap allocator:"); + for (i=0; regions[i].xSizeInBytes!=0; i++) { + if (regions[i].xTag != -1) { + ESP_EARLY_LOGI(TAG, "Region %02d: %08X len %08X tag %d", i, + (int)regions[i].pucStartAddress, regions[i].xSizeInBytes, regions[i].xTag); + } + } + //Initialize the malloc implementation. + vPortDefineHeapRegionsTagged( regions ); } /* @@ -223,7 +223,7 @@ Standard malloc() implementation. Will return ho-hum byte-accessible data memory */ void *pvPortMalloc( size_t xWantedSize ) { - return pvPortMallocCaps( xWantedSize, MALLOC_CAP_8BIT ); + return pvPortMallocCaps( xWantedSize, MALLOC_CAP_8BIT ); } /* @@ -231,30 +231,30 @@ Routine to allocate a bit of memory with certain capabilities. caps is a bitfiel */ void *pvPortMallocCaps( size_t xWantedSize, uint32_t caps ) { - int prio; - int tag, j; - void *ret=NULL; - uint32_t remCaps; - for (prio=0; prio Date: Sun, 9 Oct 2016 16:42:49 +0800 Subject: [PATCH 050/343] components/openssl: add internal openssl X509 debug function --- .../openssl/include/internal/ssl_methods.h | 6 ++- .../openssl/include/internal/ssl_types.h | 2 + components/openssl/include/openssl/ssl.h | 22 +++++++++++ components/openssl/include/platform/ssl_pm.h | 1 + components/openssl/library/ssl_methods.c | 2 +- components/openssl/library/ssl_x509.c | 9 +++++ components/openssl/platform/ssl_pm.c | 38 +++++++++++++++++++ 7 files changed, 77 insertions(+), 3 deletions(-) diff --git a/components/openssl/include/internal/ssl_methods.h b/components/openssl/include/internal/ssl_methods.h index 7a63b9e949..cd2f8c0533 100644 --- a/components/openssl/include/internal/ssl_methods.h +++ b/components/openssl/include/internal/ssl_methods.h @@ -71,12 +71,14 @@ #define IMPLEMENT_X509_METHOD(func_name, \ new, \ free, \ - load) \ + load, \ + show_info) \ const X509_METHOD* func_name(void) { \ static const X509_METHOD func_name##_data LOCAL_ATRR = { \ new, \ free, \ - load \ + load, \ + show_info \ }; \ return &func_name##_data; \ } diff --git a/components/openssl/include/internal/ssl_types.h b/components/openssl/include/internal/ssl_types.h index c571865c1e..19944c7819 100644 --- a/components/openssl/include/internal/ssl_types.h +++ b/components/openssl/include/internal/ssl_types.h @@ -275,6 +275,8 @@ struct x509_method_st { void (*x509_free)(X509 *x); int (*x509_load)(X509 *x, const unsigned char *buf, int len); + + int (*x509_show_info)(X509 *x); }; struct pkey_method_st { diff --git a/components/openssl/include/openssl/ssl.h b/components/openssl/include/openssl/ssl.h index 1d115214fd..d8400e66b5 100644 --- a/components/openssl/include/openssl/ssl.h +++ b/components/openssl/include/openssl/ssl.h @@ -447,6 +447,28 @@ int SSL_pending(const SSL *ssl); */ int SSL_want_nothing(const SSL *ssl); +/** + * @brief check if SSL want to read + * + * @param ssl - SSL point + * + * @return result + * 0 : false + * 1 : true + */ +int SSL_want_read(const SSL *ssl); + +/** + * @brief check if SSL want to write + * + * @param ssl - SSL point + * + * @return result + * 0 : false + * 1 : true + */ +int SSL_want_write(const SSL *ssl); + /** * @brief get the SSL context current method * diff --git a/components/openssl/include/platform/ssl_pm.h b/components/openssl/include/platform/ssl_pm.h index cf1d213799..a516d57422 100644 --- a/components/openssl/include/platform/ssl_pm.h +++ b/components/openssl/include/platform/ssl_pm.h @@ -42,6 +42,7 @@ OSSL_HANDSHAKE_STATE ssl_pm_get_state(const SSL *ssl); void ssl_pm_set_bufflen(SSL *ssl, int len); +int x509_pm_show_info(X509 *x); int x509_pm_new(X509 *x, X509 *m_x); void x509_pm_free(X509 *x); int x509_pm_load(X509 *x, const unsigned char *buffer, int len); diff --git a/components/openssl/library/ssl_methods.c b/components/openssl/library/ssl_methods.c index 8159511c49..0002360846 100644 --- a/components/openssl/library/ssl_methods.c +++ b/components/openssl/library/ssl_methods.c @@ -71,7 +71,7 @@ IMPLEMENT_SSL_METHOD(SSL3_VERSION, -1, TLS_method_func, SSLv3_method); */ IMPLEMENT_X509_METHOD(X509_method, x509_pm_new, x509_pm_free, - x509_pm_load); + x509_pm_load, x509_pm_show_info); /** * @brief get private key object method diff --git a/components/openssl/library/ssl_x509.c b/components/openssl/library/ssl_x509.c index d060419e6a..06e6e7b544 100644 --- a/components/openssl/library/ssl_x509.c +++ b/components/openssl/library/ssl_x509.c @@ -17,6 +17,14 @@ #include "ssl_dbg.h" #include "ssl_port.h" +/** + * @brief show X509 certification information + */ +int __X509_show_info(X509 *x) +{ + return X509_METHOD_CALL(show_info, x); +} + /** * @brief create a X509 certification object according to input X509 certification */ @@ -256,3 +264,4 @@ X509 *SSL_get_peer_certificate(const SSL *ssl) return ssl->session->peer; } + diff --git a/components/openssl/platform/ssl_pm.c b/components/openssl/platform/ssl_pm.c index 4bc631382f..bbe290f2a3 100644 --- a/components/openssl/platform/ssl_pm.c +++ b/components/openssl/platform/ssl_pm.c @@ -31,6 +31,8 @@ #define DEBUG_LOAD_BUF_STRING(str) #endif +#define X509_INFO_STRING_LENGTH 1024 + struct ssl_pm { /* local socket file description */ @@ -370,6 +372,42 @@ OSSL_HANDSHAKE_STATE ssl_pm_get_state(const SSL *ssl) return state; } +int x509_pm_show_info(X509 *x) +{ + int ret; + char *buf; + mbedtls_x509_crt *x509_crt; + struct x509_pm *x509_pm = x->x509_pm; + + if (x509_pm->x509_crt) + x509_crt = x509_pm->x509_crt; + else if (x509_pm->ex_crt) + x509_crt = x509_pm->ex_crt; + else + x509_crt = NULL; + + if (!x509_crt) + return -1; + + buf = ssl_malloc(X509_INFO_STRING_LENGTH); + if (!buf) + SSL_RET(failed1, ""); + + ret = mbedtls_x509_crt_info(buf, X509_INFO_STRING_LENGTH - 1, "", x509_crt); + if (ret <= 0) + SSL_RET(failed2, ""); + buf[ret] = 0; + + SSL_PRINT("%s", buf); + + return 0; + +failed2: + ssl_free(buf); +failed1: + return -1; +} + int x509_pm_new(X509 *x, X509 *m_x) { struct x509_pm *x509_pm; From 47e83ee65e4861a79b4396fca00ee4fa9427886d Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Sun, 9 Oct 2016 17:49:16 +0800 Subject: [PATCH 051/343] components/openssl: add SSL any version function setting --- components/openssl/platform/ssl_pm.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/components/openssl/platform/ssl_pm.c b/components/openssl/platform/ssl_pm.c index bbe290f2a3..539e954c78 100644 --- a/components/openssl/platform/ssl_pm.c +++ b/components/openssl/platform/ssl_pm.c @@ -111,16 +111,19 @@ int ssl_pm_new(SSL *ssl) if (ret) SSL_ERR(ret, failed2, "mbedtls_ssl_config_defaults:[-0x%x]\n", -ret); - if (TLS1_2_VERSION == ssl->version) - version = MBEDTLS_SSL_MINOR_VERSION_3; - else if (TLS1_1_VERSION == ssl->version) - version = MBEDTLS_SSL_MINOR_VERSION_2; - else if (TLS1_VERSION == ssl->version) - version = MBEDTLS_SSL_MINOR_VERSION_1; - else - version = MBEDTLS_SSL_MINOR_VERSION_0; + if (TLS_ANY_VERSION != ssl->version) { + if (TLS1_2_VERSION == ssl->version) + version = MBEDTLS_SSL_MINOR_VERSION_3; + else if (TLS1_1_VERSION == ssl->version) + version = MBEDTLS_SSL_MINOR_VERSION_2; + else if (TLS1_VERSION == ssl->version) + version = MBEDTLS_SSL_MINOR_VERSION_1; + else + version = MBEDTLS_SSL_MINOR_VERSION_0; - //mbedtls_ssl_conf_max_version(&ssl_pm->conf, MBEDTLS_SSL_MAJOR_VERSION_3, version); + mbedtls_ssl_conf_max_version(&ssl_pm->conf, MBEDTLS_SSL_MAJOR_VERSION_3, version); + mbedtls_ssl_conf_min_version(&ssl_pm->conf, MBEDTLS_SSL_MAJOR_VERSION_3, version); + } mbedtls_ssl_conf_rng(&ssl_pm->conf, mbedtls_ctr_drbg_random, &ssl_pm->ctr_drbg); From 37a68ad6052b94ba4f3e969021eb5318bb4eb30f Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Sun, 9 Oct 2016 19:02:31 +0800 Subject: [PATCH 052/343] components/openssl: fix SSL X509 show message, leaking memory --- components/openssl/platform/ssl_pm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/openssl/platform/ssl_pm.c b/components/openssl/platform/ssl_pm.c index 539e954c78..eadd323e70 100644 --- a/components/openssl/platform/ssl_pm.c +++ b/components/openssl/platform/ssl_pm.c @@ -401,6 +401,8 @@ int x509_pm_show_info(X509 *x) SSL_RET(failed2, ""); buf[ret] = 0; + ssl_free(buf); + SSL_PRINT("%s", buf); return 0; From 034da95abb17974e5ed7ec0bfa9d1ba629636986 Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Sun, 9 Oct 2016 19:18:18 +0800 Subject: [PATCH 053/343] components/openssl: change SSL read or write statement after success --- components/openssl/library/ssl_lib.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/components/openssl/library/ssl_lib.c b/components/openssl/library/ssl_lib.c index 267d23f25f..9740282d13 100644 --- a/components/openssl/library/ssl_lib.c +++ b/components/openssl/library/ssl_lib.c @@ -390,7 +390,8 @@ int SSL_read(SSL *ssl, void *buffer, int len) ret = SSL_METHOD_CALL(read, ssl, buffer, len); - ssl->rwstate = SSL_NOTHING; + if (ret == len) + ssl->rwstate = SSL_NOTHING; return ret; } @@ -428,12 +429,10 @@ int SSL_write(SSL *ssl, const void *buffer, int len) } } while (ret > 0 && send_bytes); - ssl->rwstate = SSL_NOTHING; - - send_bytes = len - send_bytes; - if (send_bytes >= 0) - ret = send_bytes; - else + if (ret >= 0) { + ret = len - send_bytes; + ssl->rwstate = SSL_NOTHING; + } else ret = -1; return ret; From ecefb1305a08ba5bad49894273a3c47f82fbe0ab Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Mon, 10 Oct 2016 10:40:00 +0800 Subject: [PATCH 054/343] components/openssl: change header file relationship of level --- components/openssl/include/internal/ssl_stack.h | 11 +++++++++++ components/openssl/include/internal/ssl_types.h | 11 ----------- components/openssl/include/openssl/ssl.h | 1 - 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/components/openssl/include/internal/ssl_stack.h b/components/openssl/include/internal/ssl_stack.h index b37c8dffa9..7a7051a026 100644 --- a/components/openssl/include/internal/ssl_stack.h +++ b/components/openssl/include/internal/ssl_stack.h @@ -7,6 +7,17 @@ #include "ssl_types.h" +#define STACK_OF(type) struct stack_st_##type + +#define SKM_DEFINE_STACK_OF(t1, t2, t3) \ + STACK_OF(t1); \ + static ossl_inline STACK_OF(t1) *sk_##t1##_new_null(void) \ + { \ + return (STACK_OF(t1) *)OPENSSL_sk_new_null(); \ + } \ + +#define DEFINE_STACK_OF(t) SKM_DEFINE_STACK_OF(t, t, t) + /** * @brief create a openssl stack object * diff --git a/components/openssl/include/internal/ssl_types.h b/components/openssl/include/internal/ssl_types.h index 19944c7819..5aaee94176 100644 --- a/components/openssl/include/internal/ssl_types.h +++ b/components/openssl/include/internal/ssl_types.h @@ -37,17 +37,6 @@ typedef void BIO; #define X509_METHOD_CALL(f, x, ...) x->method->x509_##f(x, ##__VA_ARGS__) #define EVP_PKEY_METHOD_CALL(f, k, ...) k->method->pkey_##f(k, ##__VA_ARGS__) -#define STACK_OF(type) struct stack_st_##type - -#define SKM_DEFINE_STACK_OF(t1, t2, t3) \ - STACK_OF(t1); \ - static ossl_inline STACK_OF(t1) *sk_##t1##_new_null(void) \ - { \ - return (STACK_OF(t1) *)OPENSSL_sk_new_null(); \ - } \ - -#define DEFINE_STACK_OF(t) SKM_DEFINE_STACK_OF(t, t, t) - typedef int (*OPENSSL_sk_compfunc)(const void *, const void *); struct stack_st; diff --git a/components/openssl/include/openssl/ssl.h b/components/openssl/include/openssl/ssl.h index d8400e66b5..7f8eb88302 100644 --- a/components/openssl/include/openssl/ssl.h +++ b/components/openssl/include/openssl/ssl.h @@ -19,7 +19,6 @@ extern "C" { #endif -#include "platform/ssl_port.h" #include "internal/ssl_x509.h" #include "internal/ssl_pkey.h" From 5d60a1153d04ac90dd037b39bc79392bca72c02c Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Mon, 10 Oct 2016 11:18:45 +0800 Subject: [PATCH 055/343] components/openssl: Modify the documentation of OpenSSL-APIs 1. add description of non-supported APIs 2. remove non-supported APIs now 3. add more supported APIs --- components/openssl/OpenSSL-APIs.rst | 197 ++++++++++------------------ 1 file changed, 68 insertions(+), 129 deletions(-) diff --git a/components/openssl/OpenSSL-APIs.rst b/components/openssl/OpenSSL-APIs.rst index 6a8a68c1ff..e7877b128c 100644 --- a/components/openssl/OpenSSL-APIs.rst +++ b/components/openssl/OpenSSL-APIs.rst @@ -1,10 +1,15 @@ OpenSSL-APIs -============ +------------ All original source code in this repository is Copyright (C) 2015-2016 Espressif Systems. This source code is licensed under the Apache License 2.0 as described in the file LICENSE. +OpenSSL APIs not mentioned in this article are not open to public for the time, +also do not have the corresponding function. +If user calls it directly, it will always return an error or may show cannot link +at compile time. + Chapter Introduction ==================== @@ -17,8 +22,7 @@ Chapter Introduction Chapter 1. SSL Context Method Create ==================================== - -1.1 const SSL_METHOD* ``SSLv23_client_method`` (void) +1.1 const SSL_METHOD* ``SSLv3_client_method`` (void) Arguments:: @@ -26,7 +30,7 @@ Chapter 1. SSL Context Method Create Return:: - SSLV2 and 3 version SSL context client method point + SSLV3.0 version SSL context client method point Description:: @@ -36,12 +40,11 @@ Chapter 1. SSL Context Method Create void example(void) { - const SSL_METHOD *method = SSLv23_client_method(); + const SSL_METHOD *method = SSLv3_client_method(); ... } - 1.2 const SSL_METHOD* ``TLSv1_client_method`` (void) Arguments:: @@ -65,32 +68,7 @@ Chapter 1. SSL Context Method Create ... } - -1.3 const SSL_METHOD* ``SSLv3_client_method`` (void) - - Arguments:: - - none - - Return:: - - SSLV3.0 version SSL context client method point - - Description:: - - create the target SSL context method - - Example:: - - void example(void) - { - const SSL_METHOD *method = SSLv3_client_method(); - - ... - } - - -1.4 const SSL_METHOD* ``TLSv1_1_client_method`` (void) +1.3 const SSL_METHOD* ``TLSv1_1_client_method`` (void) Arguments:: @@ -113,8 +91,7 @@ Chapter 1. SSL Context Method Create ... } - -1.5 const SSL_METHOD* ``TLSv1_2_client_method`` (void) +1.4 const SSL_METHOD* ``TLSv1_2_client_method`` (void) Arguments:: @@ -136,9 +113,31 @@ Chapter 1. SSL Context Method Create ... } + +1.5 const SSL_METHOD* ``TLS_client_method`` (void) + Arguments:: + + none + + Return:: + + TLSV1.2 version SSL context client method point + + Description:: + + create the default SSL context method, it's always to be TLSV1.2 + + Example:: + + void example(void) + { + const SSL_METHOD *method = TLSv1_2_client_method(); + + ... + } -1.6 const SSL_METHOD* ``SSLv23_server_method`` (void) +1.6 const SSL_METHOD* ``SSLv3_server_method`` (void) Arguments:: @@ -146,7 +145,7 @@ Chapter 1. SSL Context Method Create Return:: - SSLV2 and 3 version SSL context server method point + SSLV3.0 version SSL context server method point Description:: @@ -156,13 +155,35 @@ Chapter 1. SSL Context Method Create void example(void) { - const SSL_METHOD *method = SSLv23_server_method(); + const SSL_METHOD *method = SSLv3_server_method(); ... } +1.7 const SSL_METHOD* ``TLSv1_server_method`` (void) -1.7 const SSL_METHOD* ``TLSv1_1_server_method`` (void) + Arguments:: + + none + + Return:: + + TLSV1.0 version SSL context server method point + + Description:: + + create the target SSL context method + + Example:: + + void example(void) + { + const SSL_METHOD *method = TLSv1_server_method(); + + ... + } + +1.8 const SSL_METHOD* ``TLSv1_1_server_method`` (void) Arguments:: @@ -186,7 +207,7 @@ Chapter 1. SSL Context Method Create } -1.8 const SSL_METHOD* ``TLSv1_2_server_method`` (void) +1.9 const SSL_METHOD* ``TLSv1_2_server_method`` (void) Arguments:: @@ -209,8 +230,7 @@ Chapter 1. SSL Context Method Create ... } - -1.9 const SSL_METHOD* ``TLSv1_server_method`` (void) +1.10 const SSL_METHOD* ``TLS_server_method`` (void) Arguments:: @@ -218,47 +238,22 @@ Chapter 1. SSL Context Method Create Return:: - TLSV1.0 version SSL context server method point + TLSV1.2 version SSL context server method point Description:: - create the target SSL context method + create the default SSL context method, it's always to be TLSV1.2 Example:: void example(void) { - const SSL_METHOD *method = TLSv1_server_method(); + const SSL_METHOD *method = TLSv1_2_server_method(); ... } -1.10 const SSL_METHOD* ``SSLv3_server_method`` (void) - - Arguments:: - - none - - Return:: - - SSLV3.0 version SSL context server method point - - Description:: - - create the target SSL context method - - Example:: - - void example(void) - { - const SSL_METHOD *method = SSLv3_server_method(); - - ... - } - - - Chapter 2. SSL Context Fucntion =============================== @@ -1326,64 +1321,8 @@ Chapter 3. SSL Fucntion err = SSL_get_error(ssl, ret); } - -3.35 void ``SSL_CTX_set_default_read_buffer_len`` (SSL_CTX *ctx, size_t len) - Arguments:: - - ctx - SSL context point - len - read buffer length - - Return:: - - none - - Description:: - - set the SSL context read buffer length - - Example:: - - void example(void) - { - SSL_CTX *ctx; - size_t len; - - ... ... - - SSL_CTX_set_default_read_buffer_len(ctx, len); - } - - -3.36 void ``SSL_set_default_read_buffer_len`` (SSL *ssl, size_t len) - - Arguments:: - - ssl - SSL point - len - read buffer length - - Return:: - - none - - Description:: - - set the SSL read buffer length - - Example:: - - void example(void) - { - SSL *ssl; - size_t len; - - ... ... - - SSL_set_default_read_buffer_len(ctx, len); - } - - -3.37 int ``SSL_want`` (const SSL *ssl) +3.35 int ``SSL_want`` (const SSL *ssl) Arguments:: @@ -1410,7 +1349,7 @@ Chapter 3. SSL Fucntion } -3.38 int ``SSL_want_nothing`` (const SSL *ssl) +3.36 int ``SSL_want_nothing`` (const SSL *ssl) Arguments:: @@ -1438,7 +1377,7 @@ Chapter 3. SSL Fucntion } -3.39 int ``SSL_want_read`` (const SSL *ssl) +3.37 int ``SSL_want_read`` (const SSL *ssl) Arguments:: @@ -1466,7 +1405,7 @@ Chapter 3. SSL Fucntion } -3.40 int ``SSL_want_write`` (const SSL *ssl) +3.38 int ``SSL_want_write`` (const SSL *ssl) Arguments:: From 924fea7cc0f78832bfdd711d285c8d756912e336 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 11 Oct 2016 00:05:15 -0600 Subject: [PATCH 056/343] freertos: fix setting xCoreID for new task --- components/freertos/tasks.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/freertos/tasks.c b/components/freertos/tasks.c index 63a659b5d7..7fb40e771e 100644 --- a/components/freertos/tasks.c +++ b/components/freertos/tasks.c @@ -629,7 +629,7 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB, TaskFunction_t pxTaskCode configASSERT( puxStackBuffer != NULL ); configASSERT( pxTaskBuffer != NULL ); - configASSERT( (xCoreID>=0 && xCoreID=0 && xCoreIDpxStack = ( StackType_t * ) puxStackBuffer; + pxNewTCB->xCoreID = xCoreID; #if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) { From 90e57cdf8f3f15c3af257b42feb28ade4907d581 Mon Sep 17 00:00:00 2001 From: Yinling Date: Mon, 26 Sep 2016 14:27:57 +0800 Subject: [PATCH 057/343] add auto generated test folder to components: 1. add test cases and related scripts 2. add CI config files read README.md for detail --- components/test/CIConfigs/Function_SYS_01.yml | 5 + .../test/CIConfigs/Function_TCPIP_01.yml | 11 + .../test/CIConfigs/Function_TCPIP_02.yml | 11 + .../test/CIConfigs/Function_TCPIP_03.yml | 11 + .../test/CIConfigs/Function_TCPIP_04.yml | 11 + .../test/CIConfigs/Function_TCPIP_05.yml | 11 + .../test/CIConfigs/Function_TCPIP_06.yml | 8 + .../test/CIConfigs/Function_TCPIP_07.yml | 5 + .../test/CIConfigs/Function_WIFI_01.yml | 11 + .../test/CIConfigs/Function_WIFI_02.yml | 9 + components/test/InitialConditionAll.yml | 2923 ++++ components/test/README.md | 35 + components/test/TestCaseAll.yml | 13810 ++++++++++++++++ .../TestCaseScript/ATFunc/CmdInterruptTest.py | 130 + components/test/TestCaseScript/ATFunc/LAP.py | 64 + .../ATFunc/SendDataValidation.py | 161 + .../test/TestCaseScript/ATFunc/UARTTest.py | 164 + .../test/TestCaseScript/ATFunc/__init__.py | 2 + .../TestCaseScript/ATStress/ATPassThrough.py | 179 + .../test/TestCaseScript/ATStress/ATSleep.py | 251 + .../TestCaseScript/ATStress/SoftAPServer.py | 308 + .../TestCaseScript/ATStress/TCPClientMulti.py | 116 + .../ATStress/TCPClientSingle.py | 123 + .../TestCaseScript/ATStress/TCPSendPerf.py | 148 + .../TestCaseScript/ATStress/TCPServerMulti.py | 126 + .../TestCaseScript/ATStress/TCPTransparent.py | 280 + .../test/TestCaseScript/ATStress/UDPMulti.py | 113 + .../test/TestCaseScript/ATStress/UDPSingle.py | 105 + .../TestCaseScript/ATStress/UDPTransparent.py | 262 + .../test/TestCaseScript/ATStress/__init__.py | 2 + components/test/TestCaseScript/IOT/SCIOT.py | 357 + .../test/TestCaseScript/IOT/SCUDPServer.py | 378 + .../TestCaseScript/IOT/WifiConnUtility.py | 244 + components/test/TestCaseScript/IOT/WifiJAP.py | 183 + .../test/TestCaseScript/IOT/__init__.py | 1 + .../TestCaseScript/MeshStress/MeshSendRecv.py | 525 + .../TestCaseScript/MeshStress/__init__.py | 1 + .../test/TestCaseScript/SSLTest/Capability.py | 90 + .../TestCaseScript/SSLTest/ConfigUtility.py | 333 + .../test/TestCaseScript/SSLTest/Parameter.py | 56 + .../test/TestCaseScript/SSLTest/SSLHandler.py | 498 + .../TestCaseScript/SSLTest/SSLHandshake.py | 240 + .../test/TestCaseScript/SSLTest/SSLLowMem.py | 140 + .../TestCaseScript/SSLTest/SSLSendRecv.py | 147 + .../test/TestCaseScript/SSLTest/__init__.py | 1 + .../TestCaseScript/SleepMode/AutoSleep.py | 561 + .../TestCaseScript/SleepMode/DeepSleep.py | 259 + .../TestCaseScript/SleepMode/ForceSleep.py | 254 + .../test/TestCaseScript/SleepMode/__init__.py | 1 + .../TestCaseScript/StableTest/StableCase1.py | 160 + .../TestCaseScript/StableTest/__init__.py | 1 + .../TestCaseScript/TCPIPStress/ARPStress.py | 121 + .../TestCaseScript/TCPIPStress/PingStress.py | 122 + .../TestCaseScript/TCPIPStress/__init__.py | 1 + .../TestCaseScript/TCPStress/TCPAP4STA.py | 168 + .../TestCaseScript/TCPStress/TCPAPNSTA.py | 209 + .../TCPStress/TCPConnStressTC.py | 363 + .../TCPStress/TCPConnUtility.py | 273 + .../TestCaseScript/TCPStress/TCPConnection.py | 321 + .../TCPStress/TCPConnectionUtility.py | 251 + .../TCPStress/TCPDataValidation.py | 244 + .../TestCaseScript/TCPStress/TCPRandomSend.py | 103 + .../TestCaseScript/TCPStress/TCPSendRecv.py | 143 + .../TCPStress/TCPSoftAPSTASendRecv.py | 318 + .../TestCaseScript/TCPStress/TCPThroughput.py | 315 + .../test/TestCaseScript/TCPStress/__init__.py | 1 + .../TestCaseScript/UDPStress/UDPSendRecv.py | 130 + .../TestCaseScript/UDPStress/UDPThroughput.py | 305 + .../test/TestCaseScript/UDPStress/__init__.py | 1 + .../TestCaseScript/WiFiStress/SoftAPNSTA.py | 178 + .../WiFiStress/WifiConnUtility.py | 240 + .../test/TestCaseScript/WiFiStress/WifiJAP.py | 218 + .../TestCaseScript/WiFiStress/WifiJAPAtt.py | 173 + .../WiFiStress/WifiSmartConfig.py | 273 + .../TestCaseScript/WiFiStress/__init__.py | 1 + components/test/TestCaseScript/__init__.py | 2 + components/test/TestEnvAll.yml | 275 + 77 files changed, 28574 insertions(+) create mode 100644 components/test/CIConfigs/Function_SYS_01.yml create mode 100644 components/test/CIConfigs/Function_TCPIP_01.yml create mode 100644 components/test/CIConfigs/Function_TCPIP_02.yml create mode 100644 components/test/CIConfigs/Function_TCPIP_03.yml create mode 100644 components/test/CIConfigs/Function_TCPIP_04.yml create mode 100644 components/test/CIConfigs/Function_TCPIP_05.yml create mode 100644 components/test/CIConfigs/Function_TCPIP_06.yml create mode 100644 components/test/CIConfigs/Function_TCPIP_07.yml create mode 100644 components/test/CIConfigs/Function_WIFI_01.yml create mode 100644 components/test/CIConfigs/Function_WIFI_02.yml create mode 100644 components/test/InitialConditionAll.yml create mode 100644 components/test/README.md create mode 100644 components/test/TestCaseAll.yml create mode 100755 components/test/TestCaseScript/ATFunc/CmdInterruptTest.py create mode 100644 components/test/TestCaseScript/ATFunc/LAP.py create mode 100755 components/test/TestCaseScript/ATFunc/SendDataValidation.py create mode 100644 components/test/TestCaseScript/ATFunc/UARTTest.py create mode 100755 components/test/TestCaseScript/ATFunc/__init__.py create mode 100755 components/test/TestCaseScript/ATStress/ATPassThrough.py create mode 100644 components/test/TestCaseScript/ATStress/ATSleep.py create mode 100755 components/test/TestCaseScript/ATStress/SoftAPServer.py create mode 100755 components/test/TestCaseScript/ATStress/TCPClientMulti.py create mode 100755 components/test/TestCaseScript/ATStress/TCPClientSingle.py create mode 100755 components/test/TestCaseScript/ATStress/TCPSendPerf.py create mode 100755 components/test/TestCaseScript/ATStress/TCPServerMulti.py create mode 100755 components/test/TestCaseScript/ATStress/TCPTransparent.py create mode 100755 components/test/TestCaseScript/ATStress/UDPMulti.py create mode 100755 components/test/TestCaseScript/ATStress/UDPSingle.py create mode 100755 components/test/TestCaseScript/ATStress/UDPTransparent.py create mode 100755 components/test/TestCaseScript/ATStress/__init__.py create mode 100755 components/test/TestCaseScript/IOT/SCIOT.py create mode 100755 components/test/TestCaseScript/IOT/SCUDPServer.py create mode 100755 components/test/TestCaseScript/IOT/WifiConnUtility.py create mode 100755 components/test/TestCaseScript/IOT/WifiJAP.py create mode 100755 components/test/TestCaseScript/IOT/__init__.py create mode 100755 components/test/TestCaseScript/MeshStress/MeshSendRecv.py create mode 100755 components/test/TestCaseScript/MeshStress/__init__.py create mode 100755 components/test/TestCaseScript/SSLTest/Capability.py create mode 100755 components/test/TestCaseScript/SSLTest/ConfigUtility.py create mode 100755 components/test/TestCaseScript/SSLTest/Parameter.py create mode 100644 components/test/TestCaseScript/SSLTest/SSLHandler.py create mode 100755 components/test/TestCaseScript/SSLTest/SSLHandshake.py create mode 100644 components/test/TestCaseScript/SSLTest/SSLLowMem.py create mode 100644 components/test/TestCaseScript/SSLTest/SSLSendRecv.py create mode 100755 components/test/TestCaseScript/SSLTest/__init__.py create mode 100755 components/test/TestCaseScript/SleepMode/AutoSleep.py create mode 100755 components/test/TestCaseScript/SleepMode/DeepSleep.py create mode 100755 components/test/TestCaseScript/SleepMode/ForceSleep.py create mode 100755 components/test/TestCaseScript/SleepMode/__init__.py create mode 100755 components/test/TestCaseScript/StableTest/StableCase1.py create mode 100755 components/test/TestCaseScript/StableTest/__init__.py create mode 100755 components/test/TestCaseScript/TCPIPStress/ARPStress.py create mode 100755 components/test/TestCaseScript/TCPIPStress/PingStress.py create mode 100755 components/test/TestCaseScript/TCPIPStress/__init__.py create mode 100755 components/test/TestCaseScript/TCPStress/TCPAP4STA.py create mode 100755 components/test/TestCaseScript/TCPStress/TCPAPNSTA.py create mode 100755 components/test/TestCaseScript/TCPStress/TCPConnStressTC.py create mode 100755 components/test/TestCaseScript/TCPStress/TCPConnUtility.py create mode 100755 components/test/TestCaseScript/TCPStress/TCPConnection.py create mode 100755 components/test/TestCaseScript/TCPStress/TCPConnectionUtility.py create mode 100755 components/test/TestCaseScript/TCPStress/TCPDataValidation.py create mode 100755 components/test/TestCaseScript/TCPStress/TCPRandomSend.py create mode 100755 components/test/TestCaseScript/TCPStress/TCPSendRecv.py create mode 100644 components/test/TestCaseScript/TCPStress/TCPSoftAPSTASendRecv.py create mode 100755 components/test/TestCaseScript/TCPStress/TCPThroughput.py create mode 100755 components/test/TestCaseScript/TCPStress/__init__.py create mode 100755 components/test/TestCaseScript/UDPStress/UDPSendRecv.py create mode 100755 components/test/TestCaseScript/UDPStress/UDPThroughput.py create mode 100755 components/test/TestCaseScript/UDPStress/__init__.py create mode 100755 components/test/TestCaseScript/WiFiStress/SoftAPNSTA.py create mode 100755 components/test/TestCaseScript/WiFiStress/WifiConnUtility.py create mode 100755 components/test/TestCaseScript/WiFiStress/WifiJAP.py create mode 100755 components/test/TestCaseScript/WiFiStress/WifiJAPAtt.py create mode 100755 components/test/TestCaseScript/WiFiStress/WifiSmartConfig.py create mode 100755 components/test/TestCaseScript/WiFiStress/__init__.py create mode 100755 components/test/TestCaseScript/__init__.py create mode 100644 components/test/TestEnvAll.yml diff --git a/components/test/CIConfigs/Function_SYS_01.yml b/components/test/CIConfigs/Function_SYS_01.yml new file mode 100644 index 0000000000..501f15f6ba --- /dev/null +++ b/components/test/CIConfigs/Function_SYS_01.yml @@ -0,0 +1,5 @@ +Config: {debug mode: false, execute count: 1, execute order: in order} +DUT: [SSC1] +Filter: +- ADD: + ID: [SYS_MISC_0101, SYS_MISC_0201] diff --git a/components/test/CIConfigs/Function_TCPIP_01.yml b/components/test/CIConfigs/Function_TCPIP_01.yml new file mode 100644 index 0000000000..9b43ab589b --- /dev/null +++ b/components/test/CIConfigs/Function_TCPIP_01.yml @@ -0,0 +1,11 @@ +Config: {debug mode: false, execute count: 1, execute order: in order} +DUT: [SSC2, SSC1] +Filter: +- ADD: + ID: [TCPIP_ICMP_0101, TCPIP_ARP_0202, ^TCPIP_DHCP_0302, ^TCPIP_DHCP_0301, ^TCPIP_UDP_0113, + TCPIP_DHCP_0302, TCPIP_DHCP_0301, TCPIP_ARP_0204, TCPIP_TCP_0412, TCPIP_TCP_0403, + TCPIP_TCP_0402, TCPIP_TCP_0401, TCPIP_TCP_0407, TCPIP_TCP_0406, TCPIP_TCP_0404, + TCPIP_TCP_0408, ^TCPIP_TCP_0202, TCPIP_TCP_0110, ^TCPIP_TCP_0203, TCPIP_DHCP_0101, + TCPIP_DHCP_0103, TCPIP_DHCP_0102, ^TCPIP_UDP_0303, ^TCPIP_UDP_0302, ^TCPIP_UDP_0301, + TCPIP_DNS_0102, TCPIP_DNS_0101, TCPIP_IP_0101, TCPIP_IP_0102, ^TCPIP_IGMP_0102, + ^TCPIP_IGMP_0101] diff --git a/components/test/CIConfigs/Function_TCPIP_02.yml b/components/test/CIConfigs/Function_TCPIP_02.yml new file mode 100644 index 0000000000..7e0a3ead43 --- /dev/null +++ b/components/test/CIConfigs/Function_TCPIP_02.yml @@ -0,0 +1,11 @@ +Config: {debug mode: false, execute count: 1, execute order: in order} +DUT: [SSC2, SSC1] +Filter: +- ADD: + ID: [^TCPIP_IGMP_0104, ^TCPIP_UDP_0110, TCPIP_IGMP_0104, TCPIP_IGMP_0103, TCPIP_IGMP_0102, + TCPIP_IGMP_0101, ^TCPIP_UDP_0201, ^TCPIP_ICMP_0101, TCPIP_UDP_0108, TCPIP_UDP_0109, + TCPIP_UDP_0106, TCPIP_UDP_0107, TCPIP_UDP_0104, TCPIP_UDP_0105, TCPIP_UDP_0102, + TCPIP_UDP_0103, TCPIP_UDP_0101, TCPIP_IGMP_0204, TCPIP_IGMP_0201, TCPIP_IGMP_0202, + TCPIP_IGMP_0203, ^TCPIP_TCP_0404, ^TCPIP_TCP_0406, ^TCPIP_TCP_0407, ^TCPIP_TCP_0401, + ^TCPIP_TCP_0402, ^TCPIP_TCP_0403, ^TCPIP_TCP_0408, TCPIP_UDP_0201, ^TCPIP_UDP_0307, + ^TCPIP_UDP_0306] diff --git a/components/test/CIConfigs/Function_TCPIP_03.yml b/components/test/CIConfigs/Function_TCPIP_03.yml new file mode 100644 index 0000000000..33dcd14bea --- /dev/null +++ b/components/test/CIConfigs/Function_TCPIP_03.yml @@ -0,0 +1,11 @@ +Config: {debug mode: false, execute count: 1, execute order: in order} +DUT: [SSC2, SSC1] +Filter: +- ADD: + ID: [^TCPIP_UDP_0305, ^TCPIP_UDP_0304, ^TCPIP_TCP_0101, ^TCPIP_TCP_0103, ^TCPIP_TCP_0102, + ^TCPIP_TCP_0105, ^TCPIP_TCP_0104, ^TCPIP_TCP_0107, ^TCPIP_TCP_0106, ^TCPIP_DHCP_0210, + ^TCPIP_DHCP_0211, TCPIP_TCP_0212, TCPIP_TCP_0210, ^TCPIP_TCP_0210, ^TCPIP_TCP_0212, + TCPIP_DHCP_0211, TCPIP_DHCP_0210, TCPIP_UDP_0202, TCPIP_TCP_0411, ^TCPIP_IP_0102, + ^TCPIP_UDP_0105, ^TCPIP_UDP_0104, ^TCPIP_UDP_0107, ^TCPIP_UDP_0106, ^TCPIP_UDP_0101, + ^TCPIP_UDP_0103, ^TCPIP_UDP_0102, ^TCPIP_DHCP_0102, ^TCPIP_DHCP_0103, ^TCPIP_UDP_0108, + ^TCPIP_IGMP_0201] diff --git a/components/test/CIConfigs/Function_TCPIP_04.yml b/components/test/CIConfigs/Function_TCPIP_04.yml new file mode 100644 index 0000000000..af2cc7d22f --- /dev/null +++ b/components/test/CIConfigs/Function_TCPIP_04.yml @@ -0,0 +1,11 @@ +Config: {debug mode: false, execute count: 1, execute order: in order} +DUT: [SSC2, SSC1] +Filter: +- ADD: + ID: [^TCPIP_IGMP_0203, ^TCPIP_IGMP_0202, ^TCPIP_IGMP_0204, TCPIP_UDP_0114, TCPIP_UDP_0111, + TCPIP_UDP_0110, TCPIP_UDP_0113, TCPIP_UDP_0112, ^TCPIP_TCP_0201, ^TCPIP_TCP_0206, + ^TCPIP_TCP_0207, TCPIP_TCP_0501, ^TCPIP_DNS_0101, ^TCPIP_DNS_0103, ^TCPIP_DNS_0102, + TCPIP_TCP_0106, TCPIP_TCP_0107, TCPIP_TCP_0104, TCPIP_TCP_0105, TCPIP_TCP_0102, + TCPIP_TCP_0103, TCPIP_TCP_0101, ^TCPIP_TCP_0116, ^TCPIP_TCP_0114, ^TCPIP_TCP_0115, + ^TCPIP_TCP_0112, ^TCPIP_TCP_0113, ^TCPIP_TCP_0110, ^TCPIP_TCP_0111, TCPIP_ARP_0101, + TCPIP_UDP_0304] diff --git a/components/test/CIConfigs/Function_TCPIP_05.yml b/components/test/CIConfigs/Function_TCPIP_05.yml new file mode 100644 index 0000000000..a89ece34cc --- /dev/null +++ b/components/test/CIConfigs/Function_TCPIP_05.yml @@ -0,0 +1,11 @@ +Config: {debug mode: false, execute count: 1, execute order: in order} +DUT: [SSC2, SSC1] +Filter: +- ADD: + ID: [TCPIP_UDP_0305, TCPIP_UDP_0306, TCPIP_UDP_0307, TCPIP_UDP_0301, TCPIP_UDP_0302, + TCPIP_UDP_0303, ^TCPIP_DHCP_0209, ^TCPIP_DHCP_0208, ^TCPIP_DHCP_0207, ^TCPIP_DHCP_0206, + ^TCPIP_DHCP_0205, ^TCPIP_DHCP_0204, ^TCPIP_DHCP_0203, ^TCPIP_DHCP_0202, ^TCPIP_DHCP_0201, + TCPIP_TCP_0204, TCPIP_TCP_0207, TCPIP_TCP_0206, TCPIP_TCP_0201, ^TCPIP_DHCP_0101, + TCPIP_TCP_0203, TCPIP_TCP_0202, TCPIP_TCP_0208, TCPIP_DNS_0103, TCPIP_DHCP_0206, + TCPIP_DHCP_0207, TCPIP_DHCP_0204, TCPIP_DHCP_0205, TCPIP_DHCP_0202, TCPIP_DHCP_0203, + ^TCPIP_TCP_0204] diff --git a/components/test/CIConfigs/Function_TCPIP_06.yml b/components/test/CIConfigs/Function_TCPIP_06.yml new file mode 100644 index 0000000000..929aafd13e --- /dev/null +++ b/components/test/CIConfigs/Function_TCPIP_06.yml @@ -0,0 +1,8 @@ +Config: {debug mode: false, execute count: 1, execute order: in order} +DUT: [SSC2, SSC1] +Filter: +- ADD: + ID: [TCPIP_DHCP_0201, ^TCPIP_TCP_0208, TCPIP_DHCP_0208, TCPIP_DHCP_0209, ^TCPIP_TCP_0412, + ^TCPIP_TCP_0411, TCPIP_ARP_0203, ^TCPIP_UDP_0112, ^TCPIP_UDP_0114, ^TCPIP_UDP_0202, + ^TCPIP_IGMP_0103, ^TCPIP_IP_0101, TCPIP_ARP_0201, TCPIP_TCP_0115, TCPIP_TCP_0114, + TCPIP_TCP_0116, TCPIP_TCP_0111, TCPIP_TCP_0113, TCPIP_TCP_0112] diff --git a/components/test/CIConfigs/Function_TCPIP_07.yml b/components/test/CIConfigs/Function_TCPIP_07.yml new file mode 100644 index 0000000000..d42b5902ad --- /dev/null +++ b/components/test/CIConfigs/Function_TCPIP_07.yml @@ -0,0 +1,5 @@ +Config: {debug mode: false, execute count: 1, execute order: in order} +DUT: [SSC1] +Filter: +- ADD: + ID: [TCPIP_TCP_0405, ^TCPIP_TCP_0405] diff --git a/components/test/CIConfigs/Function_WIFI_01.yml b/components/test/CIConfigs/Function_WIFI_01.yml new file mode 100644 index 0000000000..594a1fc212 --- /dev/null +++ b/components/test/CIConfigs/Function_WIFI_01.yml @@ -0,0 +1,11 @@ +Config: {debug mode: false, execute count: 1, execute order: in order} +DUT: [SSC2, SSC1] +Filter: +- ADD: + ID: [^WIFI_CONN_0601, ^WIFI_ADDR_0101, ^WIFI_CONN_0903, WIFI_SCAN_0103, WIFI_SCAN_0102, + WIFI_SCAN_0101, WIFI_SCAN_0105, WIFI_SCAN_0104, WIFI_CONN_0201, WIFI_CONN_0702, + WIFI_CONN_0703, WIFI_CONN_0701, WIFI_CONN_0904, ^WIFI_CONN_0201, ^WIFI_CONN_0701, + ^WIFI_CONN_0703, ^WIFI_SCAN_0102, ^WIFI_SCAN_0103, ^WIFI_SCAN_0104, ^WIFI_SCAN_0105, + ^WIFI_ADDR_0102, WIFI_CONN_0401, ^WIFI_CONN_0103, WIFI_ADDR_0101, WIFI_ADDR_0102, + WIFI_CONN_0301, ^WIFI_CONN_0801, WIFI_CONN_0104, ^WIFI_CONN_0301, WIFI_CONN_0501, + WIFI_CONN_0502] diff --git a/components/test/CIConfigs/Function_WIFI_02.yml b/components/test/CIConfigs/Function_WIFI_02.yml new file mode 100644 index 0000000000..30735791b7 --- /dev/null +++ b/components/test/CIConfigs/Function_WIFI_02.yml @@ -0,0 +1,9 @@ +Config: {debug mode: false, execute count: 1, execute order: in order} +DUT: [SSC2, SSC1] +Filter: +- ADD: + ID: [^WIFI_CONN_0401, WIFI_MODE_0101, WIFI_MODE_0103, WIFI_MODE_0102, ^WIFI_CONN_0904, + ^WIFI_CONN_0902, ^WIFI_CONN_0901, WIFI_CONN_0601, WIFI_CONN_0901, WIFI_CONN_0902, + WIFI_CONN_0903, WIFI_CONN_0503, ^WIFI_CONN_0104, WIFI_CONN_0101, WIFI_CONN_0102, + WIFI_CONN_0103, ^WIFI_CONN_0702, WIFI_CONN_0801, ^WIFI_CONN_0101, ^WIFI_CONN_0503, + ^WIFI_CONN_0502, ^WIFI_CONN_0501, ^WIFI_SCAN_0101] diff --git a/components/test/InitialConditionAll.yml b/components/test/InitialConditionAll.yml new file mode 100644 index 0000000000..797ccad550 --- /dev/null +++ b/components/test/InitialConditionAll.yml @@ -0,0 +1,2923 @@ +initial condition: +- check cmd set: + - '' + - - ASSERT + - [dummy] + - - SSC SSC[1-] mesh -Q -t 4 + - ['R SSC[1-] T '] + - - MESHTREE + - ['R PC_COM RE "MESHTREE:%%s%20nodes"%%()'] + force restore cmd set: + - '' + - - SSC SSC[1-] reboot + - ['P SSC[1-] C !!!ready!!!'] + - - SSC SSC[1-] mesh -I -g -a 4 -k -i + -p -h 5 + - ['P SSC[1-] C ENCRYPTION,OK C GROUP,OK C SERVER,OK C HOP,OK'] + - - SSC SSC1 mesh -A -s -k + - ['P SSC1 C +MESHINIT:AP,OK'] + - - SSC SSC1 mesh -E -o 1 -t 1 + - ['P SSC1 C +MESH:ENABLED'] + - - SSC SSC[2-] mesh -E -o 1 -t 2 + - [''] + - - DELAY 60 + - ['P SSC[2-] C +MESH:ENABLED'] + - - SSC SSC[1-] mesh -C + - ['P SSC[1-] C +MESH:CONNECTED'] + - - SSC SSC[1-] mesh -Q -t 4 + - ['R SSC[1-] T '] + - - MESHTREE + - ['R PC_COM RE "MESHTREE:%%s%20nodes"%%()'] + initial condition detail: root as LOCAL, rest node as ONLINE, mesh network established + restore cmd set: + - '' + - - SSC SSC[1-] mesh -E -o 0 + - ['P SSC[1-] C +MESH:DISABLED'] + - - SSC SSC[1-] mesh -I -g -a 4 -k -i + -p -h 5 + - ['P SSC[1-] C ENCRYPTION,OK C GROUP,OK C SERVER,OK C HOP,OK'] + - - SSC SSC1 mesh -A -s -k + - ['P SSC1 C +MESHINIT:AP,OK'] + - - SSC SSC1 mesh -E -o 1 -t 1 + - ['P SSC1 C +MESH:ENABLED'] + - - SSC SSC[2-] mesh -E -o 1 -t 2 + - [''] + - - DELAY 60 + - ['P SSC[2-] C +MESH:ENABLED'] + - - SSC SSC[1-] mesh -C + - ['P SSC[1-] C +MESH:CONNECTED'] + - - SSC SSC[1-] mesh -Q -t 4 + - ['R SSC[1-] T '] + - - MESHTREE + - ['R PC_COM RE "MESHTREE:%%s%20nodes"%%()'] + restore post cmd set: + - '' + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 24.0 + tag: ENABLED_2 + test script: InitCondBase +- check cmd set: + - '' + - - ASSERT + - [dummy] + - - SSC SSC[1-] mesh -Q -t 4 + - ['R SSC[1-] T '] + - - MESHTREE + - ['R PC_COM RE "MESHTREE:%%s%20nodes"%%()'] + force restore cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC[1-] mesh -E -o 0 + - ['P SSC[1-] C +MESH:DISABLED'] + - - SSC SSC[1-] mesh -I -g -a 4 -k -i + -p -h 5 + - ['P SSC[1-] C ENCRYPTION,OK C GROUP,OK C SERVER,OK C HOP,OK'] + - - SSC SSC[1-] mesh -A -s -k + - ['P SSC[1-] C +MESHINIT:AP,OK'] + - - SSC SSC1 mesh -E -o 1 -t 2 + - ['P SSC1 C +MESH:ENABLED'] + - - SOC SOC1 MACCEPT GSOC1 + - [R SOC_COM L OK] + - - SSC SSC[2-] mesh -E -o 1 -t 2 + - ['P SSC[2-] C +MESH:ENABLED'] + - - DELAY 60 + - [''] + - - SSC SSC[1-] mesh -C + - ['P SSC[1-] C +MESH:CONNECTED'] + - - SSC SSC[1-] mesh -Q -t 4 + - ['R SSC[1-] T '] + - - MESHTREE + - ['R PC_COM RE "MESHTREE:%%s%20nodes"%%()'] + - - SSC SSC[1-] mesh -O -t 1 -o 1 + - ['P SSC[1-] C +MESH:OK'] + initial condition detail: all mesh node enabled as ONLINE, mesh network established + restore cmd set: + - '' + - - SSC SSC[1-] reboot + - ['P SSC[1-] C !!!ready!!!'] + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC[1-] mesh -E -o 0 + - ['P SSC[1-] C +MESH:DISABLED'] + - - SSC SSC[1-] mesh -I -g -a 4 -k -i + -p -h 5 + - ['P SSC[1-] C ENCRYPTION,OK C GROUP,OK C SERVER,OK C HOP,OK'] + - - SSC SSC[1-] mesh -A -s -k + - ['P SSC[1-] C +MESHINIT:AP,OK'] + - - SSC SSC1 mesh -E -o 1 -t 2 + - ['P SSC1 C +MESH:ENABLED'] + - - SOC SOC1 MACCEPT GSOC1 + - [R SOC_COM L OK] + - - SSC SSC[2-] mesh -E -o 1 -t 2 + - ['P SSC[2-] C +MESH:ENABLED'] + - - DELAY 60 + - [''] + - - SSC SSC[1-] mesh -C + - ['P SSC[1-] C +MESH:CONNECTED'] + - - SSC SSC[1-] mesh -Q -t 4 + - ['R SSC[1-] T '] + - - MESHTREE + - ['R PC_COM RE "MESHTREE:%%s%20nodes"%%()'] + - - SSC SSC[1-] mesh -O -t 1 -o 1 + - ['P SSC[1-] C +MESH:OK'] + restore post cmd set: + - '' + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 17.0 + tag: ENABLED_1 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 upgrade -Q -t 1 + - ['R SSC1 C BIN_ID,0'] + - - SSC SSC1 upgrade -Q -t 2 -b 0 + - ['R SSC1 C BIN_INFO,0'] + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + force restore cmd set: + - '' + - - SSC SSC1 upgrade -R -r 1 -s + - [R SSC1 NC ERROR C !!!ready!!!] + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SOC SOC1 ULISTEN + - [R SOC_COM L OK] + - - SOC SOC1 SETOPT REPLY BIN + - [R SOC_COM C OK] + - - SSC SSC1 upgrade -I -b 0 -f 0 + - ['P SSC1 C +UPGRADE:OK'] + - - SSC SSC1 upgrade -U -i -p -u + - ['P SSC1 C +UPGRADE:SUCCEED'] + - - SSC SSC1 upgrade -R -b 0 + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + initial condition detail: APSTA mode, connected to AP, running BIN0 (located on + flash id 0) + restore cmd set: + - '' + - - SSC SSC1 upgrade -Q -t 2 -b 0 + - ['R SSC1 C BIN_INFO,0'] + - - SSC SSC1 upgrade -R -b 0 + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + restore post cmd set: + - '' + - - SSC SSC1 upgrade -D + - ['R SSC1 C +UPGRADE:OK'] + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 24.0 + tag: STAAPBIN0 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:3'] + - - SSC SSC1 ap -Q + - ['R SSC1 RE "\+APCONFIG:%%s,%%s,\d+,\d+,\d+,4,"%%(,)'] + - - SSC SSC1 ap -L + - ['R SSC1 RE "\+LSTA:.+,%%s"%%()'] + - - SSC SSC1 dhcp -Q -o 2 + - ['R SSC1 C +DHCP:AP,STARTED'] + - - SSC SSC1 mac -Q -o 2 + - [R SSC1 P ] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 ap -S -s -p -t 3 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - WIFI CONN + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + initial condition detail: testing ap on sta + ap mode, PC join AP (autogen) + restore cmd set: + - '' + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 ap -S -s -p -t 3 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - WIFI CONN + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 66.0 + tag: APSTA2 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:3'] + - - SSC SSC1 ap -Q + - ['R SSC1 RE "\+APCONFIG:%%s,%%s,\d+,\d+,\d+,4,"%%(,)'] + - - SSC SSC1 dhcp -Q -o 2 + - ['R SSC1 C +DHCP:AP,STARTED'] + - - SSC SSC1 mac -Q -o 2 + - [R SSC1 P ] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 ap -S -s -p -t 3 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + initial condition detail: testing ap on sta + ap mode (autogen) + restore cmd set: + - '' + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 ap -S -s -p -t 3 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 59.0 + tag: APSTA1 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:3'] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:'] + - - SSC SSC1 dhcp -Q -o 1 + - ['R SSC1 C +DHCP:STA,STARTED'] + - - SSC SSC1 mac -Q -o 1 + - [R SSC1 P ] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + initial condition detail: testing sta on sta + ap mode, quit AP (autogen) + restore cmd set: + - '' + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 45.0 + tag: STAAP1 + test script: InitCondBase +- check cmd set: + - '' + - - DELAY 0.1 + - [dummy] + force restore cmd set: + - '' + - - DELAY 0.1 + - [dummy] + initial condition detail: none 2 + restore cmd set: + - '' + - - DELAY 0.1 + - [dummy] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 108.0 + tag: ATNone2 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:3'] + - - SSC SSC1 sta -Q + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC1 dhcp -Q -o 1 + - ['R SSC1 C +DHCP:STA,STARTED'] + - - SSC SSC1 mac -Q -o 1 + - [R SSC1 P ] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + initial condition detail: testing sta on sta + ap mode, join AP, DHCP on (autogen) + restore cmd set: + - '' + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 52.0 + tag: STAAP2 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:3'] + - - ATS AT1 AT+CWJAP_CUR? + - ['R AT1 C +CWJAP_CUR:', R AT1 P ] + - - ATS AT1 AT+CIPMUX? + - ['R AT1 L +CIPMUX:1'] + - - ATS AT1 AT+CWDHCP_CUR? + - ['R AT1 C DHCP:3'] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=1 + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + initial condition detail: StationSoftAP mode, connected to AP, multi link, use dhcp + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=1 + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 94.0 + tag: ATAPSTA3 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 C +CWMODE_CUR:2 C OK'] + - - ATS AT2 AT+CWMODE_CUR? + - ['R AT2 C +CWMODE_CUR:3 C OK'] + - - ATS AT1 AT+CWJAP_CUR? + - [R AT1 NC OK L ERROR] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=2 + - [R AT1 L OK] + - - ATS AT2 AT+CWMODE_DEF=3 + - [R AT2 L OK] + initial condition detail: Target 1 in SoftAP mode, Target 2 in StationSoftAP mode, + use dhcp + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=2 + - [R AT1 L OK] + - - ATS AT2 AT+CWMODE_DEF=3 + - [R AT2 L OK] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 80.0 + tag: ATT2_2 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 C +CWMODE_CUR:3 L OK'] + - - ATS AT1 AT+CWLIF + - [R AT1 P ] + - - ATS AT1 AT+CIPMUX? + - ['R AT1 L +CIPMUX:1'] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - DELAY 5 + - [''] + - - ATC AT1 CWSAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + - - WIFI CONN + + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - ATS AT1 AT+CWLIF + - [R AT1 P ] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=1 + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + initial condition detail: StationSoftAP mode, PC join Target AP, multi link, use + dhcp + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=1 + - [R AT1 R *] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CWLIF + - [R AT1 P ] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 31.0 + tag: ATAP3 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:1'] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:'] + - - SSC SSC1 dhcp -Q -o 1 + - ['R SSC1 C +DHCP:STA,STARTED'] + - - SSC SSC1 mac -Q -o 1 + - [R SSC1 P ] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + initial condition detail: sta mode, quit AP, will NOT autogen a TC with initial + condition STAAP1 + restore cmd set: + - '' + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 17.0 + tag: STAO1 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT + - [R AT1 L OK] + - - ATS AT1 AT + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+RST + - [R AT1 L OK] + initial condition detail: StationSoftAP mode, both PC join Target AP, single link, + use dhcp + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 3.0 + tag: ATAP5 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 C +CWMODE_CUR:3 L OK'] + - - ATS AT1 AT+CWLIF + - [R AT1 P ] + - - ATS AT1 AT+CIPMUX? + - ['R AT1 L +CIPMUX:0'] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - DELAY 10 + - [''] + - - ATC AT1 CWSAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + - - WIFI CONN + + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - ATS AT1 AT+CWLIF + - [R AT1 P ] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=0 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + initial condition detail: StationSoftAP mode, PC join Target AP, single link, use + dhcp + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=0 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATS AT1 AT+CWLIF + - [R AT1 P ] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 45.0 + tag: ATAP4 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT + - [R AT1 L OK] + - - ATS AT1 AT + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+RST + - [R AT1 L OK] + initial condition detail: StationSoftAP mode, both PC join Target AP, multi link, + use dhcp + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 3.0 + tag: ATAP6 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 upgrade -Q -t 1 + - ['R SSC1 C BIN_ID,0'] + - - SSC SSC1 upgrade -Q -t 2 -b 0 + - ['R SSC1 C BIN_INFO,0'] + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + force restore cmd set: + - '' + - - SSC SSC1 upgrade -R -r 1 -s + - [R SSC1 NC ERROR C !!!ready!!!] + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SOC SOC1 ULISTEN + - [R SOC_COM L OK] + - - SOC SOC1 SETOPT REPLY BIN + - [R SOC_COM C OK] + - - SSC SSC1 upgrade -I -b 0 -f 0 + - ['P SSC1 C +UPGRADE:OK'] + - - SSC SSC1 upgrade -U -i -p -u + - ['P SSC1 C +UPGRADE:SUCCEED'] + - - SSC SSC1 upgrade -R -b 0 + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + initial condition detail: AP only mode, running BIN0 (located on flash id 0) + restore cmd set: + - '' + - - SSC SSC1 upgrade -Q -t 2 -b 0 + - ['R SSC1 C BIN_INFO,0'] + - - SSC SSC1 upgrade -R -b 0 + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + restore post cmd set: + - '' + - - SSC SSC1 upgrade -D + - ['R SSC1 C +UPGRADE:OK'] + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 31.0 + tag: APOBIN0 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:1'] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:'] + - - SSC SSC1 dhcp -Q -o 1 + - ['R SSC1 C +DHCP:STA,STARTED'] + - - SSC SSC1 mac -Q -o 1 + - [R SSC1 P ] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + initial condition detail: sta mode, quit AP, DHCP on + restore cmd set: + - '' + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 17.0 + tag: STAM1 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:1'] + - - SSC SSC1 sta -Q + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC1 dhcp -Q -o 1 + - ['R SSC1 C +DHCP:STA,STARTED'] + - - SSC SSC1 mac -Q -o 1 + - [R SSC1 P ] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + initial condition detail: sta mode, join AP, DHCP on + restore cmd set: + - '' + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 24.0 + tag: STAM2 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT + - [R AT1 L OK] + - - ATS AT1 AT + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+RST + - [R AT1 L OK] + initial condition detail: none + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 3.0 + tag: ATNone + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:3'] + - - ATS AT1 AT+CWJAP_CUR? + - ['R AT1 C +CWJAP_CUR:', R AT1 P ] + - - ATS AT1 AT+CIPMUX? + - ['R AT1 L +CIPMUX:0'] + - - ATS AT1 AT+CWDHCP_CUR? + - ['R AT1 C DHCP:3'] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=0 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + initial condition detail: StationSoftAP mode, connected to AP, single link, use + dhcp + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=0 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 101.0 + tag: ATAPSTA4 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:1'] + - - ATS AT1 AT+CWJAP_CUR? + - ['R AT1 C +CWJAP_CUR:', R AT1 P ] + - - ATS AT1 AT+CIPMUX? + - ['R AT1 L +CIPMUX:0'] + - - ATS AT1 AT+CWDHCP_CUR? + - ['R AT1 C DHCP:3'] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 R *] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=0 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + initial condition detail: same as STA4, but will not autogen STA+AP STA test case + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 R *] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=0 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 17.0 + tag: ATOSTA4 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:1'] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 L OK] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 L OK] + initial condition detail: same as STA1, but will not autogen STA+AP STA test case + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 L OK] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 10.0 + tag: ATOSTA1 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:3'] + - - ATS AT1 AT+CWLIF + - [R AT1 P ] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - DELAY 5 + - [''] + - - ATC AT1 CWSAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + - - WIFI CONN + + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - ATS AT1 AT+CWLIF + - [R AT1 P ] + initial condition detail: StationSoftAP mode + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATS AT1 AT+CWLIF + - [R AT1 P ] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 24.0 + tag: ATAP1 + test script: InitCondBase +- check cmd set: + - '' + - - DELAY 0.1 + - [dummy] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + initial condition detail: none + restore cmd set: + - '' + - - DELAY 0.1 + - [dummy] + restore post cmd set: + - '' + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 10.0 + tag: None + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT + - [R AT1 L OK] + - - ATS AT1 AT+RESTORE + - [R AT1 L OK, R AT1 C ready] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT + - [R AT1 L OK] + - - ATS AT1 AT+RESTORE + - [R AT1 L OK, R AT1 C ready] + initial condition detail: 'first time usage. Use restore function. ' + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+RESTORE + - [R AT1 L OK, R AT1 C ready] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 143.0 + tag: ATFTU + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT + - [R AT1 L OK] + - - ATS AT1 AT + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+RST + - [R AT1 L OK] + initial condition detail: SoftAP mode, both PC join Target AP, single link, use + dhcp + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 3.0 + tag: ATAPO5 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:1'] + - - SSC SSC1 sta -Q + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC1 dhcp -Q -o 1 + - ['R SSC1 C +DHCP:STA,STARTED'] + - - SSC SSC1 mac -Q -o 1 + - [R SSC1 P ] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + initial condition detail: sta mode, join AP, DHCP on, will NOT autogen a TC with + initial condition STAAP2 + restore cmd set: + - '' + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 24.0 + tag: STAO2 + test script: InitCondBase +- check cmd set: + - '' + - - ASSERT + - [dummy] + force restore cmd set: + - '' + - - SSC SSC[1-] reboot + - ['P SSC[1-] C !!!ready!!!'] + - - SSC SSC[1-] mesh -E -o 0 + - ['P SSC[1-] C +MESH:DISABLED'] + - - SSC SSC[1-] op -S -o 1 + - ['P SSC[1-] C +MODE:OK'] + - - SSC SSC[1-] sta -D + - ['P SSC[1-] C +QAP:OK'] + initial condition detail: all mesh node disabled + restore cmd set: + - '' + - - SSC SSC[1-] mesh -E -o 0 + - ['P SSC[1-] C +MESH:DISABLED'] + - - SSC SSC[1-] op -S -o 1 + - ['P SSC[1-] C +MODE:OK'] + - - SSC SSC[1-] sta -D + - ['P SSC[1-] C +QAP:OK'] + restore post cmd set: + - '' + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 31.0 + tag: DISABLED + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 C +CWMODE_CUR:3 C OK'] + - - ATS AT2 AT+CWMODE_CUR? + - ['R AT2 C +CWMODE_CUR:1 C OK'] + - - ATS AT1 AT+CWJAP_CUR? + - [R AT1 NC OK L ERROR] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATS AT2 AT+CWMODE_DEF=1 + - [R AT2 L OK] + - - ATS AT1 AT+CWQAP + - [R AT1 L OK] + initial condition detail: Target 1 in StationSoftAP mode, Target 2 in station mode, + use dhcp + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATS AT2 AT+CWMODE_DEF=1 + - [R AT2 L OK] + - - ATS AT1 AT+CWQAP + - [R AT1 L OK] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 52.0 + tag: ATT2_1 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:2'] + - - SSC SSC1 ap -Q + - ['R SSC1 RE "\+APCONFIG:%%s,%%s,\d+,\d+,\d+,4,"%%(,)'] + - - SSC SSC1 ap -L + - ['R SSC1 RE "\+LSTA:.+,%%s"%%()'] + - - SSC SSC1 dhcp -Q -o 2 + - ['R SSC1 C +DHCP:AP,STARTED'] + - - SSC SSC1 mac -Q -o 2 + - [R SSC1 P ] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 ap -S -s -p -t 3 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - WIFI CONN + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + initial condition detail: AP mode, will NOT autogen a TC with initial condition + APSTA2 + restore cmd set: + - '' + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 ap -S -s -p -t 3 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - WIFI CONN + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 38.0 + tag: APO2 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:2'] + - - SSC SSC1 ap -Q + - ['R SSC1 RE "\+APCONFIG:%%s,%%s,\d+,\d+,\d+,4,"%%(,)'] + - - SSC SSC1 dhcp -Q -o 2 + - ['R SSC1 C +DHCP:AP,STARTED'] + - - SSC SSC1 mac -Q -o 2 + - [R SSC1 P ] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC1 ap -S -s -p -t 3 + - ['R SSC1 C +SAP:OK'] + initial condition detail: AP mode, will NOT autogen a TC with initial condition + APSTA1 + restore cmd set: + - '' + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC1 ap -S -s -p -t 3 + - ['R SSC1 C +SAP:OK'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 31.0 + tag: APO1 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 C +CWMODE_CUR:2 L OK'] + - - ATS AT1 AT+CWLIF + - [R AT1 P ] + - - ATS AT1 AT+CIPMUX? + - ['R AT1 L +CIPMUX:1'] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CWDHCP_DEF=0,1 + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=2 + - [R AT1 L OK] + - - ATC AT1 CWSAP_DEF + - [R AT1 L OK] + - - WIFI CONN + + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - ATS AT1 AT+CWLIF + - [R AT1 P ] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=1 + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CWDHCP_DEF=0,1 + - [R AT1 R *] + initial condition detail: SoftAP mode, PC join Target AP, multi link, use dhcp + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=2 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=1 + - [R AT1 R *] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CWLIF + - [R AT1 P ] + - - ATS AT1 AT+CWDHCP_DEF=0,1 + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 66.0 + tag: ATAPO3 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:2'] + - - SSC SSC1 mac -Q -o 2 + - [R SSC1 P ] + - - SSC SSC1 espnow -D + - ['R SSC1 C +ESPNOW:'] + force restore cmd set: + - '' + - - SSC SSC[1-] reboot + - ['R SSC[1-] C !!!ready!!!'] + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 mac -S -m -o 2 + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC1 espnow -D + - ['R SSC1 C +ESPNOW:'] + initial condition detail: one target in AP mode and espnow is de-initialized + restore cmd set: + - '' + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 mac -S -m -o 2 + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC1 espnow -D + - ['R SSC1 C +ESPNOW:'] + restore post cmd set: + - '' + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 17.0 + tag: NOW1 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC[1-] op -Q + - ['R SSC[1-] C +CURMODE:2'] + - - SSC SSC[1-] mac -Q -o 3 + - ['R SSC[1-] P ]_ap_mac> P ]_mac>'] + - - SSC SSC[1-] espnow -D + - ['R SSC[1-] C +ESPNOW:'] + - - SSC SSC[1-] espnow -I + - ['R SSC[1-] C +ESPNOW:OK'] + - - SSC SSC[1-] espnow -R -t Set -r 2 + - ['R SSC[1-] C +ESPNOW:OK'] + force restore cmd set: + - '' + - - SSC SSC[1-] reboot + - ['R SSC[1-] C !!!ready!!!'] + - - SSC SSC[1-] op -S -o 3 + - ['R SSC[1-] C +MODE:OK'] + - - SSC SSC[1-] mac -S -m ]_ap_mac> -o 2 + - ['R SSC[1-] C +MAC:AP,OK'] + - - SSC SSC[1-] mac -S -m ]_mac> -o 1 + - ['R SSC[1-] C +MAC:STA,OK'] + - - SSC SSC[1-] op -S -o 2 + - ['R SSC[1-] C +MODE:OK'] + - - SSC SSC[1-] espnow -D + - ['R SSC[1-] C +ESPNOW:'] + - - SSC SSC[1-] espnow -I + - ['R SSC[1-] C +ESPNOW:OK'] + - - SSC SSC[1-] espnow -R -t Set -r 2 + - ['R SSC[1-] C +ESPNOW:OK'] + initial condition detail: multiple () targets in AP mode, espnow is initialized + with self role slave + restore cmd set: + - '' + - - SSC SSC[1-] op -S -o 3 + - ['R SSC[1-] C +MODE:OK'] + - - SSC SSC[1-] mac -S -m ]_ap_mac> -o 2 + - ['R SSC[1-] C +MAC:AP,OK'] + - - SSC SSC[1-] mac -S -m ]_mac> -o 1 + - ['R SSC[1-] C +MAC:STA,OK'] + - - SSC SSC[1-] op -S -o 2 + - ['R SSC[1-] C +MODE:OK'] + - - SSC SSC[1-] espnow -D + - ['R SSC[1-] C +ESPNOW:'] + - - SSC SSC[1-] espnow -I + - ['R SSC[1-] C +ESPNOW:OK'] + - - SSC SSC[1-] espnow -R -t Set -r 2 + - ['R SSC[1-] C +ESPNOW:OK'] + restore post cmd set: + - '' + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 24.0 + tag: NOW2 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 C +CWMODE_CUR:2 L OK'] + - - ATS AT1 AT+CWLIF + - [R AT1 P ] + - - ATS AT1 AT+CIPMUX? + - ['R AT1 L +CIPMUX:0'] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATS AT1 AT+CWDHCP_DEF=0,1 + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=2 + - [R AT1 L OK] + - - ATC AT1 CWSAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=0,1 + - [R AT1 R *] + - - WIFI CONN + + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - ATS AT1 AT+CWLIF + - [R AT1 P ] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=0 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + initial condition detail: SoftAP mode, PC join Target AP, single link, use dhcp + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=2 + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=0 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATS AT1 AT+CWLIF + - [R AT1 P ] + - - ATS AT1 AT+CWDHCP_DEF=0,1 + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 73.0 + tag: ATAPO4 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 sp -D + - ['R SSC1 C +SP:OK'] + force restore cmd set: + - '' + - - SSC SSC1 sp -D + - ['R SSC1 C +SP:OK'] + initial condition detail: one target and simple is de-inited + restore cmd set: + - '' + - - SSC SSC1 sp -D + - ['R SSC1 C +SP:OK'] + restore post cmd set: + - '' + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 31.0 + tag: PAIR1 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT + - [R AT1 L OK] + - - ATS AT1 AT + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+RST + - [R AT1 L OK] + initial condition detail: SoftAP mode, both PC join Target AP, multi link, use dhcp + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 3.0 + tag: ATAPO6 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC[1,2] op -Q + - ['R SSC[1,2] C +MODE:[3,3]'] + - - SSC SSC[1,2] mac -Q -o 3 + - ['R SSC[1,2] P P '] + - - SSC SSC[1,2] sp -D + - ['R SSC[1,2] C +SP:OK'] + - - SSC SSC[1,2] sp -I + - ['R SSC[1,2] C +SP:OK'] + force restore cmd set: + - '' + - - SSC SSC[1,2] reboot + - ['R SSC[1,2] C !!!ready!!!'] + - - SSC SSC[1,2] op -S -o [3,3] + - ['R SSC[1,2] C +MODE:OK'] + - - SSC SSC[1,2] mac -S -m -o 2 + - ['R SSC[1,2] C +MAC:AP,OK'] + - - SSC SSC[1,2] mac -S -m -o 1 + - ['R SSC[1,2] C +MAC:STA,OK'] + - - SSC SSC[1,2] sp -D + - ['R SSC[1,2] C +SP:OK'] + - - SSC SSC[1,2] sp -I + - ['R SSC[1,2] C +SP:OK'] + initial condition detail: target1 and target2 in STA+AP mode, two targets de-init + and init simple pair + restore cmd set: + - '' + - - SSC SSC[1,2] op -S -o [3,3] + - ['R SSC[1,2] C +MODE:OK'] + - - SSC SSC[1,2] mac -S -m -o 2 + - ['R SSC[1,2] C +MAC:AP,OK'] + - - SSC SSC[1,2] mac -S -m -o 1 + - ['R SSC[1,2] C +MAC:STA,OK'] + - - SSC SSC[1,2] sp -D + - ['R SSC[1,2] C +SP:OK'] + - - SSC SSC[1,2] sp -I + - ['R SSC[1,2] C +SP:OK'] + restore post cmd set: + - '' + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 45.0 + tag: PAIR3 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC[1,2] op -Q + - ['R SSC[1,2] C +MODE:[2,1]'] + - - SSC SSC[1,2] mac -Q -o 3 + - ['R SSC[1,2] P P '] + - - SSC SSC[1,2] sp -D + - ['R SSC[1,2] C +SP:OK'] + - - SSC SSC[1,2] sp -I + - ['R SSC[1,2] C +SP:OK'] + force restore cmd set: + - '' + - - SSC SSC[1,2] reboot + - ['R SSC[1,2] C !!!ready!!!'] + - - SSC SSC[1,2] op -S -o 3 + - ['R SSC[1,2] C +MODE:OK'] + - - SSC SSC[1,2] mac -S -m -o 2 + - ['R SSC[1,2] C +MAC:AP,OK'] + - - SSC SSC[1,2] mac -S -m -o 1 + - ['R SSC[1,2] C +MAC:STA,OK'] + - - SSC SSC[1,2] op -S -o [2,1] + - ['R SSC[1,2] C +MODE:OK'] + - - SSC SSC[1,2] sp -D + - ['R SSC[1,2] C +SP:OK'] + - - SSC SSC[1,2] sp -I + - ['R SSC[1,2] C +SP:OK'] + initial condition detail: target1 in AP mode, target2 in STA mode, two targets de-init + and init simple pair + restore cmd set: + - '' + - - SSC SSC[1,2] op -S -o 3 + - ['R SSC[1,2] C +MODE:OK'] + - - SSC SSC[1,2] mac -S -m -o 2 + - ['R SSC[1,2] C +MAC:AP,OK'] + - - SSC SSC[1,2] mac -S -m -o 1 + - ['R SSC[1,2] C +MAC:STA,OK'] + - - SSC SSC[1,2] op -S -o [2,1] + - ['R SSC[1,2] C +MODE:OK'] + - - SSC SSC[1,2] sp -D + - ['R SSC[1,2] C +SP:OK'] + - - SSC SSC[1,2] sp -I + - ['R SSC[1,2] C +SP:OK'] + restore post cmd set: + - '' + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 38.0 + tag: PAIR2 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:2'] + - - SSC SSC2 op -Q + - ['R SSC2 C +CURMODE:1'] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:'] + - - SSC SSC2 soc -T + - [''] + - - SSC SSC1 dhcp -Q -o 2 + - ['R SSC1 C +DHCP:AP,STARTED'] + - - SSC SSC2 dhcp -Q -o 1 + - ['R SSC2 C +DHCP:STA,STARTED'] + - - SSC SSC1 mac -Q -o 2 + - [R SSC1 P ] + - - SSC SSC2 mac -Q -o 1 + - [R SSC2 P ] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC2 reboot + - [R SSC2 C !!!ready!!!] + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC2 op -S -o 1 + - ['R SSC2 C +MODE:OK'] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:'] + - - SSC SSC2 soc -T + - [''] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC2 dhcp -S -o 1 + - [R SSC2 C +DHCP] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC2 mac -S -o 1 -m + - ['R SSC2 C +MAC:STA,OK'] + initial condition detail: same as T2_1 but will NOT autogen a TC with initial condition + T2_2 + restore cmd set: + - '' + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC2 op -S -o 1 + - ['R SSC2 C +MODE:OK'] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:'] + - - SSC SSC2 soc -T + - [''] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC2 dhcp -S -o 1 + - [R SSC2 C +DHCP] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC2 mac -S -o 1 -m + - ['R SSC2 C +MAC:STA,OK'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 73.0 + tag: T2O_1 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:2'] + - - ATS AT1 AT+CWDHCP_DEF=0,1 + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=2 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=0,1 + - [R AT1 R *] + initial condition detail: SoftAP mode, use dhcp + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=2 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=0,1 + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 59.0 + tag: ATAPO1 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:2'] + - - SSC SSC1 ap -Q + - ['R SSC1 RE "\+APCONFIG:%%s,%%s,\d+,\d+,\d+,4,"%%(,)'] + - - SSC SSC1 dhcp -Q -o 2 + - ['R SSC1 C +DHCP:AP,STARTED'] + - - SSC SSC1 mac -Q -o 2 + - [R SSC1 P ] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC1 ap -S -s -p -t 3 + - ['R SSC1 C +SAP:OK'] + initial condition detail: AP mode, DHCP on + restore cmd set: + - '' + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC1 ap -S -s -p -t 3 + - ['R SSC1 C +SAP:OK'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 31.0 + tag: APM1 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:2'] + - - SSC SSC2 op -Q + - ['R SSC2 C +CURMODE:1'] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:'] + - - SSC SSC2 soc -T + - [''] + - - SSC SSC1 dhcp -Q -o 2 + - ['R SSC1 C +DHCP:AP,STARTED'] + - - SSC SSC2 dhcp -Q -o 1 + - ['R SSC2 C +DHCP:STA,STARTED'] + - - SSC SSC1 mac -Q -o 2 + - [R SSC1 P ] + - - SSC SSC2 mac -Q -o 1 + - [R SSC2 P ] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC2 reboot + - [R SSC2 C !!!ready!!!] + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC2 op -S -o 1 + - ['R SSC2 C +MODE:OK'] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:'] + - - SSC SSC2 soc -T + - [''] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC2 dhcp -S -o 1 + - [R SSC2 C +DHCP] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC2 mac -S -o 1 -m + - ['R SSC2 C +MAC:STA,OK'] + initial condition detail: target 1 as SoftAP, target 2 as STA + restore cmd set: + - '' + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC2 op -S -o 1 + - ['R SSC2 C +MODE:OK'] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:'] + - - SSC SSC2 soc -T + - [''] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC2 dhcp -S -o 1 + - [R SSC2 C +DHCP] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC2 mac -S -o 1 -m + - ['R SSC2 C +MAC:STA,OK'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 73.0 + tag: T2_1 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 C +CWMODE_CUR:3 C OK'] + - - ATS AT2 AT+CWMODE_CUR? + - ['R AT2 C +CWMODE_CUR:1 C OK'] + - - ATS AT1 AT+CWJAP_CUR? + - [R AT1 NC OK L ERROR] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATS AT2 AT+CWMODE_DEF=1 + - [R AT2 L OK] + - - ATS AT1 AT+CWQAP + - [R AT1 L OK] + initial condition detail: same as OT2_1, but will not autogen STA+AP STA test case + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATS AT2 AT+CWMODE_DEF=1 + - [R AT2 L OK] + - - ATS AT1 AT+CWQAP + - [R AT1 L OK] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 52.0 + tag: ATOT2_1 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:3'] + - - ATS AT1 AT+CWJAP_CUR? + - ['R AT1 C +CWJAP_CUR:', R AT1 P ] + - - ATS AT1 AT+CIPMUX? + - ['R AT1 L +CIPMUX:1'] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATC AT1 CIPSTA_DEF + - [R AT1 L OK] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=1 + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATC AT1 CIPSTA_DEF + - [R AT1 L OK] + initial condition detail: StationSoftAP mode, connected to AP, multi link, use static + ip + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=1 + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATC AT1 CIPSTA_DEF + - [R AT1 L OK] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 129.0 + tag: ATAPSTA5 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 upgrade -Q -t 1 + - ['R SSC1 C BIN_ID,0'] + - - SSC SSC1 upgrade -Q -t 2 -b 0 + - ['R SSC1 C BIN_INFO,0'] + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + force restore cmd set: + - '' + - - SSC SSC1 upgrade -R -r 1 -s + - [R SSC1 NC ERROR C !!!ready!!!] + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SOC SOC1 ULISTEN + - [R SOC_COM L OK] + - - SOC SOC1 SETOPT REPLY BIN + - [R SOC_COM C OK] + - - SSC SSC1 upgrade -I -b 0 -f 0 + - ['P SSC1 C +UPGRADE:OK'] + - - SSC SSC1 upgrade -U -i -p -u + - ['P SSC1 C +UPGRADE:SUCCEED'] + - - SSC SSC1 upgrade -R -b 0 + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + initial condition detail: STA mode, connected to AP, running BIN0 (located on flash + id 0) + restore cmd set: + - '' + - - SSC SSC1 upgrade -Q -t 2 -b 0 + - ['R SSC1 C BIN_INFO,0'] + - - SSC SSC1 upgrade -R -b 0 + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + restore post cmd set: + - '' + - - SSC SSC1 upgrade -D + - ['R SSC1 C +UPGRADE:OK'] + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 17.0 + tag: STAMBIN0 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:1'] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 L OK] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 L OK] + initial condition detail: station mode, DHCP client on, use dhcp + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 L OK] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 10.0 + tag: ATSTA2 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC[1-3] op -Q + - ['R SSC[1-3] C +CURMODE:3'] + - - SSC SSC[1-3] phy -Q -o 3 + - ['R SSC[1-3] C STA,n,40 C AP,n,40'] + force restore cmd set: + - '' + - - SSC SSC[1-3] reboot + - ['R SSC[1-3] C !!!ready!!!'] + - - SSC SSC[1-3] op -S -o 3 + - ['R SSC[1-3] C +MODE:OK'] + - - SSC SSC[1-3] phy -S -o 3 -m n -b 40 + - ['R SSC[1-3] C +PHY:OK'] + initial condition detail: '1. target 1 and target 2 set to AP+STA mode, target 3 + set to STA mode + + 2. all interface of target 2,3 set to 11n ht40 + + 3. config softAP of target 1 and target 2' + restore cmd set: + - '' + - - SSC SSC[1-3] op -S -o 3 + - ['R SSC[1-3] C +MODE:OK'] + - - SSC SSC[1-3] phy -S -o 3 -m n -b 40 + - ['R SSC[1-3] C +PHY:OK'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 sta -R -r 1 + - [R SSC1 C OK] + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 87.0 + tag: T3_PHY1 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:3'] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + initial condition detail: StationSoftAP mode, DHCP client on + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 87.0 + tag: ATAPSTA2 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:3'] + - - SSC SSC2 op -Q + - ['R SSC2 C +CURMODE:3'] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:'] + - - SSC SSC2 soc -T + - [R SSC2 C +CLOSEALL] + - - SSC SSC1 dhcp -Q -o 2 + - ['R SSC1 C +DHCP:AP,STARTED'] + - - SSC SSC2 dhcp -Q -o 1 + - ['R SSC2 C +DHCP:STA,STARTED'] + - - SSC SSC1 mac -Q -o 2 + - [R SSC1 P ] + - - SSC SSC2 mac -Q -o 1 + - [R SSC2 P ] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC2 reboot + - [R SSC2 C !!!ready!!!] + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC2 op -S -o 3 + - ['R SSC2 C +MODE:OK'] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:'] + - - SSC SSC2 soc -T + - [R SSC2 C +CLOSEALL] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC2 dhcp -S -o 1 + - [R SSC2 C +DHCP] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC2 mac -S -o 1 -m + - ['R SSC2 C +MAC:STA,OK'] + initial condition detail: target 1 as AP+STA, target 2 as AP+STA (autogen) + restore cmd set: + - '' + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC2 op -S -o 3 + - ['R SSC2 C +MODE:OK'] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:'] + - - SSC SSC2 soc -T + - [R SSC2 C +CLOSEALL] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC2 dhcp -S -o 1 + - [R SSC2 C +DHCP] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC2 mac -S -o 1 -m + - ['R SSC2 C +MAC:STA,OK'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 80.0 + tag: T2_2 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:3'] + - - ATS AT1 AT+CWJAP_CUR? + - ['R AT1 C +CWJAP_CUR:', R AT1 P ] + - - ATS AT1 AT+CIPMUX? + - ['R AT1 L +CIPMUX:0'] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATC AT1 CIPSTA_DEF + - [R AT1 L OK] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=0 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATC AT1 CIPSTA_DEF + - [R AT1 L OK] + initial condition detail: StationSoftAP mode, connected to AP, single link, use + static ip + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=0 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATC AT1 CIPSTA_DEF + - [R AT1 L OK] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 136.0 + tag: ATAPSTA6 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:1'] + - - ATS AT1 AT+CWJAP_CUR? + - ['R AT1 C +CWJAP_CUR:', R AT1 P ] + - - ATS AT1 AT+CIPMUX? + - ['R AT1 L +CIPMUX:0'] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATC AT1 CIPSTA_DEF + - [R AT1 L OK] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=0 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATC AT1 CIPSTA_DEF + - [R AT1 L OK] + initial condition detail: station mode, connected to AP, single link, use static + ip + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=0 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATC AT1 CIPSTA_DEF + - [R AT1 L OK] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 122.0 + tag: ATSTA6 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:1'] + - - ATS AT1 AT+CWJAP_CUR? + - ['R AT1 C +CWJAP_CUR:', R AT1 P ] + - - ATS AT1 AT+CIPMUX? + - ['R AT1 L +CIPMUX:1'] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATC AT1 CIPSTA_DEF + - [R AT1 L OK] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=1 + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATC AT1 CIPSTA_DEF + - [R AT1 L OK] + initial condition detail: station mode, connected to AP, multi link, use static + ip + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=1 + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATC AT1 CIPSTA_DEF + - [R AT1 L OK] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 115.0 + tag: ATSTA5 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:1'] + - - ATS AT1 AT+CWJAP_CUR? + - ['R AT1 C +CWJAP_CUR:', R AT1 P ] + - - ATS AT1 AT+CIPMUX? + - ['R AT1 L +CIPMUX:0'] + - - ATS AT1 AT+CWDHCP_CUR? + - ['R AT1 C DHCP:3'] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 R *] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=0 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + initial condition detail: station mode, connected to AP, single link, use dhcp + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 R *] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=0 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 17.0 + tag: ATSTA4 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:1'] + - - ATS AT1 AT+CWJAP_CUR? + - ['R AT1 C +CWJAP_CUR:', R AT1 P ] + - - ATS AT1 AT+CIPMUX? + - ['R AT1 L +CIPMUX:1'] + - - ATS AT1 AT+CWDHCP_CUR? + - ['R AT1 C DHCP:3'] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 R *] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=1 + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + initial condition detail: station mode, connected to AP, multi link, use dhcp + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 R *] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=1 + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 38.0 + tag: ATSTA3 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:2'] + - - SSC SSC1 ap -Q + - ['R SSC1 RE "\+APCONFIG:%%s,%%s,\d+,\d+,\d+,4,"%%(,)'] + - - SSC SSC1 ap -L + - ['R SSC1 RE "\+LSTA:.+,%%s"%%()'] + - - SSC SSC1 dhcp -Q -o 2 + - ['R SSC1 C +DHCP:AP,STARTED'] + - - SSC SSC1 mac -Q -o 2 + - [R SSC1 P ] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 ap -S -s -p -t 3 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - WIFI CONN + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + initial condition detail: AP mode, PC join AP, DHCP on + restore cmd set: + - '' + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 ap -S -s -p -t 3 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - WIFI CONN + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 38.0 + tag: APM2 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:1'] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 L OK] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 L OK] + initial condition detail: station mode, use dhcp + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 L OK] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 10.0 + tag: ATSTA1 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:3'] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + initial condition detail: StationSoftAP mode + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 87.0 + tag: ATAPSTA1 + test script: InitCondBase diff --git a/components/test/README.md b/components/test/README.md new file mode 100644 index 0000000000..0e4172d62c --- /dev/null +++ b/components/test/README.md @@ -0,0 +1,35 @@ +# The test folder in SDK + +## File Structure + +``` +test --- CIConfigs --- sanity_test1.yml (Runner config files) + | |-- stress_test1.yml + |-- TestCaseAll.yml (TestCaseFiles) + |-- TestEnvAll.yml (TestCaseFiles) + |-- InitialConditionAll.yml (TestCaseFiles) + |-- TestCaseScript --- ... (Test case scripts) +``` + +1. CIConfigs folder + * config for CI config files are put in this folder + * CI config files configs the cases and some other options for the CI job with same name +1. Test case files + * TestCaseAll.yml (test cases) + * InitialConditionAll.yml (initial conditions) + * TestEnvAll.yml (test environments) + * [how to modify test cases](https://gitlab.espressif.cn:6688/yinling/auto_test_script/blob/master/public/Design/TestCaseFiles.DesignNote.md) +1. Test case scripts + * some cases are implemented by specified script. those scripts are put in this folder. + + +## Modify test cases + +1. check if the "SDK" of the test case only contain the current SDK + * if Yes, then just modify the test case behavior + * if No: + 1. then remove current SDK name from "SDK" of the test case + 2. Add a new test case, and set "SDK" only support current SDK name +2. use [auto_test_script](https://gitlab.espressif.cn:6688/yinling/auto_test_script) to load the modified case and verify the modification +3. create a merge request and assign to HYL (or add comment @yinling for merging test). +After review it will be merged to SDK and will be The cases will be synced to database in auto_test_script. diff --git a/components/test/TestCaseAll.yml b/components/test/TestCaseAll.yml new file mode 100644 index 0000000000..c5e10b794a --- /dev/null +++ b/components/test/TestCaseAll.yml @@ -0,0 +1,13810 @@ +test cases: +- CI ready: 'Yes' + ID: ^WIFI_CONN_0601 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - WIFI CONN + + - ['R PC_COM C +WIFICONN:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 ap -L + - ['R SSC1 C +LSTA:', 'R SSC1 C +LSTA:', R SSC1 C +LSTADONE] + comment: '' + execution time: 0.0 + expected result: '1.target1 set AP + + 2.PC WIFI CONNECTED + + 3.target2 jap target 1 + + 4.查询到两个sta 连接到target1 上' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. target1下设置ssid 和pwd 加密方式 + + 2.PC WIFI CONNECTED target1 + + 3.target2 jap target 1 + + 4.查询到两个sta 连接到target1 上' + sub module: WIFI Connect + summary: list stations connected to soft ap test + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: list SoftAP connected station + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_ICMP_0101 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ping -i + - ['R SSC1 C +PING:OK'] + - - SSC SSC1 ping -i -c 2 + - ['R SSC1 C +PING:OK'] + comment: '' + execution time: 0.0 + expected result: '1.ok + + 2.ok' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: '1.ping -i + + 2.ping -i -c 2' + sub module: ICMP + summary: ping function test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: ping function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: SYS_MISC_0101 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + comment: '' + execution time: 0.0 + expected result: 重启成功 + initial condition: None + initial condition description (auto): none + module: System + steps: 系统重启 + sub module: Misc + summary: test reboot function + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: sw reboot + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_ARP_0202 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - STRING ether%20src%20%%s%20or%20ether%20dst%20%%s + + - [R PC_COM C OK] + - - NIC NIC1 START capture+send+block_arp_ip + - ['R PC_COM C +NIC_START:OK'] + - - NIC NIC1 SEND ARP arp_op_code "request" arp_target_proto_addr "192.168.11.240" + ethernet_len_type "ARP" ethernet_dst_addr "ff:ff:ff:ff:ff:ff" + - [''] + - - DELAY 2 + - [P PC_COM C +DELAYDONE, P NIC1 NPDU (Ethernet.dst_addr=)(Ethernet.len_type="ARP")] + - - NIC NIC1 SEND ARP arp_op_code "request" arp_target_proto_addr arp_sender_hw_addr + "18:18:18:18:18:18" ethernet_len_type "ARP" ethernet_dst_addr "ff:ff:ff:ff:ff:ff" + - [''] + - - DELAY 2 + - [P PC_COM C +DELAYDONE, P NIC1 NPDU (Ethernet.dst_addr=)(Ethernet.len_type="ARP")] + - - NIC NIC1 SEND ARP arp_op_code "request" arp_target_proto_addr arp_sender_proto_addr + ethernet_dst_addr "ff:ff:ff:ff:ff:ff" + - [''] + - - DELAY 2 + - [P PC_COM C +DELAYDONE, P NIC1 NPDU (Ethernet.dst_addr=)(Ethernet.len_type="ARP")] + comment: '' + execution time: 0.0 + expected result: 1. PC can't recv ARP reply from target + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: 1. PC send ARP req with target_hw_addr, sender_hw_addr and sender_proto_addr + not correct + sub module: ARP + summary: PC send invalid ARP request to target 2 + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: handling ARP request + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_DHCP_0302 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 ip -S -i 192.168.123.123 -o 2 + - ['R SSC1 C +IP:ERROR'] + - - SSC SSC1 dhcp -L -s 192.168.2.2 -e 192.168.2.10 + - ['R SSC1 C +DHCP:LEASE,ERROR'] + - - SSC SSC1 ap -S -s -p -t + - [''] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 ip -S -i 192.168.4.1 -o 2 + - ['R SSC1 C +IP:OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.10 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC2 sta -C -s -p + - [''] + - - DELAY 10 + - [P PC_COM C +DELAYDONE, 'P SSC2 NC +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: '1.target 1 OK + + 2.target1 ERROR + + 3.target1 ERROR + + 4.target2 jap target1 OK + + 5.target1 OK + + 6.target1 OK + + 7.target1 OK + + 8.target2 jap target1 OK' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: TCPIP + steps: "1.target1 打开DHCP 2\n2.target1 设置softAP ip 192.168.123.123\n3.target1 设置地址池\n\ + 4.target1下设置ssid 和pwd 加密方式\n5.target2 连接target1 \n6.target1 关闭DHCP 2\n7.target1\ + \ 设置softAP ip \n8.target1 设置正确的地址池\n9.target2 连接target1" + sub module: DHCP + summary: ap dhcp static ip interaction + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: interaction + test point 2: static IP and DHCP interaction test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_DHCP_0301 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 dhcp -E -o 1 + - ['R SSC1 C +DHCP:STA,OK'] + - - SSC SSC1 ip -S -i 192.168.123.123 -o 1 + - ['R SSC1 C +IP:OK'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC1 ip -S -i 0.0.0.0 -o 1 + - ['R SSC1 C +IP:OK'] + - - SSC SSC1 sta -C -s -p + - [''] + - - DELAY 10 + - [P PC_COM C +DELAYDONE, 'P SSC1 NC +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.JAP CONNETED + + 4.OK + + 5.等待10s,JAP fail' + initial condition: STAAP1 + initial condition description (auto): testing sta on sta + ap mode, quit AP (autogen + by STAM1) + module: TCPIP + steps: '1.target1 关闭DHCP 1 + + 2.target1 设置sta ip 192.168.123.123 + + 4.target1 jap AP + + 5.target1 设置sta ip 0.0.0.0 + + 6.target1 jap AP' + sub module: DHCP + summary: sta dhcp static ip interaction + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: interaction + test point 2: static IP and DHCP interaction test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_UDP_0113 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + comment: '' + execution time: 0.0 + expected result: '1.ok + + 2.ok + + 3.ok + + 4.ok + + 5.ok' + initial condition: APSTA2 + initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen + by APM2) + module: TCPIP + steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 2.target1上UDP传输,Bind socket2,本地ip target_udp_port2 + + 3.target1上UDP传输,Bind socket3,本地ip target_udp_port3 + + 4.target1上UDP传输,Bind socket4,本地ip target_udp_port4 + + 5.target1上UDP传输,Bind socket5,本地ip target_udp_port5' + sub module: UDP + summary: AP mode, create max udp socket test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_DHCP_0302 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 ip -S -i 192.168.123.123 -o 2 + - ['R SSC1 C +IP:ERROR'] + - - SSC SSC1 dhcp -L -s 192.168.2.2 -e 192.168.2.10 + - ['R SSC1 C +DHCP:LEASE,ERROR'] + - - SSC SSC1 ap -S -s -p -t + - [''] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 ip -S -i 192.168.4.1 -o 2 + - ['R SSC1 C +IP:OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.10 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC2 sta -C -s -p + - [''] + - - DELAY 10 + - [P PC_COM C +DELAYDONE, 'P SSC2 NC +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: '1.target 1 OK + + 2.target1 ERROR + + 3.target1 ERROR + + 4.target2 jap target1 OK + + 5.target1 OK + + 6.target1 OK + + 7.target1 OK + + 8.target2 jap target1 OK' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + module: TCPIP + steps: "1.target1 打开DHCP 2\n2.target1 设置softAP ip 192.168.123.123\n3.target1 设置地址池\n\ + 4.target1下设置ssid 和pwd 加密方式\n5.target2 连接target1 \n6.target1 关闭DHCP 2\n7.target1\ + \ 设置softAP ip \n8.target1 设置正确的地址池\n9.target2 连接target1 " + sub module: DHCP + summary: ap dhcp static ip interaction + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: interaction + test point 2: static IP and DHCP interaction test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_DHCP_0301 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 dhcp -E -o 1 + - ['R SSC1 C +DHCP:STA,OK'] + - - SSC SSC1 ip -S -i 192.168.123.123 -o 1 + - ['R SSC1 C +IP:OK'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC1 ip -S -i 0.0.0.0 -o 1 + - ['R SSC1 C +IP:OK'] + - - SSC SSC1 sta -C -s -p + - [''] + - - DELAY 10 + - [P PC_COM C +DELAYDONE, 'P SSC1 NC +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.JAP CONNETED + + 4.OK + + 5.等待10s,JAP fail' + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + module: TCPIP + steps: '1.target1 关闭DHCP 1 + + 2.target1 设置sta ip 192.168.123.123 + + 4.target1 jap AP + + 5.target1 设置sta ip 0.0.0.0 + + 6.target1 jap AP' + sub module: DHCP + summary: sta dhcp static ip interaction + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: interaction + test point 2: static IP and DHCP interaction test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: SYS_MISC_0201 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ram -H + - ['R SSC1 RE FREEHEAP:\d+\r\n'] + comment: '' + execution time: 0.0 + expected result: ' + + 可以查询到一个数值 + + ' + initial condition: None + initial condition description (auto): none + module: System + steps: 查询空闲ram + sub module: Misc + summary: get heap size test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: 'get heap size ' + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_ARP_0204 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - STRING ether%20src%20%%s%20or%20ether%20dst%20%%s + + - [R PC_COM C OK] + - - NIC NIC1 START capture+send+block_arp_ip + - ['R PC_COM C +NIC_START:OK'] + - - NIC NIC1 SEND ARP arp_op_code 0xFF arp_target_proto_addr ethernet_dst_addr + "ff:ff:ff:ff:ff:ff" + - [''] + - - DELAY 2 + - [P PC_COM C +DELAYDONE, P NIC1 NPDU (Ethernet.dst_addr=)(Ethernet.len_type="ARP")] + comment: '' + execution time: 0.0 + expected result: 1. PC can't recv ARP reply from target + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: 1. PC send ARP with error op_code + sub module: ARP + summary: PC send invalid ARP request to target 4 + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: handling ARP request + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0412 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.OK + + 7.OK' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket1 + + 3.target1上使用步骤2创建的socket1,去连接 PC的ip,test_tcp_port1 + + 4.PC与target1创建好TCP 连接,有ACCEPT + + 5.target1上创建TCP socket2 + + 6.关闭socket1 连接 + + 7.关闭socket2连接' + sub module: TCP + summary: close TCP send after socket changed + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: TCP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0403 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SSC SSC1 op -S -o 2 + - ['P SSC1 C +MODE:OK', 'P SSC1 RE CLOSED:\d+,0'] + - - SSC SSC1 soc -S -s -l 5 + - ['P SSC1 RE SEND:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.ERROR' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1上使用步骤2创建的socket1,去连接\ + \ PC的ip,test_tcp_port1\n4.PC与target1创建好TCP 连接,有ACCEPT\n5.修改8266的Mode为softAP mode\ + \ \n6.8266往PC上发送5字节数据" + sub module: TCP + summary: do TCP send after mode changed + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: TCP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0402 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SSC SSC1 sta -D + - ['P SSC1 C +QAP:OK', 'P SSC1 RE CLOSED:\d+,0'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.OK' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket1 + + 3.target1上使用步骤2创建的socket1,去连接 PC的ip,test_tcp_port1 + + 4.PC与target1创建好TCP 连接,有ACCEPT + + 5.断开与AP 连接 + + 6.关闭建立的socket1连接' + sub module: TCP + summary: "close TCP socket after WIFI \ndisconnected" + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: TCP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0401 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SSC SSC1 sta -D + - ['P SSC1 C +QAP:OK', 'P SSC1 RE CLOSED:\d+,0'] + - - SSC SSC1 soc -S -s -l 5 + - ['P SSC1 RE SEND:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.ERROR' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket1 + + 3.target1上使用步骤2创建的socket1,去连接 PC的ip,test_tcp_port1 + + 4.PC与target1创建好TCP 连接,有ACCEPT + + 5.断开与AP 连接 + + 6.8266往PC上发送5字节数据' + sub module: TCP + summary: do TCP send after WIFI disconnected + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: TCP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^WIFI_ADDR_0101 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 mac -S -o 1 -m 44:55:66:77:88:99 + - ['R SSC1 C +MAC:STA,OK'] + - - SSC SSC1 mac -S -o 2 -m 22:33:44:55:66:77 + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC1 mac -Q -o 3 + - ['R SSC1 C +STAMAC:44:55:66:77:88:99 C +APMAC:22:33:44:55:66:77'] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.ok + + 3.ok + + 4.ok + + 5.ok + + 6.ok' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: "1.target1 设置mode 为sta+softAP mode\n2.target1 设置sta mode 下的mac \n3.target1\ + \ 设置softAP mode 下的mac\n4.target1 查询softAP+sta 下的mac\n5.target1 设置sta mode 下的mac\ + \ 为target1_mac\n6.target1 设置softAP mode 下的mac 为target1_ap_mac" + sub module: MAC Address + summary: set mac, query mac + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: mac address function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0407 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SSC SSC1 dhcp -E -o 1 + - ['R SSC1 C +DHCP:STA,OK'] + - - SSC SSC1 ip -S -o 1 -i 192.168.111.210 + - ['P SSC1 C +IP:OK', 'P SSC1 RE CLOSED:\d+,0'] + - - SSC SSC1 ip -Q -o 1 + - ['R SSC1 C +STAIP:192.168.111.210'] + - - SSC SSC1 soc -S -s -l 5 + - ['P SSC1 RE SEND:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.OK + + 7.OK + + 8.ERROR' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1上使用步骤2创建的socket1,去连接\ + \ PC的ip,test_tcp_port1\n4.PC与target1创建好TCP 连接,有ACCEPT\n5.关闭8266的DHCP 1\n6.设置sta\ + \ ip \n7.查询sta ip 地址是否生效\n8.8266往PC上发送5字节数据" + sub module: TCP + summary: do TCP send after IP changed + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: TCP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0406 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - NIC DISABLED + - [R PC_COM C OK] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.OK' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1上使用步骤2创建的socket1,去连接\ + \ PC的ip,test_tcp_port1\n4.PC与target1创建好TCP 连接,有ACCEPT\n5.PC上网卡禁止掉 \n6.关闭建立的socket1连接" + sub module: TCP + summary: close TCP socket after PC NIC disabled + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: TCP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0404 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SSC SSC1 op -S -o 2 + - ['P SSC1 C +MODE:OK', 'P SSC1 RE CLOSED:\d+,0'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.OK' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1上使用步骤2创建的socket1,去连接\ + \ PC的ip,test_tcp_port1\n4.PC与target1创建好TCP 连接,有ACCEPT\n5.修改8266的Mode为softAP mode\ + \ \n6.关闭建立的socket1连接" + sub module: TCP + summary: close TCP socket after mode changed + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: TCP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^WIFI_CONN_0903 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -C -s -p bacfd + - ['R SSC1 C +JAP:DISCONNECTED,4,2'] + comment: '' + execution time: 0.0 + expected result: 1. disconect event reason REASON_AUTH_EXPIRE + initial condition: STAAP1 + initial condition description (auto): testing sta on sta + ap mode, quit AP (autogen + by STAM1) + module: WIFI MAC + steps: 1. connect WEP ap with error password (valid wep password) + sub module: WIFI Connect + summary: test wifi disconnect reason REASON_AUTH_EXPIRE + test environment: SSC_T1_WEP + test environment description (auto): '1 SSC target connect with PC by UART. + + One WEP share key AP placed near SSC1.' + test point 1: basic function + test point 2: wifi disconnect reason test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0408 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SSC SSC1 dhcp -E -o 1 + - ['R SSC1 C +DHCP:STA,OK'] + - - SSC SSC1 ip -S -o 1 -i 192.168.111.210 + - ['P SSC1 C +IP:OK', 'P SSC1 RE CLOSED:\d+,0'] + - - SSC SSC1 ip -Q -o 1 + - ['R SSC1 C +STAIP:192.168.111.210'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.OK + + 7.OK + + 8.OK' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1上使用步骤2创建的socket1,去连接\ + \ PC的ip,test_tcp_port1\n4.PC与target1创建好TCP 连接,有ACCEPT\n5.关闭8266的DHCP 1\n6.设置sta\ + \ ip \n7.查询sta ip 地址是否生效\n8.关闭建立的socket1连接" + sub module: TCP + summary: close TCP socket after IP changed + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: TCP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0202 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,ERROR'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,ERROR'] + - - SSC SSC1 soc -D -s + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,ERROR'] + - - SSC SSC1 soc -L -s 1000 + - ['R SSC1 RE LISTEN:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.ERROR + + 4.OK + + 5.OK + + 6.ERROR + + 7.OK + + 8.ERROR + + 9.ERROR' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建UDP传输socket,bind到本地ip 0.0.0.0, + + 3.target1上使用步骤2创建的socket,去建立TCP 监听 + + 4.target1上创建TCP socket + + 5.target1上使用步骤4创建的socket,去连接 PC的ip, + + 6.target1上使用步骤4创建的socket,创建TCP 监听 + + 7.target1上shutdown 步骤4的socket + + 8.target1上使用步骤4创建的socket,创建TCP 监听 + + 9.target1上使用不存在socket,创建TCP 监听' + sub module: TCP + summary: STA mode, server listen test. use socket in state that can't listen + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) in different state + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0110 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [SOCR SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP -i 0.0.0.0 -p 0 + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,OK', P SOC1 C +ACCEPT] + - - SSC SSC1 soc -B -t TCP -i 0.0.0.0 -p 0 + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i 123.456.678.789 -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.ERROR + + 6.ERROR' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket,bind到本地ip 0.0.0.0,本地端口 0 + + 3.target1上使用步骤2创建的socket,去连接 PC的ip,test_tcp_port1 + + 4.target1上创建TCP socket,bind到本地ip 0.0.0.0,本地端口 0 + + 5.target1上使用步骤4创建的socket,去连接不存在的ip,test_tcp_port1 + + 6.target1上使用步骤2创建的socket,去连接 PC的ip,远端端口不存在。' + sub module: TCP + summary: AP mode, connect test. use different ip, port + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0203 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s + - ['R SSC1 RE SEND:\d+,ERROR'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s + - ['R SSC1 RE SEND:\d+,ERROR'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -S -s + - ['R SSC1 RE SEND:\d+,ERROR'] + - - SSC SSC1 soc -S -s 1000 + - ['R SSC1 RE SEND:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.ERROR + + 4.OK + + 5.ERROR + + 6.OK + + 7.OK + + 8.ERROR + + 9.ERROR' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建UDP传输socket1, + + 3.target1上使用步骤2创建的socket1,去发送数据 + + 4.target1上创建TCP socket2 + + 5.target1上使用步骤4创建的socket2,去发送数据 + + 6.target1上使用步骤4创建的socket2,创建TCP连接,连接成功 + + 7.target1上shutdown 步骤4的socket2 + + 8.target1往socket2发送错误命令发送数据 + + 9.target1上不指定socket往上发送数据' + sub module: TCP + summary: send test. use socket in state that can't send + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) in different state + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_DHCP_0101 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 dhcp -E -o 1 + - ['R SSC1 C +DHCP:STA,OK'] + - - SSC SSC1 ip -S -i 0.0.0.0 + - ['R SSC1 C +IP:OK'] + - - SSC SSC1 sta -C -s -p + - [''] + - - DELAY 20 + - [P PC_COM C +DELAYDONE, 'P SSC1 NC +JAP:CONNECTED'] + - - SSC SSC1 dhcp -S -o 1 + - ['R SSC1 C +DHCP:STA,OK'] + - - SSC SSC1 ip -Q + - ['R SSC1 C +STAIP:0.0.0.0'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC1 ip -Q + - ['R SSC1 RE "\+STAIP:%%s"%%()'] + comment: '' + execution time: 0.0 + expected result: "1.target1 关闭DHCP OK\n2.target1 设置ip add OK\n3.target1 连接AP fail\n\ + 4.target1 打开DHCP OK\n5.查询到sta ip \n6.target1 连接AP ok\n7.查询到sta ip 为target_ip" + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + module: TCPIP + steps: "1.target1 关闭DHCP OK\n2.target1 设置ip add OK\n3.target1 连接AP fail\n4.target1\ + \ 打开DHCP OK\n5.查询到sta ip \n6.target1 连接AP ok\n7.查询到sta ip 为target_ip" + sub module: DHCP + summary: dhcp client function test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP client function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_DHCP_0103 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 3 + - ['R SSC1 C +DHCP:AP,OK C +DHCP:STA,OK'] + - - SSC SSC1 dhcp -Q -o 3 + - ['R SSC1 C +DHCP:STA,STARTED C +DHCP:AP,STARTED'] + - - SSC SSC1 dhcp -Q -o 1 + - ['R SSC1 C +DHCP:STA,STARTED NC +DHCP:AP,STARTED'] + - - SSC SSC1 dhcp -Q -o 2 + - ['R SSC1 NC +DHCP:STA,STARTED C +DHCP:AP,STARTED'] + - - SSC SSC1 dhcp -E -o 3 + - ['R SSC1 C +DHCP:AP,OK C +DHCP:STA,OK'] + - - SSC SSC1 dhcp -Q -o 3 + - ['R SSC1 C +DHCP:STA,STOPPED C +DHCP:AP,STOPPED'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.STA&AP STARTED + + 4.STA STARTED + + 5.AP STARTED + + 6.OK + + 7.STA&AP STOPPED' + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + module: TCPIP + steps: '1.target1 设置mode 为sta+softAP mode + + 2.target1 打开DHCP 3 + + 3.target1 查询DHCP 状态 + + 4.target1 查询sta DHCP 状态 + + 5.target1 查询softAP DHCP 状态 + + 6.target1 关闭 DHCP 3 + + 7.target1 查询 DHCP 状态' + sub module: DHCP + summary: dhcp status query + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP client function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_DHCP_0102 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC2 sta -C -s -p + - [''] + - - DELAY 20 + - [P PC_COM C +DELAYDONE, 'P SSC2 NC +JAP:CONNECTED'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: "1.target1 set AP OK \n2.target1 关闭DHCP OK\n3.target2 jap target\ + \ 1,FAIL \n4.target1 打开DHCP OK\n5.target2 jap target 1,ok" + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + module: TCPIP + steps: "1.target1 set AP OK \n2.target1 关闭DHCP OK\n3.target2 jap target 1,FAIL \n\ + 4.target1 打开DHCP OK\n5.target2 jap target 1,ok" + sub module: DHCP + summary: dhcp server function test + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP client function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_UDP_0303 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 5 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] + - - SSC SSC1 op -S -o 2 + - ['P SSC1 C +MODE:OK'] + - - SSC SSC1 soc -S -s -i -p -l 5 + - ['P SSC1 RE SEND:(\d+),OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.ERROR' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: "1.PC上SOC1 UDP传输,bing \n2.target1上UDP传输,Bind socket1,本地ip\ + \ target_udp_port1\n3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据\n\ + 4.修改8266的Mode为softAP mode \n5.8266往PC上发送5字节数据" + sub module: UDP + summary: do UDP send after mode changed + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: UDP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_SCAN_0103 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:'] + - - SSC SSC1 ap -S -s -p 123456789 -t 3 -n 6 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -S -n 5 + - [R SSC2 NP C +SCANDONE] + - - SSC SSC2 sta -S -n 6 + - ['R SSC2 C +SCAN:', R SSC2 P ] + comment: '' + execution time: 0.0 + expected result: '1.target1 QAP + + 2. target1 set AP,set channel 6 + + 3.target2 上scan不到 channel 5 + + 4.target2 上查询channel 6的' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + module: WIFI MAC + steps: '1.target1 断开连接AP + + 2.target1下设置ssid 和pwd 加密方式,set channel 6 + + 3.target2 上scan channel 5 + + 4.target2 上查询channel 6的' + sub module: WIFI Scan + summary: scan with scan config channel + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: scan with different config + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_SCAN_0102 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC2 sta -S -b ff:ff:ff:ff:ff:11 + - ['R SSC2 NC +SCAN: C +SCANDONE'] + - - SSC SSC2 sta -S -b + - ['R SSC2 RE "\+SCAN:.+,%%s"%%()', 'R SSC2 NC +SCAN: C +SCANDONE'] + comment: '' + execution time: 0.0 + expected result: '1.target2 上不能查询到此mac + + 2.target2上查询到' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + module: WIFI MAC + steps: '1.target2 上查询此macff:ff:ff:ff:ff:11 + + 2.target2上查询' + sub module: WIFI Scan + summary: scan with scan config bssid + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: scan with different config + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_SCAN_0101 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC2 sta -S -s .,juhg123 + - ['R SSC2 NC +SCAN: C +SCANDONE'] + - - SSC SSC1 ap -S -s -p 123456789 -t 3 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -S -s + - ['R SSC2 C +SCAN:', R SSC2 P , 'R SSC2 NC +SCAN: C +SCANDONE'] + comment: '' + execution time: 0.0 + expected result: '1.target 2上不能scan .,juhg123 + + 2.target1 set AP + + 3.target2上查询到' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + module: WIFI MAC + steps: '1.target 2 scan .,juhg123 + + 2.target1下设置ssid 和pwd 加密方式 + + 3.target2 scan ' + sub module: WIFI Scan + summary: scan with scan config ssid + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: scan with different config + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_SCAN_0105 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:'] + - - SSC SSC1 ap -S -s -p 123456789 -t 3 -h 0 -n 11 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -S -s -b -n 11 + - [R SSC2 P C +SCANDONE] + - - SSC SSC2 sta -S -s -b -n 11 + - [R SSC2 NP C +SCANDONE] + - - SSC SSC2 sta -S -s -b ff:ff:ff:ff:ff:11 -n 11 + - [R SSC2 P , R SSC2 NP C +SCANDONE] + - - SSC SSC2 sta -S -s -b -n 10 + - [R SSC2 P , R SSC2 NP C +SCANDONE] + comment: '' + execution time: 0.0 + expected result: '1.target1 QAP + + 2. target1 set AP,set ssid broad cast,set channel 11 + + 3.target2 上查询到 + + 4.target2 上查询不到 + + 5.target2 上查询不到 + + 6.target2 上查询不到' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + module: WIFI MAC + steps: '1.target1 QAP + + 2. target1 set AP,set ssid broad cast,set channel 11 + + 3.target2 上查询到 + + 4.target2 上查询不到 + + 5.target2 上查询不到 + + 6.target2 上查询不到' + sub module: WIFI Scan + summary: scan with several configs + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: scan with different config + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_SCAN_0104 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p 123456789 -t 3 -h 0 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -S -h 0 + - [R SSC2 P C +SCANDONE] + - - SSC SSC2 sta -S -h 1 + - [R SSC2 P C +SCANDONE] + - - SSC SSC1 ap -S -s -p 123456789 -h 1 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -S -h 0 + - [R SSC2 NP C +SCANDONE] + - - SSC SSC2 sta -S -h 1 + - [R SSC2 P C +SCANDONE] + comment: '' + execution time: 0.0 + expected result: '1.target1 set AP,set ssid broad cast + + 2.target 2上scan + + 3.target 2上scan + + 4.target1 set AP,set ssid hidden, + + 5.target 2上不能查询到 + + 6.target 2上查询到' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + module: WIFI MAC + steps: '1.target1下设置ssid 和pwd 加密方式,set ssid broad cast + + 2.target 2上scan + + 3.target 2上scan + + 4.target1下设置ssid 和pwd 加密方式,set ssid hidden, + + 5.target 2上查询 + + 6.target 2上查询' + sub module: WIFI Scan + summary: scan with scan config show hidden + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: scan with different config + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_UDP_0302 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 5 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] + - - SSC SSC1 sta -D + - ['P SSC1 C +QAP:OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.OK' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: '1.PC上SOC1 UDP传输,bing + + 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据 + + 4.断开与AP 连接 + + 5.关闭建立的socket1连接' + sub module: UDP + summary: "close UDP socket after WIFI \ndisconnected" + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: UDP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_UDP_0301 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -i -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 5 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] + - - SSC SSC1 sta -D + - ['P SSC1 C +QAP:OK'] + - - SSC SSC1 soc -S -s -i -p -l 5 + - ['P SSC1 RE SEND:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.ERROR' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: '1.PC上SOC1 UDP传输,bing + + 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据 + + 4.断开与AP 连接 + + 5.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据' + sub module: UDP + summary: do UDP send after WIFI disconnected + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: UDP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_CONN_0201 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC1 sta -Q + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:OK'] + - - SSC SSC1 sta -Q + - ['R SSC1 C +JAP:DISCONNECTED'] + comment: '' + execution time: 0.0 + expected result: '1.target1 jion AP 成功 + + 2.查询JAP的状态 + + 3.target1 断开AP + + 4.查询target1 JAP 是DISCONN' + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + module: WIFI MAC + steps: '1.target1 jion AP 成功 + + 2.查询JAP的状态 + + 3.target1 断开AP + + 4.查询target1 JAP 是DISCONN' + sub module: WIFI Connect + summary: JAP query test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: query JAP status + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_CONN_0702 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:OK', 'R SSC1 C +JAP:DISCONNECTED,3'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:OK', 'R SSC1 C +JAP:DISCONNECTED,2'] + comment: '' + execution time: 0.0 + expected result: '1. get status AP not exist in disconnect event + + 2. get status wrong password in disconnect event' + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + module: WIFI MAC + steps: '1. sta connect to ap not exist + + 2. sta connect to ap with wrong password + + ' + sub module: WIFI Connect + summary: check wifi status wrong password, no ap found + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: wifi connect status check + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_CONN_0703 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -C -s -p bacfd + - ['R SSC1 C +JAP:DISCONNECTED,4,2'] + comment: '' + execution time: 0.0 + expected result: 1. connect status connect fail in disconnect evnet + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + module: WIFI MAC + steps: 1. connect WEP ap with error password (valid wep password) + sub module: WIFI Connect + summary: check wifi status connect fail + test environment: SSC_T1_WEP + test environment description (auto): '1 SSC target connect with PC by UART. + + One WEP share key AP placed near SSC1.' + test point 1: basic function + test point 2: wifi connect status check + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_CONN_0701 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -D + - [R SSC1 C QAP] + - - SSC SSC1 sta -Q + - ['R SSC1 C +STA_STATUS:0'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:OK'] + - - SSC SSC1 sta -Q + - ['R SSC1 C +STA_STATUS:1', 'R SSC1 C +JAP:CONNECTED'] + - - SSC SSC1 sta -Q + - ['R SSC1 C +STA_STATUS:5'] + - - APC OFF + - [P PC_COM L OK, P SSC1 C bcn_timout] + - - SSC SSC1 sta -Q + - ['R SSC1 C +STA_STATUS:4'] + - - APC ON + - [P PC_COM L OK] + comment: '' + execution time: 0.0 + expected result: '1. idle state + + 2. connecting state + + 3. got IP state + + 4. connect fail state' + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + module: WIFI MAC + steps: '1. sta disconnected, query status + + 2. sta connect to AP, query status + + 3. got IP, query status + + 4. AP power off, query status when beacon timeout' + sub module: WIFI Connect + summary: check wifi status idle, connecting, got ip and connect fail + test environment: SSC_T1_APC + test environment description (auto): "PC has 1 wired NIC connected to AP.\nPC has\ + \ 1 wired NIC connected to APC (static IP within the same subnet with APC). \n\ + APC control AP power supply. \nPC has 1 WiFi NIC. \n1 SSC target connect with\ + \ PC by UART." + test point 1: basic function + test point 2: wifi connect status check + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_DNS_0102 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -H -d iot.espressif.cn + - ['R SSC1 A :\+HOSTIP:OK,(.+)\r\n'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :\+BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p 9001 + - ['R SSC1 RE \+CONNECT:\d+,OK'] + - - SSC SSC1 soc -S -s -l 10 + - ['P SSC1 RE \+SEND:\d+,OK', P SSC1 SL +10] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: '1. get host name "espressif.cn" + + 2. connect, send, recv1. get host name "espressif.cn" + + 2. connect, send, recv' + sub module: DNS + summary: TCP connect to iot.espressif.com + test environment: SSC_T1_2 + test environment description (auto): 'Able to access WAN after connect to AP. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DNS function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_DNS_0101 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -H -d iot.espressif.cn + - ['R SSC1 C +HOSTIP:OK,115.29.202.58'] + comment: '' + execution time: 0.0 + expected result: 1.OK + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: 1. get host name "espressif.cn" + sub module: DNS + summary: get host by name test + test environment: SSC_T1_2 + test environment description (auto): 'Able to access WAN after connect to AP. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DNS function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_CONN_0904 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 3 -m 1 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p 1234567890 + - ['R SSC2 C +JAP:DISCONNECTED,1,204'] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:OK'] + - - WIFI CONN + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:DISCONNECTED,1,5'] + - - WIFI DISCONN + - [P PC_COM C OK, 'R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 ap -S -s -p -t 3 -m 1 + - ['P SSC1 C +SAP:OK', 'P SSC2 C +JAP:DISCONNECTED,5,4'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. disconnect event REASON_HANDSHAKE_TIMEOUT + + 3. succeed + + 4. succeed + + 5. disconnect event REASON_ASSOC_TOOMANY + + 6. succeed, target2 connect succeed + + 7. disconnect event REASON_ASSOC_EXPIRE' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + module: WIFI MAC + steps: '1. config target1 softap max sta allowed 1 + + 2. target2 connect to target1 with wrong password + + 3. target2 disconnect + + 4. PC WIFI NIC connect to target1 + + 5. target2 connect to target1 with correct password + + 6. PC WIFI NIC disconnect + + 7. reconfig softap' + sub module: WIFI Connect + summary: test wifi disconnect reason REASON_ASSOC_TOOMANY, REASON_HANDSHAKE_TIMEOUT, + REASON_ASSOC_EXPIRE + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: wifi disconnect reason test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_IP_0101 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 dhcp -S -o 1 + - ['R SSC1 C +DHCP:STA,OK'] + - - SSC SSC1 ip -S -o 1 -i 192.168.123.123 + - ['R SSC1 C +IP:ERROR'] + - - SSC SSC1 dhcp -E -o 1 + - ['R SSC1 C +DHCP:STA,OK'] + - - SSC SSC1 ip -S -o 1 -i 192.168.123.123 + - ['R SSC1 C +IP:OK'] + - - SSC SSC1 ip -Q -o 1 + - ['R SSC1 C +STAIP:192.168.123.123'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.ERROR + + 3.OK + + 4.OK + + 5.STAIP:192.168.123.123' + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + module: TCPIP + steps: '1.target1 打开DHCP 1 + + 2.target1 设置sta ip 192.168.123.123 + + 4.target1 关闭DHCP 1 + + 5.target1 设置sta ip 192.168.123.123 + + 6.target1 查询 当前sta ip ' + sub module: IP + summary: sta set and query static ip test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: set and query static IP + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_IP_0102 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 ip -S -o 2 -i 192.168.123.123 + - ['R SSC1 C +IP:ERROR'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 ip -S -o 2 -i 192.168.123.123 + - ['R SSC1 C +IP:OK'] + - - SSC SSC1 ip -Q -o 2 + - ['R SSC1 C +APIP:192.168.123.123'] + - - SSC SSC1 ip -S -o 2 -i + - ['R SSC1 C +IP:OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.ERROR + + 3.OK + + 4.OK + + 5.APIP:192.168.123.123 + + 6.OK' + initial condition: APM1 + initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial + condition APSTA1 + module: TCPIP + steps: "1.target1 打开DHCP 2\n2.target1 设置softAP ip 192.168.123.123\n4.target1 关闭DHCP\ + \ 2\n5.target1 设置softAP ip 192.168.123.123\n6.target1 查询 当前sta ip \n7.target1\ + \ 设置softAP ip 为target_ap_ip" + sub module: IP + summary: ap set and query static ip test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: set and query static IP + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^WIFI_CONN_0201 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC1 sta -Q + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:OK'] + - - SSC SSC1 sta -Q + - ['R SSC1 C +JAP:DISCONNECTED'] + comment: '' + execution time: 0.0 + expected result: '1.target1 jion AP 成功 + + 2.查询JAP的状态 + + 3.target1 断开AP + + 4.查询target1 JAP 是DISCONN' + initial condition: STAAP1 + initial condition description (auto): testing sta on sta + ap mode, quit AP (autogen + by STAM1) + module: WIFI MAC + steps: '1.target1 jion AP 成功 + + 2.查询JAP的状态 + + 3.target1 断开AP + + 4.查询target1 JAP 是DISCONN' + sub module: WIFI Connect + summary: JAP query test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: query JAP status + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_IGMP_0102 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 igmp -J -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 igmp -L -h -m 224.1.1.2 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -L -h 192.168.237.77 -m 224.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -L -h 192.168.237.77 -m 240.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -L -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + comment: '' + execution time: 0.0 + expected result: '1. success + + 2. failed + + 3. failed + + 4. failed + + 5. succeed' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: '1. join group with correct host addr and multicast addr + + 2. leave group with correct host addr and wrong multicast addr + + 3. leave group with wrong host addr and correct multicast addr + + 4. leave group with wrong host addr and wrong multicast addr + + 5. leave group with correct host addr and correct multicast addr' + sub module: IGMP + summary: station IGMP leave group address check + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: IGMP API parameter check + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_IGMP_0101 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 igmp -J -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 igmp -L -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 igmp -J -h -m 223.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -J -h -m 240.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -J -h 192.168.237.77 -m 224.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -J -h 192.168.237.77 -m 240.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + comment: '' + execution time: 0.0 + expected result: '1. success + + 2. failed + + 3. failed + + 4. failed' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: '1. join group with correct host addr and multicast addr + + 2. join group with correct host addr and wrong multicast addr + + 3. join group with wrong host addr and correct multicast addr + + 4. join group with wrong host addr and wrong multicast addr' + sub module: IGMP + summary: station IGMP join group address check + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: IGMP API parameter check + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_IGMP_0104 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 igmp -J -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 igmp -L -h -m 224.1.1.2 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -L -h 192.168.237.77 -m 224.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -L -h 192.168.237.77 -m 240.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -L -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + comment: '' + execution time: 0.0 + expected result: '1. success + + 2. failed + + 3. failed + + 4. failed + + 5. succeed' + initial condition: APSTA2 + initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen + by APM2) + module: TCPIP + steps: '1. join group with correct host addr and multicast addr + + 2. leave group with correct host addr and wrong multicast addr + + 3. leave group with wrong host addr and correct multicast addr + + 4. leave group with wrong host addr and wrong multicast addr + + 5. leave group with correct host addr and correct multicast addr' + sub module: IGMP + summary: softAP IGMP leave group address check + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: IGMP API parameter check + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^WIFI_CONN_0701 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -D + - [R SSC1 C QAP] + - - SSC SSC1 sta -Q + - ['R SSC1 C +STA_STATUS:0'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:OK'] + - - SSC SSC1 sta -Q + - ['R SSC1 C +STA_STATUS:1', 'R SSC1 C +JAP:CONNECTED'] + - - SSC SSC1 sta -Q + - ['R SSC1 C +STA_STATUS:5'] + - - APC OFF + - [P PC_COM L OK, P SSC1 C bcn_timout] + - - SSC SSC1 sta -Q + - ['R SSC1 C +STA_STATUS:4'] + - - APC ON + - [P PC_COM L OK] + comment: '' + execution time: 0.0 + expected result: '1. idle state + + 2. connecting state + + 3. got IP state + + 4. connect fail state' + initial condition: STAAP1 + initial condition description (auto): testing sta on sta + ap mode, quit AP (autogen + by STAM1) + module: WIFI MAC + steps: '1. sta disconnected, query status + + 2. sta connect to AP, query status + + 3. got IP, query status + + 4. AP power off, query status when beacon timeout' + sub module: WIFI Connect + summary: check wifi status idle, connecting, got ip and connect fail + test environment: SSC_T1_APC + test environment description (auto): "PC has 1 wired NIC connected to AP.\nPC has\ + \ 1 wired NIC connected to APC (static IP within the same subnet with APC). \n\ + APC control AP power supply. \nPC has 1 WiFi NIC. \n1 SSC target connect with\ + \ PC by UART." + test point 1: basic function + test point 2: wifi connect status check + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^WIFI_CONN_0703 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -C -s -p bacfd + - ['R SSC1 C +JAP:DISCONNECTED,4,2'] + comment: '' + execution time: 0.0 + expected result: 1. connect status connect fail in disconnect evnet + initial condition: STAAP1 + initial condition description (auto): testing sta on sta + ap mode, quit AP (autogen + by STAM1) + module: WIFI MAC + steps: 1. connect WEP ap with error password (valid wep password) + sub module: WIFI Connect + summary: check wifi status connect fail + test environment: SSC_T1_WEP + test environment description (auto): '1 SSC target connect with PC by UART. + + One WEP share key AP placed near SSC1.' + test point 1: basic function + test point 2: wifi connect status check + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_UDP_0110 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 1 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 1] + - - SSC SSC1 soc -S -s -i -p -l 1472 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 1472] + - - SSC SSC1 soc -S -s -i -p -l 1473 + - ['P SSC1 RE SEND:(\d+),OK', P SOC_COM NC SOC_RECVFROM] + - - SSC SSC1 soc -S -s -i -p -l 1472 -n 10 + -j 20 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 14720] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.OK,没收到UDP包 + + 6.OK' + initial condition: APSTA2 + initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen + by APM2) + module: TCPIP + steps: '1.PC上SOC1 UDP传输,bing + + 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1字节数据 + + 4.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1472字节数据 + + 5.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1473字节数据 + + 6.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1472*10字节数据' + sub module: UDP + summary: AP mode, sendto test with different length + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^WIFI_SCAN_0102 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC2 sta -S -b ff:ff:ff:ff:ff:11 + - ['R SSC2 NC +SCAN: C +SCANDONE'] + - - SSC SSC2 sta -S -b + - ['R SSC2 RE "\+SCAN:.+,%%s"%%()', 'R SSC2 NC +SCAN: C +SCANDONE'] + comment: '' + execution time: 0.0 + expected result: '1.target2 上不能查询到此mac + + 2.target2上查询到' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1.target2 上查询此macff:ff:ff:ff:ff:11 + + 2.target2上查询' + sub module: WIFI Scan + summary: scan with scan config bssid + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: scan with different config + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^WIFI_SCAN_0103 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:'] + - - SSC SSC1 ap -S -s -p 123456789 -t 3 -n 6 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -S -n 5 + - [R SSC2 NP C +SCANDONE] + - - SSC SSC2 sta -S -n 6 + - ['R SSC2 C +SCAN:', R SSC2 P ] + comment: '' + execution time: 0.0 + expected result: '1.target1 QAP + + 2. target1 set AP,set channel 6 + + 3.target2 上scan不到 channel 5 + + 4.target2 上查询channel 6的' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1.target1 断开连接AP + + 2.target1下设置ssid 和pwd 加密方式,set channel 6 + + 3.target2 上scan channel 5 + + 4.target2 上查询channel 6的' + sub module: WIFI Scan + summary: scan with scan config channel + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: scan with different config + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^WIFI_SCAN_0104 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p 123456789 -t 3 -h 0 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -S -h 0 + - [R SSC2 P C +SCANDONE] + - - SSC SSC2 sta -S -h 1 + - [R SSC2 P C +SCANDONE] + - - SSC SSC1 ap -S -s -p 123456789 -h 1 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -S -h 0 + - [R SSC2 NP C +SCANDONE] + - - SSC SSC2 sta -S -h 1 + - [R SSC2 P C +SCANDONE] + comment: '' + execution time: 0.0 + expected result: '1.target1 set AP,set ssid broad cast + + 2.target 2上scan + + 3.target 2上scan + + 4.target1 set AP,set ssid hidden, + + 5.target 2上不能查询到 + + 6.target 2上查询到' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1.target1下设置ssid 和pwd 加密方式,set ssid broad cast + + 2.target 2上scan + + 3.target 2上scan + + 4.target1下设置ssid 和pwd 加密方式,set ssid hidden, + + 5.target 2上查询 + + 6.target 2上查询' + sub module: WIFI Scan + summary: scan with scan config show hidden + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: scan with different config + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^WIFI_SCAN_0105 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:'] + - - SSC SSC1 ap -S -s -p 123456789 -t 3 -h 0 -n 11 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -S -s -b -n 11 + - [R SSC2 P C +SCANDONE] + - - SSC SSC2 sta -S -s -b -n 11 + - [R SSC2 NP C +SCANDONE] + - - SSC SSC2 sta -S -s -b ff:ff:ff:ff:ff:11 -n 11 + - [R SSC2 P , R SSC2 NP C +SCANDONE] + - - SSC SSC2 sta -S -s -b -n 10 + - [R SSC2 P , R SSC2 NP C +SCANDONE] + comment: '' + execution time: 0.0 + expected result: '1.target1 QAP + + 2. target1 set AP,set ssid broad cast,set channel 11 + + 3.target2 上查询到 + + 4.target2 上查询不到 + + 5.target2 上查询不到 + + 6.target2 上查询不到' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1.target1 QAP + + 2. target1 set AP,set ssid broad cast,set channel 11 + + 3.target2 上查询到 + + 4.target2 上查询不到 + + 5.target2 上查询不到 + + 6.target2 上查询不到' + sub module: WIFI Scan + summary: scan with several configs + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: scan with different config + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_IGMP_0104 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 igmp -J -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 igmp -L -h -m 224.1.1.2 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -L -h 192.168.237.77 -m 224.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -L -h 192.168.237.77 -m 240.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -L -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + comment: '' + execution time: 0.0 + expected result: '1. success + + 2. failed + + 3. failed + + 4. failed + + 5. succeed' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + module: TCPIP + steps: '1. join group with correct host addr and multicast addr + + 2. leave group with correct host addr and wrong multicast addr + + 3. leave group with wrong host addr and correct multicast addr + + 4. leave group with wrong host addr and wrong multicast addr + + 5. leave group with correct host addr and correct multicast addr' + sub module: IGMP + summary: softAP IGMP leave group address check + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: IGMP API parameter check + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_IGMP_0103 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 igmp -J -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 igmp -L -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 igmp -J -h -m 223.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -J -h -m 240.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -J -h 192.168.237.77 -m 224.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -J -h 192.168.237.77 -m 240.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + comment: '' + execution time: 0.0 + expected result: '1. success + + 2. failed + + 3. failed + + 4. failed' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + module: TCPIP + steps: '1. join group with correct host addr and multicast addr + + 2. join group with correct host addr and wrong multicast addr + + 3. join group with wrong host addr and correct multicast addr + + 4. join group with wrong host addr and wrong multicast addr' + sub module: IGMP + summary: softAP IGMP join group address check + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: IGMP API parameter check + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_IGMP_0102 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 igmp -J -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 igmp -L -h -m 224.1.1.2 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -L -h 192.168.237.77 -m 224.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -L -h 192.168.237.77 -m 240.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -L -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + comment: '' + execution time: 0.0 + expected result: '1. success + + 2. failed + + 3. failed + + 4. failed + + 5. succeed' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: '1. join group with correct host addr and multicast addr + + 2. leave group with correct host addr and wrong multicast addr + + 3. leave group with wrong host addr and correct multicast addr + + 4. leave group with wrong host addr and wrong multicast addr + + 5. leave group with correct host addr and correct multicast addr' + sub module: IGMP + summary: station IGMP leave group address check + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: IGMP API parameter check + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_IGMP_0101 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 igmp -J -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 igmp -L -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 igmp -J -h -m 223.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -J -h -m 240.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -J -h 192.168.237.77 -m 224.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -J -h 192.168.237.77 -m 240.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + comment: '' + execution time: 0.0 + expected result: '1. success + + 2. failed + + 3. failed + + 4. failed' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: '1. join group with correct host addr and multicast addr + + 2. join group with correct host addr and wrong multicast addr + + 3. join group with wrong host addr and correct multicast addr + + 4. join group with wrong host addr and wrong multicast addr' + sub module: IGMP + summary: station IGMP join group address check + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: IGMP API parameter check + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_UDP_0201 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -W -s -o 0 + - ['R SSC1 RE WORKTHREAD:\d+,OK'] + - - SOC SOC1 SENDTO 1472 + - [''] + - - SOC SOC1 SENDTO 1472 + - [''] + - - SOC SOC1 SENDTO 1472 + - [''] + - - SOC SOC1 SENDTO 1472 + - [''] + - - SOC SOC1 SENDTO 1472 + - [''] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.PC OK + + 5.PC OK + + 6.PC OK + + 7.PC OK + + 8.PC OK SOC_CLOSE=SOC1' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: '1.PC上SOC1 UDP传输,bing + + 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 3.target1上关闭工作线程 + + 4.PC往8266上发送1472字节数据 + + 5.PC往8266上发送1472字节数据 + + 6.PC往8266上发送1472字节数据 + + 7.PC往8266上发送1472字节数据 + + 8.PC往8266上发送1472字节数据' + sub module: UDP + summary: STA mode, recv buffer test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: use UDP SAP (socket/espconn API) in different state + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_ICMP_0101 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ping -i + - ['R SSC1 C +PING:OK'] + - - SSC SSC1 ping -i -c 2 + - ['R SSC1 C +PING:OK'] + comment: '' + execution time: 0.0 + expected result: '1.ok + + 2.ok' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: '1.ping -i + + 2.ping -i -c 2' + sub module: ICMP + summary: ping function test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: ping function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^WIFI_ADDR_0102 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 mac -S -o 2 -m 44:55:66:77:88:99 + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC1 ap -S -s -p -t + - [''] + - - SSC SSC2 sta -S -b 44:55:66:77:88:99 + - ['R SSC2 RE \+SCAN:.+,44:55:66:77:88:99,'] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC2 mac -Q -o 1 + - ['R SSC2 A :\+STAMAC:(.+)\r\n'] + - - SSC SSC2 mac -S -o 1 -m 22:33:44:55:66:77 + - ['R SSC2 C +MAC:STA,OK'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 ap -L + - ['R SSC1 C +LSTA:22:33:44:55:66:77'] + - - SSC SSC2 mac -S -o 1 -m + - ['R SSC2 C +MAC:STA,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.ok + + 3.ok + + 4.ok + + 5.ok + + 6.ok + + 7.ok + + 8.ok + + 9.ok' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: "1.target1 设置sta mode下的mac 44:55:66:77:88:99\n2.target1下设置ssid 和pwd 加密方式\n\ + 3.target2 查询mac为44:55:66:77:88:99的ssid\n4.target1 设置sta mode下的mac target_ap_mac\n\ + 5.target2 查询sta mode 下的mac 为target2_mac_tmp\n6.target2 设置sta mode 下的mac 为22:33:44:55:66:77\n\ + 7.target2 jap target1\n8.target1 查询连接到的sta \n9.target2 设置sta mode 下的mac 为 target2_mac" + sub module: MAC Address + summary: set mac and do scan/JAP/SAP + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: mac address function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0108 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -i 0.0.0.0 -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 C BIND:ERROR'] + - - SSC SSC1 soc -B -t TCP -p + - ['R SSC1 RE BIND:(\d+),OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.ERROR + + 4.OK' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + module: TCPIP + steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 2.target1上UDP传输,Bind socket2,本地ip 0.0.0.0 target_udp_port2 + + 3.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 4.target1上创建TCP socket3, target_udp_port1' + sub module: UDP + summary: AP mode, udp bind test. use different ip, port + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0109 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - WIFI CONN + + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC2 ip + - ['R SSC2 A :STAIP:(.+)\r\n'] + - - SSC SSC2 soc -B -t UDP -p + - ['R SSC2 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 5 + - [R SOC1 UL 5] + - - SSC SSC1 soc -S -s -i -p -l 5 + - ['R SSC2 RE "RECVFROM:%%s,5,%%s,%%u"%%(,,)'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.OK' + initial condition: T2O_1 + initial condition description (auto): same as T2_1 but will NOT autogen a TC with + initial condition T2_2 + module: TCPIP + steps: '1.PC上SOC1 UDP传输,bing + + 2.PC上SOC2 UDP传输,bing + + 3.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 4.target1上使用步骤3创建的socket1,往pc_ip,test_tcp_port1上发送10字节数据 + + 5.target1上使用步骤3创建的socket1,往pc_ip2,test_tcp_port2上发送10字节数据' + sub module: UDP + summary: AP mode, sendto test. use different ip, port + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0106 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + comment: '' + execution time: 0.0 + expected result: '1.ok + + 2.ok + + 3.ok + + 4.ok + + 5.ok' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 2.target1上UDP传输,Bind socket2,本地ip target_udp_port2 + + 3.target1上UDP传输,Bind socket3,本地ip target_udp_port3 + + 4.target1上UDP传输,Bind socket4,本地ip target_udp_port4 + + 5.target1上UDP传输,Bind socket5,本地ip target_udp_port5' + sub module: UDP + summary: STA mode, create max udp socket test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0107 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -I + - ['P SSC1 RE "SOCINFO:%%s,1,.+,%%d"%%(,)'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 2.target1上查询创建socket信息' + sub module: UDP + summary: STA mode, get active socket info test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0104 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SOC SOC1 SENDTO 1 + - [R SSC1 SL +1] + - - SOC SOC1 SENDTO 1472 + - ['R SSC1 RE "RECVFROM:%%s,1472,%%s,%%u"%%(,,)'] + - - SOC SOC1 SENDTO 1473 + - [P SSC1 NC +RECVFROM, P SOC_COM C OK] + - - SOC SOC2 BIND + - [R SOC_COM L OK] + - - SOC SOC2 SENDTO 1472 + - ['R SSC1 RE "RECVFROM:%%s,1472,%%s,%%u"%%(,,)'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.OK,没收到UDP包 + + 6.OK + + 7.OK' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: '1.PC上SOC1 UDP传输,bing + + 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 3.PC往8266上发送1字节数据 + + 4.PC往8266上发送1472字节数据 + + 5.PC往8266上发送1473字节数据 + + 6.PC上SOC2 UDP传输,bing + + 7.PC往8266上发送1472字节数据' + sub module: UDP + summary: STA mode, recvfrom basic test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0105 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 2.关闭socket1' + sub module: UDP + summary: STA mode, close UDP sockets test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0102 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SOC SOC2 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 10 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 10] + - - SSC SSC1 soc -S -s -i -p -l 10 + - ['P SSC1 RE SEND:(\d+),OK', P SOC2 UL 10] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.OK' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: '1.PC上SOC1 UDP传输,bing + + 2.PC上SOC2 UDP传输,bing + + 3.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 4.target1上使用步骤3创建的socket1,往pc_ip,test_tcp_port1上发送10字节数据 + + 5.target1上使用步骤3创建的socket1,往pc_ip2,test_tcp_port2上发送10字节数据' + sub module: UDP + summary: STA mode, sendto test. use different ip, port + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0103 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 1 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 1] + - - SSC SSC1 soc -S -s -i -p -l 1472 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 1472] + - - SSC SSC1 soc -S -s -i -p -l 1473 + - ['P SSC1 RE SEND:(\d+),OK', P SOC_COM NC SOC_RECVFROM] + - - SSC SSC1 soc -S -s -i -p -l 1472 -n 10 -j 20 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 14720] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.OK,没有到UDP包 + + 6.OK' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: '1.PC上SOC1 UDP传输,bing + + 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1字节数据 + + 4.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1472字节数据 + + 5.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1473字节数据 + + 6.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1472*10字节数据' + sub module: UDP + summary: STA mode, sendto test with different length + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0101 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -i 0.0.0.0 -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 C BIND:ERROR'] + - - SSC SSC1 soc -B -t TCP -p + - ['R SSC1 RE BIND:(\d+),OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.ERROR + + 4.OK' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 2.target1上UDP传输,Bind socket2,本地ip 0.0.0.0 target_udp_port2 + + 3.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 4.target1上创建TCP socket3, target_udp_port1' + sub module: UDP + summary: STA mode, udp bind test. use different ip, port + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_IGMP_0204 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 igmp -J -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 soc -B -t UDP -i 224.1.1.1 -p + - ['R SSC1 A :\+BIND:(\d+),OK'] + - - SSC SSC2 soc -B -t UDP -p + - ['R SSC2 A :\+BIND:(\d+),OK'] + - - SSC SSC2 soc -S -s -i 224.1.1.1 -p -l 10 + - [R SSC1 SL +1] + - - SSC SSC1 igmp -L -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. succeed + + 4. target1 recv multicast packet' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + module: TCPIP + steps: '1. target2 join SoftAP + + 2. target1 join group and create UDP socket using multicast addr + + 3. target2 create UDP socket + + 4. target2 send to multicast addr' + sub module: IGMP + summary: softAP send multicast packets + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: IGMP send/recv test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_IGMP_0201 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 igmp -J -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 soc -B -t UDP -i 224.1.1.1 -p + - ['R SSC1 A :\+BIND:(\d+),OK'] + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SOC SOC1 SENDTO 1 224.1.1.1 + - [R SSC1 SL +1] + - - SSC SSC1 igmp -L -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. able to recv packet' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: '1. join group + + 2. create UDP socket using multicast addr + + 3. PC send UDP packet to multicast addr' + sub module: IGMP + summary: station IGMP recv packets + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: IGMP send/recv test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_IGMP_0202 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC2 op -S -o 1 + - ['R SSC2 C +MODE:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 igmp -J -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 soc -B -t UDP -i 224.1.1.1 -p + - ['R SSC1 A :\+BIND:(\d+),OK'] + - - SSC SSC2 soc -B -t UDP -p + - ['R SSC2 A :\+BIND:(\d+),OK'] + - - SSC SSC2 soc -S -s -i 224.1.1.1 -p -l 10 + - [R SSC1 SL +1] + - - SSC SSC1 igmp -L -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. succeed + + 4. target1 recv multicast packet' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: '1. target2 set to sta mode and join AP + + 2. target1 join group and create UDP socket using multicast addr + + 3. target2 create UDP socket + + 4. target2 send to multicast addr' + sub module: IGMP + summary: station send multicast packets + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: IGMP send/recv test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_IGMP_0203 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 igmp -J -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 soc -B -t UDP -i 224.1.1.1 -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SOC SOC1 SENDTO 1 224.1.1.1 + - [R SSC1 SL +1] + - - SSC SSC1 igmp -L -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. able to recv packet' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + module: TCPIP + steps: '1. join group + + 2. create UDP socket using multicast addr + + 3. PC send UDP packet to multicast addr' + sub module: IGMP + summary: softAP IGMP recv packets + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: IGMP send/recv test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_CONN_0401 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -R -a 0 + - ['R SSC1 C +AUTORECONN:OK'] + - - SSC SSC1 sta -R -a 2 + - ['R SSC1 C +AUTORECONN:0'] + - - SSC SSC1 reboot + - [''] + - - DELAY 15 + - [''] + - - SSC SSC1 sta -Q + - ['R SSC1 C JAP:DISCONNECTED'] + - - SSC SSC1 sta -R -a 1 + - ['R SSC1 C +AUTORECONN:OK'] + - - SSC SSC1 sta -R -a 2 + - ['R SSC1 C +AUTORECONN:1'] + - - SSC SSC1 reboot + - ['R SSC1 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: '1.设置autoreconn,关闭 + + 2.查询当前autoreconn状态是否关闭 + + 3.重启系统,等待15s + + 4.查询target1 未自动重连AP + + 5.设置autoreconn,开启 + + 6.查询当前autoreconn状态是否开启 + + 7.系统重启后target1 自动重连AP' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: WIFI MAC + steps: '1.设置autoreconn,关闭 + + 2.查询当前autoreconn状态是否关闭 + + 3.重启系统,等待15s + + 4.查询target1 未自动重连AP + + 5.设置autoreconn,开启 + + 6.查询当前autoreconn状态是否开启 + + 7.系统重启后target1 自动重连AP' + sub module: WIFI Connect + summary: auto reconnect test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: power on auto reconnect test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0404 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SSC SSC1 op -S -o 2 + - ['P SSC1 C +MODE:OK', 'P SSC1 RE CLOSED:\d+,0'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.OK' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1上使用步骤2创建的socket1,去连接\ + \ PC的ip,test_tcp_port1\n4.PC与target1创建好TCP 连接,有ACCEPT\n5.修改8266的Mode为softAP mode\ + \ \n6.关闭建立的socket1连接" + sub module: TCP + summary: close TCP socket after mode changed + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: TCP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0406 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - NIC DISABLED + - [R PC_COM C OK] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.OK' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1上使用步骤2创建的socket1,去连接\ + \ PC的ip,test_tcp_port1\n4.PC与target1创建好TCP 连接,有ACCEPT\n5.PC上网卡禁止掉 \n6.关闭建立的socket1连接" + sub module: TCP + summary: close TCP socket after PC NIC disabled + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: TCP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0407 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SSC SSC1 dhcp -E -o 1 + - ['R SSC1 C +DHCP:STA,OK'] + - - SSC SSC1 ip -S -o 1 -i 192.168.111.210 + - ['P SSC1 C +IP:OK', 'P SSC1 RE CLOSED:\d+,0'] + - - SSC SSC1 ip -Q -o 1 + - ['R SSC1 C +STAIP:192.168.111.210'] + - - SSC SSC1 soc -S -s -l 5 + - ['P SSC1 RE SEND:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.OK + + 7.OK + + 8.ERROR' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1上使用步骤2创建的socket1,去连接\ + \ PC的ip,test_tcp_port1\n4.PC与target1创建好TCP 连接,有ACCEPT\n5.关闭8266的DHCP 1\n6.设置sta\ + \ ip \n7.查询sta ip 地址是否生效\n8.8266往PC上发送5字节数据" + sub module: TCP + summary: do TCP send after IP changed + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: TCP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0401 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SSC SSC1 sta -D + - ['P SSC1 C +QAP:OK', 'P SSC1 RE CLOSED:\d+,0'] + - - SSC SSC1 soc -S -s -l 5 + - ['P SSC1 RE SEND:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.ERROR' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket1 + + 3.target1上使用步骤2创建的socket1,去连接 PC的ip,test_tcp_port1 + + 4.PC与target1创建好TCP 连接,有ACCEPT + + 5.断开与AP 连接 + + 6.8266往PC上发送5字节数据' + sub module: TCP + summary: do TCP send after WIFI disconnected + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: TCP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0402 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SSC SSC1 sta -D + - ['P SSC1 C +QAP:OK', 'P SSC1 RE CLOSED:\d+,0'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.OK' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket1 + + 3.target1上使用步骤2创建的socket1,去连接 PC的ip,test_tcp_port1 + + 4.PC与target1创建好TCP 连接,有ACCEPT + + 5.断开与AP 连接 + + 6.关闭建立的socket1连接' + sub module: TCP + summary: "close TCP socket after WIFI \ndisconnected" + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: TCP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0403 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SSC SSC1 op -S -o 2 + - ['P SSC1 C +MODE:OK', 'P SSC1 RE CLOSED:\d+,0'] + - - SSC SSC1 soc -S -s -l 5 + - ['P SSC1 RE SEND:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.ERROR' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1上使用步骤2创建的socket1,去连接\ + \ PC的ip,test_tcp_port1\n4.PC与target1创建好TCP 连接,有ACCEPT\n5.修改8266的Mode为softAP mode\ + \ \n6.8266往PC上发送5字节数据" + sub module: TCP + summary: do TCP send after mode changed + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: TCP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0408 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SSC SSC1 dhcp -E -o 1 + - ['R SSC1 C +DHCP:STA,OK'] + - - SSC SSC1 ip -S -o 1 -i 192.168.111.210 + - ['P SSC1 C +IP:OK', 'P SSC1 RE CLOSED:\d+,0'] + - - SSC SSC1 ip -Q -o 1 + - ['R SSC1 C +STAIP:192.168.111.210'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.OK + + 7.OK + + 8.OK' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1上使用步骤2创建的socket1,去连接\ + \ PC的ip,test_tcp_port1\n4.PC与target1创建好TCP 连接,有ACCEPT\n5.关闭8266的DHCP 1\n6.设置sta\ + \ ip \n7.查询sta ip 地址是否生效\n8.关闭建立的socket1连接" + sub module: TCP + summary: close TCP socket after IP changed + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: TCP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0201 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -W -s -o 0 + - ['R SSC1 RE WORKTHREAD:\d+,OK'] + - - SOC SOC1 SENDTO 1472 + - [''] + - - SOC SOC1 SENDTO 1472 + - [''] + - - SOC SOC1 SENDTO 1472 + - [''] + - - SOC SOC1 SENDTO 1472 + - [''] + - - SOC SOC1 SENDTO 1472 + - [''] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.PC OK + + 5.PC OK + + 6.PC OK + + 7.PC OK + + 8.PC OK SOC_CLOSE=SOC1' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: '1.PC上SOC1 UDP传输,bing + + 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 3.target1上关闭工作线程 + + 4.PC往8266上发送1472字节数据 + + 5.PC往8266上发送1472字节数据 + + 6.PC往8266上发送1472字节数据 + + 7.PC往8266上发送1472字节数据 + + 8.PC往8266上发送1472字节数据' + sub module: UDP + summary: STA mode, recv buffer test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: use UDP SAP (socket/espconn API) in different state + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_UDP_0307 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 5 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] + - - SSC SSC1 dhcp -E -o 1 + - ['R SSC1 C +DHCP:STA,OK'] + - - SSC SSC1 ip -S -o 1 -i 192.168.111.210 + - ['P SSC1 C +IP:OK'] + - - SSC SSC1 ip -Q -o 1 + - ['R SSC1 C +STAIP:192.168.111.210'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.OK + + 7.OK' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: "1.PC上SOC1 UDP传输,bing \n2.target1上UDP传输,Bind socket1,本地ip\ + \ target_udp_port1\n3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据\n\ + 4.关闭8266的DHCP 1\n5.设置sta ip \n6.查询sta ip 地址是否生效\n7.关闭建立的socket1连接" + sub module: UDP + summary: close UDP socket after IP changed + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: UDP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_UDP_0306 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 5 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] + - - SSC SSC1 dhcp -E -o 1 + - ['R SSC1 C +DHCP:STA,OK'] + - - SSC SSC1 ip -S -o 1 -i 192.168.111.210 + - ['P SSC1 C +IP:OK'] + - - SSC SSC1 ip -Q -o 1 + - ['R SSC1 C +STAIP:192.168.111.210'] + - - SSC SSC1 soc -S -s -i -p -l 1 + - ['P SSC1 RE SEND:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.OK + + 7.OK' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: "1.PC上SOC1 UDP传输,bing \n2.target1上UDP传输,Bind socket1,本地ip\ + \ target_udp_port1\n3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据\n\ + 4.关闭8266的DHCP 1\n5.设置sta ip \n6.查询sta ip 地址是否生效\n7.8266往PC上发送5字节数据" + sub module: UDP + summary: do UDP send after IP changed + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: UDP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_UDP_0305 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 5 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] + - - NIC DISABLED + - [R PC_COM C OK] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.OK' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: "1.PC上SOC1 UDP传输,bing \n2.target1上UDP传输,Bind socket1,本地ip\ + \ target_udp_port1\n3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据\n\ + 4.PC上网卡禁止掉 \n5.关闭建立的socket1连接" + sub module: UDP + summary: close UDP socket after PC NIC disabled + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: UDP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_UDP_0304 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 5 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] + - - SSC SSC1 op -S -o 2 + - ['P SSC1 C +MODE:OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.OK' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: "1.PC上SOC1 UDP传输,bing \n2.target1上UDP传输,Bind socket1,本地ip\ + \ target_udp_port1\n3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据\n\ + 4.修改8266的Mode为softAP mode \n5.关闭建立的socket1连接" + sub module: UDP + summary: close UDP socket after mode changed + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: UDP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^WIFI_CONN_0103 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t -h + 0 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -S -h 0 + - [R SSC2 P , R SSC2 C +SCANDONE] + - - SSC SSC1 ap -S -s -p -t -h + 1 + - ['R SSC1 C +SAP:OK'] + - - DELAY 3 + - [''] + - - SSC SSC2 sta -S -h 0 + - [R SSC2 C +SCANDONE] + - - DELAY 3 + - [''] + - - SSC SSC2 sta -S -h 0 + - [R SSC2 NP C +SCANDONE] + comment: '' + execution time: 0.0 + expected result: '1.target1 set AP,set ssid broad cast + + 2.target 2上scan target_ap_mac + + 3.target1 set AP,set ssid hidden, + + 4.target 2上不能scan target_ap_mac' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. target1下设置ssid 和pwd 加密方式,set ssid broad cast + + 2.target 2上scan target_ap_mac + + 3. target1下设置ssid 和pwd 加密方式,set ssid hidden, + + 4.target 2上scan target_ap_mac' + sub module: WIFI Connect + summary: station SAP+JAP test, ssid hidden + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: SAP/JAP with different config + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0101 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [SOCR SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP -i 0.0.0.0 -p 0 + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,OK', P SOC1 C +ACCEPT] + - - SSC SSC1 soc -B -t TCP -i 0.0.0.0 -p 0 + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i 123.456.678.789 -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.ERROR + + 6.ERROR' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket,bind到本地ip 0.0.0.0,本地端口 0 + + 3.target1上使用步骤2创建的socket,去连接 PC的ip,test_tcp_port1 + + 4.target1上创建TCP socket,bind到本地ip 0.0.0.0,本地端口 0 + + 5.target1上使用步骤4创建的socket,去连接不存在的ip,test_tcp_port1 + + 6.target1上使用步骤2创建的socket,去连接 PC的ip,远端端口不存在。' + sub module: TCP + summary: STA mode, connect test. use different ip, port + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0103 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SOC SOC2 SEND 5 + - [R SSC1 SL +5] + - - SSC SSC1 soc -S -s -l 5 + - ['P SSC1 RE SEND:\d+,OK', P SOC2 RL 5] + - - SOC SOC2 SEND 146000 + - [R SSC1 SL +146000] + - - SSC SSC1 soc -S -s -l 1460 -n 100 + - ['P SSC1 RE SEND:\d+,OK', P SOC2 RL 146000] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK,pc上回accept + + 4.OK + + 5.target收到5 byte + + 6.PC收到5 byte + + 7.target收到 146000 byte + + 8.OK,PC 回SOC_RECV=SOC2,RECV_LEN=字节数' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: '1. PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket + + 3.target1上使用步骤2创建的socket,去连接 PC的ip,test_tcp_port1 + + 4.PC与target1 创建好TCP 连接,有ACCEPT + + 5.PC send 5 bytes to 8266 + + 6.8266 send 5 bytes to PC + + 7. PC send 100 * 1460 data to 8266, + + 8.8266 send 100 * 1460 to PC.' + sub module: TCP + summary: STA mode, send/recv basic test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0102 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -B -t TCP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,OK'] + - - SOC SOC1 CONNECT + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+', P SOC_COM C OK] + - - SOC SOC1 CONNECT + - [P SOC_COM C ERROR, P SSC1 NC ACCEPT] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.PC TCP client accept + + 4.error' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: '1.target1上创建TCP socket,bind到本地端口 + + 2.target1上使用步骤1创建的socket,创建TCP 监听 + + 3.PC TCP 连接到target1 , + + 4.PC tcp 连接到不存在的port ,' + sub module: TCP + summary: STA mode, server listen test. use different kinds of port + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0105 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + - - SSC SSC1 soc -B -t TCP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,OK'] + - - SOC SOC2 CONNECT + - ['R SSC1 A :ACCEPT:(\d+),\d+,.+,\d+'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.OK + + 6.OK + + 7.target1关闭socket1 + + 8.target1关闭socket2 + + 9.OK + + 10.OK,pc tcp server accept成功 + + 11.target1关闭socket1 + + 12.OK + + 13.OK,pc tcp server accept成功 + + 14.OK + + 15.target1关闭socket1' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1关闭socket1\n\ + 4.target1上创建TCP socket 端口随机\n5.target1上使用步骤4创建的socket1,去监听\n6.PC CONNECT,\ + \ ,tcp 连接创建成功,创建socket2 \n7.target1关闭socket1\n8.target1关闭socket2\n\ + 9.target1上创建TCP socket1\n10.target1上使用步骤10创建的socket1,去连接 PC的ip,test_tcp_port1,PC有ACCEPT\n\ + 11.target1关闭socket1\n12.target1上创建TCP socket1\n13.target1上使用步骤13创建的socket1,去连接\ + \ PC的ip,test_tcp_port1,PC有ACCEPT\n14.target1shutdown socket1\n15.target1关闭socket1" + sub module: TCP + summary: STA mode, close for different types of TCP sockets test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0104 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s -h B + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s -h W + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s -h R + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK,pc tcp server accept OK + + 4.OK + + 5.OK + + 6.OK,pc tcp server accept OK + + 7.OK + + 8.OK + + 9.OK,pc tcp server accept OK + + 10.OK' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: '1. PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket + + 3.target1上使用步骤2创建的socket,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 4.target1 shutdown socket1 B + + 5.target1上创建TCP socket + + 6.target1上使用步骤5创建的socket,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 7.target1 shutdown socket2 W + + 8.target1上创建TCP socket + + 9.target1上使用步骤8创建的socket,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 10.target1 shutdown socket3 R' + sub module: TCP + summary: STA mode, shutdown basic test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0107 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -B -t TCP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,OK'] + - - SOC SOC2 CONNECT + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] + - - SOC SOC3 CONNECT + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] + - - SOC SOC4 CONNECT + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] + - - SOC SOC5 CONNECT + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] + - - SOC SOC6 CONNECT + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] + comment: '' + execution time: 0.0 + expected result: '1.+BIND:0,OK,0.0.0.0 + + 2.OK + + 3.OK,pc tcp server accept成功 + + 4.OK,pc tcp server accept成功 + + 5.OK,pc tcp server accept成功 + + 6.OK,pc tcp server accept成功 + + 7.OK,pc tcp server accept成功' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: "1.target1上创建TCP socket 端口随机\n2.target1上使用步骤4创建的socket1,去监听\n3.PC CONNECT,\ + \ ,tcp 连接创建成功,创建socket2 \n4.PC CONNECT, ,tcp 连接创建成功,创建socket3\ + \ \n5.PC CONNECT, ,tcp 连接创建成功,创建socket4 \n6.PC CONNECT,\ + \ ,tcp 连接创建成功,创建socket5 \n7.PC CONNECT, ,tcp 连接创建成功,创建socket6" + sub module: TCP + summary: STA mode, accept max TCP client by server test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0106 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK,pc tcp server accept成功 + + 4 OK + + 5.OK,pc tcp server accept成功 + + 6.OK + + 7.OK,pc tcp server accept成功 + + 8 OK + + 9.OK,pc tcp server accept成功 + + 10.OK + + 11.OK,pc tcp server accept成功' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket1 + + 3.target1上使用步骤2创建的socket1,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 4.target1上创建TCP socket2 + + 5.target1上使用步骤4创建的socket2,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 6.target1上创建TCP socket3 + + 7.target1上使用步骤6创建的socket3,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 8.target1上创建TCP socket4 + + 9.target1上使用步骤8创建的socket4,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 10.target1上创建TCP socket5 + + 11.target1上使用步骤10创建的socket5,去连接 PC的ip,test_tcp_port1,PC有ACCEPT' + sub module: TCP + summary: STA mode, create max TCP sockets test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_DHCP_0210 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - WIFI CONN2 192.168.4.2 + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - SSC SSC1 ap -L + - [R SSC1 C 192.168.4.2 C 192.168.4.3 P P ] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. succeed + + 4. succeed + + 5. find target2 and PC' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: TCPIP + steps: '1. config softap to a random ssid + + 2. target2 connect to target1 softap + + 3. disable DHCP server, do config and enable + + 4. PC NIC connect to target1 softap try to renew IP 192.168.4.2 + + 5. softap list connected station' + sub module: DHCP + summary: dhcp server reconfig, old client able to get IP (discover with requested + IP) + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_DHCP_0211 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - WIFI CONN 192.168.4.2 + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - DELAY 10 + - [''] + - - SSC SSC1 ap -L + - [R SSC1 C 192.168.4.2 C 192.168.4.3 P P ] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. succeed + + 4. succeed + + 5. find target2 and PC' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: TCPIP + steps: '1. config softap to a random ssid + + 2. target2 connect to target1 softap + + 3. disable DHCP server, do config and enable + + 4. PC NIC connect to target1 softap try to renew IP 192.168.4.2 + + 5. softap list connected station' + sub module: DHCP + summary: dhcp server reconfig, old client able to renew IP (direct send request) + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0212 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP -i + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -B -t TCP -i + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -B -t TCP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,OK'] + - - SOC SOC2 CONNECT 0 + - ['R SSC1 A :ACCEPT:(\d+),\d+,.+,\d+'] + - - SSC SSC1 soc -I + - ['P SSC1 RE "SOCINFO:%%s,2,%%s,\d+,%%s,%%d"%%(,,,)', + 'P SSC1 RE "SOCINFO:%%s,2,.+,\d+,.+,\d+"%%()', 'P SSC1 RE "SOCINFO:%%s,82,.+,%%d,.+,\d+"%%(,)', + 'P SSC1 RE "SOCINFO:%%s,2,%%s,%%d,%%s,\d+"%%(,,,)'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK,pc tcp server accept成功 + + 4.OK + + 5.OK + + 6.OK + + 7.OK + + 8.OK + + 9.PC OK, target1 +ACCEPT:3,2,,port + + 10.+SOCINFO:,,, + + +SOCINFO:,,, + + +SOCINFO:, + + +SOCINFO:,,, + + +SOCINF0ALL' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + module: TCPIP + steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1,本地ip target_ip\n3.target1上使用步骤2创建的socket1,去连接\ + \ PC的ip,test_tcp_port1,PC有ACCEPT\n4.target1上创建TCP socket2,本地ip target_ip\n5.target1上使用步骤4创建的socket2,去连接\ + \ PC的ip,test_tcp_port1,PC有ACCEPT\n6.target1 shutdown socket2 \n7.target1上创建TCP\ + \ socket3,本地端口random_port\n8.target1上使用步骤7创建的socket3,去监听\n9.PC CONNECT,\ + \ ,tcp 连接创建成功,创建socket4 \n10.target1 查询the socket information" + sub module: TCP + summary: AP mode, get active socket info test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) in different state + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0210 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SSC SSC1 soc -W -s -o 0 + - ['R SSC1 RE WORKTHREAD:\d+,OK'] + - - SOC SOC2 SEND 146000 + - [P SOC_COM R *] + - - SSC SSC1 soc -W -s -o 1 + - ['P SSC1 RE WORKTHREAD:\d+,OK', P SSC1 SL +2920] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK,pc tcp server accept成功 + + 4.OK + + 6.OK + + 7.收到 146000 数据 + + ' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + module: TCPIP + steps: '1. PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket + + 3.target1上使用步骤2创建的socket,去连接 PC的ip,test_tcp_port1 + + 4.PC与target1 创建好TCP 连接,有ACCEPT + + 5.target停止调用recv + + 6.PC send 100 * 1460 data to 8266, + + 7.target重新调用recv' + sub module: TCP + summary: AP mode, recv buffer test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) in different state + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0210 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SSC SSC1 soc -W -s -o 0 + - ['R SSC1 RE WORKTHREAD:\d+,OK'] + - - SOC SOC2 SEND 146000 + - [P SOC_COM R *] + - - SSC SSC1 soc -W -s -o 1 + - ['P SSC1 RE WORKTHREAD:\d+,OK', P SSC1 SL +2920] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK,pc tcp server accept成功 + + 4.OK + + 6.OK + + 7.收到 146000 数据' + initial condition: APSTA2 + initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen + by APM2) + module: TCPIP + steps: '1. PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket + + 3.target1上使用步骤2创建的socket,去连接 PC的ip,test_tcp_port1 + + 4.PC与target1 创建好TCP 连接,有ACCEPT + + 5.target停止调用recv + + 6.PC send 100 * 1460 data to 8266, + + 7.target重新调用recv' + sub module: TCP + summary: AP mode, recv buffer test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) in different state + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0212 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP -i + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -B -t TCP -i + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -B -t TCP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,OK'] + - - SOC SOC2 CONNECT 0 + - ['R SSC1 A :ACCEPT:(\d+),\d+,.+,\d+'] + - - SSC SSC1 soc -I + - ['P SSC1 RE "SOCINFO:%%s,2,%%s,\d+,%%s,%%d"%%(,,,)', + 'P SSC1 RE "SOCINFO:%%s,2,.+,\d+,.+,\d+"%%()', 'P SSC1 RE "SOCINFO:%%s,82,.+,%%d,.+,\d+"%%(,)', + 'P SSC1 RE "SOCINFO:%%s,2,%%s,%%d,%%s,\d+"%%(,,,)'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK,pc tcp server accept成功 + + 4.OK + + 5.OK + + 6.OK + + 7.OK + + 8.OK + + 9.PC OK, target1 +ACCEPT:3,2,,port + + 10.+SOCINFO:,,, + + +SOCINFO:,,, + + +SOCINFO:, + + +SOCINFO:,,, + + +SOCINF0ALL' + initial condition: APSTA2 + initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen + by APM2) + module: TCPIP + steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1,本地ip target_ip\n3.target1上使用步骤2创建的socket1,去连接\ + \ PC的ip,test_tcp_port1,PC有ACCEPT\n4.target1上创建TCP socket2,本地ip target_ip\n5.target1上使用步骤4创建的socket2,去连接\ + \ PC的ip,test_tcp_port1,PC有ACCEPT\n6.target1 shutdown socket2 \n7.target1上创建TCP\ + \ socket3,本地端口random_port\n8.target1上使用步骤7创建的socket3,去监听\n9.PC CONNECT,\ + \ ,tcp 连接创建成功,创建socket4 \n10.target1 查询the socket information" + sub module: TCP + summary: AP mode, get active socket info test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) in different state + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_DHCP_0211 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - WIFI CONN 192.168.4.2 + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - DELAY 10 + - [''] + - - SSC SSC1 ap -L + - [R SSC1 C 192.168.4.2 C 192.168.4.3 P P ] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. succeed + + 4. succeed + + 5. find target2 and PC' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + module: TCPIP + steps: '1. config softap to a random ssid + + 2. target2 connect to target1 softap + + 3. disable DHCP server, do config and enable + + 4. PC NIC connect to target1 softap try to renew IP 192.168.4.2 + + 5. softap list connected station' + sub module: DHCP + summary: dhcp server reconfig, old client able to renew IP (direct send request) + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_DHCP_0210 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - WIFI CONN2 192.168.4.2 + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - SSC SSC1 ap -L + - [R SSC1 C 192.168.4.2 C 192.168.4.3 P P ] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. succeed + + 4. succeed + + 5. find target2 and PC' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + module: TCPIP + steps: '1. config softap to a random ssid + + 2. target2 connect to target1 softap + + 3. disable DHCP server, do config and enable + + 4. PC NIC connect to target1 softap try to renew IP 192.168.4.2 + + 5. softap list connected station' + sub module: DHCP + summary: dhcp server reconfig, old client able to get IP (discover with requested + IP) + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_ADDR_0101 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 mac -S -o 1 -m 44:55:66:77:88:99 + - ['R SSC1 C +MAC:STA,OK'] + - - SSC SSC1 mac -S -o 2 -m 22:33:44:55:66:77 + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC1 mac -Q -o 3 + - ['R SSC1 C +STAMAC:44:55:66:77:88:99 C +APMAC:22:33:44:55:66:77'] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.ok + + 3.ok + + 4.ok + + 5.ok + + 6.ok' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + module: WIFI MAC + steps: "1.target1 设置mode 为sta+softAP mode\n2.target1 设置sta mode 下的mac \n3.target1\ + \ 设置softAP mode 下的mac\n4.target1 查询softAP+sta 下的mac\n5.target1 设置sta mode 下的mac\ + \ 为target1_mac\n6.target1 设置softAP mode 下的mac 为target1_ap_mac\n" + sub module: MAC Address + summary: set mac, query mac + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: mac address function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_ADDR_0102 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 mac -S -o 2 -m 44:55:66:77:88:99 + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC1 ap -S -s -p -t + - [''] + - - SSC SSC2 sta -S -b 44:55:66:77:88:99 + - ['R SSC2 RE \+SCAN:.+,44:55:66:77:88:99,'] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC2 mac -Q -o 1 + - ['R SSC2 A :\+STAMAC:(.+)\r\n'] + - - SSC SSC2 mac -S -o 1 -m 22:33:44:55:66:77 + - ['R SSC2 C +MAC:STA,OK'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 ap -L + - ['R SSC1 C +LSTA:22:33:44:55:66:77'] + - - SSC SSC2 mac -S -o 1 -m + - ['R SSC2 C +MAC:STA,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.ok + + 3.ok + + 4.ok + + 5.ok + + 6.ok + + 7.ok + + 8.ok + + 9.ok' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + module: WIFI MAC + steps: "1.target1 设置sta mode下的mac 44:55:66:77:88:99\n2.target1下设置ssid 和pwd 加密方式\n\ + 3.target2 查询mac为44:55:66:77:88:99的ssid\n4.target1 设置sta mode下的mac target_ap_mac\n\ + 5.target2 查询sta mode 下的mac 为target2_mac_tmp\n6.target2 设置sta mode 下的mac 为22:33:44:55:66:77\n\ + 7.target2 jap target1\n8.target1 查询连接到的sta \n9.target2 设置sta mode 下的mac 为 target2_mac\n" + sub module: MAC Address + summary: set mac and do scan/JAP/SAP + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: mac address function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0202 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -W -s -o 0 + - ['R SSC1 RE WORKTHREAD:\d+,OK'] + - - SOC SOC1 SENDTO 1472 + - [''] + - - SOC SOC1 SENDTO 1472 + - [''] + - - SOC SOC1 SENDTO 1472 + - [''] + - - SOC SOC1 SENDTO 1472 + - [''] + - - SOC SOC1 SENDTO 1472 + - [''] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.PC OK + + 5.PC OK + + 6.PC OK + + 7.PC OK + + 8.PC OK SOC_CLOSE=SOC1' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + module: TCPIP + steps: '1.PC上SOC1 UDP传输,bing + + 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 3.target1上关闭工作线程 + + 4.PC往8266上发送1472字节数据 + + 5.PC往8266上发送1472字节数据 + + 6.PC往8266上发送1472字节数据 + + 7.PC往8266上发送1472字节数据 + + 8.PC往8266上发送1472字节数据' + sub module: UDP + summary: AP mode, recv buffer test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: use UDP SAP (socket/espconn API) in different state + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0411 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -l 5 + - ['P SSC1 RE SEND:\d+,ERROR'] + - - SSC SSC1 soc -S -s -l 5 + - ['P SSC1 RE SEND:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.ERROR + + 7.OK' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket1 + + 3.target1上使用步骤2创建的socket1,去连接 PC的ip,test_tcp_port1 + + 4.PC与target1创建好TCP 连接,有ACCEPT + + 5.target1上创建TCP socket2 + + 6.8266往PC socket2上发送5字节数据 + + 7.8266往PC socket1上发送5字节数据' + sub module: TCP + summary: do TCP send after socket changed + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: TCP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_CONN_0301 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t -h + 0 -m 8 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 ap -Q + - ['R SSC1 RE "\+APCONFIG:%%s,%%s,\d+,3,0,8,\d+"%%(,)'] + comment: '' + execution time: 0.0 + expected result: '1. target1 set AP + + 2.target 1上查询到跟设置AP时一致 + + ' + initial condition: APM1 + initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial + condition APSTA1 + module: WIFI MAC + steps: '1. target1 set AP + + 2.target 1上查询到跟设置AP时一致 + + ' + sub module: WIFI Connect + summary: AP config query test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: query AP config + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_IP_0102 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 ip -S -o 2 -i 192.168.123.123 + - ['R SSC1 C +IP:ERROR'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 ip -S -o 2 -i 192.168.123.123 + - ['R SSC1 C +IP:OK'] + - - SSC SSC1 ip -Q -o 2 + - ['R SSC1 C +APIP:192.168.123.123'] + - - SSC SSC1 ip -S -o 2 -i + - ['R SSC1 C +IP:OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.ERROR + + 3.OK + + 4.OK + + 5.APIP:192.168.123.123 + + 6.OK' + initial condition: APSTA1 + initial condition description (auto): testing ap on sta + ap mode (autogen by APM1) + module: TCPIP + steps: "1.target1 打开DHCP 2\n2.target1 设置softAP ip 192.168.123.123\n4.target1 关闭DHCP\ + \ 2\n5.target1 设置softAP ip 192.168.123.123\n6.target1 查询 当前sta ip \n7.target1\ + \ 设置softAP ip 为target_ap_ip" + sub module: IP + summary: ap set and query static ip test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: set and query static IP + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_UDP_0105 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 2.关闭socket1' + sub module: UDP + summary: STA mode, close UDP sockets test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_UDP_0104 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SOC SOC1 SENDTO 1 + - [R SSC1 SL +1] + - - SOC SOC1 SENDTO 1472 + - ['R SSC1 RE "RECVFROM:%%s,1472,%%s,%%u"%%(,,)'] + - - SOC SOC1 SENDTO 1473 + - [P SSC1 NC +RECVFROM, P SOC_COM C OK] + - - SOC SOC2 BIND + - [R SOC_COM L OK] + - - SOC SOC2 SENDTO 1472 + - ['R SSC1 RE "RECVFROM:%%s,1472,%%s,%%u"%%(,,)'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.OK,没收到UDP包 + + 6.OK + + 7.OK' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: '1.PC上SOC1 UDP传输,bing + + 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 3.PC往8266上发送1字节数据 + + 4.PC往8266上发送1472字节数据 + + 5.PC往8266上发送1473字节数据 + + 6.PC上SOC2 UDP传输,bing + + 7.PC往8266上发送1472字节数据' + sub module: UDP + summary: STA mode, recvfrom basic test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_UDP_0107 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -I + - ['P SSC1 RE "SOCINFO:%%s,1,.+,%%d"%%(,)'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 2.target1上查询创建socket信息' + sub module: UDP + summary: STA mode, get active socket info test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_UDP_0106 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + comment: '' + execution time: 0.0 + expected result: '1.ok + + 2.ok + + 3.ok + + 4.ok + + 5.ok' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 2.target1上UDP传输,Bind socket2,本地ip target_udp_port2 + + 3.target1上UDP传输,Bind socket3,本地ip target_udp_port3 + + 4.target1上UDP传输,Bind socket4,本地ip target_udp_port4 + + 5.target1上UDP传输,Bind socket5,本地ip target_udp_port5' + sub module: UDP + summary: STA mode, create max udp socket test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_UDP_0101 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -i 0.0.0.0 -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 C BIND:ERROR'] + - - SSC SSC1 soc -B -t TCP -p + - ['R SSC1 RE BIND:(\d+),OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.ERROR + + 4.OK' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 2.target1上UDP传输,Bind socket2,本地ip 0.0.0.0 target_udp_port2 + + 3.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 4.target1上创建TCP socket3, target_udp_port1' + sub module: UDP + summary: STA mode, udp bind test. use different ip, port + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_UDP_0103 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 1 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 1] + - - SSC SSC1 soc -S -s -i -p -l 1472 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 1472] + - - SSC SSC1 soc -S -s -i -p -l 1473 + - ['P SSC1 RE SEND:(\d+),OK', P SOC_COM NC SOC_RECVFROM] + - - SSC SSC1 soc -S -s -i -p -l 1472 -n 10 -j 20 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 14720] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.OK,没有到UDP包 + + 6.OK' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: '1.PC上SOC1 UDP传输,bing + + 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1字节数据 + + 4.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1472字节数据 + + 5.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1473字节数据 + + 6.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1472*10字节数据' + sub module: UDP + summary: STA mode, sendto test with different length + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_UDP_0102 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SOC SOC2 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 10 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 10] + - - SSC SSC1 soc -S -s -i -p -l 10 + - ['P SSC1 RE SEND:(\d+),OK', P SOC2 UL 10] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.OK' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: '1.PC上SOC1 UDP传输,bing + + 2.PC上SOC2 UDP传输,bing + + 3.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 4.target1上使用步骤3创建的socket1,往pc_ip,test_tcp_port1上发送10字节数据 + + 5.target1上使用步骤3创建的socket1,往pc_ip2,test_tcp_port2上发送10字节数据' + sub module: UDP + summary: STA mode, sendto test. use different ip, port + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_DHCP_0102 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC2 sta -C -s -p + - [''] + - - DELAY 20 + - [P PC_COM C +DELAYDONE, 'P SSC2 NC +JAP:CONNECTED'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: "1.target1 set AP OK \n2.target1 关闭DHCP OK\n3.target2 jap target\ + \ 1,FAIL \n4.target1 打开DHCP OK\n5.target2 jap target 1,ok" + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: TCPIP + steps: "1.target1 set AP OK \n2.target1 关闭DHCP OK\n3.target2 jap target 1,FAIL \n\ + 4.target1 打开DHCP OK\n5.target2 jap target 1,ok" + sub module: DHCP + summary: dhcp server function test + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP client function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_DHCP_0103 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 3 + - ['R SSC1 C +DHCP:AP,OK C +DHCP:STA,OK'] + - - SSC SSC1 dhcp -Q -o 3 + - ['R SSC1 C +DHCP:STA,STARTED C +DHCP:AP,STARTED'] + - - SSC SSC1 dhcp -Q -o 1 + - ['R SSC1 C +DHCP:STA,STARTED NC +DHCP:AP,STARTED'] + - - SSC SSC1 dhcp -Q -o 2 + - ['R SSC1 NC +DHCP:STA,STARTED C +DHCP:AP,STARTED'] + - - SSC SSC1 dhcp -E -o 3 + - ['R SSC1 C +DHCP:AP,OK C +DHCP:STA,OK'] + - - SSC SSC1 dhcp -Q -o 3 + - ['R SSC1 C +DHCP:STA,STOPPED C +DHCP:AP,STOPPED'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.STA&AP STARTED + + 4.STA STARTED + + 5.AP STARTED + + 6.OK + + 7.STA&AP STOPPED' + initial condition: STAAP1 + initial condition description (auto): testing sta on sta + ap mode, quit AP (autogen + by STAM1) + module: TCPIP + steps: '1.target1 设置mode 为sta+softAP mode + + 2.target1 打开DHCP 3 + + 3.target1 查询DHCP 状态 + + 4.target1 查询sta DHCP 状态 + + 5.target1 查询softAP DHCP 状态 + + 6.target1 关闭 DHCP 3 + + 7.target1 查询 DHCP 状态' + sub module: DHCP + summary: dhcp status query + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP client function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^WIFI_CONN_0801 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 0 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 ap -S -s -p -t 2 + - ['P SSC1 C +SAP:OK', 'P SSC2 C +JAP:AUTHCHANGED,2,0'] + - - SSC SSC1 ap -S -s -p -t 3 + - ['P SSC1 C +SAP:OK', 'P SSC2 C +JAP:AUTHCHANGED,3,2'] + - - SSC SSC1 ap -S -s -p -t 4 + - ['P SSC1 C +SAP:OK', 'P SSC2 C +JAP:AUTHCHANGED,4,3'] + - - SSC SSC1 ap -S -s -p -t 0 + - ['P SSC1 C +SAP:OK', 'P SSC2 C +JAP:AUTHCHANGED,0,4'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. auth change event old mode 0 new mode 2 + + 4. auth change event old mode 2 new mode 3 + + 5. auth change event old mode 3 new mode 4 + + 6. auth change event old mode 4 new mode 0' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. set target1 softap auth mode 0 + + 2. target2 connect to target1 + + 3. set target1 softap auth mode 2, wait sta connected + + 4. set target1 softap auth mode 3, wait sta connected + + 5. set target1 softap auth mode 4, wait sta connected + + 6. set target1 softap auth mode 0, wait sta connected' + sub module: WIFI Connect + summary: test auth change event + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: wifi auth changed event test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_UDP_0108 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -i 0.0.0.0 -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 C BIND:ERROR'] + - - SSC SSC1 soc -B -t TCP -p + - ['R SSC1 RE BIND:(\d+),OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.ERROR + + 4.OK' + initial condition: APSTA2 + initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen + by APM2) + module: TCPIP + steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 2.target1上UDP传输,Bind socket2,本地ip 0.0.0.0 target_udp_port2 + + 3.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 4.target1上创建TCP socket3, target_udp_port1' + sub module: UDP + summary: AP mode, udp bind test. use different ip, port + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_CONN_0104 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t -m + 1 + - ['R SSC1 C +SAP:OK'] + - - WIFI DISCONN + - ['R PC_COM C +WIFIDISCONN:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] + - - WIFI CONN + + - ['R PC_COM C +WIFICONN:ERROR'] + comment: '' + execution time: 0.0 + expected result: '1. target1 set AP,set max allowed sta as 1 + + 2. use PC disconnect, + + 3.target 2 jap succeed + + 4.PC WIFI can not CONN' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + module: WIFI MAC + steps: '1.target1下设置ssid 和pwd 加密方式,set max allowed sta as 1 + + 2.use PC disconnect target1 + + 3.target 2 jap target1 + + 4.PC WIFI CONNECT target1' + sub module: WIFI Connect + summary: station SAP test, max allowed sta + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: SAP/JAP with different config + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_IGMP_0201 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 igmp -J -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 soc -B -t UDP -i 224.1.1.1 -p + - ['R SSC1 A :\+BIND:(\d+),OK'] + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SOC SOC1 SENDTO 1 224.1.1.1 + - [R SSC1 SL +1] + - - SSC SSC1 igmp -L -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. able to recv packet' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: '1. join group + + 2. create UDP socket using multicast addr + + 3. PC send UDP packet to multicast addr' + sub module: IGMP + summary: station IGMP recv packets + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: IGMP send/recv test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_IGMP_0203 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 igmp -J -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 soc -B -t UDP -i 224.1.1.1 -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SOC SOC1 SENDTO 1 224.1.1.1 + - [R SSC1 SL +1] + - - SSC SSC1 igmp -L -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. able to recv packet' + initial condition: APSTA2 + initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen + by APM2) + module: TCPIP + steps: '1. join group + + 2. create UDP socket using multicast addr + + 3. PC send UDP packet to multicast addr' + sub module: IGMP + summary: softAP IGMP recv packets + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: IGMP send/recv test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_IGMP_0202 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC2 op -S -o 1 + - ['R SSC2 C +MODE:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 igmp -J -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 soc -B -t UDP -i 224.1.1.1 -p + - ['R SSC1 A :\+BIND:(\d+),OK'] + - - SSC SSC2 soc -B -t UDP -p + - ['R SSC2 A :\+BIND:(\d+),OK'] + - - SSC SSC2 soc -S -s -i 224.1.1.1 -p -l 10 + - [R SSC1 SL +1] + - - SSC SSC1 igmp -L -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. succeed + + 4. target1 recv multicast packet' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: '1. target2 set to sta mode and join AP + + 2. target1 join group and create UDP socket using multicast addr + + 3. target2 create UDP socket + + 4. target2 send to multicast addr' + sub module: IGMP + summary: station send multicast packets + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: IGMP send/recv test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_IGMP_0204 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 igmp -J -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 soc -B -t UDP -i 224.1.1.1 -p + - ['R SSC1 A :\+BIND:(\d+),OK'] + - - SSC SSC2 soc -B -t UDP -p + - ['R SSC2 A :\+BIND:(\d+),OK'] + - - SSC SSC2 soc -S -s -i 224.1.1.1 -p -l 10 + - [R SSC1 SL +1] + - - SSC SSC1 igmp -L -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. succeed + + 4. target1 recv multicast packet' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: TCPIP + steps: '1. target2 join SoftAP + + 2. target1 join group and create UDP socket using multicast addr + + 3. target2 create UDP socket + + 4. target2 send to multicast addr' + sub module: IGMP + summary: softAP send multicast packets + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: IGMP send/recv test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^WIFI_CONN_0301 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t -h + 0 -m 8 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 ap -Q + - ['R SSC1 RE "\+APCONFIG:%%s,%%s,\d+,3,0,8,\d+"%%(,)'] + comment: '' + execution time: 0.0 + expected result: '1. target1 set AP + + 2.target 1上查询到跟设置AP时一致' + initial condition: APSTA1 + initial condition description (auto): testing ap on sta + ap mode (autogen by APM1) + module: WIFI MAC + steps: '1. target1 set AP + + 2.target 1上查询到跟设置AP时一致' + sub module: WIFI Connect + summary: AP config query test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: query AP config + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0114 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -I + - ['P SSC1 RE "SOCINFO:%%s,1,.+,%%d"%%(,)'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + module: TCPIP + steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 2.target1上查询创建socket信息' + sub module: UDP + summary: AP mode, get active socket info test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0111 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - WIFI CONN + + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC2 ip + - ['R SSC2 A :STAIP:(.+)\r\n'] + - - SSC SSC2 soc -B -t UDP -p + - ['R SSC2 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SOC SOC1 SENDTO 5 + - ['R SSC1 RE "RECVFROM:%%s,5,%%s,%%u"%%(,,)'] + - - SSC SSC2 soc -S -s -i -p -l 5 + - ['R SSC1 RE "RECVFROM:%%s,5,%%s,%%u"%%(,,)'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.OK,没收到UDP包 + + 6.OK + + 7.OK' + initial condition: T2O_1 + initial condition description (auto): same as T2_1 but will NOT autogen a TC with + initial condition T2_2 + module: TCPIP + steps: '1.PC上SOC1 UDP传输,bing + + 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 3.PC往8266上发送1字节数据 + + 4.PC往8266上发送1472字节数据 + + 5.PC往8266上发送1473字节数据 + + 6.PC上SOC2 UDP传输,bing + + 7.PC往8266上发送1472字节数据' + sub module: UDP + summary: AP mode, recvfrom basic test + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0110 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 1 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 1] + - - SSC SSC1 soc -S -s -i -p -l 1472 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 1472] + - - SSC SSC1 soc -S -s -i -p -l 1473 + - ['P SSC1 RE SEND:(\d+),OK', P SOC_COM NC SOC_RECVFROM] + - - SSC SSC1 soc -S -s -i -p -l 1472 -n 10 + -j 20 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 14720] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.OK,没收到UDP包 + + 6.OK' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + module: TCPIP + steps: '1.PC上SOC1 UDP传输,bing + + 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1字节数据 + + 4.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1472字节数据 + + 5.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1473字节数据 + + 6.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1472*10字节数据' + sub module: UDP + summary: AP mode, sendto test with different length + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0113 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + comment: '' + execution time: 0.0 + expected result: '1.ok + + 2.ok + + 3.ok + + 4.ok + + 5.ok' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + module: TCPIP + steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 2.target1上UDP传输,Bind socket2,本地ip target_udp_port2 + + 3.target1上UDP传输,Bind socket3,本地ip target_udp_port3 + + 4.target1上UDP传输,Bind socket4,本地ip target_udp_port4 + + 5.target1上UDP传输,Bind socket5,本地ip target_udp_port5' + sub module: UDP + summary: AP mode, create max udp socket test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0112 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + module: TCPIP + steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 2.关闭socket1' + sub module: UDP + summary: AP mode, close UDP sockets test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_CONN_0501 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC2 sta -R -r 1 + - ['R SSC2 C +RECONN:OK'] + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - DELAY 10 + - [''] + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - DELAY 15 + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC2 sta -R -r 0 + - ['R SSC2 C +RECONN:OK'] + - - SSC SSC2 sta -R -r 2 + - ['R SSC2 C +RECONN:0'] + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - DELAY 10 + - [''] + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - DELAY 15 + - [P PC_COM C +DELAYDONE, 'P SSC2 NC +JAP:CONNECTED'] + - - SSC SSC2 sta -R -r 1 + - ['R SSC2 C +RECONN:OK'] + comment: '' + execution time: 0.0 + expected result: '1.设置reconn,开启(此功能不需要重启系统) + + 2.target1 set AP + + 3.target2 JAP target1 成功 + + 4.target2 断开target1 连接 + + 5.等待10s,target2 自动重连target1 + + 6.成功 + + 7.查询reconn状态,关闭 + + 8.修改mode 成功 + + 9.等待15s,target2 不会自动重连target1' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + module: WIFI MAC + steps: "1.设置reconn,开启(此功能不需要重启系统)\n2.target1下设置ssid 和pwd 加密方式\n3.target2 JAP target1\ + \ \n4.target1 修改mode 为sta mode\n5.等待10s,target1 修改mode 为softAP mode\n6.设置reconn,关闭\n\ + 7.查询reconn状态,关闭\n8.target1 修改mode 为sta mode\n9.等待15s,target1 修改mode 为softAP mode" + sub module: WIFI Connect + summary: reconnect policy test + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: reconnect policy test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_CONN_0502 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC2 sta -R -r 1 + - ['R SSC2 C +RECONN:OK'] + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - DELAY 5 + - ['R SSC2 C +JAP:DISCONNECTED'] + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - DELAY 10 + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:OK'] + - - DELAY 10 + - [P PC_COM C +DELAYDONE, 'P SSC2 NC +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: '1.target1 set AP + + 2.target2 jap target 1 + + 3.设置reconn,开启(此功能不需要重启系统) + + 4.target2 断开target1 连接 + + 5.等待10s,target2 自动重连target1 + + 6.target2 断开target1 连接' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + module: WIFI MAC + steps: '1.target1下设置ssid 和pwd 加密方式 + + 2.target2 jap target 1 + + 3.设置reconn,开启(此功能不需要重启系统) + + 4.target2 断开target1 连接 + + 5.等待10s,target2 自动重连target1 + + 6.target2 断开target1 连接' + sub module: WIFI Connect + summary: will not do reconnect after manually disconnected + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: reconnect policy test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^WIFI_CONN_0401 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -R -a 0 + - ['R SSC1 C +AUTORECONN:OK'] + - - SSC SSC1 sta -R -a 2 + - ['R SSC1 C +AUTORECONN:0'] + - - SSC SSC1 reboot + - [''] + - - DELAY 15 + - [''] + - - SSC SSC1 sta -Q + - ['R SSC1 C JAP:DISCONNECTED'] + - - SSC SSC1 sta -R -a 1 + - ['R SSC1 C +AUTORECONN:OK'] + - - SSC SSC1 sta -R -a 2 + - ['R SSC1 C +AUTORECONN:1'] + - - SSC SSC1 reboot + - ['R SSC1 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: '1.设置autoreconn,关闭 + + 2.查询当前autoreconn状态是否关闭 + + 3.重启系统,等待15s + + 4.查询target1 未自动重连AP + + 5.设置autoreconn,开启 + + 6.查询当前autoreconn状态是否开启 + + 7.系统重启后target1 自动重连AP' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: WIFI MAC + steps: '1.设置autoreconn,关闭 + + 2.查询当前autoreconn状态是否关闭 + + 3.重启系统,等待15s + + 4.查询target1 未自动重连AP + + 5.设置autoreconn,开启 + + 6.查询当前autoreconn状态是否开启 + + 7.系统重启后target1 自动重连AP' + sub module: WIFI Connect + summary: auto reconnect test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: power on auto reconnect test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_MODE_0101 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - ['R SSC1 C +DHCP:STA,OK'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC2 sta -S + - [R SSC2 NP C +SCANDONE] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:OK'] + comment: '' + execution time: 0.0 + expected result: '1.target1下设置ssid 和pwd 、加密方式成功 + + 2.修改target 1的mode 为sta mode + + 3.target1的dhcp打开 + + 4.target1成功连接上AP + + 5.target2上不能查询到target_ssid + + 6.target1断开AP' + initial condition: T2O_1 + initial condition description (auto): same as T2_1 but will NOT autogen a TC with + initial condition T2_2 + module: WIFI MAC + steps: '1.target1下设置ssid 和pwd 加密方式 + + 2.修改target1的mode 为sta mode + + 3.target1的dhcp打开 + + 4.target1连接AP + + 5.target2查询target_ssid + + 6.target1断开AP' + sub module: WIFI Mode + summary: mode switch test (sta mode) + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: wifi mode fucntion + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_MODE_0103 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -S -o 1 + - ['R SSC1 C +DHCP:STA,OK'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC2 sta -S + - [R SSC2 P , R SSC2 C +SCANDONE] + comment: '' + execution time: 0.0 + expected result: '1.target1 change to AP mode + + 2.target1 set AP + + 3.target 1 的dhcp 打开 + + 4.target 1 成功连接上AP + + 5.target 2 上查询到target_ssid' + initial condition: T2O_1 + initial condition description (auto): same as T2_1 but will NOT autogen a TC with + initial condition T2_2 + module: WIFI MAC + steps: '1.target1 change to AP mode + + 2.target1下设置ssid 和pwd 加密方式 + + 3.target1 的dhcp 打开 + + 4.target1 连接AP + + 5.target2 上查询target_ssid' + sub module: WIFI Mode + summary: mode switch test (STA+AP mode) + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: wifi mode fucntion + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_MODE_0102 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -S + - [R SSC2 P , R SSC2 C +SCANDONE] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:ERROR'] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:ERROR'] + comment: '' + execution time: 0.0 + expected result: '1. target1 set AP + + 2.target 2 上查询到target_ssid + + 3. target1 can''t join AP + + 4. target1 can''t QAP' + initial condition: T2O_1 + initial condition description (auto): same as T2_1 but will NOT autogen a TC with + initial condition T2_2 + module: WIFI MAC + steps: '1.target1下设置ssid 和pwd 加密方式 + + 2.target 2 上查询target_ssid + + 3.target1 join AP + + 4.target1 DISCONN AP' + sub module: WIFI Mode + summary: mode switch test (AP mode) + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: wifi mode fucntion + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^WIFI_CONN_0904 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 3 -m 1 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p 1234567890 + - ['R SSC2 C +JAP:DISCONNECTED,1,204'] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:OK'] + - - WIFI CONN + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:DISCONNECTED,1,5'] + - - WIFI DISCONN + - [P PC_COM C OK, 'R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 ap -S -s -p -t 3 -m 1 + - ['P SSC1 C +SAP:OK', 'P SSC2 C +JAP:DISCONNECTED,5,4'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. disconnect event REASON_HANDSHAKE_TIMEOUT + + 3. succeed + + 4. succeed + + 5. disconnect event REASON_ASSOC_TOOMANY + + 6. succeed, target2 connect succeed + + 7. disconnect event REASON_ASSOC_EXPIRE' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. config target1 softap max sta allowed 1 + + 2. target2 connect to target1 with wrong password + + 3. target2 disconnect + + 4. PC WIFI NIC connect to target1 + + 5. target2 connect to target1 with correct password + + 6. PC WIFI NIC disconnect + + 7. reconfig softap' + sub module: WIFI Connect + summary: test wifi disconnect reason REASON_ASSOC_TOOMANY, REASON_HANDSHAKE_TIMEOUT, + REASON_ASSOC_EXPIRE + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: wifi disconnect reason test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^WIFI_CONN_0902 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - APC OFF + - [P PC_COM L OK, 'R SSC1 C +JAP:DISCONNECTED,1,200'] + - - APC ON + - [P PC_COM L OK] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. disconnect event REASON_BEACON_TIMEOUT' + initial condition: STAAP1 + initial condition description (auto): testing sta on sta + ap mode, quit AP (autogen + by STAM1) + module: WIFI MAC + steps: '1. connect to AP + + 2. AP power off' + sub module: WIFI Connect + summary: test wifi disconnect reason REASON_BEACON_TIMEOUT + test environment: SSC_T1_APC + test environment description (auto): "PC has 1 wired NIC connected to AP.\nPC has\ + \ 1 wired NIC connected to APC (static IP within the same subnet with APC). \n\ + APC control AP power supply. \nPC has 1 WiFi NIC. \n1 SSC target connect with\ + \ PC by UART." + test point 1: basic function + test point 2: wifi disconnect reason test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^WIFI_CONN_0901 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: basic function + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC1 sta -D + - ['R SSC1 C +JAP:DISCONNECTED,0,8'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:DISCONNECTED,2,15'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:DISCONNECTED,1,201'] + comment: '' + execution time: 0.0 + expected result: '1. disconnect event reason REASON_ASSOC_LEAVE + + 2. disconnect event reason REASON_4WAY_HANDSHAKE_TIMEOUT + + 3. disconnect event reason REASON_NO_AP_FOUND' + initial condition: STAAP1 + initial condition description (auto): testing sta on sta + ap mode, quit AP (autogen + by STAM1) + module: WIFI MAC + steps: '1. sta connect to AP, and disconnect + + 2. connect to AP with wrong password + + 3. connect to AP not exist' + sub module: WIFI Connect + summary: test wifi disconnect reason REASON_ASSOC_LEAVE, REASON_4WAY_HANDSHAKE_TIMEOUT, + REASON_NO_AP_FOUND + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: wifi disconnect reason test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0201 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [SOCR SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -i 0.0.0.0 -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,OK'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s -h B + - ['P SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: '1.ok + + 2.OK + + 3.ERROR + + 4.OK + + 5.OK + + 6.ERROR + + 7.OK + + 8.OK + + 9.OK + + 10.OK + + 11.OK + + 12.ERROR' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建UDP传输socket,bind到本地ip 0.0.0.0, + + 3.target1上使用步骤2创建的socket,去连接 PC的ip, + + 4.target1上创建TCP socket + + 5.target1上使用步骤4创建的socket,创建TCP 监听 + + 6.target1上使用步骤4创建的socket,去连接 PC的ip, + + 7.target1上创建TCP socket + + 8.target1上使用步骤7创建的socket,去连接 PC的ip, + + 9.target1上关闭步骤7创建的socket + + 10.target1上使用步骤7创建的socket,去连接 PC的ip, + + 11.target1上关闭所有创建的socket + + 12.target1上使用步骤2创建的socket,去连接 PC的ip,' + sub module: TCP + summary: STA mode, connect test. use socket in state that can't connect + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) in different state + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0206 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP -i + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -B -t TCP -i + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -B -t TCP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,OK'] + - - SOC SOC2 CONNECT + - ['R SSC1 A :ACCEPT:(\d+),\d+,.+,\d+'] + - - SSC SSC1 soc -I + - ['P SSC1 RE "SOCINFO:%%s,2,%%s,\d+,%%s,%%d"%%(,,,)', + 'P SSC1 RE "SOCINFO:%%s,2,.+,\d+,.+,\d+"%%()', 'P SSC1 RE "SOCINFO:%%s,82,.+,%%d,.+,\d+"%%(,)', + 'P SSC1 RE "SOCINFO:%%s,2,%%s,%%d,%%s,\d+"%%(,,,)'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK,pc tcp server accept成功 + + 4.OK + + 5.OK + + 6.OK + + 7.OK + + 8.OK + + 9.PC OK, target1 +ACCEPT:3,2,,port + + 10.+SOCINFO:,,, + + +SOCINFO:,,, + + +SOCINFO:, + + +SOCINFO:,,, + + +SOCINF0ALL' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1,本地ip target_ip\n3.target1上使用步骤2创建的socket1,去连接\ + \ PC的ip,test_tcp_port1,PC有ACCEPT\n4.target1上创建TCP socket2,本地ip target_ip\n5.target1上使用步骤4创建的socket2,去连接\ + \ PC的ip,test_tcp_port1,PC有ACCEPT\n6.target1 shutdown socket2 \n7.target1上创建TCP\ + \ socket3,本地端口random_port\n8.target1上使用步骤7创建的socket3,去监听\n9.PC CONNECT,\ + \ ,tcp 连接创建成功,创建socket4 \n10.target1 查询the socket information" + sub module: TCP + summary: STA mode, get active socket info test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) in different state + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0207 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [SOCR SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -i 0.0.0.0 -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,OK'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s -h B + - ['P SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: '1.ok + + 2 OK + + 3.ERROR + + 4.OK + + 5.OK + + 6.ERROR + + 7.OK + + 8.OK + + 9.OK + + 10.OK + + 11.OK + + 12.ERROR' + initial condition: APSTA2 + initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen + by APM2) + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建UDP传输socket,bind到本地ip 0.0.0.0, + + 3.target1上使用步骤2创建的socket,去连接 PC的ip, + + 4.target1上创建TCP socket + + 5.target1上使用步骤4创建的socket,创建TCP 监听 + + 6.target1上使用步骤4创建的socket,去连接 PC的ip, + + 7.target1上创建TCP socket + + 8.target1上使用步骤7创建的socket,去连接 PC的ip, + + 9.target1上关闭步骤7创建的socket + + 10.target1上使用步骤7创建的socket,去连接 PC的ip, + + 11.target1上关闭所有创建的socket + + 12.target1上使用步骤2创建的socket,去连接 PC的ip,' + sub module: TCP + summary: AP mode, connect test. use socket in state that can't connect + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) in different state + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0501 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - STRING ether%20src%20%%s%20or%20ether%20dst%20%%s + + - [R PC_COM C OK] + - - NIC NIC1 START capture+block_ip + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - [''] + - - DELAY 10 + - ['R SSC1 RE CONNECT:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: 2. connect failed, no exception + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: '1. PC do not reply any IP packet on NIC + + 2. target try to connect to TCP server with PC NIC IP' + sub module: TCP + summary: PC do not reply TCP SYN of target + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: TCP connect and disconnect abnormal case + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_DNS_0101 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -H -d iot.espressif.cn + - ['R SSC1 C +HOSTIP:OK,115.29.202.58'] + comment: '' + execution time: 0.0 + expected result: 1.OK + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: 1. get host name "espressif.cn" + sub module: DNS + summary: get host by name test + test environment: SSC_T1_2 + test environment description (auto): 'Able to access WAN after connect to AP. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DNS function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_DNS_0103 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -H -d iot.espressif.cn + - ['R SSC1 A :\+HOSTIP:OK,(.+)\r\n'] + - - SSC SSC1 soc -B -t UDP + - ['R SSC1 A :\+BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p 9003 -l 10 + - ['P SSC1 RE \+SEND:\d+,OK', P SSC1 SL +10] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: '1. get host name "espressif.cn" + + 2. sendto, recvfrom1. get host name "espressif.cn" + + 2. sendto, recvfrom' + sub module: DNS + summary: UDP send to iot.expressif.com + test environment: SSC_T1_2 + test environment description (auto): 'Able to access WAN after connect to AP. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DNS function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_DNS_0102 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -H -d iot.espressif.cn + - ['R SSC1 A :\+HOSTIP:OK,(.+)\r\n'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :\+BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p 9001 + - ['R SSC1 RE \+CONNECT:\d+,OK'] + - - SSC SSC1 soc -S -s -l 10 + - ['P SSC1 RE \+SEND:\d+,OK', P SSC1 SL +10] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: '1. get host name "espressif.cn" + + 2. connect, send, recv1. get host name "espressif.cn" + + 2. connect, send, recv' + sub module: DNS + summary: TCP connect to iot.espressif.com + test environment: SSC_T1_2 + test environment description (auto): 'Able to access WAN after connect to AP. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DNS function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0106 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK,pc tcp server accept成功 + + 4 OK + + 5.OK,pc tcp server accept成功 + + 6.OK + + 7.OK,pc tcp server accept成功 + + 8 OK + + 9.OK,pc tcp server accept成功 + + 10.OK + + 11.OK,pc tcp server accept成功' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket1 + + 3.target1上使用步骤2创建的socket1,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 4.target1上创建TCP socket2 + + 5.target1上使用步骤4创建的socket2,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 6.target1上创建TCP socket3 + + 7.target1上使用步骤6创建的socket3,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 8.target1上创建TCP socket4 + + 9.target1上使用步骤8创建的socket4,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 10.target1上创建TCP socket5 + + 11.target1上使用步骤10创建的socket5,去连接 PC的ip,test_tcp_port1,PC有ACCEPT' + sub module: TCP + summary: STA mode, create max TCP sockets test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0107 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -B -t TCP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,OK'] + - - SOC SOC2 CONNECT + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] + - - SOC SOC3 CONNECT + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] + - - SOC SOC4 CONNECT + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] + - - SOC SOC5 CONNECT + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] + - - SOC SOC6 CONNECT + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] + comment: '' + execution time: 0.0 + expected result: '1.+BIND:0,OK,0.0.0.0 + + 2.OK + + 3.OK,pc tcp server accept成功 + + 4.OK,pc tcp server accept成功 + + 5.OK,pc tcp server accept成功 + + 6.OK,pc tcp server accept成功 + + 7.OK,pc tcp server accept成功' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: "1.target1上创建TCP socket 端口随机\n2.target1上使用步骤4创建的socket1,去监听\n3.PC CONNECT,\ + \ ,tcp 连接创建成功,创建socket2 \n4.PC CONNECT, ,tcp 连接创建成功,创建socket3\ + \ \n5.PC CONNECT, ,tcp 连接创建成功,创建socket4 \n6.PC CONNECT,\ + \ ,tcp 连接创建成功,创建socket5 \n7.PC CONNECT, ,tcp 连接创建成功,创建socket6\ + \ " + sub module: TCP + summary: STA mode, accept max TCP client by server test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0104 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s -h B + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s -h W + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s -h R + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK,pc tcp server accept OK + + 4.OK + + 5.OK + + 6.OK,pc tcp server accept OK + + 7.OK + + 8.OK + + 9.OK,pc tcp server accept OK + + 10.OK' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: '1. PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket + + 3.target1上使用步骤2创建的socket,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 4.target1 shutdown socket1 B + + 5.target1上创建TCP socket + + 6.target1上使用步骤5创建的socket,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 7.target1 shutdown socket2 W + + 8.target1上创建TCP socket + + 9.target1上使用步骤8创建的socket,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 10.target1 shutdown socket3 R' + sub module: TCP + summary: STA mode, shutdown basic test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0105 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + - - SSC SSC1 soc -B -t TCP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,OK'] + - - SOC SOC2 CONNECT + - ['R SSC1 A :ACCEPT:(\d+),\d+,.+,\d+'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.OK + + 6.OK + + 7.target1关闭socket1 + + 8.target1关闭socket2 + + 9.OK + + 10.OK,pc tcp server accept成功 + + 11.target1关闭socket1 + + 12.OK + + 13.OK,pc tcp server accept成功 + + 14.OK + + 15.target1关闭socket1' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1关闭socket1\n\ + 4.target1上创建TCP socket 端口随机\n5.target1上使用步骤4创建的socket1,去监听\n6.PC CONNECT,\ + \ ,tcp 连接创建成功,创建socket2 \n7.target1关闭socket1\n8.target1关闭socket2\n\ + 9.target1上创建TCP socket1\n10.target1上使用步骤10创建的socket1,去连接 PC的ip,test_tcp_port1,PC有ACCEPT\n\ + 11.target1关闭socket1\n12.target1上创建TCP socket1\n13.target1上使用步骤13创建的socket1,去连接\ + \ PC的ip,test_tcp_port1,PC有ACCEPT\n14.target1shutdown socket1\n15.target1关闭socket1" + sub module: TCP + summary: STA mode, close for different types of TCP sockets test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0102 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -B -t TCP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,OK'] + - - SOC SOC1 CONNECT + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+', P SOC_COM C OK] + - - SOC SOC1 CONNECT + - [P SOC_COM C ERROR, P SSC1 NC ACCEPT] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.PC TCP client accept + + 4.error' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: '1.target1上创建TCP socket,bind到本地端口 + + 2.target1上使用步骤1创建的socket,创建TCP 监听 + + 3.PC TCP 连接到target1 , + + 4.PC tcp 连接到不存在的port ,' + sub module: TCP + summary: STA mode, server listen test. use different kinds of port + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0103 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SOC SOC2 SEND 5 + - [R SSC1 SL +5] + - - SSC SSC1 soc -S -s -l 5 + - ['P SSC1 RE SEND:\d+,OK', P SOC2 RL 5] + - - SOC SOC2 SEND 146000 + - [R SSC1 SL +146000] + - - SSC SSC1 soc -S -s -l 1460 -n 100 + - ['P SSC1 RE SEND:\d+,OK', P SOC2 RL 146000] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK,pc上回accept + + 4.OK + + 5.target收到5 byte + + 6.PC收到5 byte + + 7.target收到 146000 byte + + 8.OK,PC 回SOC_RECV=SOC2,RECV_LEN=字节数' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: '1. PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket + + 3.target1上使用步骤2创建的socket,去连接 PC的ip,test_tcp_port1 + + 4.PC与target1 创建好TCP 连接,有ACCEPT + + 5.PC send 5 bytes to 8266 + + 6.8266 send 5 bytes to PC + + 7. PC send 100 * 1460 data to 8266, + + 8.8266 send 100 * 1460 to PC. ' + sub module: TCP + summary: STA mode, send/recv basic test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0101 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [SOCR SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP -i 0.0.0.0 -p 0 + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,OK', P SOC1 C +ACCEPT] + - - SSC SSC1 soc -B -t TCP -i 0.0.0.0 -p 0 + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i 123.456.678.789 -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.ERROR + + 6.ERROR' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket,bind到本地ip 0.0.0.0,本地端口 0 + + 3.target1上使用步骤2创建的socket,去连接 PC的ip,test_tcp_port1 + + 4.target1上创建TCP socket,bind到本地ip 0.0.0.0,本地端口 0 + + 5.target1上使用步骤4创建的socket,去连接不存在的ip,test_tcp_port1 + + 6.target1上使用步骤2创建的socket,去连接 PC的ip,远端端口不存在。' + sub module: TCP + summary: STA mode, connect test. use different ip, port + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0116 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -B -t TCP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,OK'] + - - SOC SOC2 CONNECT 0 + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] + - - SOC SOC3 CONNECT 0 + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] + - - SOC SOC4 CONNECT 0 + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] + - - SOC SOC5 CONNECT 0 + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] + - - SOC SOC6 CONNECT 0 + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] + comment: '' + execution time: 0.0 + expected result: '1.+BIND:0,OK,0.0.0.0 + + 2.OK + + 3.OK,pc tcp server accept成功 + + 4.OK,pc tcp server accept成功 + + 5.OK,pc tcp server accept成功 + + 6.OK,pc tcp server accept成功 + + 7.OK,pc tcp server accept成功' + initial condition: APSTA2 + initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen + by APM2) + module: TCPIP + steps: "1.target1上创建TCP socket 端口随机\n2.target1上使用步骤4创建的socket1,去监听\n3.PC CONNECT,\ + \ ,tcp 连接创建成功,创建socket2 \n4.PC CONNECT, ,tcp 连接创建成功,创建socket3\ + \ \n5.PC CONNECT, ,tcp 连接创建成功,创建socket4 \n6.PC CONNECT,\ + \ ,tcp 连接创建成功,创建socket5 \n7.PC CONNECT, ,tcp 连接创建成功,创建socket6" + sub module: TCP + summary: AP mode, accept max TCP client by server test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0114 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + - - SSC SSC1 soc -B -t TCP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,OK'] + - - SOC SOC2 CONNECT 0 + - ['R SSC1 A :ACCEPT:(\d+),\d+,.+,\d+'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.OK + + 6.OK,target1上accept 成功 + + 7.target1关闭socket1 + + 8.target1关闭socket2 + + 9.OK + + 10.OK,pc tcp server accept成功 + + 11.target1关闭socket1 + + 12.OK + + 13.OK,pc tcp server accept成功 + + 14.OK + + 15.target1关闭socket1' + initial condition: APSTA2 + initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen + by APM2) + module: TCPIP + steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1关闭socket1\n\ + 4.target1上创建TCP socket 端口随机\n5.target1上使用步骤4创建的socket1,去监听\n6.PC CONNECT,\ + \ ,tcp 连接创建成功,创建socket2 \n7.target1关闭socket1\n8.target1关闭socket2\n\ + 9.target1上创建TCP socket1\n10.target1上使用步骤10创建的socket1,去连接 PC的ip,test_tcp_port1,PC有ACCEPT\n\ + 11.target1关闭socket1\n12.target1上创建TCP socket1\n13.target1上使用步骤13创建的socket1,去连接\ + \ PC的ip,test_tcp_port1,PC有ACCEPT\n14.target1shutdown socket1\n15.target1关闭socket1" + sub module: TCP + summary: AP mode, close for different types of TCP sockets test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0115 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK,pc tcp server accept成功 + + 4 OK + + 5.OK,pc tcp server accept成功 + + 6.OK + + 7.OK,pc tcp server accept成功 + + 8 OK + + 9.OK,pc tcp server accept成功 + + 10.OK + + 11.OK,pc tcp server accept成功' + initial condition: APSTA2 + initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen + by APM2) + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket1 + + 3.target1上使用步骤2创建的socket1,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 4.target1上创建TCP socket2 + + 5.target1上使用步骤4创建的socket2,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 6.target1上创建TCP socket3 + + 7.target1上使用步骤6创建的socket3,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 8.target1上创建TCP socket4 + + 9.target1上使用步骤8创建的socket4,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 10.target1上创建TCP socket5 + + 11.target1上使用步骤10创建的socket5,去连接 PC的ip,test_tcp_port1,PC有ACCEPT' + sub module: TCP + summary: AP mode, create max TCP sockets test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0112 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SOC SOC2 SEND 5 + - [R SSC1 SL +5] + - - SSC SSC1 soc -S -s -l 5 + - ['P SSC1 RE SEND:\d+,OK', P SOC2 RL 5] + - - SOC SOC2 SEND 146000 + - [R SSC1 SL +146000] + - - SSC SSC1 soc -S -s -l 1460 -n 100 + - ['P SSC1 RE SEND:\d+,OK', P SOC2 RL 146000] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK,pc tcp server accept成功 + + 4.OK + + 5.target收到5byte数据 + + 6.PC收到5byte数据 + + 7.target收到146000 byte数据 + + 8.OK,PC 收到146000 byte数据' + initial condition: APSTA2 + initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen + by APM2) + module: TCPIP + steps: '1. PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket + + 3.target1上使用步骤2创建的socket,去连接 PC的ip,test_tcp_port1 + + 4.PC与target1 创建好TCP 连接,有ACCEPT + + 5.PC send 5 bytes to 8266 + + 6.8266 send 5 bytes to PC + + 7. PC send 100 * 1460 data to 8266, + + 8.8266 send 100 * 1460 to PC.' + sub module: TCP + summary: AP mode, send/recv basic test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0113 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s -h B + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s -h W + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s -h R + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK,pc tcp server accept成功 + + 4.OK + + 5.OK + + 6.OK,pc tcp server accept成功 + + 7.OK + + 8.OK + + 9.OK,pc tcp server accept成功 + + 10.OK' + initial condition: APSTA2 + initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen + by APM2) + module: TCPIP + steps: '1. PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket + + 3.target1上使用步骤2创建的socket,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 4.target1 shutdown socket1 B + + 5.target1上创建TCP socket + + 6.target1上使用步骤5创建的socket,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 7.target1 shutdown socket2 W + + 8.target1上创建TCP socket + + 9.target1上使用步骤8创建的socket,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 10.target1 shutdown socket3 R' + sub module: TCP + summary: AP mode, shutdown basic test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0110 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [SOCR SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP -i 0.0.0.0 -p 0 + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,OK', P SOC1 C +ACCEPT] + - - SSC SSC1 soc -B -t TCP -i 0.0.0.0 -p 0 + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i 123.456.678.789 -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.ERROR + + 6.ERROR' + initial condition: APSTA2 + initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen + by APM2) + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket,bind到本地ip 0.0.0.0,本地端口 0 + + 3.target1上使用步骤2创建的socket,去连接 PC的ip,test_tcp_port1 + + 4.target1上创建TCP socket,bind到本地ip 0.0.0.0,本地端口 0 + + 5.target1上使用步骤4创建的socket,去连接不存在的ip,test_tcp_port1 + + 6.target1上使用步骤2创建的socket,去连接 PC的ip,远端端口不存在。' + sub module: TCP + summary: AP mode, connect test. use different ip, port + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0111 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -B -t TCP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,OK'] + - - SOC SOC1 CONNECT 0 + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+', P SOC_COM C OK] + - - SOC SOC1 CONNECT 0 + - [P SOC_COM C ERROR, P SSC1 NC ACCEPT] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.PC TCP client accept + + 4.error' + initial condition: APSTA2 + initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen + by APM2) + module: TCPIP + steps: '1.target1上创建TCP socket,bind到本地端口 + + 2.target1上使用步骤1创建的socket,创建TCP 监听 + + 3.PC TCP 连接到target1 , + + 4.PC tcp 连接到不存在的port ,' + sub module: TCP + summary: AP mode, server listen test. use different kinds of port + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_ARP_0101 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - STRING ether%20src%20%%s%20or%20ether%20dst%20%%s + + - [R PC_COM C OK] + - - NIC NIC1 START capture+send+block_arp_ip + - ['R PC_COM C +NIC_START:OK'] + - - NIC NIC1 SEND ARP arp_op_code "request" arp_target_proto_addr ethernet_dst_addr + "ff:ff:ff:ff:ff:ff" + - ['P PC_COM C +NIC_SEND:OK', P NIC1 PDU (Ethernet.dst_addr=)(ARP.hw_type="Ethernet")(ARP.protocol="IPv4")(ARP.hw_len="6")(ARP.proto_len="4")(ARP.op_code="reply")(ARP.sender_hw_addr=)(ARP.sender_proto_addr=)(ARP.target_hw_addr=)(ARP.target_proto_addr=)] + comment: '' + execution time: 0.0 + expected result: 1. PC recv target valid ARP reply + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: 1. PC send ARP req to target + sub module: ARP + summary: PC send valid ARP request to target + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: handling ARP request + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0304 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 5 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] + - - SSC SSC1 op -S -o 2 + - ['P SSC1 C +MODE:OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.OK' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: "1.PC上SOC1 UDP传输,bing \n2.target1上UDP传输,Bind socket1,本地ip\ + \ target_udp_port1\n3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据\n\ + 4.修改8266的Mode为softAP mode \n5.关闭建立的socket1连接" + sub module: UDP + summary: close UDP socket after mode changed + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: UDP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0305 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 5 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] + - - NIC DISABLED + - [R PC_COM C OK] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.OK' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: "1.PC上SOC1 UDP传输,bing \n2.target1上UDP传输,Bind socket1,本地ip\ + \ target_udp_port1\n3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据\n\ + 4.PC上网卡禁止掉 \n5.关闭建立的socket1连接" + sub module: UDP + summary: close UDP socket after PC NIC disabled + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: UDP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0306 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 5 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] + - - SSC SSC1 dhcp -E -o 1 + - ['R SSC1 C +DHCP:STA,OK'] + - - SSC SSC1 ip -S -o 1 -i 192.168.111.210 + - ['P SSC1 C +IP:OK'] + - - SSC SSC1 ip -Q -o 1 + - ['R SSC1 C +STAIP:192.168.111.210'] + - - SSC SSC1 soc -S -s -i -p -l 1 + - ['P SSC1 RE SEND:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.OK + + 7.OK' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: "1.PC上SOC1 UDP传输,bing \n2.target1上UDP传输,Bind socket1,本地ip\ + \ target_udp_port1\n3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据\n\ + 4.关闭8266的DHCP 1\n5.设置sta ip \n6.查询sta ip 地址是否生效\n7.8266往PC上发送5字节数据" + sub module: UDP + summary: do UDP send after IP changed + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: UDP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0307 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 5 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] + - - SSC SSC1 dhcp -E -o 1 + - ['R SSC1 C +DHCP:STA,OK'] + - - SSC SSC1 ip -S -o 1 -i 192.168.111.210 + - ['P SSC1 C +IP:OK'] + - - SSC SSC1 ip -Q -o 1 + - ['R SSC1 C +STAIP:192.168.111.210'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.OK + + 7.OK' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: "1.PC上SOC1 UDP传输,bing \n2.target1上UDP传输,Bind socket1,本地ip\ + \ target_udp_port1\n3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据\n\ + 4.关闭8266的DHCP 1\n5.设置sta ip \n6.查询sta ip 地址是否生效\n7.关闭建立的socket1连接" + sub module: UDP + summary: close UDP socket after IP changed + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: UDP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0301 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -i -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 5 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] + - - SSC SSC1 sta -D + - ['P SSC1 C +QAP:OK'] + - - SSC SSC1 soc -S -s -i -p -l 5 + - ['P SSC1 RE SEND:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.ERROR' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: '1.PC上SOC1 UDP传输,bing + + 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据 + + 4.断开与AP 连接 + + 5.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据' + sub module: UDP + summary: do UDP send after WIFI disconnected + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: UDP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0302 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 5 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] + - - SSC SSC1 sta -D + - ['P SSC1 C +QAP:OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.OK + + ' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: '1.PC上SOC1 UDP传输,bing + + 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据 + + 4.断开与AP 连接 + + 5.关闭建立的socket1连接' + sub module: UDP + summary: "close UDP socket after WIFI \ndisconnected" + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: UDP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0303 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 5 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] + - - SSC SSC1 op -S -o 2 + - ['P SSC1 C +MODE:OK'] + - - SSC SSC1 soc -S -s -i -p -l 5 + - ['P SSC1 RE SEND:(\d+),OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.ERROR' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: "1.PC上SOC1 UDP传输,bing \n2.target1上UDP传输,Bind socket1,本地ip\ + \ target_udp_port1\n3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据\n\ + 4.修改8266的Mode为softAP mode \n5.8266往PC上发送5字节数据" + sub module: UDP + summary: do UDP send after mode changed + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: UDP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_CONN_0601 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - WIFI CONN + + - ['R PC_COM C +WIFICONN:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 ap -L + - ['R SSC1 C +LSTA:', 'R SSC1 C +LSTA:', R SSC1 C +LSTADONE] + comment: '' + execution time: 0.0 + expected result: '1.target1 set AP + + 2.PC WIFI CONNECTED + + 3.target2 jap target 1 + + 4.查询到两个sta 连接到target1 上' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + module: WIFI MAC + steps: '1. target1下设置ssid 和pwd 加密方式 + + 2.PC WIFI CONNECTED target1 + + 3.target2 jap target 1 + + 4.查询到两个sta 连接到target1 上' + sub module: WIFI Connect + summary: list stations connected to soft ap test + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: list SoftAP connected station + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_DHCP_0209 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - WIFI CONN 192.168.4.2 + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - DELAY 20 + - [''] + - - SSC SSC1 ap -L + - [R SSC1 C 192.168.4.2 C 192.168.4.3 P P ] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. succeed + + 4. succeed + + 5. find target2 and PC' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: TCPIP + steps: '1. config softap to a random ssid + + 2. target2 connect to target1 softap + + 3. disable DHCP server, do config and enable + + 4. PC NIC connect to target1 softap + + 5. softap list connected station' + sub module: DHCP + summary: dhcp server reconfig, old client and new client able to get IP + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_DHCP_0208 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['P SSC1 C +DHCP:AP,OK', 'P SSC2 C +JAP:DISCONNECTED'] + - - SSC SSC2 sta -D + - ['R SSC2 C +JAP:DISCONNECTED'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - WIFI CONN 192.168.4.2 + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - SSC SSC1 ap -L + - [R SSC1 C 192.168.4.2 P ] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. succeed + + 4. get IP 192.168.4.2 + + 5. can only find target2 with IP 192.168.4.2' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: TCPIP + steps: '1. config softap to a random ssid + + 2. PC NIC connect to target1 softap + + 3. disable DHCP server, do config and enable + + 4. target2 connect to target1 softap + + 5. softap list connected station' + sub module: DHCP + summary: dhcp server reconfig and new client able to get first IP in pool + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_DHCP_0207 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - WIFI CONN 192.168.4.2 + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - WIFI DISCONN2 + - ['R PC_COM NC ERROR C +WIFIDISCONN:OK'] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:OK'] + - - SSC SSC2 mac -S -o 1 -m 10:22:33:44:55:66 + - ['R SSC2 C +MAC:STA,OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC2 ip -Q -o 1 + - ['R SSC2 C +STAIP:192.168.4.2'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. get IP 192.168.4.2 + + 4. succeed + + 5. succeed + + 6. get IP 192.168.4.2' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: TCPIP + steps: '1. config softap to a random ssid + + 2. disable DHCP server, do config and enable + + 3. PC WIFI NIC connect to target1 softap + + 4. target2 connect to target1 softap and disnnect + + 5. PC release IP and disconnected + + 6. target2 change mac and connect to target1' + sub module: DHCP + summary: dhcp server prefer assign released IP to new client + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_DHCP_0206 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - LOOP 4 4 "['01','02','03','01']" "[2,3,4,2]" + - [''] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:OK'] + - - SSC SSC2 mac -S -o 1 -m 10:22:33:44:55:{%s} + - ['R SSC2 C +MAC:STA,OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC2 ip -Q -o 1 + - ['R SSC2 C +STAIP:192.168.4.{%s}'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 4. get IP 192.168.4.2 - 192.168.4.4 + + 5. get IP 192.168.4.2' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: TCPIP + steps: '1. config softap to a random ssid + + 2. disable DHCP server, do config and enable + + 3. target2 change mac, connect to softap, disconnect + + 4. Loop step3 twice + + 5. change to first mac, connect to softap' + sub module: DHCP + summary: dhcp server assign same IP to same MAC when it's not released + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_DHCP_0205 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.3 -t 1 + - ['P SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['P SSC1 C +DHCP:AP,OK', 'P SSC2 C +JAP:DISCONNECTED'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. target2 wifi disconnected' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: TCPIP + steps: '1. config softap to a random ssid + + 2. target2 connect to target1 + + 3. disable DHCP server, do config and enable' + sub module: DHCP + summary: disconnect STA if config dhcp server + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_DHCP_0204 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.3 -t 1 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC2 ip -Q -o 1 + - ['R SSC2 C +STAIP:192.168.4.2'] + - - DELAY 90 + - [''] + - - SSC SSC2 ip -Q -o 1 + - ['R SSC2 C +STAIP:192.168.4.2'] + - - SSC SSC2 sta -D + - ['R SSC2 C +JAP:DISCONNECTED'] + - - DELAY 60 + - [''] + - - SSC SSC2 mac -S -o 1 -m 10:22:33:44:55:66 + - ['R SSC2 C +MAC:STA,OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC2 ip -Q -o 1 + - ['R SSC2 C +STAIP:192.168.4.2'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. get IP 192.168.4.2 + + 5. succeed + + 6. succeed + + 8. get IP 192.168.4.2' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: TCPIP + steps: '1. config softap to a random ssid + + 2. config DHCP timeout as 1 minute + + 3. target2 connect to target1 + + 4. wait 90 seconds + + 5. check if target2 IP is same + + 6. target2 disconnect + + 7. wait 60s + + 8. target2 change mac and connect to target1' + sub module: DHCP + summary: dhcp server timeout test + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_DHCP_0203 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.3 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - LOOP 2 4 "['01','02']" "[2,3]" + - [''] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:OK'] + - - SSC SSC2 mac -S -o 1 -m 10:22:33:44:55:{%s} + - ['R SSC2 C +MAC:STA,OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC2 ip -Q -o 1 + - ['R SSC2 C +STAIP:192.168.4.{%s}'] + - - SSC SSC2 mac -S -o 1 -m 10:22:33:44:55:66 + - ['R SSC2 C +MAC:STA,OK'] + - - DELAY 20 + - [''] + - - SSC SSC2 ip -Q -o 1 + - ['R SSC2 C +STAIP:0.0.0.0'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. succeed + + 4.1 succeed + + 4.2 failed' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: TCPIP + steps: '1. config softap to a random ssid + + 2. config DHCP Server on Target1(.4.2 - .4.3) + + 3. target change mac, connect to Target1 + + 4. Loop step3 twice' + sub module: DHCP + summary: dhcp server ip pool empty + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_DHCP_0202 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - LOOP 3 4 "['01','02','03']" "[2,3,4]" + - [''] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:OK'] + - - SSC SSC2 mac -S -o 1 -m 10:22:33:44:55:{%s} + - ['R SSC2 C +MAC:STA,OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC2 ip -Q -o 1 + - ['R SSC2 C +STAIP:192.168.4.{%s}'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3,4: get IP from dhcp pool with correct sequence' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: TCPIP + steps: '1. config softap to a random ssid + + 2. config DHCP Server on Target1 + + 3. target change mac, connect to Target1 + + 4. Loop step3' + sub module: DHCP + summary: dhcp server ip pool + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_DHCP_0201 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 ip -S -o 2 -i + - ['R SSC1 C +IP:OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.1 -e 192.168.4.10 + - ['R SSC1 C +DHCP:LEASE,ERROR'] + - - SSC SSC1 dhcp -L -s 192.168.4.5 -e 192.168.4.2 + - ['R SSC1 C +DHCP:LEASE,ERROR'] + - - SSC SSC1 dhcp -L -s 192.168.2.2 -e 192.168.2.5 + - ['R SSC1 C +DHCP:LEASE,ERROR'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + comment: '' + execution time: 0.0 + expected result: '1.target1 关闭DHCP 2 OK + + 2.target1 设置ip 成功 + + 3.设置dhcp 地址池 OK + + 4.ERROR + + 5.ERROR + + 6.ERROR + + 7.target1 打开DHCP ok' + initial condition: APSTA1 + initial condition description (auto): testing ap on sta + ap mode (autogen by APM1) + module: TCPIP + steps: "1.target1 关闭DHCP 2 \n2.target1 设置ip \n3.设置dhcp 地址池\n4.设置dhcp错误的参数\n5.设置dhcp错误的参数\n\ + 6.设置dhcp错误的参数\n7.target1 打开DHCP ok" + sub module: DHCP + summary: server dhcp lease test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0204 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SSC SSC1 soc -W -s -o 0 + - ['R SSC1 RE WORKTHREAD:\d+,OK'] + - - SOC SOC2 SEND 146000 + - [P SOC_COM R *] + - - SSC SSC1 soc -W -s -o 1 + - ['P SSC1 RE WORKTHREAD:\d+,OK', P SSC1 SL +2920] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK,pc server accept OK + + 4.OK + + 5.OK + + 6.OK + + 7.target收到146000 byte + + ' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: '1. PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket + + 3.target1上使用步骤2创建的socket,去连接 PC的ip,test_tcp_port1 + + 4.PC与target1 创建好TCP 连接,有ACCEPT + + 5.target上不进行recv + + 6.PC send 100 * 1460 data to target, + + 7.在target上开始recv' + sub module: TCP + summary: STA mode, recv buffer test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) in different state + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0207 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [SOCR SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -i 0.0.0.0 -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,OK'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s -h B + - ['P SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: '1.ok + + 2 OK + + 3.ERROR + + 4.OK + + 5.OK + + 6.ERROR + + 7.OK + + 8.OK + + 9.OK + + 10.OK + + 11.OK + + 12.ERROR' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建UDP传输socket,bind到本地ip 0.0.0.0, + + 3.target1上使用步骤2创建的socket,去连接 PC的ip, + + 4.target1上创建TCP socket + + 5.target1上使用步骤4创建的socket,创建TCP 监听 + + 6.target1上使用步骤4创建的socket,去连接 PC的ip, + + 7.target1上创建TCP socket + + 8.target1上使用步骤7创建的socket,去连接 PC的ip, + + 9.target1上关闭步骤7创建的socket + + 10.target1上使用步骤7创建的socket,去连接 PC的ip, + + 11.target1上关闭所有创建的socket + + 12.target1上使用步骤2创建的socket,去连接 PC的ip,' + sub module: TCP + summary: AP mode, connect test. use socket in state that can't connect + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) in different state + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0206 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP -i + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -B -t TCP -i + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -B -t TCP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,OK'] + - - SOC SOC2 CONNECT + - ['R SSC1 A :ACCEPT:(\d+),\d+,.+,\d+'] + - - SSC SSC1 soc -I + - ['P SSC1 RE "SOCINFO:%%s,2,%%s,\d+,%%s,%%d"%%(,,,)', + 'P SSC1 RE "SOCINFO:%%s,2,.+,\d+,.+,\d+"%%()', 'P SSC1 RE "SOCINFO:%%s,82,.+,%%d,.+,\d+"%%(,)', + 'P SSC1 RE "SOCINFO:%%s,2,%%s,%%d,%%s,\d+"%%(,,,)'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK,pc tcp server accept成功 + + 4.OK + + 5.OK + + 6.OK + + 7.OK + + 8.OK + + 9.PC OK, target1 +ACCEPT:3,2,,port + + 10.+SOCINFO:,,, + + +SOCINFO:,,, + + +SOCINFO:, + + +SOCINFO:,,, + + +SOCINF0ALL' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1,本地ip target_ip\n3.target1上使用步骤2创建的socket1,去连接\ + \ PC的ip,test_tcp_port1,PC有ACCEPT\n4.target1上创建TCP socket2,本地ip target_ip\n5.target1上使用步骤4创建的socket2,去连接\ + \ PC的ip,test_tcp_port1,PC有ACCEPT\n6.target1 shutdown socket2 \n7.target1上创建TCP\ + \ socket3,本地端口random_port\n8.target1上使用步骤7创建的socket3,去监听\n9.PC CONNECT,\ + \ ,tcp 连接创建成功,创建socket4 \n10.target1 查询the socket information" + sub module: TCP + summary: STA mode, get active socket info test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) in different state + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0201 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [SOCR SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -i 0.0.0.0 -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,OK'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s -h B + - ['P SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: '1.ok + + 2.OK + + 3.ERROR + + 4.OK + + 5.OK + + 6.ERROR + + 7.OK + + 8.OK + + 9.OK + + 10.OK + + 11.OK + + 12.ERROR' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建UDP传输socket,bind到本地ip 0.0.0.0, + + 3.target1上使用步骤2创建的socket,去连接 PC的ip, + + 4.target1上创建TCP socket + + 5.target1上使用步骤4创建的socket,创建TCP 监听 + + 6.target1上使用步骤4创建的socket,去连接 PC的ip, + + 7.target1上创建TCP socket + + 8.target1上使用步骤7创建的socket,去连接 PC的ip, + + 9.target1上关闭步骤7创建的socket + + 10.target1上使用步骤7创建的socket,去连接 PC的ip, + + 11.target1上关闭所有创建的socket + + 12.target1上使用步骤2创建的socket,去连接 PC的ip,' + sub module: TCP + summary: STA mode, connect test. use socket in state that can't connect + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) in different state + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_DHCP_0101 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 dhcp -E -o 1 + - ['R SSC1 C +DHCP:STA,OK'] + - - SSC SSC1 ip -S -i 0.0.0.0 + - ['R SSC1 C +IP:OK'] + - - SSC SSC1 sta -C -s -p + - [''] + - - DELAY 20 + - [P PC_COM C +DELAYDONE, 'P SSC1 NC +JAP:CONNECTED'] + - - SSC SSC1 dhcp -S -o 1 + - ['R SSC1 C +DHCP:STA,OK'] + - - SSC SSC1 ip -Q + - ['R SSC1 C +STAIP:0.0.0.0'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC1 ip -Q + - ['R SSC1 RE "\+STAIP:%%s"%%()'] + comment: '' + execution time: 0.0 + expected result: "1.target1 关闭DHCP OK\n2.target1 设置ip add OK\n3.target1 连接AP fail\n\ + 4.target1 打开DHCP OK\n5.查询到sta ip \n6.target1 连接AP ok\n7.查询到sta ip 为target_ip" + initial condition: STAAP1 + initial condition description (auto): testing sta on sta + ap mode, quit AP (autogen + by STAM1) + module: TCPIP + steps: "1.target1 关闭DHCP OK\n2.target1 设置ip add OK\n3.target1 连接AP fail\n4.target1\ + \ 打开DHCP OK\n5.查询到sta ip \n6.target1 连接AP ok\n7.查询到sta ip 为target_ip" + sub module: DHCP + summary: dhcp client function test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP client function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0203 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s + - ['R SSC1 RE SEND:\d+,ERROR'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s + - ['R SSC1 RE SEND:\d+,ERROR'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -S -s + - ['R SSC1 RE SEND:\d+,ERROR'] + - - SSC SSC1 soc -S -s 1000 + - ['R SSC1 RE SEND:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.ERROR + + 4.OK + + 5.ERROR + + 6.OK + + 7.OK + + 8.ERROR + + 9.ERROR' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建UDP传输socket1, + + 3.target1上使用步骤2创建的socket1,去发送数据 + + 4.target1上创建TCP socket2 + + 5.target1上使用步骤4创建的socket2,去发送数据 + + 6.target1上使用步骤4创建的socket2,创建TCP连接,连接成功 + + 7.target1上shutdown 步骤4的socket2 + + 8.target1往socket2发送错误命令发送数据 + + 9.target1上不指定socket往上发送数据' + sub module: TCP + summary: send test. use socket in state that can't send + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) in different state + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0202 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,ERROR'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,ERROR'] + - - SSC SSC1 soc -D -s + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,ERROR'] + - - SSC SSC1 soc -L -s 1000 + - ['R SSC1 RE LISTEN:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.ERROR + + 4.OK + + 5.OK + + 6.ERROR + + 7.OK + + 8.ERROR + + 9.ERROR' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建UDP传输socket,bind到本地ip 0.0.0.0, + + 3.target1上使用步骤2创建的socket,去建立TCP 监听 + + 4.target1上创建TCP socket + + 5.target1上使用步骤4创建的socket,去连接 PC的ip, + + 6.target1上使用步骤4创建的socket,创建TCP 监听 + + 7.target1上shutdown 步骤4的socket + + 8.target1上使用步骤4创建的socket,创建TCP 监听 + + 9.target1上使用不存在socket,创建TCP 监听' + sub module: TCP + summary: STA mode, server listen test. use socket in state that can't listen + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) in different state + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0208 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,ERROR'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,ERROR'] + - - SSC SSC1 soc -D -s + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,ERROR'] + - - SSC SSC1 soc -L -s 1000 + - ['R SSC1 RE LISTEN:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.ERROR + + 4 OK + + 5.OK + + 6.ERROR + + 7.OK + + 8.ERROR + + 9.ERROR' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建UDP传输socket,bind到本地ip 0.0.0.0, + + 3.target1上使用步骤2创建的socket,去建立TCP 监听 + + 4.target1上创建TCP socket + + 5.target1上使用步骤4创建的socket,去连接 PC的ip, + + 6.target1上使用步骤4创建的socket,创建TCP 监听 + + 7.target1上shutdown 步骤4的socket + + 8.target1上使用步骤4创建的socket,创建TCP 监听 + + 9.target1上使用不存在socket,创建TCP 监听' + sub module: TCP + summary: AP mode, server listen test. use socket in state that can't listen + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) in different state + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_DNS_0103 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -H -d iot.espressif.cn + - ['R SSC1 A :\+HOSTIP:OK,(.+)\r\n'] + - - SSC SSC1 soc -B -t UDP + - ['R SSC1 A :\+BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p 9003 -l 10 + - ['P SSC1 RE \+SEND:\d+,OK', P SSC1 SL +10] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: '1. get host name "espressif.cn" + + 2. sendto, recvfrom1. get host name "espressif.cn" + + 2. sendto, recvfrom' + sub module: DNS + summary: UDP send to iot.expressif.com + test environment: SSC_T1_2 + test environment description (auto): 'Able to access WAN after connect to AP. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DNS function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_DHCP_0206 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - LOOP 4 4 "['01','02','03','01']" "[2,3,4,2]" + - [''] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:OK'] + - - SSC SSC2 mac -S -o 1 -m 10:22:33:44:55:{%s} + - ['R SSC2 C +MAC:STA,OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC2 ip -Q -o 1 + - ['R SSC2 C +STAIP:192.168.4.{%s}'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 4. get IP 192.168.4.2 - 192.168.4.4 + + 5. get IP 192.168.4.2' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + module: TCPIP + steps: '1. config softap to a random ssid + + 2. disable DHCP server, do config and enable + + 3. target2 change mac, connect to softap, disconnect + + 4. Loop step3 twice + + 5. change to first mac, connect to softap' + sub module: DHCP + summary: dhcp server assign same IP to same MAC when it's not released + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_DHCP_0207 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - WIFI CONN 192.168.4.2 + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - WIFI DISCONN2 + - ['R PC_COM NC ERROR C +WIFIDISCONN:OK'] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:OK'] + - - SSC SSC2 mac -S -o 1 -m 10:22:33:44:55:66 + - ['R SSC2 C +MAC:STA,OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC2 ip -Q -o 1 + - ['R SSC2 C +STAIP:192.168.4.2'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. get IP 192.168.4.2 + + 4. succeed + + 5. succeed + + 6. get IP 192.168.4.2' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + module: TCPIP + steps: '1. config softap to a random ssid + + 2. disable DHCP server, do config and enable + + 3. PC WIFI NIC connect to target1 softap + + 4. target2 connect to target1 softap and disnnect + + 5. PC release IP and disconnected + + 6. target2 change mac and connect to target1' + sub module: DHCP + summary: dhcp server prefer assign released IP to new client + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_DHCP_0204 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.3 -t 1 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC2 ip -Q -o 1 + - ['R SSC2 C +STAIP:192.168.4.2'] + - - DELAY 90 + - [''] + - - SSC SSC2 ip -Q -o 1 + - ['R SSC2 C +STAIP:192.168.4.2'] + - - SSC SSC2 sta -D + - ['R SSC2 C +JAP:DISCONNECTED'] + - - DELAY 60 + - [''] + - - SSC SSC2 mac -S -o 1 -m 10:22:33:44:55:66 + - ['R SSC2 C +MAC:STA,OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC2 ip -Q -o 1 + - ['R SSC2 C +STAIP:192.168.4.2'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. get IP 192.168.4.2 + + 5. succeed + + 6. succeed + + 8. get IP 192.168.4.2' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + module: TCPIP + steps: '1. config softap to a random ssid + + 2. config DHCP timeout as 1 minute + + 3. target2 connect to target1 + + 4. wait 90 seconds + + 5. check if target2 IP is same + + 6. target2 disconnect + + 7. wait 60s + + 8. target2 change mac and connect to target1' + sub module: DHCP + summary: dhcp server timeout test + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_DHCP_0205 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.3 -t 1 + - ['P SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['P SSC1 C +DHCP:AP,OK', 'P SSC2 C +JAP:DISCONNECTED'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. target2 wifi disconnected' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + module: TCPIP + steps: '1. config softap to a random ssid + + 2. target2 connect to target1 + + 3. disable DHCP server, do config and enable' + sub module: DHCP + summary: disconnect STA if config dhcp server + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_DHCP_0202 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - LOOP 3 4 "['01','02','03']" "[2,3,4]" + - [''] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:OK'] + - - SSC SSC2 mac -S -o 1 -m 10:22:33:44:55:{%s} + - ['R SSC2 C +MAC:STA,OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC2 ip -Q -o 1 + - ['R SSC2 C +STAIP:192.168.4.{%s}'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3,4: get IP from dhcp pool with correct sequence' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + module: TCPIP + steps: '1. config softap to a random ssid + + 2. config DHCP Server on Target1 + + 3. target change mac, connect to Target1 + + 4. Loop step3' + sub module: DHCP + summary: dhcp server ip pool + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_DHCP_0203 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.3 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - LOOP 2 4 "['01','02']" "[2,3]" + - [''] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:OK'] + - - SSC SSC2 mac -S -o 1 -m 10:22:33:44:55:{%s} + - ['R SSC2 C +MAC:STA,OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC2 ip -Q -o 1 + - ['R SSC2 C +STAIP:192.168.4.{%s}'] + - - SSC SSC2 mac -S -o 1 -m 10:22:33:44:55:66 + - ['R SSC2 C +MAC:STA,OK'] + - - DELAY 20 + - [''] + - - SSC SSC2 ip -Q -o 1 + - ['R SSC2 C +STAIP:0.0.0.0'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. succeed + + 4.1 succeed + + 4.2 failed' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + module: TCPIP + steps: '1. config softap to a random ssid + + 2. config DHCP Server on Target1(.4.2 - .4.3) + + 3. target change mac, connect to Target1 + + 4. Loop step3 twice' + sub module: DHCP + summary: dhcp server ip pool empty + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0204 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SSC SSC1 soc -W -s -o 0 + - ['R SSC1 RE WORKTHREAD:\d+,OK'] + - - SOC SOC2 SEND 146000 + - [P SOC_COM R *] + - - SSC SSC1 soc -W -s -o 1 + - ['P SSC1 RE WORKTHREAD:\d+,OK', P SSC1 SL +2920] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK,pc server accept OK + + 4.OK + + 5.OK + + 6.OK + + 7.target收到146000 byte' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: '1. PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket + + 3.target1上使用步骤2创建的socket,去连接 PC的ip,test_tcp_port1 + + 4.PC与target1 创建好TCP 连接,有ACCEPT + + 5.target上不进行recv + + 6.PC send 100 * 1460 data to target, + + 7.在target上开始recv' + sub module: TCP + summary: STA mode, recv buffer test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) in different state + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_DHCP_0201 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 ip -S -o 2 -i + - ['R SSC1 C +IP:OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.1 -e 192.168.4.10 + - ['R SSC1 C +DHCP:LEASE,ERROR'] + - - SSC SSC1 dhcp -L -s 192.168.4.5 -e 192.168.4.2 + - ['R SSC1 C +DHCP:LEASE,ERROR'] + - - SSC SSC1 dhcp -L -s 192.168.2.2 -e 192.168.2.5 + - ['R SSC1 C +DHCP:LEASE,ERROR'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + comment: '' + execution time: 0.0 + expected result: '1.target1 关闭DHCP 2 OK + + 2.target1 设置ip 成功 + + 3.设置dhcp 地址池 OK + + 4.ERROR + + 5.ERROR + + 6.ERROR + + 7.target1 打开DHCP ok' + initial condition: APM1 + initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial + condition APSTA1 + module: TCPIP + steps: "1.target1 关闭DHCP 2 \n2.target1 设置ip \n3.设置dhcp 地址池\n4.设置dhcp错误的参数\n5.设置dhcp错误的参数\n\ + 6.设置dhcp错误的参数\n7.target1 打开DHCP ok" + sub module: DHCP + summary: server dhcp lease test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0208 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,ERROR'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,ERROR'] + - - SSC SSC1 soc -D -s + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,ERROR'] + - - SSC SSC1 soc -L -s 1000 + - ['R SSC1 RE LISTEN:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.ERROR + + 4 OK + + 5.OK + + 6.ERROR + + 7.OK + + 8.ERROR + + 9.ERROR' + initial condition: APSTA2 + initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen + by APM2) + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建UDP传输socket,bind到本地ip 0.0.0.0, + + 3.target1上使用步骤2创建的socket,去建立TCP 监听 + + 4.target1上创建TCP socket + + 5.target1上使用步骤4创建的socket,去连接 PC的ip, + + 6.target1上使用步骤4创建的socket,创建TCP 监听 + + 7.target1上shutdown 步骤4的socket + + 8.target1上使用步骤4创建的socket,创建TCP 监听 + + 9.target1上使用不存在socket,创建TCP 监听' + sub module: TCP + summary: AP mode, server listen test. use socket in state that can't listen + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) in different state + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_DHCP_0208 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['P SSC1 C +DHCP:AP,OK', 'P SSC2 C +JAP:DISCONNECTED'] + - - SSC SSC2 sta -D + - ['R SSC2 C +JAP:DISCONNECTED'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - WIFI CONN 192.168.4.2 + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - SSC SSC1 ap -L + - [R SSC1 C 192.168.4.2 P ] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. succeed + + 4. get IP 192.168.4.2 + + 5. can only find target2 with IP 192.168.4.2' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + module: TCPIP + steps: '1. config softap to a random ssid + + 2. PC NIC connect to target1 softap + + 3. disable DHCP server, do config and enable + + 4. target2 connect to target1 softap + + 5. softap list connected station' + sub module: DHCP + summary: dhcp server reconfig and new client able to get first IP in pool + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_DHCP_0209 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - WIFI CONN 192.168.4.2 + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - DELAY 20 + - [''] + - - SSC SSC1 ap -L + - [R SSC1 C 192.168.4.2 C 192.168.4.3 P P ] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. succeed + + 4. succeed + + 5. find target2 and PC' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + module: TCPIP + steps: '1. config softap to a random ssid + + 2. target2 connect to target1 softap + + 3. disable DHCP server, do config and enable + + 4. PC NIC connect to target1 softap + + 5. softap list connected station' + sub module: DHCP + summary: dhcp server reconfig, old client and new client able to get IP + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0412 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.OK + + 7.OK' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket1 + + 3.target1上使用步骤2创建的socket1,去连接 PC的ip,test_tcp_port1 + + 4.PC与target1创建好TCP 连接,有ACCEPT + + 5.target1上创建TCP socket2 + + 6.关闭socket1 连接 + + 7.关闭socket2连接' + sub module: TCP + summary: close TCP send after socket changed + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: TCP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0411 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -l 5 + - ['P SSC1 RE SEND:\d+,ERROR'] + - - SSC SSC1 soc -S -s -l 5 + - ['P SSC1 RE SEND:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.ERROR + + 7.OK' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket1 + + 3.target1上使用步骤2创建的socket1,去连接 PC的ip,test_tcp_port1 + + 4.PC与target1创建好TCP 连接,有ACCEPT + + 5.target1上创建TCP socket2 + + 6.8266往PC socket2上发送5字节数据 + + 7.8266往PC socket1上发送5字节数据' + sub module: TCP + summary: do TCP send after socket changed + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: TCP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_CONN_0901 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: basic function + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC1 sta -D + - ['R SSC1 C +JAP:DISCONNECTED,0,8'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:DISCONNECTED,2,15'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:DISCONNECTED,1,201'] + comment: '' + execution time: 0.0 + expected result: '1. disconnect event reason REASON_ASSOC_LEAVE + + 2. disconnect event reason REASON_4WAY_HANDSHAKE_TIMEOUT + + 3. disconnect event reason REASON_NO_AP_FOUND' + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + module: WIFI MAC + steps: '1. sta connect to AP, and disconnect + + 2. connect to AP with wrong password + + 3. connect to AP not exist' + sub module: WIFI Connect + summary: test wifi disconnect reason REASON_ASSOC_LEAVE, REASON_4WAY_HANDSHAKE_TIMEOUT, + REASON_NO_AP_FOUND + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: wifi disconnect reason test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_CONN_0902 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - APC OFF + - [P PC_COM L OK, 'R SSC1 C +JAP:DISCONNECTED,1,200'] + - - APC ON + - [P PC_COM L OK] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. disconnect event REASON_BEACON_TIMEOUT' + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + module: WIFI MAC + steps: '1. connect to AP + + 2. AP power off' + sub module: WIFI Connect + summary: test wifi disconnect reason REASON_BEACON_TIMEOUT + test environment: SSC_T1_APC + test environment description (auto): "PC has 1 wired NIC connected to AP.\nPC has\ + \ 1 wired NIC connected to APC (static IP within the same subnet with APC). \n\ + APC control AP power supply. \nPC has 1 WiFi NIC. \n1 SSC target connect with\ + \ PC by UART." + test point 1: basic function + test point 2: wifi disconnect reason test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_ARP_0203 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - STRING ether%20src%20%%s%20or%20ether%20dst%20%%s + + - [R PC_COM C OK] + - - NIC NIC1 START capture+send+block_arp_ip + - ['R PC_COM C +NIC_START:OK'] + - - NIC NIC1 SEND ARP arp_op_code "request" arp_target_proto_addr arp_hw_len + 10 ethernet_dst_addr "ff:ff:ff:ff:ff:ff" + - [''] + - - DELAY 2 + - [P PC_COM C +DELAYDONE, P NIC1 NPDU (Ethernet.dst_addr=)(Ethernet.len_type="ARP")] + - - NIC NIC1 SEND ARP arp_op_code "request" arp_target_proto_addr arp_proto_len + 10 ethernet_dst_addr "ff:ff:ff:ff:ff:ff" + - [''] + - - DELAY 2 + - [P PC_COM C +DELAYDONE, P NIC1 NPDU (Ethernet.dst_addr=)(Ethernet.len_type="ARP")] + comment: '' + execution time: 0.0 + expected result: 1. PC can't recv ARP reply from target + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: 1. PC send ARP req with hw_addr_len and proto_addr_len not correct + sub module: ARP + summary: PC send invalid ARP request to target 3 + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: handling ARP request + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_CONN_0903 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -C -s -p bacfd + - ['R SSC1 C +JAP:DISCONNECTED,4,2'] + comment: '' + execution time: 0.0 + expected result: 1. disconect event reason REASON_AUTH_EXPIRE + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + module: WIFI MAC + steps: 1. connect WEP ap with error password (valid wep password) + sub module: WIFI Connect + summary: test wifi disconnect reason REASON_AUTH_EXPIRE + test environment: SSC_T1_WEP + test environment description (auto): '1 SSC target connect with PC by UART. + + One WEP share key AP placed near SSC1.' + test point 1: basic function + test point 2: wifi disconnect reason test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_CONN_0503 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -R -r 0 + - [R SSC1 C OK] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:OK', 'R SSC1 NC +JAP:DISCONNECTED,1 C +JAP:DISCONNECTED,3'] + - - DELAY 5 + - ['R SSC1 NC +JAP:DISCONNECTED', P PC_COM C +DELAYDONE] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:OK', 'R SSC1 NC +JAP:DISCONNECTED,1 C +JAP:DISCONNECTED,2'] + - - DELAY 5 + - ['R SSC1 NC +JAP:DISCONNECTED', P PC_COM C +DELAYDONE] + - - SSC SSC1 sta -R -r 1 + - [SSC SSC1 C OK] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. not reconnect when connect failed, status when recv disconnect event is correct + + 3. not reconnect when connect failed, status when recv disconnect event is correct + + 4. succeed' + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + module: WIFI MAC + steps: '1. set sta reconnect policy as not reconnect + + 2. sta connect to ap not exist + + 3. sta connect to ap with wrong password + + 4. reset sta reconnect policy as auto reconnect + + ' + sub module: WIFI Connect + summary: reconnect policy interact with failed STA connect/reconnect + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: reconnect policy test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_UDP_0112 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK' + initial condition: APSTA2 + initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen + by APM2) + module: TCPIP + steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 2.关闭socket1' + sub module: UDP + summary: AP mode, close UDP sockets test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_UDP_0114 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -I + - ['P SSC1 RE "SOCINFO:%%s,1,.+,%%d"%%(,)'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK' + initial condition: APSTA2 + initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen + by APM2) + module: TCPIP + steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 2.target1上查询创建socket信息' + sub module: UDP + summary: AP mode, get active socket info test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^WIFI_CONN_0104 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t -m + 1 + - ['R SSC1 C +SAP:OK'] + - - WIFI DISCONN + - ['R PC_COM C +WIFIDISCONN:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] + - - WIFI CONN + + - ['R PC_COM C +WIFICONN:ERROR'] + comment: '' + execution time: 0.0 + expected result: '1. target1 set AP,set max allowed sta as 1 + + 2. use PC disconnect, + + 3.target 2 jap succeed + + 4.PC WIFI can not CONN' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1.target1下设置ssid 和pwd 加密方式,set max allowed sta as 1 + + 2.use PC disconnect target1 + + 3.target 2 jap target1 + + 4.PC WIFI CONNECT target1' + sub module: WIFI Connect + summary: station SAP test, max allowed sta + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: SAP/JAP with different config + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_UDP_0202 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -W -s -o 0 + - ['R SSC1 RE WORKTHREAD:\d+,OK'] + - - SOC SOC1 SENDTO 1472 + - [''] + - - SOC SOC1 SENDTO 1472 + - [''] + - - SOC SOC1 SENDTO 1472 + - [''] + - - SOC SOC1 SENDTO 1472 + - [''] + - - SOC SOC1 SENDTO 1472 + - [''] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.PC OK + + 5.PC OK + + 6.PC OK + + 7.PC OK + + 8.PC OK SOC_CLOSE=SOC1' + initial condition: APSTA2 + initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen + by APM2) + module: TCPIP + steps: '1.PC上SOC1 UDP传输,bing + + 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 3.target1上关闭工作线程 + + 4.PC往8266上发送1472字节数据 + + 5.PC往8266上发送1472字节数据 + + 6.PC往8266上发送1472字节数据 + + 7.PC往8266上发送1472字节数据 + + 8.PC往8266上发送1472字节数据' + sub module: UDP + summary: AP mode, recv buffer test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: use UDP SAP (socket/espconn API) in different state + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_IGMP_0103 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 igmp -J -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 igmp -L -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 igmp -J -h -m 223.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -J -h -m 240.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -J -h 192.168.237.77 -m 224.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -J -h 192.168.237.77 -m 240.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + comment: '' + execution time: 0.0 + expected result: '1. success + + 2. failed + + 3. failed + + 4. failed' + initial condition: APSTA2 + initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen + by APM2) + module: TCPIP + steps: '1. join group with correct host addr and multicast addr + + 2. join group with correct host addr and wrong multicast addr + + 3. join group with wrong host addr and correct multicast addr + + 4. join group with wrong host addr and wrong multicast addr' + sub module: IGMP + summary: softAP IGMP join group address check + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: IGMP API parameter check + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_CONN_0101 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -t 0 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC1 ap -S -s -p -t 2 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC1 ap -S -s -p -t 1 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -S + - ['R SSC2 RE "\+SCAN:%%s,.+,0,\d+"%%()'] + - - SSC SSC1 ap -S -s -p -t 5 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -S + - ['R SSC2 RE "\+SCAN:%%s,.+,0,\d+"%%()'] + comment: '' + execution time: 0.0 + expected result: "1.target1 set AP,open, \n2.target 2 jap succeed\n3.target1 set\ + \ AP,wpa_psk \n4.target 2 jap succeed\n5.target1 set AP, wpa2_psk \n6.target 2\ + \ jap succeed\n7.target1 set AP,wap_wpa2_psk\n8.target 2 jap succeed\n9.target1\ + \ set AP,加密方式为t 1\n10.target 2 上查询到target_ssid\n11.target1 set AP,加密方式为t 5\n12.target\ + \ 2 上查询到target_ssid" + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + module: WIFI MAC + steps: "1.target1下设置ssid 和pwd,加密方式 open\n2.target2 jap target1\n3.target1下设置ssid\ + \ 和pwd,加密方式 wpa_psk \n4.target2 jap target1\n5.target1下设置ssid 和pwd,加密方式 wpa2_psk\ + \ \n6.target 2 jap target1\n7.target1下设置ssid 和pwd,加密方式 wap_wpa2_psk\n8.target2\ + \ jap target1\n9.target1下设置ssid 和pwd,加密方式 wep \n10.target2上查询target_ssid\n11.target1下设置ssid\ + \ 和pwd,加密方式 t 5 错误的加密方式\n12.target2上查询 target_ssid" + sub module: WIFI Connect + summary: station SAP+JAP test, different encryption + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: SAP/JAP with different config + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_CONN_0102 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -t 0 -n 1 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC1 ap -S -s -t 0 -n 13 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC1 ap -S -s -n 15 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -S + - ['R SSC2 RE "\+SCAN:%%s,.+,\d+,1"%%()'] + comment: '' + execution time: 0.0 + expected result: '1. target1 set AP,set channel 1 + + 2.target 2 jap succeed + + 3.target1 set AP,set channel 10 + + 4.target 2 jap succeed + + 5.target1 set AP,set channel 15 + + 6.target 2 上查询到target_ssid' + initial condition: T2O_1 + initial condition description (auto): same as T2_1 but will NOT autogen a TC with + initial condition T2_2 + module: WIFI MAC + steps: '1. target1下设置ssid 和pwd 加密方式,set channel 1 + + 2.target2 jap target 1 + + 3.target1下设置ssid 和pwd 加密方式,set channel 10 + + 4.target2 jap target 1 + + 5.target1下设置ssid 和pwd 加密方式,set channel 15 + + 6.target 2 上查询target_ssid' + sub module: WIFI Connect + summary: station SAP+JAP test, different channel + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: SAP/JAP with different config + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_CONN_0103 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t -h + 0 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -S -h 0 + - [R SSC2 P , R SSC2 C +SCANDONE] + - - SSC SSC1 ap -S -s -p -t -h + 1 + - ['R SSC1 C +SAP:OK'] + - - DELAY 3 + - [''] + - - SSC SSC2 sta -S -h 0 + - [R SSC2 C +SCANDONE] + - - DELAY 3 + - [''] + - - SSC SSC2 sta -S -h 0 + - [R SSC2 NP C +SCANDONE] + comment: '' + execution time: 0.0 + expected result: '1.target1 set AP,set ssid broad cast + + 2.target 2上scan target_ap_mac + + 3.target1 set AP,set ssid hidden, + + 4.target 2上不能scan target_ap_mac' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + module: WIFI MAC + steps: '1. target1下设置ssid 和pwd 加密方式,set ssid broad cast + + 2.target 2上scan target_ap_mac + + 3. target1下设置ssid 和pwd 加密方式,set ssid hidden, + + 4.target 2上scan target_ap_mac' + sub module: WIFI Connect + summary: station SAP+JAP test, ssid hidden + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: SAP/JAP with different config + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_IP_0101 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 dhcp -S -o 1 + - ['R SSC1 C +DHCP:STA,OK'] + - - SSC SSC1 ip -S -o 1 -i 192.168.123.123 + - ['R SSC1 C +IP:ERROR'] + - - SSC SSC1 dhcp -E -o 1 + - ['R SSC1 C +DHCP:STA,OK'] + - - SSC SSC1 ip -S -o 1 -i 192.168.123.123 + - ['R SSC1 C +IP:OK'] + - - SSC SSC1 ip -Q -o 1 + - ['R SSC1 C +STAIP:192.168.123.123'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.ERROR + + 3.OK + + 4.OK + + 5.STAIP:192.168.123.123' + initial condition: STAAP1 + initial condition description (auto): testing sta on sta + ap mode, quit AP (autogen + by STAM1) + module: TCPIP + steps: '1.target1 打开DHCP 1 + + 2.target1 设置sta ip 192.168.123.123 + + 4.target1 关闭DHCP 1 + + 5.target1 设置sta ip 192.168.123.123 + + 6.target1 查询 当前sta ip' + sub module: IP + summary: sta set and query static ip test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: set and query static IP + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^WIFI_CONN_0702 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:OK', 'R SSC1 C +JAP:DISCONNECTED,3'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:OK', 'R SSC1 C +JAP:DISCONNECTED,2'] + comment: '' + execution time: 0.0 + expected result: '1. get status AP not exist in disconnect event + + 2. get status wrong password in disconnect event' + initial condition: STAAP1 + initial condition description (auto): testing sta on sta + ap mode, quit AP (autogen + by STAM1) + module: WIFI MAC + steps: '1. sta connect to ap not exist + + 2. sta connect to ap with wrong password' + sub module: WIFI Connect + summary: check wifi status wrong password, no ap found + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: wifi connect status check + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_CONN_0801 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 0 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 ap -S -s -p -t 2 + - ['P SSC1 C +SAP:OK', 'P SSC2 C +JAP:AUTHCHANGED,2,0'] + - - SSC SSC1 ap -S -s -p -t 3 + - ['P SSC1 C +SAP:OK', 'P SSC2 C +JAP:AUTHCHANGED,3,2'] + - - SSC SSC1 ap -S -s -p -t 4 + - ['P SSC1 C +SAP:OK', 'P SSC2 C +JAP:AUTHCHANGED,4,3'] + - - SSC SSC1 ap -S -s -p -t 0 + - ['P SSC1 C +SAP:OK', 'P SSC2 C +JAP:AUTHCHANGED,0,4'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. auth change event old mode 0 new mode 2 + + 4. auth change event old mode 2 new mode 3 + + 5. auth change event old mode 3 new mode 4 + + 6. auth change event old mode 4 new mode 0' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + module: WIFI MAC + steps: '1. set target1 softap auth mode 0 + + 2. target2 connect to target1 + + 3. set target1 softap auth mode 2, wait sta connected + + 4. set target1 softap auth mode 3, wait sta connected + + 5. set target1 softap auth mode 4, wait sta connected + + 6. set target1 softap auth mode 0, wait sta connected' + sub module: WIFI Connect + summary: test auth change event + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: wifi auth changed event test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^WIFI_CONN_0101 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -t 0 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC1 ap -S -s -p -t 2 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC1 ap -S -s -p -t 1 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -S + - ['R SSC2 RE "\+SCAN:%%s,.+,0,\d+"%%()'] + - - SSC SSC1 ap -S -s -p -t 5 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -S + - ['R SSC2 RE "\+SCAN:%%s,.+,0,\d+"%%()'] + comment: '' + execution time: 0.0 + expected result: "1.target1 set AP,open, \n2.target 2 jap succeed\n3.target1 set\ + \ AP,wpa_psk \n4.target 2 jap succeed\n5.target1 set AP, wpa2_psk \n6.target 2\ + \ jap succeed\n7.target1 set AP,wap_wpa2_psk\n8.target 2 jap succeed\n9.target1\ + \ set AP,加密方式为t 1\n10.target 2 上查询到target_ssid\n11.target1 set AP,加密方式为t 5\n12.target\ + \ 2 上查询到target_ssid" + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: "1.target1下设置ssid 和pwd,加密方式 open\n2.target2 jap target1\n3.target1下设置ssid\ + \ 和pwd,加密方式 wpa_psk \n4.target2 jap target1\n5.target1下设置ssid 和pwd,加密方式 wpa2_psk\ + \ \n6.target 2 jap target1\n7.target1下设置ssid 和pwd,加密方式 wap_wpa2_psk\n8.target2\ + \ jap target1\n9.target1下设置ssid 和pwd,加密方式 wep \n10.target2上查询target_ssid\n11.target1下设置ssid\ + \ 和pwd,加密方式 t 5 错误的加密方式\n12.target2上查询 target_ssid" + sub module: WIFI Connect + summary: station SAP+JAP test, different encryption + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: SAP/JAP with different config + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_ARP_0201 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - STRING ether%20src%20%%s%20or%20ether%20dst%20%%s + + - [R PC_COM C OK] + - - NIC NIC1 START capture+send+block_arp_ip + - ['R PC_COM C +NIC_START:OK'] + - - NIC NIC1 SEND ARP arp_op_code "request" arp_hw_type 0xF1F1 arp_target_proto_addr + ethernet_dst_addr "ff:ff:ff:ff:ff:ff" + - [''] + - - DELAY 2 + - [P PC_COM C +DELAYDONE, P NIC1 NPDU (Ethernet.dst_addr=)(Ethernet.len_type="ARP")] + - - NIC NIC1 SEND ARP arp_op_code "request" arp_proto_type 0xF1F1 arp_target_proto_addr + ethernet_dst_addr "ff:ff:ff:ff:ff:ff" + - [''] + - - DELAY 2 + - [P PC_COM C +DELAYDONE, P NIC1 NPDU (Ethernet.dst_addr=)(Ethernet.len_type="ARP")] + comment: '' + execution time: 0.0 + expected result: 1. PC can't recv ARP reply from target + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: 1. PC send ARP req with unsupported hw type and protocol type + sub module: ARP + summary: PC send invalid ARP request to target 1 + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: handling ARP request + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: ^WIFI_CONN_0503 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -R -r 0 + - [R SSC1 C OK] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:OK', 'R SSC1 NC +JAP:DISCONNECTED,1 C +JAP:DISCONNECTED,3'] + - - DELAY 5 + - ['R SSC1 NC +JAP:DISCONNECTED', P PC_COM C +DELAYDONE] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:OK', 'R SSC1 NC +JAP:DISCONNECTED,1 C +JAP:DISCONNECTED,2'] + - - DELAY 5 + - ['R SSC1 NC +JAP:DISCONNECTED', P PC_COM C +DELAYDONE] + - - SSC SSC1 sta -R -r 1 + - [SSC SSC1 C OK] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. not reconnect when connect failed, status when recv disconnect event is correct + + 3. not reconnect when connect failed, status when recv disconnect event is correct + + 4. succeed' + initial condition: STAAP1 + initial condition description (auto): testing sta on sta + ap mode, quit AP (autogen + by STAM1) + module: WIFI MAC + steps: '1. set sta reconnect policy as not reconnect + + 2. sta connect to ap not exist + + 3. sta connect to ap with wrong password + + 4. reset sta reconnect policy as auto reconnect' + sub module: WIFI Connect + summary: reconnect policy interact with failed STA connect/reconnect + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: reconnect policy test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^WIFI_CONN_0502 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC2 sta -R -r 1 + - ['R SSC2 C +RECONN:OK'] + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - DELAY 5 + - ['R SSC2 C +JAP:DISCONNECTED'] + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - DELAY 10 + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:OK'] + - - DELAY 10 + - [P PC_COM C +DELAYDONE, 'P SSC2 NC +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: '1.target1 set AP + + 2.target2 jap target 1 + + 3.设置reconn,开启(此功能不需要重启系统) + + 4.target2 断开target1 连接 + + 5.等待10s,target2 自动重连target1 + + 6.target2 断开target1 连接' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1.target1下设置ssid 和pwd 加密方式 + + 2.target2 jap target 1 + + 3.设置reconn,开启(此功能不需要重启系统) + + 4.target2 断开target1 连接 + + 5.等待10s,target2 自动重连target1 + + 6.target2 断开target1 连接' + sub module: WIFI Connect + summary: will not do reconnect after manually disconnected + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: reconnect policy test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^WIFI_CONN_0501 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC2 sta -R -r 1 + - ['R SSC2 C +RECONN:OK'] + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - DELAY 10 + - [''] + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - DELAY 15 + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC2 sta -R -r 0 + - ['R SSC2 C +RECONN:OK'] + - - SSC SSC2 sta -R -r 2 + - ['R SSC2 C +RECONN:0'] + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - DELAY 10 + - [''] + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - DELAY 15 + - [P PC_COM C +DELAYDONE, 'P SSC2 NC +JAP:CONNECTED'] + - - SSC SSC2 sta -R -r 1 + - ['R SSC2 C +RECONN:OK'] + comment: '' + execution time: 0.0 + expected result: '1.设置reconn,开启(此功能不需要重启系统) + + 2.target1 set AP + + 3.target2 JAP target1 成功 + + 4.target2 断开target1 连接 + + 5.等待10s,target2 自动重连target1 + + 6.成功 + + 7.查询reconn状态,关闭 + + 8.修改mode 成功 + + 9.等待15s,target2 不会自动重连target1' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: "1.设置reconn,开启(此功能不需要重启系统)\n2.target1下设置ssid 和pwd 加密方式\n3.target2 JAP target1\ + \ \n4.target1 修改mode 为sta mode\n5.等待10s,target1 修改mode 为softAP mode\n6.设置reconn,关闭\n\ + 7.查询reconn状态,关闭\n8.target1 修改mode 为sta mode\n9.等待15s,target1 修改mode 为softAP mode" + sub module: WIFI Connect + summary: reconnect policy test + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: reconnect policy test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0115 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK,pc tcp server accept成功 + + 4 OK + + 5.OK,pc tcp server accept成功 + + 6.OK + + 7.OK,pc tcp server accept成功 + + 8 OK + + 9.OK,pc tcp server accept成功 + + 10.OK + + 11.OK,pc tcp server accept成功' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket1 + + 3.target1上使用步骤2创建的socket1,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 4.target1上创建TCP socket2 + + 5.target1上使用步骤4创建的socket2,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 6.target1上创建TCP socket3 + + 7.target1上使用步骤6创建的socket3,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 8.target1上创建TCP socket4 + + 9.target1上使用步骤8创建的socket4,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 10.target1上创建TCP socket5 + + 11.target1上使用步骤10创建的socket5,去连接 PC的ip,test_tcp_port1,PC有ACCEPT' + sub module: TCP + summary: AP mode, create max TCP sockets test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^WIFI_SCAN_0101 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC2 sta -S -s .,juhg123 + - ['R SSC2 NC +SCAN: C +SCANDONE'] + - - SSC SSC1 ap -S -s -p 123456789 -t 3 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -S -s + - ['R SSC2 C +SCAN:', R SSC2 P , 'R SSC2 NC +SCAN: C +SCANDONE'] + comment: '' + execution time: 0.0 + expected result: '1.target 2上不能scan .,juhg123 + + 2.target1 set AP + + 3.target2上查询到' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1.target 2 scan .,juhg123 + + 2.target1下设置ssid 和pwd 加密方式 + + 3.target2 scan ' + sub module: WIFI Scan + summary: scan with scan config ssid + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: scan with different config + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0114 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + - - SSC SSC1 soc -B -t TCP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,OK'] + - - SOC SOC2 CONNECT 0 + - ['R SSC1 A :ACCEPT:(\d+),\d+,.+,\d+'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.OK + + 6.OK,target1上accept 成功 + + 7.target1关闭socket1 + + 8.target1关闭socket2 + + 9.OK + + 10.OK,pc tcp server accept成功 + + 11.target1关闭socket1 + + 12.OK + + 13.OK,pc tcp server accept成功 + + 14.OK + + 15.target1关闭socket1' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + module: TCPIP + steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1关闭socket1\n\ + 4.target1上创建TCP socket 端口随机\n5.target1上使用步骤4创建的socket1,去监听\n6.PC CONNECT,\ + \ ,tcp 连接创建成功,创建socket2 \n7.target1关闭socket1\n8.target1关闭socket2\n\ + 9.target1上创建TCP socket1\n10.target1上使用步骤10创建的socket1,去连接 PC的ip,test_tcp_port1,PC有ACCEPT\n\ + 11.target1关闭socket1\n12.target1上创建TCP socket1\n13.target1上使用步骤13创建的socket1,去连接\ + \ PC的ip,test_tcp_port1,PC有ACCEPT\n14.target1shutdown socket1\n15.target1关闭socket1" + sub module: TCP + summary: AP mode, close for different types of TCP sockets test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0116 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -B -t TCP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,OK'] + - - SOC SOC2 CONNECT 0 + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] + - - SOC SOC3 CONNECT 0 + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] + - - SOC SOC4 CONNECT 0 + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] + - - SOC SOC5 CONNECT 0 + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] + - - SOC SOC6 CONNECT 0 + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] + comment: '' + execution time: 0.0 + expected result: '1.+BIND:0,OK,0.0.0.0 + + 2.OK + + 3.OK,pc tcp server accept成功 + + 4.OK,pc tcp server accept成功 + + 5.OK,pc tcp server accept成功 + + 6.OK,pc tcp server accept成功 + + 7.OK,pc tcp server accept成功' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + module: TCPIP + steps: "1.target1上创建TCP socket 端口随机\n2.target1上使用步骤4创建的socket1,去监听\n3.PC CONNECT,\ + \ ,tcp 连接创建成功,创建socket2 \n4.PC CONNECT, ,tcp 连接创建成功,创建socket3\ + \ \n5.PC CONNECT, ,tcp 连接创建成功,创建socket4 \n6.PC CONNECT,\ + \ ,tcp 连接创建成功,创建socket5 \n7.PC CONNECT, ,tcp 连接创建成功,创建socket6\ + \ " + sub module: TCP + summary: AP mode, accept max TCP client by server test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0111 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -B -t TCP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,OK'] + - - SOC SOC1 CONNECT 0 + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+', P SOC_COM C OK] + - - SOC SOC1 CONNECT 0 + - [P SOC_COM C ERROR, P SSC1 NC ACCEPT] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.PC TCP client accept + + 4.error' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + module: TCPIP + steps: '1.target1上创建TCP socket,bind到本地端口 + + 2.target1上使用步骤1创建的socket,创建TCP 监听 + + 3.PC TCP 连接到target1 , + + 4.PC tcp 连接到不存在的port ,' + sub module: TCP + summary: AP mode, server listen test. use different kinds of port + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0113 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s -h B + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s -h W + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s -h R + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK,pc tcp server accept成功 + + 4.OK + + 5.OK + + 6.OK,pc tcp server accept成功 + + 7.OK + + 8.OK + + 9.OK,pc tcp server accept成功 + + 10.OK' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + module: TCPIP + steps: '1. PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket + + 3.target1上使用步骤2创建的socket,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 4.target1 shutdown socket1 B + + 5.target1上创建TCP socket + + 6.target1上使用步骤5创建的socket,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 7.target1 shutdown socket2 W + + 8.target1上创建TCP socket + + 9.target1上使用步骤8创建的socket,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 10.target1 shutdown socket3 R' + sub module: TCP + summary: AP mode, shutdown basic test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0112 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SOC SOC2 SEND 5 + - [R SSC1 SL +5] + - - SSC SSC1 soc -S -s -l 5 + - ['P SSC1 RE SEND:\d+,OK', P SOC2 RL 5] + - - SOC SOC2 SEND 146000 + - [R SSC1 SL +146000] + - - SSC SSC1 soc -S -s -l 1460 -n 100 + - ['P SSC1 RE SEND:\d+,OK', P SOC2 RL 146000] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK,pc tcp server accept成功 + + 4.OK + + 5.target收到5byte数据 + + 6.PC收到5byte数据 + + 7.target收到146000 byte数据 + + 8.OK,PC 收到146000 byte数据' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + module: TCPIP + steps: '1. PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket + + 3.target1上使用步骤2创建的socket,去连接 PC的ip,test_tcp_port1 + + 4.PC与target1 创建好TCP 连接,有ACCEPT + + 5.PC send 5 bytes to 8266 + + 6.8266 send 5 bytes to PC + + 7. PC send 100 * 1460 data to 8266, + + 8.8266 send 100 * 1460 to PC. ' + sub module: TCP + summary: AP mode, send/recv basic test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) diff --git a/components/test/TestCaseScript/ATFunc/CmdInterruptTest.py b/components/test/TestCaseScript/ATFunc/CmdInterruptTest.py new file mode 100755 index 0000000000..e11ae6f1d8 --- /dev/null +++ b/components/test/TestCaseScript/ATFunc/CmdInterruptTest.py @@ -0,0 +1,130 @@ +from TCAction import TCActionBase +from NativeLog import NativeLog +from TCAction import CmdHandler +import time + + +ATCmdList = ["GMR", + "UART=115200,8,1,0,0", + "CWMODE=3", + "CWJAP=\"TL_WR845N_T\",\"1234567890\"", + "CWLAP", + "CWQAP", + "CWSAP=\"asdf\",\"123456789\",5,3", + "CWLIF", + "CWDHCP=3", + "AT+CWAUTOCONN", + "CIPSTAMAC=\"18:fe:34:97:f3:43\"", + "CIPAPMAC=\"1a:fe:34:97:f3:43\"", + "CIPSTA=\"192.168.1.2\"", + "CIPAP=\"192.168.4.1\"", + "CIPSTATUS", + "CIPSTART=\"UDP\",\"192.168.1.4\",6531,7895,1", + "CIPSTART=\"TCP\",\"192.168.1.4\",6531", + "CIPCLOSE", + "CIFSR", + "CIPMUX=1", + "CIPSERVER=1,4567", + "CIPMODE=0", + "CIPSTO=7200", + "PING=\"192.168.1.4\""] + + +class CmdInterruptTest(TCActionBase.CommonTCActionBase): + + def __init__(self, name, test_env, cmd_set, timeout=20, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + pass + + def load_and_exe_one_step(self, checker_stings, test_action_strings, fail_string, + check_freq=0.1, check_time=50, sleep_time=0.1): + # set checker for next executing step + checkers = CmdHandler.parse_results(checker_stings, self.test_env) + self.result_cntx.set_next_step(checkers, check_time, check_freq) + # execute 1 step + for action_string in test_action_strings: + test_action = CmdHandler.parse_action(action_string, self.test_env) + CmdHandler.do_actions(test_action, self.test_env) + time.sleep(sleep_time) + + ret = self.wait_to_execute() + + if ret is False: # # timeout + self.result_cntx.set_result(fail_string) + if ret == check_time: + self.result_cntx.set_result(fail_string) + ret = False + + self.require_waiting() + + return ret + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + # step 1, sleep time 0.1 + for cmd1 in ATCmdList: + # check if match CMD - AT - busy - OK/ERROR pattern + checker_stings = ["ATR AT1 C busy", "ATR AT1 R *"] + test_action_string = ["ATS AT1 AT+%s" % cmd1, "ATS AT1 AT"] + fail_string = "Fail, Fail on step 1" + if self.load_and_exe_one_step(checker_stings, test_action_string, + fail_string, sleep_time=0.1) is False: + # check again if match CMD - OK/ERROR - AT - OK pattern + checker_stings = ["ATR AT1 R *", "ATR AT1 C AT L OK"] + test_action_string = ["ATS AT1 AT+%s" % cmd1, "ATS AT1 AT"] + fail_string = "Fail, Fail on step 1" + if self.load_and_exe_one_step(checker_stings, test_action_string, + fail_string, sleep_time=0.1) is False: + NativeLog.add_trace_critical("CMD Fail: AT+%s; sleep time is 0.1" % cmd1) + + # step 2, sleep time 0 + for cmd1 in ATCmdList: + # check if match CMD - AT - busy - OK/ERROR pattern + checker_stings = ["ATR AT1 C busy", "ATR AT1 R *"] + test_action_string = ["ATS AT1 AT+%s" % cmd1, "ATS AT1 AT"] + fail_string = "Fail, Fail on step 1" + if self.load_and_exe_one_step(checker_stings, test_action_string, + fail_string, sleep_time=0.1) is False: + # check again if match CMD - OK/ERROR - AT - OK pattern + checker_stings = ["ATR AT1 R *", "ATR AT1 C AT L OK"] + test_action_string = ["ATS AT1 AT+%s" % cmd1, "ATS AT1 AT"] + fail_string = "Fail, Fail on step 1" + if self.load_and_exe_one_step(checker_stings, test_action_string, + fail_string, sleep_time=0.1) is False: + NativeLog.add_trace_critical("CMD Fail: AT+%s; sleep time is 0" % cmd1) + + # step 3, cat string + for cmd1 in ATCmdList: + # check if match CMD - AT - busy - OK/ERROR pattern + checker_stings = ["ATR AT1 C busy", "ATR AT1 R *"] + test_action_string = ["ATSO AT1 AT+%s\r\nAT\r\n" % cmd1] + fail_string = "Fail, Fail on step 1" + if self.load_and_exe_one_step(checker_stings, test_action_string, + fail_string, sleep_time=0.1) is False: + # check again if match CMD - OK/ERROR - AT - OK pattern + checker_stings = ["ATR AT1 R *", "ATR AT1 C AT L OK"] + test_action_string = ["ATS AT1 AT+%s" % cmd1, "ATS AT1 AT"] + fail_string = "Fail, Fail on step 1" + if self.load_and_exe_one_step(checker_stings, test_action_string, + fail_string, sleep_time=0.1) is False: + NativeLog.add_trace_critical("CMD Fail: AT+%s; cat string" % cmd1) + + # finally, execute done + self.result_cntx.set_result("Succeed") + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + +if __name__ == '__main__': + main() + diff --git a/components/test/TestCaseScript/ATFunc/LAP.py b/components/test/TestCaseScript/ATFunc/LAP.py new file mode 100644 index 0000000000..b389e48c04 --- /dev/null +++ b/components/test/TestCaseScript/ATFunc/LAP.py @@ -0,0 +1,64 @@ +from TCAction import TCActionBase +import time +import re + + +class LAP(TCActionBase.CommonTCActionBase): + def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + pass + + def cleanup(self): + # restore set LAPOPT + if self.load_and_exe_one_step(["R AT1 L OK"], + ["ATS AT1 AT+CWLAPOPT=0,127"], + "Failed to set LAP option") is False: + return + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + # step 1. set LAPOPT + if self.load_and_exe_one_step(["R AT1 L OK"], + ["ATS AT1 AT+CWLAPOPT=1,4"], + "Failed to set LAP option") is False: + return + + # step 2. LAP + if self.load_and_exe_one_step(["R AT1 A :([[^OK]]+)OK"], # [] is list generator, use [[]] for [] + ["ATS AT1 AT+CWLAP"], + "Failed to LAP") is False: + return + lap_result = self.get_parameter("lap_result") + rssi_list = re.findall("CWLAP:\((-\d+)\)", lap_result) + if len(rssi_list) > 1: + for i in range(len(rssi_list)-1): + if int(rssi_list[i]) < int(rssi_list[i+1]): + break + else: + self.result_cntx.set_result("Succeed") + else: + self.result_cntx.set_result("Succeed") + pass + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + pass + pass + + +def main(): + pass + + +if __name__ == '__main__': + main() diff --git a/components/test/TestCaseScript/ATFunc/SendDataValidation.py b/components/test/TestCaseScript/ATFunc/SendDataValidation.py new file mode 100755 index 0000000000..27f1e7f7c1 --- /dev/null +++ b/components/test/TestCaseScript/ATFunc/SendDataValidation.py @@ -0,0 +1,161 @@ +from TCAction import TCActionBase +from TCAction import CmdHandler +from NativeLog import NativeLog +import time +import threading +import sys +reload(sys) +sys.setdefaultencoding('iso-8859-1') # # use encoding that with 1 Byte length and contain 256 chars + + +VALIDATION_STRING = "".join([chr((m+65) % 256) for m in range(256)]) # make it start from 'A' + + +class ResultCheckCntx(TCActionBase.ResultCheckContext): + + def __init__(self, test_action, test_env, name): + TCActionBase.ResultCheckContext.__init__(self, test_action, test_env, name) + pass + + def run(self): + tx_result = -1 + rx_result = -1 + + while True: + exit_flag = self.wait_exit_event(2) + # force exit + if exit_flag is True: + break + try: + self.lock_data() + rx_port = filter(lambda x: x[0] == "AT1", self.data_cache) + tx_port = filter(lambda x: x[0] == "SOC2", self.data_cache) + finally: + self.unlock_data() + + if len(rx_port) == 1: + data = rx_port[0][1] + rx_result = data.find(VALIDATION_STRING) + if len(tx_port) == 1: + data = tx_port[0][1] + tx_result = data.find(VALIDATION_STRING) + + if tx_result != -1: + self.test_action.tx_check_done.set() + if rx_result != -1: + self.test_action.rx_check_done.set() + + +class SendDataValidation(TCActionBase.CommonTCActionBase): + + def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + self.timestamp = time.strftime("%d%H%M%S", time.localtime()) + self.tx_check_done = threading.Event() + self.rx_check_done = threading.Event() + + pass + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + try: + # configurable params + # enable target TCP TX + tx_enable = self.tx_enable + # enable target TCP RX + rx_enable = self.rx_enable + # transparent mode select + is_transparent_mode = self.is_transparent_mode + # configurable params + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for TCPTransparent script, error is %s" % e) + raise StandardError("Error configuration") + + # step1 create PC server + checker_stings = ["SOCR SOC_COM L OK"] + test_action_string = ["SOC SOC1 LISTEN "] + fail_string = "Fail, Fail on create PC server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step2 target connect, switch to transparent + checker_stings = ["SOCR SOC1 C +ACCEPT", "ATR AT1 NC CLOSE L OK"] + test_action_strings = ["ATC AT1 CIPSTART \"TCP\" "] + fail_string = "Fail, Fail on connect to PC server" + if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: + return + + checker_stings = ["SOCR SOC_COM L OK"] + test_action_strings = ["SOC SOC1 ACCEPT SOC2"] + if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: + return + + # set to transparent mode + if is_transparent_mode is True: + checker_stings = ["ATR AT1 L OK"] + test_action_strings = ["ATS AT1 AT+CIPMODE=1"] + if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: + return + + checker_stings = ["ATR AT1 C >"] + test_action_strings = ["ATS AT1 AT+CIPSEND"] + if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: + return + else: + checker_stings = ["ATR AT1 C >"] + test_action_strings = ["ATS AT1 AT+CIPSEND=256"] + if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: + return + + # step 3 + + # switch to new result check context + self.result_cntx.stop_thread() + self.result_cntx.join() + self.result_cntx = ResultCheckCntx(self, self.test_env, self.tc_name) + self.result_cntx.start() + + # step 3 send data + if rx_enable is True: + test_action = CmdHandler.parse_action("SOC SOC2 SEND 256", self.test_env) + CmdHandler.do_actions(test_action[0], self.test_env) + self.rx_check_done.wait(5) + if self.rx_check_done.isSet() is False: + # rx fail + return + # flush all data + self.result_cntx.data_flush() + self.tx_check_done.clear() + + if tx_enable is True: + test_action = CmdHandler.parse_action("ATSN AT1 256", self.test_env) + CmdHandler.do_actions(test_action[0], self.test_env) + self.tx_check_done.wait(5) + if self.tx_check_done.isSet() is False: + # tx fail + return + + # finally, execute done + self.result_cntx.set_result("Succeed") + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + pass + + +def main(): + pass + +if __name__ == '__main__': + main() + diff --git a/components/test/TestCaseScript/ATFunc/UARTTest.py b/components/test/TestCaseScript/ATFunc/UARTTest.py new file mode 100644 index 0000000000..184f440d49 --- /dev/null +++ b/components/test/TestCaseScript/ATFunc/UARTTest.py @@ -0,0 +1,164 @@ +import socket +import serial + +from TCAction import PerformanceTCBase +from TCAction import TCActionBase +from NativeLog import NativeLog + + +class UARTTest(PerformanceTCBase.PerformanceTCBase): + def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): + PerformanceTCBase.PerformanceTCBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + self.test_mode = "command" + self.baudrate = None + self.bytesize = None + self.parity = None + self.stopbits = None + self.xonxoff = None + self.rtscts = None + + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + pass + + def cleanup(self): + # restore UART config + self.restore_serial_port("AT1") + PerformanceTCBase.PerformanceTCBase.cleanup(self) + + STOP_BITS = { + 1: serial.STOPBITS_ONE, + 2: serial.STOPBITS_ONE_POINT_FIVE, + 3: serial.STOPBITS_TWO, + } + BYTE_SIZE = { + 5: serial.FIVEBITS, + 6: serial.SIXBITS, + 7: serial.SEVENBITS, + 8: serial.EIGHTBITS, + } + PARITY = { + 0: serial.PARITY_NONE, + 1: serial.PARITY_ODD, + 2: serial.PARITY_EVEN, + } + RTSCTS = {} + + def config_serial_port(self): + port = self.test_env.get_port_by_name("AT1") + kwargs = dict() + if self.baudrate is not None: + kwargs["baudrate"] = self.baudrate + if self.bytesize is not None: + kwargs["bytesize"] = self.BYTE_SIZE[self.bytesize] + if self.parity is not None: + kwargs["parity"] = self.PARITY[self.parity] + if self.stopbits is not None: + kwargs["stopbits"] = self.STOP_BITS[self.stopbits] + if self.xonxoff is not None: + kwargs["xonxoff"] = self.xonxoff + if self.rtscts is not None: + kwargs["rtscts"] = self.rtscts + NativeLog.add_prompt_trace("[change PC UART config] %s" % kwargs) + port.reconfig(**kwargs) + + def send_commands(self): + # first change UART config + self.config_serial_port() + # do send commands + for i in range(1, 256): + cmd = bytes().join([chr(x % 256) for x in range(i)]) + try: + self.serial_write_line("AT1", cmd) + except StandardError, e: + NativeLog.add_exception_log(e) + pass + self.flush_data("AT1") + # restore UART config + self.restore_serial_port("AT1") + + def send_data(self): + # create TCP connection and enter send mode + pc_ip = self.get_parameter("pc_ip") + tcp_port = self.get_parameter("test_tcp_port1") + server_sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) + server_sock.bind((pc_ip, tcp_port)) + server_sock.settimeout(10) + server_sock.listen(5) + self.serial_write_line("AT1", "AT+CIPSTART=\"TCP\",\"%s\",%s" % (pc_ip, tcp_port)) + self.check_response("AT1", "OK") + sock, addr = server_sock.accept() + server_sock.close() + self.serial_write_line("AT1", "AT+CIPSEND=1460") + self.check_response("AT1", ">") + # change UART config + self.config_serial_port() + # send data + try: + self.serial_write("AT1", bytes().join([chr(x % 256) for x in range(146000)])) + except StandardError, e: + NativeLog.add_exception_log(e) + pass + sock.send("A"*1460) + # restore UART config + sock.close() + self.restore_serial_port("AT1") + + def pass_through_mode(self): + # create TCP connection and enter pass through mode + pc_ip = self.get_parameter("pc_ip") + tcp_port = self.get_parameter("test_tcp_port1") + server_sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) + server_sock.bind((pc_ip, tcp_port)) + server_sock.settimeout(10) + server_sock.listen(5) + self.serial_write_line("AT1", "AT+CIPMODE=1") + self.check_response("AT1", "OK") + self.serial_write_line("AT1", "AT+CIPSTART=\"TCP\",\"%s\",%s" % (pc_ip, tcp_port)) + self.check_response("AT1", "OK") + sock, addr = server_sock.accept() + server_sock.close() + self.serial_write_line("AT1", "AT+CIPSEND") + self.check_response("AT1", ">") + # change UART config + self.config_serial_port() + # send data + try: + self.serial_write("AT1", bytes().join([chr(x % 256) for x in range(146000)])) + except StandardError, e: + NativeLog.add_exception_log(e) + pass + sock.send("A" * 1460) + # restore UART config + sock.close() + self.restore_serial_port("AT1") + + def execute(self): + TCActionBase.TCActionBase.execute(self) + # test sending command + try: + if self.test_mode == "command": + self.send_commands() + elif self.test_mode == "send_data": + self.send_data() + elif self.test_mode == "pass_through": + self.pass_through_mode() + else: + raise StandardError("test mode not supported: %s" % self.test_mode) + self.set_result("Succeed") + except StandardError, e: + NativeLog.add_exception_log(e) + self.set_result("Failed") + + +def main(): + pass + + +if __name__ == '__main__': + main() diff --git a/components/test/TestCaseScript/ATFunc/__init__.py b/components/test/TestCaseScript/ATFunc/__init__.py new file mode 100755 index 0000000000..5a3bbc44dd --- /dev/null +++ b/components/test/TestCaseScript/ATFunc/__init__.py @@ -0,0 +1,2 @@ +__all__ = ["TCPClientMulti", "TCPClientSingle", "TCPServerMulti", + "TCPTransparent", "UDPMulti", "UDPSingle"] \ No newline at end of file diff --git a/components/test/TestCaseScript/ATStress/ATPassThrough.py b/components/test/TestCaseScript/ATStress/ATPassThrough.py new file mode 100755 index 0000000000..5149ffe3de --- /dev/null +++ b/components/test/TestCaseScript/ATStress/ATPassThrough.py @@ -0,0 +1,179 @@ +import time + +from TCAction import TCActionBase +from NativeLog import NativeLog + + +BEACON_TIMEOUT = 3 +WAIT_FOR_RECONNECT = 20 + + +class ATPassThrough(TCActionBase.CommonTCActionBase): + + def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + self.do_scan = True + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + pass + + def cleanup(self): + TCActionBase.CommonTCActionBase.cleanup(self) + # turn on logging + self.test_env.uart_ports["AT1"].set_uart_logging_flag(True) + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + # configurable params + try: + at_send_length = self.at_send_length + soc_send_length = self.soc_send_length + test_count = self.test_count + tx_enable = self.tx_enable + rx_enable = self.rx_enable + att_set = self.att_set + do_scan = self.do_scan + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for TCPClientMulti script, error is %s" % e) + raise StandardError("Error configuration") + # configurable params + + # step0, set att and join ap + fail_string = "Fail, Fail on JAP, set to single link mode" + + checker_stings = ["R PC_COM L OK"] + test_action_string = ["ATT 1"] + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["R AT1 C ready"] + test_action_string = ["ATS AT1 AT+RST"] + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["R AT1 L OK"] + test_action_string = ["ATS AT1 AT+CWMODE=1"] + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["R AT1 L OK"] + test_action_string = ["ATC AT1 CWJAP "] + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["R AT1 L OK"] + test_action_string = ["ATS AT1 AT+CIPMUX=0"] + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step1, create TCP connection and enter pass through mode + fail_string = "Fail, Fail on create server, create connection or enter pass through mode" + + checker_stings = ["R SOC_COM L OK"] + test_action_string = ["SOC SOC1 LISTEN "] + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["R SOC1 C +ACCEPT", "R AT1 NC CLOSE L OK"] + test_action_string = ["ATC AT1 CIPSTART \"TCP\" "] + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["R AT1 L OK"] + test_action_strings = ["ATS AT1 AT+CIPMODE=1"] + if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: + return + + checker_stings = ["R AT1 C >"] + test_action_strings = ["ATS AT1 AT+CIPSEND"] + if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: + return + + checker_stings = ["R SOC_COM L OK"] + test_action_strings = ["SOC SOC1 ACCEPT SOC2"] + if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: + return + + # step2 + # while + # set att from, send data on both direction + # if TCP connection disconnected, then set att to 1, wait reconnect succeed, continue test + for i in xrange(test_count): + for _att in att_set: + + # set att + checker_stings = ["R PC_COM L OK"] + test_action_string = ["ATT %d" % _att] + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + time.sleep(BEACON_TIMEOUT) + + # do scan to get ssid + if do_scan is True: + checker_stings = [] + test_action_string = ["ATSO AT1 +++"] + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["R AT1 L OK"] + test_action_string = ["ATC AT1 CWLAP "] + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["R AT1 C >"] + test_action_strings = ["ATS AT1 AT+CIPSEND"] + if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: + return + + # send data + checker_stings = [] + test_action_string = [] + if tx_enable is True: + checker_stings += ["P SOC2 RL %d" % at_send_length] + test_action_string += ["ATSN AT1 %d" % at_send_length] + if rx_enable is True: + checker_stings += ["P AT1 RL %d" % soc_send_length] + test_action_string += ["SOC SOC2 SEND %d" % soc_send_length] + + if len(test_action_string) > 0: + if self.load_and_exe_one_step(checker_stings, test_action_string, "", + check_freq=1, check_time=30) is False: + # send data fail + NativeLog.add_prompt_trace("Failed to send data @ att %d" % _att) + # set att back to 1 + checker_stings = ["R PC_COM L OK"] + test_action_string = ["ATT 1"] + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + # wait for reconnect + time.sleep(WAIT_FOR_RECONNECT) + fail_string = "Failed, failed to accept socket" + checker_stings = ["SOCR SOC_COM L OK"] + test_action_strings = ["SOC SOC1 ACCEPT SOC2"] + if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: + return + break + pass + + # finally, execute done + self.result_cntx.set_result("Succeed") + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + +if __name__ == '__main__': + main() + diff --git a/components/test/TestCaseScript/ATStress/ATSleep.py b/components/test/TestCaseScript/ATStress/ATSleep.py new file mode 100644 index 0000000000..586862a777 --- /dev/null +++ b/components/test/TestCaseScript/ATStress/ATSleep.py @@ -0,0 +1,251 @@ +import random +import os +import time + +from TCAction import TCActionBase, PerformanceTCBase +from NativeLog import NativeLog +from Utility import MakeFolder +from Utility import MultimeterUtil + +LOG_PATH = os.path.join("AT_LOG", "SLEEP") + +SLEEP_MODE_LIST = ["none_sleep", "light_sleep", "modem_sleep"] +SLEEP_MODE = dict(zip(SLEEP_MODE_LIST, range(len(SLEEP_MODE_LIST)))) + +SAMPLE_RATE_SLEEP_MODE_CHANGE = 0.002 +SAMPLE_NUM_SLEEP_MODE_CHANGE = 256 + +SAMPLE_RATE = 0.002 +SAMPLE_NUM = 512 +MAX_VALUE = 1 +Y_AXIS_LABEL = "Current (mA)" +GPIO_EDGE_DELAY = 120 # 20 ms + +NONE_SLEEP_MIN_CUR = 30 +LIGHT_SLEEP_MIN_CUR = 1.5 +MODEM_SLEEP_MIN_CUR = 20 + +GPIO_WAKE_UP = 15 + +AT_WAKE_UP_IND_PIN = 14 +AT_WAKE_UP_PIN = 12 + + +class ATSleep(PerformanceTCBase.PerformanceTCBase): + + def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): + PerformanceTCBase.PerformanceTCBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + self.test_mode = "mode_change" + self.test_count = 100 + self.sleep_mode = SLEEP_MODE_LIST + self.sleep_wake_pin = AT_WAKE_UP_PIN + self.sleep_wakeup_ind_pin = AT_WAKE_UP_IND_PIN + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + self.log_folder = MakeFolder.make_folder(os.path.join(LOG_PATH, + "AT_AUTO_SLEEP_%s_%s" % + (self.test_mode, + time.strftime("%d%H%M%S", time.localtime())))) + self.multimeter = MultimeterUtil.MultimeterUtil(self.log_folder) + + @staticmethod + def find_min_items(item_list, count): + assert count < len(item_list) + min_items = [] + for i in range(count): + min_val = min(item_list) + min_items.append(min_val) + item_list.remove(min_val) + return min_items + + def sleep_mode_change(self, sleep_mode): + result = True + NativeLog.add_prompt_trace("[AutoSleep][ModeChange] %s start" % sleep_mode) + # choose sleep mode + sleep_mode_enum = SLEEP_MODE[sleep_mode] + # change GPIO to make sure target exit sleep mode, so it can process SSC commands + self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) + # set sleep mode + self.serial_write_line("AT1", "AT+SLEEP=%d" % sleep_mode_enum) + self.check_response("AT1", "OK") + self.check_response("SSC2", "+GPIO_SET:OK") + + NativeLog.add_prompt_trace("[AutoSleep][ModeChange] mode set") + time.sleep(10) + # measure current + current_line = self.multimeter.measure_current(sample_rate=SAMPLE_RATE_SLEEP_MODE_CHANGE, + sample_num=SAMPLE_NUM_SLEEP_MODE_CHANGE, + max_value=MAX_VALUE) + # do check measure + min_items = self.find_min_items(current_line, 10) + average_val = float(0) + for val in min_items: + average_val += val + average_val /= 10 + + NativeLog.add_prompt_trace("[AutoSleep][ModeChange] measure done, average min current %f" % average_val) + + if sleep_mode == "none_sleep": + if average_val < NONE_SLEEP_MIN_CUR: + result = False + elif sleep_mode == "light_sleep": + if average_val > LIGHT_SLEEP_MIN_CUR: + result = False + elif sleep_mode == "modem_sleep": + if average_val > MODEM_SLEEP_MIN_CUR or average_val < LIGHT_SLEEP_MIN_CUR: + result = False + if result is False: + NativeLog.add_trace_critical("[AutoSleep][ModeChange] %s failed" % sleep_mode) + self.multimeter.draw_graph(current_line, SAMPLE_RATE, "%s_fail" % sleep_mode, Y_AXIS_LABEL) + + time.sleep(5) + return result + + def sleep_current_measure(self, sleep_mode): + result = True + + NativeLog.add_prompt_trace("[AutoSleep][CurrentMeasure] %s start" % sleep_mode) + # choose sleep mode + sleep_mode_enum = SLEEP_MODE[sleep_mode] + # change GPIO to make sure target exit sleep mode, so it can process SSC commands + self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) + # set sleep mode + self.serial_write_line("AT1", "AT+SLEEP=%d" % sleep_mode_enum) + self.check_response("AT1", "OK") + self.check_response("SSC2", "+GPIO_SET:OK") + + NativeLog.add_prompt_trace("[AutoSleep][CurrentMeasure] set mode done") + time.sleep(10) + # measure current + current_line = self.multimeter.measure_current(sample_rate=SAMPLE_RATE, + sample_num=SAMPLE_NUM, + max_value=MAX_VALUE) + self.multimeter.draw_graph(current_line, SAMPLE_RATE, sleep_mode, Y_AXIS_LABEL) + NativeLog.add_prompt_trace("[AutoSleep][CurrentMeasure] measure done") + return result + + def light_sleep_wakeup(self): + result = True + NativeLog.add_prompt_trace("[AutoSleep][LightSleepWakeup] start") + + self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) + time.sleep(1) + self.serial_write_line("AT1", "") + time.sleep(1) + self.check_response("SSC2", "+GPIO_SET:OK", timeout=1) + + for i in range(10): + self.serial_write_line("SSC2", "gpio -G -p %d" % self.sleep_wakeup_ind_pin) + if self.check_response("SSC2", "+GPIO_GET:0", timeout=0.73) is True: + break + else: + NativeLog.add_prompt_trace("AT Sleep wakeup pin is not correct when in sleep") + + # check if respond to uart + self.flush_data("AT1") + for i in range(60): + self.serial_write("AT1", "a") + time.sleep(0.43) + time.sleep(0.1) + respond_data = self.serial_read_data("AT1") + if len(respond_data) >= 60: + NativeLog.add_trace_critical("[AutoSleep][light sleep wakeup] " + "Failed when recving data during sleep, %d" % len(respond_data)) + result = False + + NativeLog.add_prompt_trace("[AutoSleep][LightSleepWakeup] check on sleep mode done") + + # change GPIO to make target wakeup + self.serial_write_line("SSC2", "gpio -L -p %d -t 0" % GPIO_WAKE_UP) + self.check_response("SSC2", "+GPIO_SET:OK") + time.sleep(0.01) + + for i in range(3): + self.serial_write_line("SSC2", "gpio -G -p %d" % self.sleep_wakeup_ind_pin) + if self.check_response("SSC2", "+GPIO_GET:1") is False: + NativeLog.add_prompt_trace("AT Sleep wakeup pin is not correct when wakeup") + + self.serial_write_line("AT1", "") + time.sleep(1) + self.flush_data("AT1") + for i in range(60): + self.serial_write("AT1", "a") + time.sleep(0.043) + time.sleep(0.1) + respond_data = self.serial_read_data("AT1") + if len(respond_data) < 60: + NativeLog.add_trace_critical("[AutoSleep][light sleep wakeup] " + "Failed when recving data during wakeup, %d" % len(respond_data)) + result = False + + NativeLog.add_prompt_trace("[AutoSleep][LightSleepWakeup] check on wakeup mode done") + self.serial_write_line("AT1", "") + # restore GPIO level + self.serial_write_line("SSC2", "gpio -L -p %d -t 1" % GPIO_WAKE_UP) + time.sleep(2) + return result + + def cleanup(self): + self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) + self.serial_write_line("AT1", "") + self.serial_write_line("AT1", "AT+RST") + self.check_response("SSC2", "+GPIO_SET:OK") + self.check_response("AT1", "ready") + + def execute(self): + TCActionBase.TCActionBase.execute(self) + + try: + test_mode = self.test_mode + test_count = self.test_count + sleep_mode = self.sleep_mode + except StandardError, e: + return + + # make sure enter modem sleep mode before start test + self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) + self.serial_write_line("AT1", "AT+RST") + self.check_response("SSC2", "+GPIO_SET:OK") + self.check_response("AT1", "ready") + self.check_response("AT1", "WIFI GOT IP") + # set AT light sleep wakeup pin + self.serial_write_line("AT1", "AT+WAKEUPGPIO=1,%d,0" % self.sleep_wake_pin) + self.check_response("AT1", "OK") + + # start test + if "mode_change" in test_mode: + for i in range(test_count): + result = self.sleep_mode_change(random.choice(SLEEP_MODE_LIST)) + + elif "measure_current" in test_mode: + for i in range(test_count): + for mode in sleep_mode: + result = self.sleep_current_measure(mode) + pass + elif "gpio_wakeup" in test_mode: + # change GPIO to make sure target exit sleep mode, so it can process SSC commands + self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) + # config wakeup gpio + self.serial_write_line("AT1", "AT+WAKEUPGPIO=1,%d,0,%d,1" % (self.sleep_wake_pin, self.sleep_wakeup_ind_pin)) + self.check_response("AT1", "OK") + # set sleep mode + self.serial_write_line("AT1", "AT+SLEEP=%d" % SLEEP_MODE["light_sleep"]) + self.check_response("AT1", "OK") + self.check_response("SSC2", "+GPIO_SET:OK") + + for i in range(test_count): + result = self.light_sleep_wakeup() + pass + pass + + +def main(): + pass + + +if __name__ == '__main__': + main() diff --git a/components/test/TestCaseScript/ATStress/SoftAPServer.py b/components/test/TestCaseScript/ATStress/SoftAPServer.py new file mode 100755 index 0000000000..7522658f15 --- /dev/null +++ b/components/test/TestCaseScript/ATStress/SoftAPServer.py @@ -0,0 +1,308 @@ +from TCAction import PerformanceTCBase +import time +import socket +import threading +import Queue +import re +import random +from NativeLog import NativeLog + + +SEND_CMD = ("CIPSEND, CIPSENDBUF", "CIPSENDEX") + + +class RecvThread(threading.Thread): + def __init__(self, test_action): + threading.Thread.__init__(self) + self.setDaemon(True) + self.test_action = test_action + self.exit_flag = threading.Event() + pass + + def run(self): + data = "" + ipd_line = re.compile("IPD,\d,\d+:") + recv_bytes_line = re.compile("Recv \d+ bytes") + allow_send_line = re.compile("OK\r\n>") + send_ok_line = re.compile("SEND OK") + while self.exit_flag.is_set() is False: + flush_pos = 0 + data += self.test_action.serial_read_data("AT1") + # do process IPD data + match_set = ipd_line.findall(data) + for match_line in match_set: + link_id = match_line[4] + flush_pos = data.find(match_line) + len(match_line) + self.test_action.send_queue.put(link_id, 1) + pass + # do process send > + match = allow_send_line.search(data) + if match is not None: + match_line = match.group() + self.test_action.add_info_log("find OK >") + self.test_action.send_allow_evt.set() + pos = data.find(match_line) + len(match_line) + flush_pos = pos if pos > flush_pos else flush_pos + # do process Recv xx bytes + match = recv_bytes_line.search(data) + if match is not None: + match_line = match.group() + self.test_action.add_info_log("find Recv xx bytes") + self.test_action.recv_data_evt.set() + pos = data.find(match_line) + len(match_line) + flush_pos = pos if pos > flush_pos else flush_pos + + match = send_ok_line.search(data) + if match is not None: + match_line = match.group() + self.test_action.add_info_log("find send ok") + self.test_action.send_ok_evt.set() + pos = data.find(match_line) + len(match_line) + flush_pos = pos if pos > flush_pos else flush_pos + # pass + + # flush processed data + if flush_pos > 0: + data = data[flush_pos:] + + pass + + def exit(self): + self.exit_flag.set() + pass + + +class TCPClientThread(threading.Thread): + send_char = "A" + sync_lock = threading.Lock() + + def __init__(self, test_action, pc_ip, target_ip, target_port, request_len, response_len, client_id, + connect_timeout, recv_timeout): + threading.Thread.__init__(self) + self.setDaemon(True) + self.exit_flag = threading.Event() + self.test_action = test_action + self.pc_ip = pc_ip + self.target_ip = target_ip + self.target_port = target_port + self.request_len = request_len + self.response_len = response_len + self.client_id = client_id + self.connect_timeout = connect_timeout + self.recv_timeout = recv_timeout + pass + + @classmethod + def get_send_char(cls): + with cls.sync_lock: + send_char = cls.send_char + cls.send_char = chr(ord(send_char) + 1) if ord(send_char) < ord("Z") else "A" + return send_char + pass + + def run(self): + while self.exit_flag.is_set() is False: + exception_occurred = False + client_sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) + client_sock.bind((self.pc_ip, 0)) + client_sock.settimeout(20) + time1 = time.time() + name = client_sock.getsockname() + + try: + client_sock.connect((self.target_ip, self.target_port)) + except StandardError, e: + exception_occurred = True + self.test_action.add_critical_log("failed to connect succeed within 2 seconds %s, %d" + % (name[0], name[1])) + client_sock.close() + + time2 = time.time() - time1 + if exception_occurred is True: + self.test_action.add_critical_log("connect timeout %f; ip is %s, port is %d" + % (time2, name[0], name[1])) + continue + if time2 > self.connect_timeout: + self.test_action.add_critical_log("connect time too long %f; ip is %s, port is %d" + % (time2, name[0], name[1])) + + time.sleep(float(random.randint(0, 30))/100) + send_char = self.get_send_char() + data = send_char * self.request_len + try: + client_sock.send(data) + except StandardError: + NativeLog.add_trace_critical("send fail") + # try: + # data = client_sock.recv(1) + # except socket.error, e: + # self.handle_processing_fail("failed to receive data within 2 seconds") + data_received = 0 + time1 = time.time() + while data_received < self.response_len: + try: + data = client_sock.recv(4*1024) + except StandardError, e: + exception_occurred = True + break + data_received += len(data) + + time2 = time.time() - time1 + if exception_occurred is True or time2 > self.recv_timeout: + self.test_action.add_critical_log("receive time too long %f; ip is %s, port is %d"\ + % (time2, name[0], name[1])) + client_sock.close() + time.sleep(float(random.randint(0, 30))/100) + pass + pass + + def exit(self): + self.exit_flag.set() + pass + + +class SendThread(threading.Thread): + def __init__(self, test_action, test_count, send_cmd, response_len, check_send_ok): + threading.Thread.__init__(self) + self.setDaemon(True) + self.test_action = test_action + self.test_count = test_count + self.send_cmd = send_cmd + self.response_len = response_len + self.check_send_ok = check_send_ok + pass + + def run(self): + send_char = "a" + for i in xrange(self.test_count): + link_id = self.test_action.send_queue.get(1) + + self.test_action.send_allow_evt.clear() + self.test_action.serial_write_line("AT1", "AT+%s=%s,%d" % (self.send_cmd, link_id, self.response_len)) + self.test_action.add_info_log("write CIPSEND cmd") + + self.test_action.send_allow_evt.wait(10) + if self.test_action.send_allow_evt.is_set() is False: + self.test_action.add_critical_log("Failed to find OK > in 10s, test break") + break + self.test_action.send_allow_evt.clear() + + data = send_char * self.response_len + send_char = chr(ord(send_char) + 1) if ord(send_char) < ord("z") else "a" + self.test_action.recv_data_evt.clear() + self.test_action.send_ok_evt.clear() + self.test_action.serial_write("AT1", data) + self.test_action.add_info_log("data write done") + self.test_action.recv_data_evt.wait(10) + if self.test_action.recv_data_evt.is_set() is False: + self.test_action.add_critical_log("Failed to find Recv xx bytes in 10s, test break") + break + self.test_action.recv_data_evt.clear() + # if self.test_action.send_cmd == "CIPSEND": + if self.check_send_ok is True: + self.test_action.send_ok_evt.wait(10) + if self.test_action.send_ok_evt.is_set() is False: + self.test_action.add_critical_log("Failed to find SEND OK in 10s, test break") + break + self.test_action.add_info_log("send ok") + self.test_action.send_ok_evt.clear() + pass + pass + + +class SoftAPServer(PerformanceTCBase.PerformanceTCBase): + def __init__(self, name, test_env, cmd_set, timeout=120, log_path=None): + PerformanceTCBase.PerformanceTCBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + # init value for ip and port + self.pc_ip = "pc_ip" + self.server_port = "test_tcp_port1" + self.send_cmd = "CIPSEND" + self.baudrate = 115200 + self.rtscts = 3 + self.test_count = 1000 + self.request_len = 500 + self.response_len = 1600 + self.check_send_ok = True + self.concurrent_connections = 5 + self.connect_timeout = 3 + self.receive_timeout = 2 + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + self.send_queue = Queue.Queue(maxsize=100) + self.send_allow_evt = threading.Event() + self.recv_data_evt = threading.Event() + self.send_ok_evt = threading.Event() + + pass + + @staticmethod + def add_critical_log(data): + NativeLog.add_trace_critical(data+"\r\n") + pass + + @staticmethod + def add_info_log(data): + NativeLog.add_trace_info(data) + + def process(self): + # step0, use initial condition AP3 (8266 as AP, PC connected to 8266, multiple connection) + pc_ip = self.get_parameter(self.pc_ip) + target_ip = self.get_parameter("target_ip") + server_port = self.get_parameter(self.server_port) + send_cmd = self.send_cmd + test_count = self.test_count + baudrate = self.baudrate + rtscts = self.rtscts + concurrent_connections = self.concurrent_connections + check_send_ok = self.check_send_ok + connect_timeout = self.connect_timeout + receive_timeout = self.receive_timeout + + self.serial_write_line("AT1", "AT+UART_CUR=%d,8,1,0,%d" % (baudrate, rtscts)) + self.check_response("AT1", "OK\r\n") + self.reconfig_serial_port("AT1", baudrate, rtscts) + # step1, create server on 8266, create client thread + self.serial_write_line("AT1", "AT+CIPSERVER=1,%d" % server_port) + self.check_response("AT1", "OK") + + recv_thread = RecvThread(self) + send_thread = SendThread(self, test_count, send_cmd, self.response_len, check_send_ok) + send_thread.start() + recv_thread.start() + client_thread_list = [None] * concurrent_connections + for i in range(concurrent_connections): + client_thread_list[i] = TCPClientThread(self, pc_ip, target_ip, server_port, + self.request_len, self.response_len, i, + connect_timeout, receive_timeout) + client_thread_list[i].start() + pass + + # step3, wait sending thread join + send_thread.join() + + recv_thread.exit() + recv_thread.join() + + for i in range(concurrent_connections): + client_thread_list[i].exit() + client_thread_list[i].join() + pass + + self.serial_write_line("AT1", "AT+UART_CUR=115200,8,1,0,3") + self.check_response("AT1", "OK\r\n") + self.restore_serial_port("AT1") + self.set_result("Succeed") + pass + pass + + +def main(): + pass + + +if __name__ == '__main__': + main() diff --git a/components/test/TestCaseScript/ATStress/TCPClientMulti.py b/components/test/TestCaseScript/ATStress/TCPClientMulti.py new file mode 100755 index 0000000000..610a55cbc4 --- /dev/null +++ b/components/test/TestCaseScript/ATStress/TCPClientMulti.py @@ -0,0 +1,116 @@ +from TCAction import TCActionBase +from NativeLog import NativeLog + + +class TCPClientMulti(TCActionBase.CommonTCActionBase): + + def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + self.max_conn = test_env.get_variable_by_name("max_conn")[1] + pass + + def cleanup(self): + TCActionBase.CommonTCActionBase.cleanup(self) + # turn on logging + self.test_env.uart_ports["AT1"].set_uart_logging_flag(True) + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + # configurable params + try: + at_send_length = self.at_send_length + soc_send_length = self.soc_send_length + test_count = self.test_count + tx_enable = self.tx_enable + rx_enable = self.rx_enable + enable_log = self.enable_log + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for TCPClientMulti script, error is %s" % e) + raise StandardError("Error configuration") + # configurable params + + # step1 + checker_stings = ["R SOC_COM L OK"] + test_action_string = ["SOC SOC1 LISTEN "] + fail_string = "Fail, Fail on create PC server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step2 + for i in range(0, self.max_conn): + checker_stings = ["R SOC1 C +ACCEPT", "R AT1 NC CLOSE L OK"] + test_action_strings = ["ATC AT1 CIPSTART %d \"TCP\" " % i] + fail_string = "Fail, Fail on connect to PC server" + if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: + return + + checker_stings = ["R SOC_COM L OK"] + test_action_strings = ["SOC SOC1 ACCEPT SOC%d" % (i+2)] + if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: + return + + # step 3 + # turn off AT UART logging + if enable_log is False: + self.test_env.uart_ports["AT1"].set_uart_logging_flag(False) + + data = "A" * at_send_length + fail_string = "Fail, Fail on send and recv data" + + for j in range(0, test_count): + + if tx_enable is True: + for i in range(0, self.max_conn): + checker_stings = ["P AT1 C >"] + test_action_strings = ["ATS AT1 AT+CIPSEND=%d,%d" % (i, at_send_length)] + if self.load_and_exe_one_step(checker_stings, test_action_strings, + fail_string, check_time=50) is False: + NativeLog.add_trace_critical("Fail on target send command for link %d" % i) + NativeLog.add_trace_critical("Test count is %d" % j) + return + + checker_stings = ["P SOC%d RL %d" % ((i+2), at_send_length), "P AT1 C OK"] + test_action_strings = ["ATSO AT1 %s" % data] + if self.load_and_exe_one_step(checker_stings, test_action_strings, + fail_string, check_time=50) is False: + NativeLog.add_trace_critical("Fail on target send for link %d, send or recv error" % i) + NativeLog.add_trace_critical("Test count is %d" % j) + return + + if rx_enable is True: + checker_stings = [] + test_action_strings = [] + for i in range(0, self.max_conn): + checker_stings.extend(["P AT1 DL %d+%d" % (i, soc_send_length)]) + test_action_strings.extend(["SOC SOC%d SEND %d %s" % (i+2, soc_send_length, data)]) + + if self.load_and_exe_one_step(checker_stings, test_action_strings, + fail_string, check_time=50) is False: + NativeLog.add_trace_critical("Fail to receive PC sent data") + NativeLog.add_trace_critical("Test count is %d" % j) + return + + # finally, execute done + self.result_cntx.set_result("Succeed") + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + +if __name__ == '__main__': + main() + diff --git a/components/test/TestCaseScript/ATStress/TCPClientSingle.py b/components/test/TestCaseScript/ATStress/TCPClientSingle.py new file mode 100755 index 0000000000..7127c3d0f1 --- /dev/null +++ b/components/test/TestCaseScript/ATStress/TCPClientSingle.py @@ -0,0 +1,123 @@ +from TCAction import TCActionBase +from NativeLog import NativeLog + + +class TCPClientSingle(TCActionBase.CommonTCActionBase): + + def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + self.link_type = "TCP" + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + pass + + def cleanup(self): + TCActionBase.CommonTCActionBase.cleanup(self) + # turn on logging + self.test_env.uart_ports["AT1"].set_uart_logging_flag(True) + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + # configurable params + try: + at_send_length = self.at_send_length + soc_send_length = self.soc_send_length + test_count = self.test_count + tx_enable = self.tx_enable + rx_enable = self.rx_enable + enable_log = self.enable_log + link_type = self.link_type + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for TCPClientSingle script, error is %s" % e) + raise StandardError("Error configuration") + # configurable params + + # step1 + checker_stings = ["R SOC_COM L OK"] + if link_type == "TCP": + test_action_string = ["SOC SOC1 LISTEN "] + elif link_type == "SSL": + test_action_string = ["SOC SOC1 SLISTEN "] + pass + else: + raise StandardError() + fail_string = "Fail, Fail on create PC server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step2 + if link_type == "TCP": + checker_stings = ["R SOC1 C +ACCEPT", "R AT1 NC CLOSE L OK"] + test_action_strings = ["ATC AT1 CIPSTART \"TCP\" "] + elif link_type == "SSL": + checker_stings = ["R SOC1 C +SACCEPT", "R AT1 NC CLOSE L OK"] + test_action_strings = ["ATC AT1 CIPSTART \"SSL\" "] + else: + raise StandardError() + fail_string = "Fail, Fail on connect to PC server" + if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: + return + + checker_stings = ["R SOC_COM L OK"] + test_action_strings = ["SOC SOC1 ACCEPT SOC2"] + if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: + return + + # step 3 + # turn off AT UART logging + if enable_log is False: + self.test_env.uart_ports["AT1"].set_uart_logging_flag(False) + + for j in range(0, test_count): + data = "A" * at_send_length + fail_string = "Fail, Fail on send and recv data" + + if tx_enable is True: + checker_stings = ["P AT1 C >"] + test_action_strings = ["ATS AT1 AT+CIPSEND=%d" % at_send_length] + if self.load_and_exe_one_step(checker_stings, test_action_strings, + fail_string, check_time=20) is False: + NativeLog.add_trace_critical("Fail on target send command") + NativeLog.add_trace_critical("Test count is %d" % j) + return + + checker_stings = ["P SOC2 RL %d" % at_send_length, "P AT1 C OK"] + test_action_strings = ["ATSO AT1 %s" % data] + if self.load_and_exe_one_step(checker_stings, test_action_strings, + fail_string, check_time=20) is False: + NativeLog.add_trace_critical("Fail on target send, send or recv error") + NativeLog.add_trace_critical("Test count is %d" % j) + return + + if rx_enable is True: + checker_stings = ["P AT1 DL S+%d" % soc_send_length] + test_action_strings = ["SOC SOC2 SEND %d" % soc_send_length] + + if self.load_and_exe_one_step(checker_stings, test_action_strings, + fail_string, check_time=20) is False: + NativeLog.add_trace_critical("Fail to receive PC sent data") + NativeLog.add_trace_critical("Test count is %d" % j) + return + + # finally, execute done + self.result_cntx.set_result("Succeed") + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + +if __name__ == '__main__': + main() + diff --git a/components/test/TestCaseScript/ATStress/TCPSendPerf.py b/components/test/TestCaseScript/ATStress/TCPSendPerf.py new file mode 100755 index 0000000000..a2f6e1a060 --- /dev/null +++ b/components/test/TestCaseScript/ATStress/TCPSendPerf.py @@ -0,0 +1,148 @@ +import time +import os +import socket +import ssl + +from NativeLog import NativeLog +from TCAction import PerformanceTCBase +from Utility import MakeFolder + + +SEND_CMD = ("CIPSEND, CIPSENDBUF", "CIPSENDEX") + +LOG_PATH = os.path.join("AT_LOG", "Performance", "AT_SEND") + + +class TCPSendPerf(PerformanceTCBase.PerformanceTCBase): + def __init__(self, name, test_env, cmd_set, timeout=120, log_path=None): + PerformanceTCBase.PerformanceTCBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + # init value for ip and port + self.pc_ip = "pc_ip" + self.server_port = "test_tcp_port1" + self.packet_len = 1 + self.test_count = 100 + self.send_cmd = "CIPSEND" + self.baudrate = 115200 + self.rtscts = 0 + self.link_type = "TCP" + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + pass + + def process(self): + pc_ip = self.get_parameter(self.pc_ip) + server_port = self.get_parameter(self.server_port) + packet_len = self.packet_len + test_count = self.test_count + send_cmd = self.send_cmd + baudrate = self.baudrate + rtscts = self.rtscts + result = True + link_type = self.link_type + + # create TCP connection + sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) + sock.bind((pc_ip, server_port)) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + sock.settimeout(10) + sock.listen(1) + + self.serial_write_line("AT1", "AT+CIPSTART=0,\"%s\",\"%s\",%d" % (link_type, pc_ip, server_port)) + sock_client = sock.accept()[0] + if link_type == "SSL": + sock_client = ssl.wrap_socket(sock_client, + server_side=True, + certfile=os.path.join("Certificate", "default.cer"), + keyfile=os.path.join("Certificate", "default.key")) + pass + if self.check_response("AT1", "OK") is False: + result = False + + self.serial_write_line("AT1", "AT+UART_CUR=%d,8,1,0,%d" % (baudrate, rtscts)) + if self.check_response("AT1", "OK\r\n") is False: + result = False + + self.reconfig_serial_port("AT1", baudrate, rtscts) + + # restore to read line mode + self.test_env.uart_ports["AT1"].set_performance_flag(flag=True) + + sock_client.settimeout(0) + + for _dummy in range(1): + if result is False: + NativeLog.add_trace_critical("Fail to create TCP connection") + break + # send TCP packets + data = "A" * packet_len + time1 = time.time() + + i = 0 + data_recv_len = 0 + while i < test_count: + self.serial_write_line("AT1", "AT+%s=0,%d" % (send_cmd, packet_len)) + if self.check_response("AT1", ">", 0.05) is False: + continue + + i += 1 + self.serial_write("AT1", data) + if send_cmd == "CIPSENDBUF": + result = self.check_response("AT1", "Recv %d bytes" % packet_len, 3) + else: + result = self.check_response("AT1", "SEND OK", 3) + if result is False: + NativeLog.add_trace_critical("Fail during sending data") + break + try: + if link_type == "TCP": + data_recv = sock_client.recv(10*1460) + elif link_type == "SSL": + data_recv = sock_client.read(10*1024) + else: + raise StandardError() + data_recv_len += len(data_recv) + except socket.error, e: + if e.errno == 10035: + pass + elif e.message == "The read operation timed out": + pass + else: + NativeLog.add_exception_log(e) + else: + self.set_result("Succeed") + + time2 = time.time() + + folder_path = MakeFolder.make_folder(LOG_PATH) + file_name = os.path.join(folder_path, + "%s_%s_%s.log" % (send_cmd, + packet_len, + time.strftime("%d%H%M%S", time.localtime()))) + with open(file_name, "ab+") as f: + f.write("\r\n[performance] %f packets per second " + "(including failed send operation)" + % (test_count/(time2-time1))) + f.write("\r\n[performance] %f Kbps" % (data_recv_len/(125*(time2-time1)))) + + self.serial_write_line("AT1", "AT+UART_CUR=115200,8,1,0,3") + self.check_response("AT1", "OK\r\n") + self.restore_serial_port("AT1") + + # restore to read line mode + self.test_env.uart_ports["AT1"].set_performance_flag(flag=False) + # close socket + sock.close() + sock_client.close() + pass + + +def main(): + pass + + +if __name__ == '__main__': + main() diff --git a/components/test/TestCaseScript/ATStress/TCPServerMulti.py b/components/test/TestCaseScript/ATStress/TCPServerMulti.py new file mode 100755 index 0000000000..c317bc9749 --- /dev/null +++ b/components/test/TestCaseScript/ATStress/TCPServerMulti.py @@ -0,0 +1,126 @@ +from TCAction import TCActionBase +from NativeLog import NativeLog + + +class TCPServerMulti(TCActionBase.CommonTCActionBase): + + def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + self.max_conn = test_env.get_variable_by_name("max_conn")[1] + pass + + def cleanup(self): + TCActionBase.CommonTCActionBase.cleanup(self) + self.test_env.uart_ports["AT1"].set_uart_logging_flag(True) + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + # configurable params + try: + at_send_length = self.at_send_length + soc_send_length = self.soc_send_length + test_count = self.test_count + target_ip_str = self.target_ip_str + enable_log = self.enable_log + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for TCPSeverMulti script, error is %s" % e) + raise StandardError("Error configuration") + # configurable params + + # turn off AT UART logging + if enable_log is False: + self.test_env.uart_ports["AT1"].set_uart_logging_flag(False) + + # step1 create TCP server on target + checker_stings = ["R AT1 L OK"] + test_action_string = ["ATC AT1 CIPSERVER 1 "] + fail_string = "Fail, Fail on create target TCP server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step2 PC connect to target server + for j in range(0, test_count): + data = "A" * at_send_length + fail_string = "Fail, Fail on connect to target server" + + # check if all connection can send data on target + checker_stings = ["P AT1 C OK"] + test_action_strings = ["ATS AT1 AT+CIPCLOSE=%d" % self.max_conn] + if self.load_and_exe_one_step(checker_stings, test_action_strings, + fail_string, check_time=100) is False: + NativeLog.add_trace_critical("Fail to close all connection") + NativeLog.add_trace_critical("Test count is %d" % j) + continue # if fail on this step, we can recover and continue + + # a) do connect + fail_flag = False + for i in range(0, self.max_conn): + checker_stings = ["P SOC_COM C OK", "P AT1 C CONNECT"] + test_action_strings = ["SOC SOC%d CONNECT %s" % (i+1, target_ip_str)] + if self.load_and_exe_one_step(checker_stings, test_action_strings, + fail_string, check_time=50) is False: + NativeLog.add_trace_critical("Fail to connect to target for link %d" % i) + NativeLog.add_trace_critical("Test count is %d" % j) + # if fail on this step, we can recover and continue + fail_flag = True + break + + if fail_flag is True: + # fail on step a) + continue + + # b) check if all connection can recv data on target + checker_stings = [] + test_action_strings = [] + for i in range(0, self.max_conn): + checker_stings.extend(["P AT1 DL %d+%d" % (i, soc_send_length)]) + test_action_strings.extend(["SOC SOC%d SEND %d" % (i+1, soc_send_length)]) + + if self.load_and_exe_one_step(checker_stings, test_action_strings, + fail_string, check_time=50) is False: + NativeLog.add_trace_critical("Fail to receive data from PC") + NativeLog.add_trace_critical("Test count is %d" % j) + continue # if fail on this step, we can recover and continue + + # c) check if all connection can send data on target + for i in range(0, self.max_conn): + checker_stings = ["P AT1 C >"] + test_action_strings = ["ATS AT1 AT+CIPSEND=%d,%d" % (i, at_send_length)] + if self.load_and_exe_one_step(checker_stings, test_action_strings, + fail_string, check_time=50) is False: + NativeLog.add_trace_critical("Fail on target send command for link %d" % i) + NativeLog.add_trace_critical("Test count is %d" % j) + return + + checker_stings = ["P SOC%d RL %d" % ((i+1), at_send_length), "P AT1 C OK"] + test_action_strings = ["ATSO AT1 %s" % data] + if self.load_and_exe_one_step(checker_stings, test_action_strings, + fail_string, check_time=50) is False: + NativeLog.add_trace_critical("Fail on target send for link %d, send or recv error" % i) + NativeLog.add_trace_critical("Test count is %d" % j) + return + + # finally, execute done + self.result_cntx.set_result("Succeed") + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + +if __name__ == '__main__': + main() + diff --git a/components/test/TestCaseScript/ATStress/TCPTransparent.py b/components/test/TestCaseScript/ATStress/TCPTransparent.py new file mode 100755 index 0000000000..d116923bf5 --- /dev/null +++ b/components/test/TestCaseScript/ATStress/TCPTransparent.py @@ -0,0 +1,280 @@ +from TCAction import TCActionBase +from TCAction import CmdHandler +from NativeLog import NativeLog +import time +import random +import string +import os + + +class TransparentResultCheckCntx(TCActionBase.ResultCheckContext): + + def __init__(self, test_action, test_env, name): + TCActionBase.ResultCheckContext.__init__(self, test_action, test_env, name) + self.result_array = [] + self.at_data_recv_total = 0 + self.pc_data_recv_total = 0 + self.temp_data_at2wifi = "" + self.temp_data_wifi2at = "" + pass + + def run(self): + validation_required = self.test_action.data_validation + path = os.path.split(self.test_action.log_file_name) + file_name_at2wifi = os.path.join(path[0], "%s_at2wifi_pc.bin" % self.test_action.timestamp) + file_name_wifi2at = os.path.join(path[0], "%s_wifi2at_at.bin" % self.test_action.timestamp) + + while True: + exit_flag = self.wait_exit_event(2) + # force exit + if exit_flag is True: + break + rx_len = 0 + tx_len = 0 + try: + self.lock_data() + rx_port = filter(lambda x: x[0] == "AT1", self.data_cache) + tx_port = filter(lambda x: x[0] == "SOC2", self.data_cache) + self.data_cache = [] + finally: + self.unlock_data() + + if len(rx_port) == 1: + rx_len = len(rx_port[0][1]) + self.at_data_recv_total += rx_len + if validation_required is True: + self.temp_data_wifi2at += rx_port[0][1] + if len(tx_port) == 1: + tx_len = len(tx_port[0][1]) + self.pc_data_recv_total += tx_len + if validation_required is True: + self.temp_data_at2wifi += tx_port[0][1] + + self.result_array.append(["TX %8d %s" % + (tx_len/2, time.strftime("%m-%d %H:%M:%S", time.localtime()))]) + self.result_array.append(["RX %8d %s" % + (rx_len/2, time.strftime("%m-%d %H:%M:%S", time.localtime()))]) + + if validation_required is True: + with open(file_name_at2wifi, "ab+") as f: + f.write(self.temp_data_at2wifi) + with open(file_name_wifi2at, "ab+") as f: + f.write(self.temp_data_wifi2at) + + def get_validation_data(self): + return self.temp_data_at2wifi, self.temp_data_wifi2at + + def get_test_results(self): + return self.result_array, self.at_data_recv_total, self.pc_data_recv_total + + +class TCPTransparent(TCActionBase.CommonTCActionBase): + + def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + self.timestamp = time.strftime("%d%H%M%S", time.localtime()) + + pass + + def cleanup(self): + # close current result check context + self.result_cntx.stop_thread() + self.result_cntx.join() + # turn on logging + self.test_env.uart_ports["AT1"].set_uart_logging_flag(True) + # restore to read line mode + self.test_env.uart_ports["AT1"].set_performance_flag(flag=False) + + # make sure enter condition that can respond to AT command + self.result_cntx = TCActionBase.ResultCheckContext(self, self.test_env, self.tc_name) + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + checker_stings = ["ATR AT1 R *"] + test_action_string = ["ATSO AT1 +++", "DELAY 0.1", "ATS AT1 AT"] + fail_string = "Fail, Fail to reconfig UART" + + result = False + + while result is False: + result = self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) + + # reset baudrate + + checker_stings = ["ATR AT1 L OK"] + test_action_string = ["ATS AT1 AT+UART_CUR=%d,8,1,0,3" % 115200] + fail_string = "Fail, Fail to reconfig UART" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + test_action = CmdHandler.parse_action("UART AT1 %d" % 115200, self.test_env) + CmdHandler.do_actions(test_action, self.test_env) + TCActionBase.CommonTCActionBase.cleanup(self) + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + try: + # configurable params + # at send data len + at_send_data_len = self.at_send_data_len + # pc send data len + pc_send_data_len = self.pc_send_data_len + # sleep time between each send, test count + test_dispatch = self.test_dispatch + # enable target TCP TX + tx_enable = self.tx_enable + # enable target TCP RX + rx_enable = self.rx_enable + # if need to record tx/rx data to file + data_validation = self.data_validation + # UART baudrate + baudrate = self.baudrate + # HW flow control + rtscts = self.rtscts + # configurable params + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for TCPTransparent script, error is %s" % e) + raise StandardError("Error configuration") + + # step0 reconfig baudrate + if baudrate != 0: + checker_stings = ["R AT1 L OK"] + test_action_string = ["ATS AT1 AT+UART_CUR=%d,8,1,0,%d" % (baudrate, rtscts)] + fail_string = "Fail, Fail to reconfig UART" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + test_action = CmdHandler.parse_action("UART AT1 %d %d" % (baudrate, rtscts), self.test_env) + CmdHandler.do_actions(test_action, self.test_env) + + # step1 create PC server + checker_stings = ["R SOC_COM L OK"] + test_action_string = ["SOC SOC1 LISTEN "] + fail_string = "Fail, Fail on create PC server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step2 target connect, switch to transparent + checker_stings = ["R SOC1 C +ACCEPT", "R AT1 NC CLOSE L OK"] + test_action_strings = ["ATC AT1 CIPSTART \"TCP\" "] + fail_string = "Fail, Fail on connect to PC server" + if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: + return + + checker_stings = ["R SOC_COM L OK"] + test_action_strings = ["SOC SOC1 ACCEPT SOC2"] + if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: + return + + checker_stings = ["R AT1 L OK"] + test_action_strings = ["ATS AT1 AT+CIPMODE=1"] + if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: + return + + checker_stings = ["R AT1 C >"] + test_action_strings = ["ATS AT1 AT+CIPSEND"] + if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: + return + + # step 3 + # turn off AT UART logging + self.test_env.uart_ports["AT1"].set_uart_logging_flag(False) + # uart try to return data ASAP + self.test_env.uart_ports["AT1"].set_performance_flag(flag=True) + + # switch to new result check context + self.result_cntx.stop_thread() + self.result_cntx.join() + self.result_cntx = TransparentResultCheckCntx(self, self.test_env, self.tc_name) + self.result_cntx.start() + + at_data_sent_total = 0 + pc_data_sent_total = 0 + at2wifi_data = "" + wifi2at_data = "" + + for j in range(0, len(at_send_data_len) * len(pc_send_data_len)): + at_data_len = at_send_data_len[j / len(pc_send_data_len)] + pc_data_len = pc_send_data_len[j % len(pc_send_data_len)] + # data = "".join(["A"] * at_data_len) + chars = string.ascii_lowercase + data_list = ["".join([random.choice(chars) for m in range(at_data_len-16)])] + chars = string.ascii_uppercase + data_list.append("".join([random.choice(chars) for m in range(at_data_len-16)])) + chars = string.digits + data_list.append("".join([random.choice(chars) for m in range(at_data_len-16)])) + + for i in range(0, len(test_dispatch)): + for k in range(0, test_dispatch[i][1]): + data_str = "%.2d%.2d%.10d%s\r\n" % (j, i, k, data_list[k % 3]) + # time1 = time.time() + if tx_enable is True: + test_action = CmdHandler.parse_action("ATSO AT1 %s" % data_str, self.test_env) + CmdHandler.do_actions(test_action, self.test_env) + at_data_sent_total += at_data_len + if data_validation is True: + at2wifi_data += data_str + # time2 = time.time() + if rx_enable is True: + if tx_enable is True: + test_action = CmdHandler.parse_action("SOC SOC2 SENDNB %d %s" % (pc_data_len, data_str), + self.test_env) + else: + test_action = CmdHandler.parse_action("SOC SOC2 SEND %d %s" % (pc_data_len, data_str), + self.test_env) + sent_len = CmdHandler.do_action(test_action[0], self.test_env) + pc_data_sent_total += sent_len + if data_validation is True: + wifi2at_data += data_str[:sent_len] + # time3 = time.time() + # if time3-time2 > 0.1: + # break + if test_dispatch[i][0] != 0: + time.sleep(test_dispatch[i][0]) + time.sleep(3) # wait 3 seconds + + # write send data to file for data validation + if data_validation is True: + path = os.path.split(self.log_file_name) + with open(os.path.join(path[0], "%s_at2wifi_at.bin" % self.timestamp), "ab+") as f: + f.write(at2wifi_data) + with open(os.path.join(path[0], "%s_wifi2at_pc.bin" % self.timestamp), "ab+") as f: + f.write(wifi2at_data) + + temp_data_at2wifi, temp_data_wifi2at = self.result_cntx.get_validation_data() + if temp_data_at2wifi != at2wifi_data: + NativeLog.add_prompt_trace("[Validation Fail] at2wifi") + if temp_data_wifi2at != wifi2at_data: + NativeLog.add_prompt_trace("[Validation Fail] wifi2at") + + throughput_results, at_data_recv_total, pc_data_recv_total = self.result_cntx.get_test_results() + result_str = "AT sent %15d\r\n" % at_data_sent_total + result_str += "PC recv %15d\r\n" % pc_data_recv_total + result_str += "PC sent %15d\r\n" % pc_data_sent_total + result_str += "AT recv %15d\r\n" % at_data_recv_total + for _result in throughput_results: + result_str += "%s\r\n" % _result + with open(self.log_file_name, "ab+") as f: + f.write(result_str) + + # finally, execute done + self.result_cntx.set_result("Succeed") + + def result_check(self, port_name, data): + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + +if __name__ == '__main__': + main() + diff --git a/components/test/TestCaseScript/ATStress/UDPMulti.py b/components/test/TestCaseScript/ATStress/UDPMulti.py new file mode 100755 index 0000000000..4423db3ce3 --- /dev/null +++ b/components/test/TestCaseScript/ATStress/UDPMulti.py @@ -0,0 +1,113 @@ +from TCAction import TCActionBase +from NativeLog import NativeLog +import time + + +class UDPMulti(TCActionBase.CommonTCActionBase): + + def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + self.max_conn = test_env.get_variable_by_name("max_conn")[1] + pass + + def cleanup(self): + TCActionBase.CommonTCActionBase.cleanup(self) + # turn on logging + self.test_env.uart_ports["AT1"].set_uart_logging_flag(True) + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + # configurable params + try: + at_send_length = self.at_send_length + soc_send_length = self.soc_send_length + test_count = self.test_count + target_ip_str = self.target_ip_str + tx_enable = self.tx_enable + rx_enable = self.rx_enable + enable_log = self.enable_log + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for UDPMulti script, error is %s" % e) + raise StandardError("Error configuration") + # configurable params + + # step1, bind one PC UDP port + checker_stings = ["R SOC_COM L OK"] + test_action_string = ["SOC SOC1 BIND "] + fail_string = "Fail, Fail on binding socket" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step 2 create 5 UDP link on target + for i in range(0, self.max_conn): + checker_stings = ["R AT1 C CONNECT L OK"] + test_action_strings = ["ATC AT1 CIPSTART %d \"UDP\" 1" + % (i, i+1)] + fail_string = "Fail, Fail on create UDP link" + if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: + return + + # step 3 send recv data + # turn off AT UART logging + if enable_log is False: + self.test_env.uart_ports["AT1"].set_uart_logging_flag(False) + + for j in range(0, test_count): + data = "A" * at_send_length + fail_string = "Fail, Fail on send/recv data" + + if tx_enable is True: + # target link 0-5 sendto PC + for i in range(0, self.max_conn): + checker_stings = ["P AT1 C >"] + test_action_strings = ["ATS AT1 AT+CIPSEND=%d,%d" % (i, at_send_length)] + if self.load_and_exe_one_step(checker_stings, test_action_strings, + fail_string, check_time=20) is False: + NativeLog.add_trace_critical("Target fail on send cmd on link %d" % i) + NativeLog.add_trace_critical("Test count is %d" % j) + + checker_stings = ["P SOC_COM C RECV_LEN=%d P " % (at_send_length, i+1), + "P AT1 C OK"] + test_action_strings = ["ATSO AT1 %s" % data] + if self.load_and_exe_one_step(checker_stings, test_action_strings, + fail_string, check_time=20) is False: + NativeLog.add_trace_critical("Target sent UDP packet error on link %d" % i) + NativeLog.add_trace_critical("Test count is %d" % j) + + if rx_enable is True: + # PC send to target + checker_stings = [] + test_action_strings = [] + for i in range(0, self.max_conn): + checker_stings.extend(["P AT1 DL %d+%d" % (i, soc_send_length)]) + test_action_strings.extend(["SOC SOC1 SENDTO %d %s" + % (soc_send_length, i+1, target_ip_str)]) + + if self.load_and_exe_one_step(checker_stings, test_action_strings, + fail_string, check_time=20) is False: + NativeLog.add_trace_critical("PC sent UDP packet error") + NativeLog.add_trace_critical("Test count is %d" % j) + + # finally, execute done + self.result_cntx.set_result("Succeed") + + def result_check(self, port_name, data): + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + +if __name__ == '__main__': + main() + diff --git a/components/test/TestCaseScript/ATStress/UDPSingle.py b/components/test/TestCaseScript/ATStress/UDPSingle.py new file mode 100755 index 0000000000..0f30330ab6 --- /dev/null +++ b/components/test/TestCaseScript/ATStress/UDPSingle.py @@ -0,0 +1,105 @@ +from TCAction import TCActionBase +from NativeLog import NativeLog + + +class UDPSingle(TCActionBase.CommonTCActionBase): + + def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + pass + + def cleanup(self): + TCActionBase.CommonTCActionBase.cleanup(self) + # turn on logging + self.test_env.uart_ports["AT1"].set_uart_logging_flag(True) + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + # configurable params + try: + at_send_length = self.at_send_length + soc_send_length = self.soc_send_length + test_count = self.test_count + target_ip_str = self.target_ip_str + tx_enable = self.tx_enable + rx_enable = self.rx_enable + enable_log = self.enable_log + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for UDPSingle script, error is %s" % e) + raise StandardError("Error configuration") + # configurable params + + # step1, bind one PC UDP port + checker_stings = ["R SOC_COM L OK"] + test_action_string = ["SOC SOC1 BIND "] + fail_string = "Fail, Fail on binding UDP socket" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step 2 create UDP link on target + checker_stings = ["R AT1 C CONNECT L OK"] + test_action_strings = ["ATC AT1 CIPSTART \"UDP\" 1"] + fail_string = "Fail, Fail on create UDP link" + if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: + return + + # step 3 send recv data + # turn off AT UART logging + if enable_log is False: + self.test_env.uart_ports["AT1"].set_uart_logging_flag(False) + + for j in range(0, test_count): + data = "A" * at_send_length + fail_string = "Fail, Fail on send recv data" + + # target sendto PC + if tx_enable is True: + checker_stings = ["P AT1 C >"] + test_action_strings = ["ATS AT1 AT+CIPSEND=%d" % at_send_length] + if self.load_and_exe_one_step(checker_stings, test_action_strings, + fail_string, check_time=20) is False: + NativeLog.add_trace_critical("Target fail on send cmd") + NativeLog.add_trace_critical("Test count is %d" % j) + + checker_stings = ["P SOC_COM C RECV_LEN=%d P " % at_send_length, + "P AT1 C OK"] + test_action_strings = ["ATSO AT1 %s" % data] + if self.load_and_exe_one_step(checker_stings, test_action_strings, + fail_string, check_time=20) is False: + NativeLog.add_trace_critical("Target sent UDP packet error") + NativeLog.add_trace_critical("Test count is %d" % j) + + # PC send to target + if rx_enable is True: + checker_stings = (["P AT1 DL S+%d" % soc_send_length]) + test_action_strings = (["SOC SOC1 SENDTO %d %s" % (soc_send_length, target_ip_str)]) + + if self.load_and_exe_one_step(checker_stings, test_action_strings, + fail_string, check_time=20) is False: + NativeLog.add_trace_critical("PC sent UDP packet error") + NativeLog.add_trace_critical("Test count is %d" % j) + + # finally, execute done + self.result_cntx.set_result("Succeed") + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + +if __name__ == '__main__': + main() + diff --git a/components/test/TestCaseScript/ATStress/UDPTransparent.py b/components/test/TestCaseScript/ATStress/UDPTransparent.py new file mode 100755 index 0000000000..699d2b1ad8 --- /dev/null +++ b/components/test/TestCaseScript/ATStress/UDPTransparent.py @@ -0,0 +1,262 @@ +from TCAction import TCActionBase +from TCAction import CmdHandler +from NativeLog import NativeLog +import time +import random +import string +import os + + +class TransparentResultCheckCntx(TCActionBase.ResultCheckContext): + + def __init__(self, test_action, test_env, name): + TCActionBase.ResultCheckContext.__init__(self, test_action, test_env, name) + self.result_array = [] + self.at_data_recv_total = 0 + self.pc_data_recv_total = 0 + pass + + def run(self): + validation_required = self.test_action.data_validation + temp_data_at2wifi = "" + temp_data_wifi2at = "" + path = os.path.split(self.test_action.log_file_name) + file_name_at2wifi = os.path.join(path[0], "%s_at2wifi_pc.bin" % self.test_action.timestamp) + file_name_wifi2at = os.path.join(path[0], "%s_wifi2at_at.bin" % self.test_action.timestamp) + + while True: + exit_flag = self.wait_exit_event(2) + # force exit + if exit_flag is True: + break + rx_len = 0 + tx_len = 0 + try: + self.lock_data() + rx_port = filter(lambda x: x[0] == "AT1", self.data_cache) + tx_port = filter(lambda x: x[0] == "SOC1", self.data_cache) + self.data_cache = [] + finally: + self.unlock_data() + + if len(rx_port) == 1: + rx_len = len(rx_port[0][1]) + self.at_data_recv_total += rx_len + if validation_required is True: + temp_data_wifi2at += rx_port[0][1] + if len(tx_port) == 1: + tx_len = len(tx_port[0][1]) + self.pc_data_recv_total += tx_len + if validation_required is True: + temp_data_at2wifi += tx_port[0][1] + + self.result_array.append(["TX %8d %s" % + (tx_len/2, time.strftime("%m-%d %H:%M:%S", time.localtime()))]) + self.result_array.append(["RX %8d %s" % + (rx_len/2, time.strftime("%m-%d %H:%M:%S", time.localtime()))]) + + if validation_required is True: + with open(file_name_at2wifi, "ab+") as f: + f.write(temp_data_at2wifi) + with open(file_name_wifi2at, "ab+") as f: + f.write(temp_data_wifi2at) + + def get_test_results(self): + return self.result_array, self.at_data_recv_total, self.pc_data_recv_total + + +class UDPTransparent(TCActionBase.CommonTCActionBase): + + def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + self.timestamp = time.strftime("%d%H%M%S", time.localtime()) + + pass + + def cleanup(self): + # close current result check context + self.result_cntx.stop_thread() + self.result_cntx.join() + # turn on logging + self.test_env.uart_ports["AT1"].set_uart_logging_flag(True) + # restore to read line mode + self.test_env.uart_ports["AT1"].set_performance_flag(flag=False) + + # make sure enter condition that can respond to AT command + self.result_cntx = TCActionBase.ResultCheckContext(self, self.test_env, self.tc_name) + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + checker_stings = ["R AT1 R *"] + test_action_string = ["ATSO AT1 +++", "DELAY 0.1", "ATS AT1 AT"] + fail_string = "Fail, Fail to reconfig UART" + + result = False + + while result is False: + result = self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) + + # reset baudrate + + checker_stings = ["R AT1 L OK"] + test_action_string = ["ATS AT1 AT+UART_CUR=%d,8,1,0,3" % 115200] + fail_string = "Fail, Fail to reconfig UART" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + test_action = CmdHandler.parse_action("UART AT1 %d" % 115200, self.test_env) + CmdHandler.do_actions(test_action, self.test_env) + TCActionBase.CommonTCActionBase.cleanup(self) + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + try: + # configurable params + # at send data len + at_send_data_len = self.at_send_data_len + # pc send data len + pc_send_data_len = self.pc_send_data_len + # sleep time between each send, test count + test_dispatch = self.test_dispatch + # enable target TCP TX + tx_enable = self.tx_enable + # enable target TCP RX + rx_enable = self.rx_enable + # if need to record tx/rx data to file + data_validation = self.data_validation + # UART baudrate + baudrate = self.baudrate + # HW flow control + rtscts = self.rtscts + # configurable params + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for TCPTransparent script, error is %s" % e) + raise StandardError("Error configuration") + + # step0 reconfig baudrate + if baudrate != 0: + checker_stings = ["R AT1 L OK"] + test_action_string = ["ATS AT1 AT+UART_CUR=%d,8,1,0,%d" % (baudrate, rtscts)] + fail_string = "Fail, Fail to reconfig UART" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + test_action = CmdHandler.parse_action("UART AT1 %d %d" % (baudrate, rtscts), self.test_env) + CmdHandler.do_actions(test_action, self.test_env) + + # step1 create PC server + checker_stings = ["R SOC_COM L OK"] + test_action_string = ["SOC SOC1 BIND "] + fail_string = "Fail, Fail on create PC server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step2 target connect, switch to transparent + checker_stings = ["R AT1 NC CLOSE L OK"] + test_action_strings = ["ATC AT1 CIPSTART \"UDP\" 0"] + fail_string = "Fail, Fail on connect to PC server" + if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: + return + + checker_stings = ["R AT1 L OK"] + test_action_strings = ["ATS AT1 AT+CIPMODE=1"] + if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: + return + + checker_stings = ["R AT1 C >"] + test_action_strings = ["ATS AT1 AT+CIPSEND"] + if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: + return + + # step 3 + # turn off AT UART logging + self.test_env.uart_ports["AT1"].set_uart_logging_flag(False) + # restore to read data asap + self.test_env.uart_ports["AT1"].set_performance_flag(flag=True) + + # switch to new result check context + self.result_cntx.stop_thread() + self.result_cntx.join() + self.result_cntx = TransparentResultCheckCntx(self, self.test_env, self.tc_name) + self.result_cntx.start() + + at_data_sent_total = 0 + pc_data_sent_total = 0 + at2wifi_data = "" + wifi2at_data = "" + + for j in range(0, len(at_send_data_len) * len(pc_send_data_len)): + at_data_len = at_send_data_len[j / len(pc_send_data_len)] + pc_data_len = pc_send_data_len[j % len(pc_send_data_len)] + # data = "".join(["A"] * at_data_len) + chars = string.ascii_lowercase + data_list = ["".join([random.choice(chars) for m in range(at_data_len-16)])] + chars = string.ascii_uppercase + data_list.append("".join([random.choice(chars) for m in range(at_data_len-16)])) + chars = string.digits + data_list.append("".join([random.choice(chars) for m in range(at_data_len-16)])) + + for i in range(0, len(test_dispatch)): + for k in range(0, test_dispatch[i][1]): + data_str = "%.2d%.2d%.10d%s\r\n" % (j, i, k, data_list[k % 3]) + # time1 = time.time() + if tx_enable is True: + test_action = CmdHandler.parse_action("ATSO AT1 %s" % data_str, self.test_env) + CmdHandler.do_actions(test_action, self.test_env) + at_data_sent_total += at_data_len + if data_validation is True: + at2wifi_data += data_str + # time2 = time.time() + if rx_enable is True: + test_action = CmdHandler.parse_action("SOC SOC1 SENDTO %d %s %s %s" + % (pc_data_len, "", + "", data_str), self.test_env) + CmdHandler.do_actions(test_action, self.test_env) + pc_data_sent_total += pc_data_len + if data_validation is True: + wifi2at_data += data_str + # time3 = time.time() + # if time3-time2 > 0.1: + # pass + if test_dispatch[i][0] != 0: + time.sleep(test_dispatch[i][0]) + time.sleep(3) # wait 3 seconds + + # write send data to file for data validation + if data_validation is True: + path = os.path.split(self.log_file_name) + with open(os.path.join(path[0], "%s_at2wifi_at.bin" % self.timestamp), "ab+") as f: + f.write(at2wifi_data) + with open(os.path.join(path[0], "%s_wifi2at_pc.bin" % self.timestamp), "ab+") as f: + f.write(wifi2at_data) + throughput_results, at_data_recv_total, pc_data_recv_total = self.result_cntx.get_test_results() + result_str = "AT sent %15d\r\n" % at_data_sent_total + result_str += "PC recv %15d\r\n" % pc_data_recv_total + result_str += "PC sent %15d\r\n" % pc_data_sent_total + result_str += "AT recv %15d\r\n" % at_data_recv_total + for _result in throughput_results: + result_str += "%s\r\n" % _result + with open(self.log_file_name, "ab+") as f: + f.write(result_str) + + # finally, execute done + self.result_cntx.set_result("Succeed") + + def result_check(self, port_name, data): + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + +if __name__ == '__main__': + main() + diff --git a/components/test/TestCaseScript/ATStress/__init__.py b/components/test/TestCaseScript/ATStress/__init__.py new file mode 100755 index 0000000000..5a3bbc44dd --- /dev/null +++ b/components/test/TestCaseScript/ATStress/__init__.py @@ -0,0 +1,2 @@ +__all__ = ["TCPClientMulti", "TCPClientSingle", "TCPServerMulti", + "TCPTransparent", "UDPMulti", "UDPSingle"] \ No newline at end of file diff --git a/components/test/TestCaseScript/IOT/SCIOT.py b/components/test/TestCaseScript/IOT/SCIOT.py new file mode 100755 index 0000000000..5ced3ef121 --- /dev/null +++ b/components/test/TestCaseScript/IOT/SCIOT.py @@ -0,0 +1,357 @@ +import Queue + +from TCAction import TCActionBase +from NativeLog import NativeLog +from SCUDPServer import * +from TCAction.CmdExecutor import CmdExecutorBasic +from Utility import MakeFolder + +TEST_RESULT_CATEGORY = ("AP", "Phone") +TEST_RESULT_PROPERTY = ("model", "total", "succeed", "failed", "total time1", "total time2") +SINGLE_TEST_RESULT = ("AP", "Phone", "result", "time1", "time2") + +LOG_FILES = ("by_ap.tmp", "by_phone.tmp", "failed_item.tmp", "disqualified_item.tmp", "total.tmp") + +LOG_PATH = os.path.join("AT_LOG", "IOT") + + +def make_session_id(mac, test_id): + return mac_to_bytes(mac) + chr((test_id & 0xFF00) >> 8) + chr(test_id & 0xFF) + + +class TestHandler(threading.Thread): + def __init__(self, session_id, ap, phone, udp_server, test_action): + threading.Thread.__init__(self) + self.setDaemon(True) + self.udp_server = udp_server + self.session_id = session_id + self.ap = ap + self.phone = phone + self.test_action = test_action + self.recv_queue = Queue.Queue(10) + self.abort_event = threading.Event() + self.start_time = time.time() + self.test_result = None + udp_server.register_test_handler(session_id, self) + pass + + def req_receiver(self, msg, address): + self.recv_queue.put([msg, address]) + pass + + def res_receiver(self, msg, address): + self.recv_queue.put([msg, address]) + pass + + def abort_handler(self): + NativeLog.add_prompt_trace("[Test Handler][Debug] test aborted") + self.abort_event.set() + self.test_action.remove_from_available_list(self.phone) + pass + + def wait_result(self, event, timeout=None): + time_start = time.time() + while True: + if self.abort_event.isSet() is True: + return False + + if time.time() - self.start_time > ABORT_TIMEOUT: + return False + + if timeout is not None: + if time.time() - time_start > timeout: + return False + + if event == "ACK" or event == "result": + try: + ret = self.recv_queue.get(timeout=0.5) + except Queue.Empty, e: + continue + else: + msg = ret[0] + value_list = get_value_from_msg("type", msg) + msg_typ = ord(value_list[0]) + if msg_typ == TYPE_VAL[event]: + NativeLog.add_prompt_trace("[Test Handler][Debug] wait message succeed") + return msg + elif (msg_typ & 0x80) == 0: # invalid request + self.udp_server.send_response([[VALUE_NAME["type"], TYPE_VAL["Not support"]], + [VALUE_NAME["session id"], self.session_id]], + ret[1]) + pass + else: + pass + pass + + def run(self): + for i in range(1): + # step1 send broadcast to SP + msg = [[VALUE_NAME["type"], TYPE_VAL["Init new test"]], + [VALUE_NAME["session id"], self.session_id]] + self.udp_server.send_request(("", self.udp_server.udp_port), self.session_id, msg) + # wait response + if self.wait_result("ACK") is False: + break + NativeLog.add_prompt_trace("[Step1] Initial new test succeed") + + # step2 start smart config + checker_stings = ["ATR AT1 L OK"] + test_action_string = ["ATS AT1 AT+CWSTOPSMART"] + fail_string = "Fail, Failed to start smart config" + if self.test_action.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + NativeLog.add_prompt_trace(fail_string) + break + checker_stings = ["ATR AT1 L OK"] + test_action_string = ["ATS AT1 AT+CWSTARTSMART=1"] + if self.test_action.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + NativeLog.add_prompt_trace(fail_string) + break + NativeLog.add_prompt_trace("[Step2] Start smart config succeed") + + # step3 send test request to SP + msg = [[VALUE_NAME["type"], TYPE_VAL["test request"]], + [VALUE_NAME["session id"], self.session_id], + [VALUE_NAME["ap ssid"], self.ap["ssid"]], + [VALUE_NAME["ap password"], self.ap["password"]], + [VALUE_NAME["ap bssid"], mac_to_bytes(self.ap["bssid"])], + # [VALUE_NAME["ET version"], 0x20], + [VALUE_NAME["ssid hidden"], self.ap["is_hidden"]], + [VALUE_NAME["ap encryption"], AP_ENCRYPTION_VAL[self.ap["encryption"]]] + ] + self.udp_server.send_request((self.phone["ip"], self.udp_server.udp_port), self.session_id, msg) + # wait SP reply + if self.wait_result("ACK") is False: + break + NativeLog.add_prompt_trace("[Step3] Send test request succeed") + time_base = time.time() + + # step4 wait target smart config succeed + checker_stings = ["ATR AT1 C get%%20wifi%%20info C %s C %s" + % (self.ap["ssid"], self.ap["password"])] + test_action_string = [] + fail_string = "Fail, Fail to get ap info" + # if check target get smart config result fail, continue and get result from SP + ret = self.test_action.load_and_exe_one_step(checker_stings, test_action_string, + fail_string, check_time=600) + if ret is False: + NativeLog.add_prompt_trace("[Step4] Target smart config fail") + step_4_fail = True + else: + NativeLog.add_prompt_trace("[Step4] Target smart config succeed") + step_4_fail = False + time_target_succeed = time.time() - time_base + + # step5 wait SP result + msg = self.wait_result("result") + if msg is False: + NativeLog.add_prompt_trace("[Test Handler][Debug] Failed to get result from SP") + break + else: + self.udp_server.send_response([[VALUE_NAME["type"], TYPE_VAL["ACK"]], + [VALUE_NAME["session id"], self.session_id]], + (self.phone["ip"], self.udp_server.udp_port)) + tmp = get_value_from_msg(["result code", "start SC time", "recv UDP time"], msg) + result_code = ord(tmp[0]) + if result_code == RESULT_CODE_VAL["OK"]: + sp_start_time = bytes_to_time(tmp[1]) + sp_recv_udp_time = bytes_to_time(tmp[2]) + smart_config_protocol_cost = time_target_succeed - sp_start_time + user_experience_time = sp_recv_udp_time - sp_start_time + self.test_result = ["Succeed", smart_config_protocol_cost, user_experience_time] + elif result_code == RESULT_CODE_VAL["recv UDP fail"]: + sp_start_time = bytes_to_time(tmp[1]) + if step_4_fail is True: + smart_config_protocol_cost = 0 + else: + smart_config_protocol_cost = time_target_succeed - sp_start_time + self.test_result = ["Failed", smart_config_protocol_cost, 0] + pass + else: + NativeLog.add_prompt_trace("[Test Handler][Debug] Disqualified message: %s" % tmp) + + for k in range(RETRANSMIT_COUNT - 1): + if self.wait_result("result", RETRANSMIT_TIMEOUT) is not False: + self.udp_server.send_response([[VALUE_NAME["type"], TYPE_VAL["ACK"]], + [VALUE_NAME["session id"], self.session_id]], + (self.phone["ip"], self.udp_server.udp_port)) + + NativeLog.add_prompt_trace("[Step5] Receive test result from SP") + + if self.test_result is None: + self.test_result = ["Disqualified", 0, 0] + self.udp_server.deregister_test_handler(self.session_id) + NativeLog.add_prompt_trace("One Test Done") + pass + + def get_result(self): + if self.test_result is None: + NativeLog.add_trace_critical("Get result before test finish") + return self.test_result + pass + + +class SCIOT(TCActionBase.CommonTCActionBase): + def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + self.ap_list = [] + self.test_result = dict.fromkeys(TEST_RESULT_CATEGORY) + self.test_result["AP"] = [] + self.test_result["Phone"] = [] + self.available_phone_list = [] + self.pc_ip = "" + self.udp_port = "" + self.test_id = 0x00 + self.resource_lock = threading.Lock() + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy" and cmd_set[i][0] != "": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + + for i in range(1, len(cmd_set)): + for j in range(len(cmd_set[i][1])): + if cmd_set[i][1][j] != "": + cmd_string = "self.ap_list.append(dict(zip(AP_PROPERTY, " + cmd_set[i][1][j] + ")))" + exec cmd_string + for ap in self.ap_list: + self.test_result["AP"].append(dict(zip(TEST_RESULT_PROPERTY, [ap["ssid"], 0, 0, 0, 0, 0]))) + + self.log_folder = MakeFolder.make_folder(os.path.join(LOG_PATH, "TEST_%s" + % (time.strftime("%y%m%d%H%M%S", time.localtime())))) + self.log_files = dict.fromkeys(LOG_FILES) + for _file in self.log_files: + self.log_files[_file] = os.path.join(self.log_folder, + (time.strftime("%H%M%S", time.localtime())) + _file) + pass + + def update_phone_list(self, phone): + with self.resource_lock: + tmp = filter(lambda x: x["model"] == phone["model"], self.available_phone_list) + if len(tmp) == 1: + tmp[0]["ip"] = phone["ip"] + else: + self.available_phone_list.append(phone) + + tmp = filter(lambda x: x["model"] == phone["model"], self.test_result["Phone"]) + if len(tmp) == 0: + self.test_result["Phone"].append(dict(zip(TEST_RESULT_PROPERTY, [phone["model"], 0, 0, 0, 0, 0]))) + pass + + def remove_from_available_list(self, phone): + with self.resource_lock: + tmp = filter(lambda x: x["model"] == phone["model"], self.available_phone_list) + if len(tmp) == 1: + self.available_phone_list.remove(tmp[0]) + pass + + def allocate_test(self): + phone = None + test_count = 0xFFFF + with self.resource_lock: + for _phone in self.available_phone_list: + tmp = filter(lambda x: x["model"] == _phone["model"], self.test_result["Phone"]) + if len(tmp) == 1: + _count = tmp[0]["total"] + if _count < test_count: + test_count = _count + phone = _phone + ap_list = self.ap_list[test_count % len(self.ap_list):] + return phone, ap_list + pass + + def output_test_result(self, ap, phone, test_result): + result_str = "Time stamp" + ":\t" + NativeLog.generate_timestamp() + "\r\n" + result_str += "AP model" + ":\t" + str(ap["ssid"]) + "\r\n" + result_str += "AP encryption" + ":\t" + str(ap["encryption"]) + "\r\n" + result_str += "AP HT" + ":\t" + str(ap["ht"]) + "\r\n" + result_str += "AP ssid hidden" + ":\t" + str(ap["is_hidden"]) + "\r\n" + result_str += "Phone model" + ":\t" + str(phone["model"]) + "\r\n" + result_str += "Result" + ":\t" + str(test_result[0]) + "\r\n" + result_str += "Time1" + ":\t" + str(test_result[1]) + "\r\n" + result_str += "Time2" + ":\t" + str(test_result[2]) + "\r\n" + + with self.resource_lock: + tmp = [filter(lambda x: x["model"] == ap["ssid"], self.test_result["AP"])[0], + filter(lambda x: x["model"] == phone["model"], self.test_result["Phone"])[0]] + if test_result[0] == "Succeed": + for _tmp in tmp: + _tmp["total"] += 1 + _tmp["succeed"] += 1 + _tmp["total time1"] += test_result[1] + _tmp["total time2"] += test_result[2] + pass + elif test_result[0] == "Disqualified": + for _tmp in tmp: + _tmp["total"] += 1 + pass + else: + for _tmp in tmp: + _tmp["total"] += 1 + _tmp["failed"] += 1 + pass + tmp_result = dict(zip(TEST_RESULT_CATEGORY, ["", ""])) + for category in self.test_result: + for _result in self.test_result[category]: + for n in _result: + tmp_result[category] += str(n) + ":\t" + str(_result[n]) + "\r\n" + + # update to log file + with open(self.log_files["by_ap.tmp"], "wb+") as f: + f.write(tmp_result["AP"]) + with open(self.log_files["by_phone.tmp"], "wb+") as f: + f.write(tmp_result["Phone"]) + + with open(self.log_files["total.tmp"], "ab+") as f: + f.write(result_str) + if test_result[0] == "Failed": + with open(self.log_files["failed_item.tmp"], "ab+") as f: + f.write(result_str) + elif test_result[0] == "Disqualified": + with open(self.log_files["disqualified_item.tmp"], "ab+") as f: + f.write(result_str) + + pass + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + pc_ip = CmdExecutorBasic.extract_parameter(self.pc_ip, self.test_env) + if isinstance(self.udp_port, int) is False: + udp_port = CmdExecutorBasic.extract_parameter(self.udp_port, self.test_env) + else: + udp_port = self.udp_port + + server = UDPServer(pc_ip, udp_port, self.update_phone_list) + server.start() + + while True: + phone, ap_list = self.allocate_test() + if phone is None: + time.sleep(5) + continue + for ap in ap_list: + NativeLog.add_prompt_trace("AP is %s, Phone is %s" % (ap["ssid"], phone["model"])) + session_id = make_session_id(phone["mac"], self.test_id) + self.test_id += 1 + test_handler = TestHandler(session_id, ap, phone, server, self) + test_handler.start() + test_handler.join() + result = test_handler.get_result() + self.output_test_result(ap, phone, result) + + # finally, execute done + server.join() + self.result_cntx.set_result("Succeed") + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + +if __name__ == '__main__': + main() diff --git a/components/test/TestCaseScript/IOT/SCUDPServer.py b/components/test/TestCaseScript/IOT/SCUDPServer.py new file mode 100755 index 0000000000..75f24f79ac --- /dev/null +++ b/components/test/TestCaseScript/IOT/SCUDPServer.py @@ -0,0 +1,378 @@ +import socket +import time +import os +import threading + +from NativeLog import NativeLog + + +RETRANSMIT_COUNT = 5 +RETRANSMIT_TIMEOUT = 0.5 +ABORT_TIMEOUT = 120 +BEACON_SEND_RATE = 30 + + +VALUE_NAME = {"type": 0x00, + "session id": 0x01, + "result code": 0x02, + "ap ssid": 0x03, + "ap password": 0x04, + "start SC time": 0x05, + "recv UDP time": 0x06, + "SP model": 0x07, + "SP mac": 0x08, + "ET version": 0x09, + "ap bssid": 0x0A, + "ssid hidden": 0x0B, + "ap encryption": 0x0C, + } + +TYPE_VAL = {"Init new test": 0x00, + "test request": 0x01, + "result": 0x02, + "query phone": 0x03, + "ACK": 0x80, + "phone report": 0x81, + "Not support": 0xFF, + "invalid session": 0xFE, + } + +RESULT_CODE_VAL = {"OK": 0x80, + "JAP fail": 0x81, # SP join AP fail, should disqualify this result + "recv UDP fail": 0x82, # SP did not receive UDP sent by target + } + +AP_ENCRYPTION_VAL = {"OPEN": 0x00, + "WEP": 0x01, + "WPA": 0x02, + } + +AP_PROPERTY = ("ssid", "password", "bssid", "is_hidden", "encryption", "ht") +PHONE_PROPERTY = ("ip", "mac", "model") + + +SERIAL_PORT_NUM = 3 +LOG_FILE_PREFIX = "SC_IOT" +LOG_FOLDER = os.path.join("AT_LOG", "TEMP") +LOG_FILE_NAME = os.path.join(LOG_FOLDER, "%s_%s.log" % (LOG_FILE_PREFIX, time.strftime("%d%H%M%S", time.localtime()))) + + +REQUEST_LOCK = threading.Lock() +HANDLER_LOCK = threading.Lock() + + +def sync_request_list(func): + def handle_args(*args, **kwargs): + with REQUEST_LOCK: + ret = func(*args, **kwargs) + return ret + return handle_args + + +def sync_handler_list(func): + def handle_args(*args, **kwargs): + with HANDLER_LOCK: + ret = func(*args, **kwargs) + return ret + return handle_args + + +def _process_one_tlv_pair(data): + typ = ord(data[0]) + length = ord(data[1]) + value = data[2:2+length] + processed_data = data[2+length:] + return (typ, value), processed_data + pass + + +def bytes_to_msg(data): + data_to_process = data + msg = [] + while True: + one_pair, data_to_process = _process_one_tlv_pair(data_to_process) + msg.append(one_pair) + if len(data_to_process) == 0: + break + return msg + pass + + +def msg_to_bytes(msg): + byte_str = "" + for pair in msg: + byte_str += chr(pair[0]) + if isinstance(pair[1], list) is True: + byte_str += chr(len(pair[1])) + byte_str.join([chr(m) for m in pair[1]]) + elif isinstance(pair[1], str) is True: + byte_str += chr(len(pair[1])) + byte_str += pair[1] + elif isinstance(pair[1], int) is True: + byte_str += chr(1) + byte_str += chr(pair[1]) + else: + raise TypeError("msg content only support list and string type") + return byte_str + + +def get_value_from_msg(type_list, msg): + if isinstance(type_list, str) is True: + type_list = [type_list] + ret = [""] * len(type_list) + for pair in msg: + for i in range(len(type_list)): + if pair[0] == VALUE_NAME[type_list[i]]: + ret[i] = pair[1] + if "" not in ret: + # all type value found + break + else: + NativeLog.add_prompt_trace("missing required type in msg") + return ret + + +def bytes_to_time(bytes_in): + if len(bytes_in) != 4: + return 0 + t = float(ord(bytes_in[0])*256*256*256 + ord(bytes_in[1])*256*256 + + ord(bytes_in[2])*256 + ord(bytes_in[2]))/1000 + return t + pass + + +def mac_to_bytes(mac): + tmp = mac.split(':') + return "".join([chr(int(m[:2], base=16)) for m in tmp]) + pass + + +def bytes_to_mac(bytes_in): + mac = "".join(["%x:" % ord(m) for m in bytes_in] ) + return mac[:-1] + + +class RetransmitHandler(threading.Thread): + def __init__(self, udp_server): + threading.Thread.__init__(self) + self.setDaemon(True) + self.udp_server = udp_server + self.exit_event = threading.Event() + pass + + @sync_request_list + def find_required_retransmit_msg(self): + time_now = time.time() + aborted_sessions = [] + retransmit_msg = [] + msgs = filter(lambda x: time_now - x[4] >= RETRANSMIT_TIMEOUT, self.udp_server.unconfirmed_request) + for msg in msgs: + if msg[3] == 0: + aborted_sessions.append(msg[0]) + self.udp_server.unconfirmed_request.remove(msg) + else: + msg[3] -= 1 + msg[4] = time_now + retransmit_msg.append(msg) + pass + return aborted_sessions, retransmit_msg + pass + + def run(self): + while True: + self.exit_event.wait(0.1) + if self.exit_event.isSet() is True: + break + aborted_sessions, retransmit_msg = self.find_required_retransmit_msg() + for msg in retransmit_msg: + self.udp_server.udp_socket.sendto(msg[1], msg[2]) + for session_id in aborted_sessions: + self.udp_server.session_aborted(session_id) + + def exit(self): + self.exit_event.set() + pass + + +class SendBeacon(threading.Thread): + def __init__(self, sock, udp_port): + threading.Thread.__init__(self) + self.setDaemon(True) + self.udp_sock = sock + self.udp_port = udp_port + self.exit_event = threading.Event() + + def run(self): + while True: + msg = [[VALUE_NAME["type"], TYPE_VAL["query phone"]]] + data = msg_to_bytes(msg) + self.udp_sock.sendto(data, ("", self.udp_port)) + for i in range(BEACON_SEND_RATE): + self.exit_event.wait(1) + if self.exit_event.isSet() is True: + return + pass + + def exit(self): + self.exit_event.set() + pass + + +class UDPServer(threading.Thread): + def __init__(self, pc_ip, udp_port, update_phone_handler): + threading.Thread.__init__(self) + self.setDaemon(True) + sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM) + sock.bind((pc_ip, udp_port)) + sock.settimeout(1) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) + self.udp_socket = sock + self.unconfirmed_request = [] + self.test_handler_list = [] + self.pc_ip = pc_ip + self.udp_port = udp_port + self.update_phone_handler = update_phone_handler + self.retransmit_thread = RetransmitHandler(self) + self.beacon_thread = SendBeacon(self.udp_socket, self.udp_port) + self.retransmit_thread.start() + self.beacon_thread.start() + self.exit_event = threading.Event() + pass + + @sync_handler_list + def register_test_handler(self, session_id, test_handler): + tmp = filter(lambda x: x[0] == session_id, self.test_handler_list) + if len(tmp) > 0: + NativeLog.add_prompt_trace("handler with same session id exist") + else: + self.test_handler_list.append([session_id, test_handler]) + pass + + @sync_handler_list + def deregister_test_handler(self, session_id): + tmp = filter(lambda x: x[0] == session_id, self.test_handler_list) + if len(tmp) > 1: + NativeLog.add_prompt_trace("deregister test handler fail") + elif len(tmp) == 1: + self.test_handler_list.remove(tmp[0]) + pass + + @sync_handler_list + def get_test_handler(self, session_id): + ret = None + tmp = filter(lambda x: x[0] == session_id, self.test_handler_list) + if len(tmp) != 1: + NativeLog.add_prompt_trace("failed to get test handler, " + "%d handler found, session id %s" % (len(tmp), session_id)) + elif len(tmp) == 1: + ret = tmp[0][1] + return ret + pass + + def session_aborted(self, session_id): + test_handler = self.get_test_handler(session_id) + if test_handler is not None: + test_handler.abort_handler() + pass + + def confirm_request(self, session_id, msg, address): + test_handler = self.get_test_handler(session_id) + if test_handler is not None: + test_handler.res_receiver(msg, address) + self.remove_pending_request(session_id) + pass + + def receive_request(self, msg, address): + result = get_value_from_msg(["type", "session id"], msg) + msg_type = ord(result[0]) + session_id = result[1] + if msg_type != TYPE_VAL["result"]: + self.send_response([[VALUE_NAME["type"], TYPE_VAL["Not support"]]], address) + else: + test_handler = self.get_test_handler(session_id) + if test_handler is None: + self.send_response([[VALUE_NAME["type"], TYPE_VAL["invalid session"]], + [VALUE_NAME["session id"], session_id]], + address) + pass + else: + test_handler.req_receiver(msg, address) + pass + + @sync_request_list + def add_request_to_queue(self, dest_addr, session_id, data): + tmp = filter(lambda x: x[0] == session_id, self.unconfirmed_request) + if len(tmp) != 0: + NativeLog.add_prompt_trace("One pending request belong to same session id %s" % session_id) + pass + else: + self.unconfirmed_request.append([session_id, data, + dest_addr, RETRANSMIT_COUNT-1, time.time()]) + + def send_request(self, dest_addr, session_id, msg): + data = msg_to_bytes(msg) + self.add_request_to_queue(dest_addr, session_id, data) + self.udp_socket.sendto(data, dest_addr) + pass + + def send_response(self, msg, address): + self.udp_socket.sendto(msg_to_bytes(msg), address) + + @sync_request_list + def remove_pending_request(self, session_id): + tmp = filter(lambda x: x[0] == session_id, self.unconfirmed_request) + if len(tmp) > 0: + self.unconfirmed_request.remove(tmp[0]) + pass + pass + + def handle_response(self, msg, address): + result = get_value_from_msg(["type", "session id"], msg) + msg_type = ord(result[0]) + session_id = result[1] + if msg_type == TYPE_VAL["ACK"]: + self.confirm_request(session_id, msg, address) + elif msg_type == TYPE_VAL["phone report"]: + # add new available phone + tmp = get_value_from_msg(["SP model", "SP mac"], msg) + phone = dict(zip(PHONE_PROPERTY, [address[0], bytes_to_mac(tmp[1]), tmp[0]])) + self.update_phone_handler(phone) + pass + elif msg_type == TYPE_VAL["Not support"] or msg_type == TYPE_VAL["invalid session"]: + self.session_aborted(session_id) + pass + + def run(self): + while self.exit_event.isSet() is False: + try: + data, address = self.udp_socket.recvfrom(65535) + except socket.error, e: + continue + + if address[0] == self.pc_ip: + continue + + msg = bytes_to_msg(data) + msg_type = get_value_from_msg(["type"], msg)[0] + + if msg_type is None: + NativeLog.add_prompt_trace("invalid incoming msg: %s" % "".join(["0x%X, " % m for m in data])) + else: + msg_type = ord(msg_type) + # check if request or reply + if (msg_type & 0x80) != 0: + self.handle_response(msg, address) + else: + self.receive_request(msg, address) + pass + + self.retransmit_thread.exit() + self.beacon_thread.exit() + self.retransmit_thread.join() + self.beacon_thread.join() + pass + + def exit(self): + self.exit_event.set() + pass diff --git a/components/test/TestCaseScript/IOT/WifiConnUtility.py b/components/test/TestCaseScript/IOT/WifiConnUtility.py new file mode 100755 index 0000000000..d50474561b --- /dev/null +++ b/components/test/TestCaseScript/IOT/WifiConnUtility.py @@ -0,0 +1,244 @@ +from NativeLog import NativeLog +import time +import random +import string + + +ERROR_AP_PROP = {"ssid": "123456789012345678901234567890", + "ssid_len": 30, + "pwd": "12345678901234567890", + "pwd_len": 20, + "channel": 10, + "enc": 3, + "apc": 9, # invalid apc count + } + + +class WifiConnUtilError(StandardError): + pass + + +class WifiConnUtility(object): + + def __init__(self, tc_action): + self.tc_action = tc_action + self.target_type = tc_action.target_type + pass + + def set_mode(self, mode): + ret = True + fail_string = "set mode fail" + cmd = [] + checker_stings = [] + for i in range(2): + if self.target_type[0] == "SSC": + cmd.append("SSCC SSC%d op -S -o %d" % (i+1, mode[i])) + checker_stings.append("SSCP SSC%d C cur_mode C %d" % (i+1, mode[i])) + pass + else: + cmd.append("ATC AT%d CWMODE %d" % (i+1, mode[i])) + checker_stings.append("ATP AT%d L OK" % (i+1)) + pass + if self.tc_action.load_and_exe_one_step(checker_stings, cmd, + fail_string, check_time=50) is False: + NativeLog.add_trace_critical("Failed to set mode") + ret = False + return ret + pass + + def _apc_switch(self, outlet_list, action_list): + checker_stings = ["R PC_COM C OK"] + switch_cmd = "APC APC1" + fail_string = "Error when switching APC" + ret = True + + for [_outlet, _action] in zip(action_list, outlet_list): + switch_cmd += " %s %d" % (_action, _outlet) + + if self.tc_action.load_and_exe_one_step(checker_stings, [switch_cmd], + fail_string, check_time=50) is False: + NativeLog.add_trace_critical("Error when switching APC") + ret = False + return ret + pass + + def _set_target_ap(self, ap_prop): + ret = True + fail_string = "set target ap fail, %s, %s" % (ap_prop["ssid"], ap_prop["pwd"]) + if self.target_type[1] == "SSC": + if ap_prop["pwd"] == "": + cmd = ["SSCC SSC2 ap -S -s %s -t %d" % (ap_prop["ssid"], + ap_prop["enc"]) + ] + else: + cmd = ["SSCC SSC2 ap -S -s %s -p %s -t %d" % (ap_prop["ssid"], + ap_prop["pwd"], + ap_prop["enc"]) + ] + checker_stings = ["SSCP SSC2 C +SAP:OK"] + pass + else: + cmd = ["ATC AT2 CWSAP \"%s\" \"%s\" %d %d" % (ap_prop["ssid"], + ap_prop["pwd"], + ap_prop["channel"], + ap_prop["enc"]) + ] + checker_stings = ["ATR AT2 L OK"] + pass + if self.tc_action.load_and_exe_one_step(checker_stings, cmd, + fail_string, check_time=50) is False: + NativeLog.add_trace_critical("set target ap fail") + ret = False + return ret + pass + + def setup_ap(self, ap_type, ap_prop): + if ap_type == "target": + ret = self._set_target_ap(ap_prop) + pass + else: + ret = self._apc_switch(["ON"], [ap_prop["apc"]]) + # delay for 5 seconds, wait AP ready + time.sleep(5) + pass + return ret + + def do_scan(self, ap_prop): + fail_string = "Scan fail" + ret = True + # do not check if the set AP can be scanned + if self.target_type[1] == "SSC": + cmd = ["SSCC SSC1 sta -S"] + checker_stings = ["SSCR SSC1 C ssc%20scan%20done"] + pass + else: + cmd = ["ATS AT1 AT+CWLAP"] + checker_stings = ["ATR AT1 L OK"] + pass + if self.tc_action.load_and_exe_one_step(checker_stings, cmd, + fail_string, check_time=100) is False: + NativeLog.add_trace_critical("Scan fail") + ret = False + return ret + pass + + def _switch_off_target_ap(self, delay): + time.sleep(delay) + self._set_target_ap(ERROR_AP_PROP) + pass + + def _switch_on_target_ap(self, ap_prop, delay): + time.sleep(delay) + self._set_target_ap(ap_prop) + pass + + def _switch_off_ap(self, ap_type, ap_prop, delay_range): + delay = random.randint(delay_range[0]*10, delay_range[1]*10)/10 + if ap_type == "target": + self._switch_off_target_ap(delay) + else: + delay -= 1.5 + time.sleep(delay if delay > 0 else 0) + self._apc_switch(["OFF"], [ap_prop["apc"]]) + pass + + def _switch_on_ap(self, ap_type, ap_prop, delay_range): + delay = random.randint(delay_range[0]*10, delay_range[1]*10)/10 + if ap_type == "target": + self._switch_on_target_ap(ap_prop, delay) + else: + delay -= 1.5 + time.sleep(delay if delay > 0 else 0) + self._apc_switch(["ON"], [ap_prop["apc"]]) + pass + + def _join_ap(self, ap_prop, test_method): + fail_string = "join target ap fail, %s, %s" % (ap_prop["ssid"], ap_prop["pwd"]) + if self.target_type[1] == "SSC": + cmd = ["SSCC SSC1 ap -C -s %s -p %s" % (ap_prop["ssid"], + ap_prop["pwd"],) + ] + checker_stings = ["SSCR SSC1 C %s" % ap_prop["ssid"], + "SSCR SSC1 C dhcp%20client%20start", + "SSCR SSC1 C ip C mask C gw"] + pass + else: + cmd = ["ATC AT1 CWJAP \"%s\" \"%s\"" % (ap_prop["ssid"], + ap_prop["pwd"]) + ] + checker_stings = ["ATR AT1 NC ERROR NC FAIL L OK"] + pass + if test_method == "Normal": + ret = self.tc_action.load_and_exe_one_step(checker_stings, cmd, + fail_string, check_freq=0.1, check_time=350) + if ret is not False: + ret *= 0.1 + else: + ret = self.tc_action.load_and_exe_one_step([], cmd, fail_string) + return ret + pass + + def _check_join_ap_result(self, ap_prop): + ret = False + fail_string = "join ap fail, %s, %s" % (ap_prop["ssid"], ap_prop["pwd"]) + + if self.target_type[1] == "SSC": + checker_stings = ["SSCR SSC1 C dhcp%20client%20start", + "SSCR SSC1 C ip C mask C gw"] + ret = self.tc_action.load_and_exe_one_step(checker_stings, ["DELAY 0"], + fail_string, check_freq=1, check_time=120) + pass + else: + cmd = ["ATS AT1 AT+CWJAP?"] + checker_stings = ["ATR AT1 NC busy NC No%20AP C +CWJAP"] + for i in range(3): + ret = self.tc_action.load_and_exe_one_step(checker_stings, cmd, + fail_string, check_freq=1, check_time=2) + if ret is not False: + break + time.sleep(15) + + return ret + pass + + def join_ap(self, join_test_method, ap_type, ap_prop, delay): + + if join_test_method == "WRONG_PROP": + _prop = ERROR_AP_PROP + else: + _prop = ap_prop + + ret = self._join_ap(_prop, join_test_method) + + if join_test_method == "OFF_ON": + self._switch_off_ap(ap_type, ap_prop, delay[0]) + self._switch_on_ap(ap_type, ap_prop, delay[1]) + ret = self._check_join_ap_result(_prop) + pass + elif join_test_method == "OFF": + self._switch_off_ap(ap_type, ap_prop, delay[0]) + time.sleep(25) + pass + + return ret + pass + + def do_reconnect(self, reconnect_test_method, ap_type, ap_prop, delay): + ret = True + if reconnect_test_method == "OFF_ON": + self._switch_off_ap(ap_type, ap_prop, delay[0]) + self._switch_on_ap(ap_type, ap_prop, delay[1]) + ret = self._check_join_ap_result(ap_prop) + pass + elif reconnect_test_method == "OFF": + self._switch_off_ap(ap_type, ap_prop, delay[0]) + pass + return ret + pass + + +def main(): + pass + +if __name__ == '__main__': + main() diff --git a/components/test/TestCaseScript/IOT/WifiJAP.py b/components/test/TestCaseScript/IOT/WifiJAP.py new file mode 100755 index 0000000000..0bb6292955 --- /dev/null +++ b/components/test/TestCaseScript/IOT/WifiJAP.py @@ -0,0 +1,183 @@ +import os +import random +import time + +import WifiConnUtility +from NativeLog import NativeLog +from TCAction import TCActionBase +from Utility import Encoding +from Utility import MakeFolder + +STEPS = {"SCAN1": 0x01, "JAP": 0x02, "SCAN2": 0x04, "RECONNECT": 0x08} + +AP_PROP = ("ssid", "ssid_len", "pwd", + "pwd_len", "channel", "enc", "apc") + +JAP_TEST_METHOD = ("Normal", "OFF_ON", "OFF", "WRONG_PROP") + +RECONNECT_TEST_METHOD = ("OFF_ON", "OFF") + +LOG_FOLDER = os.path.join("AT_LOG", "Performance", "JAP") + + +SSID_LEN_RANGE = (1, 32) # in bytes +ENC_TYPE = (0, 2, 3, 4) # do not support WEP for 8266 soft AP +PWD_RANGE = {0: [0, 0], + 1: [5, 5], + 2: [8, 63], + 3: [8, 63], + 4: [8, 63], + } + + +class WifiJAP(TCActionBase.CommonTCActionBase): + + def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + # default value for optional configurable params + self.pwd_len = [8, 64] + self.step_config = [0x03, 0x01, 0x02, 0x0B, 0x0F] + self.join_test_method = ["Normal"] + self.join_delay = [[1.5, 5], [1.5, 5]] + self.reconnect_test_method = ["OFF_ON"] + self.reconnect_delay = [[1.5, 5], [1.5, 6]] + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy" and cmd_set[i][0] != "": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + # read AP list + self.ap_list = [] + for i in range(1, len(cmd_set)): + for j in range(len(cmd_set[i][1])): + if cmd_set[i][1][j] != "": + cmd_string = "self.ap_list.append(dict(zip(AP_PROP, " + cmd_set[i][1][j] + ")))" + exec cmd_string + + folder_path = MakeFolder.make_folder(LOG_FOLDER) + file_name = "JAP_log_%s.log" % (time.strftime("%m%d%H%M%S", time.localtime())) + self._performance_log_file = os.path.join(folder_path, file_name) + + # test statistics + self._succeed_count = self._fail_count = self._time_cost_count = 0 + self._total_time = self._longest_time = 0 + + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + # get target type "SSC" or "AT" + self.target_type = ["SSC" if test_env.get_port_by_name("AT1") is None else "AT"] + self.target_type.append("SSC" if test_env.get_port_by_name("AT1") is None else "AT") + self._utility = WifiConnUtility.WifiConnUtility(self) + pass + + def _generate_random_ap_prop(self): + ap_prop = dict.fromkeys(AP_PROP) + # generate target ap_value + ap_prop["ssid_len"] = random.randint(SSID_LEN_RANGE[0], SSID_LEN_RANGE[1]) + ap_prop["channel"] = random.choice(range(1, 14)) + ap_prop["enc"] = random.choice(ENC_TYPE) + ap_prop["pwd_len"] = random.randint(PWD_RANGE[ap_prop["enc"]][0], PWD_RANGE[ap_prop["enc"]][1]) + # generate string + if self.target_type[0] == self.target_type[1] == "AT": + ap_prop["ssid"] = Encoding.generate_random_utf8_str(ap_prop["ssid_len"]) + ap_prop["pwd"] = Encoding.generate_random_utf8_str(ap_prop["pwd_len"]) + # NativeLog.add_trace_info("ssid hex is : %x" % ap_prop["ssid"]) + # NativeLog.add_trace_info("pwd hex is : %x" % ap_prop["pwd"]) + else: + ap_prop["ssid"] = Encoding.generate_random_printable_str(ap_prop["ssid_len"]) + ap_prop["pwd"] = Encoding.generate_random_printable_str(ap_prop["pwd_len"]) + + return ap_prop + + def _logging_performance(self, ssid, join_method="Normal", time_cost=0): + # log performance to performance log file + with open(self._performance_log_file, "ab+") as f: + # log time and ssid + f.write("\r\n[%s]:\r\n[AP name] %s\r\n" % + (time.strftime("%m-%d %H:%M:%S", time.localtime()), ssid)) + if join_method == "Normal" or join_method == "OFF_ON": + if time_cost is not False: + self._succeed_count += 1 + if join_method == "Normal": + f.write("[Succeed][%f]\r\n" % time_cost) + self._longest_time = (time_cost > self._longest_time and + [time_cost] or [self._longest_time])[0] + self._time_cost_count += 1 + self._total_time += time_cost + else: + f.write("[Succeed][%s]\r\n" % join_method) + else: + self._fail_count += 1 + f.write("[Fail][%s]\r\n" % join_method) + pass + + def _logging_fail_step(self, ssid, step): + with open(self._performance_log_file, "ab+") as f: + f.write("\r\n[%s]:\r\n[AP name] %s\r\n" % + (time.strftime("%m-%d %H:%M:%S", time.localtime()), ssid)) + f.write("[Fail][%s]\r\n" % step) + pass + + def _generate_performance_report(self): + with open(self._performance_log_file, "ab+") as f: + f.write("[Test report] Succeed: %d\r\n" % self._succeed_count) + f.write("[Test report] Failed: %d\r\n" % self._fail_count) + if self._succeed_count > 0 or self._fail_count > 0: + f.write("[Test report] Pass Rate: %f\r\n" % + (self._succeed_count/(self._fail_count+self._succeed_count))) + if self._time_cost_count > 0: + f.write("[Test report] Average time: %f\r\n" % (self._total_time/self._time_cost_count)) + f.write("[Test report] Longest time: %f\r\n" % self._longest_time) + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + # mandatory configurable params + try: + target_ap_num = self.target_ap_num + test_count = self.test_count + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for WifiJAP script, error is %s" % e) + raise StandardError("Error configuration") + + # prepare ap list + _ap_list = [["target", None]] * target_ap_num + for _ap_prop in self.ap_list: + _ap_list.append(["AP", _ap_prop]) + + # set to correct mode first + # self._utility.set_mode([1, 2]) + + for _ap in _ap_list: + # arrange ap + _ap_type = _ap[0] + _ap_prop = _ap[1] + if _ap_type == "target": + _ap_prop = self._generate_random_ap_prop() + + for i in xrange(test_count): + # step 3 : mandatory step, join AP + _join_test_method = "Normal" + time_cost = self._utility.join_ap(_join_test_method, _ap_type, _ap_prop, self.join_delay) + # log performance to performance log file + self._logging_performance(_ap_prop["ssid"], _join_test_method, time_cost) + NativeLog.add_prompt_trace("[Step] Join AP done") + + NativeLog.add_prompt_trace("[WifiJAP] One AP Done") + + # generate report and cleanup + self._generate_performance_report() + + self.result_cntx.set_result("Succeed") + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + +if __name__ == '__main__': + main() diff --git a/components/test/TestCaseScript/IOT/__init__.py b/components/test/TestCaseScript/IOT/__init__.py new file mode 100755 index 0000000000..db0afd1fc5 --- /dev/null +++ b/components/test/TestCaseScript/IOT/__init__.py @@ -0,0 +1 @@ +__author__ = 'Administrator' diff --git a/components/test/TestCaseScript/MeshStress/MeshSendRecv.py b/components/test/TestCaseScript/MeshStress/MeshSendRecv.py new file mode 100755 index 0000000000..bad4619a70 --- /dev/null +++ b/components/test/TestCaseScript/MeshStress/MeshSendRecv.py @@ -0,0 +1,525 @@ +from __future__ import division +import time +import threading +import re +import random +import os +import binascii + +from TCAction import PerformanceTCBase +from NativeLog import NativeLog +from NativeLog import HTMLGenerator +from comm import MeshPort +from Utility import Encoding + +# check frequency in second +CHECK_FREQ = 0.05 +# check timeout in seconds +CHECK_TIMEOUT = 30 +# multicast group len +MULTICAST_GROUP_LEN = 2 + + +LOG_PATH = os.path.join("..", "log") + +def _convert_to_mesh_mac_format(value_in): + value_out = "" + match_list = re.findall("([0-9a-fA-F]+)", value_in) + try: + for i in range(6): + value_out += "%02X" % int(match_list[i], base=16) + pass + except StandardError, e: + NativeLog.add_exception_log(e) + raise e + return value_out + +class SendRecvTime(threading.Thread): + def __init__(self): + threading.Thread.__init__(self) + self.setDaemon(True) + self.send_time = dict() + self.recv_time = dict() + self.send_time_lock = threading.Lock() + self.recv_time_lock = threading.Lock() + + def add_send_time(self, key, timestamp): + with self.send_time_lock: + self.send_time[key] = timestamp + + def add_recv_time(self, key, timestamp): + with self.recv_time_lock: + if key in self.recv_time.keys(): + self.recv_time[key].append(timestamp) + else: + self.recv_time[key] = [timestamp] + + def calculate(self): + # add compute delay time code here + print 'send dict len:', len(self.send_time) + print 'recv dict len:', len(self.recv_time) + recv_time_keys = self.recv_time.keys() + Max_delay_time = 0.0 + Total_delay_time = 0.0 + # for i in range(len(recv_time_keys)): + # key = recv_time_keys[i] + for key in recv_time_keys: + Total_delay_time_t = 0.0 + if isinstance(self.recv_time[key], list): + for time1 in self.recv_time[key]: + if time1 - self.send_time[key] >= Max_delay_time: + Max_delay_time = time1 - self.send_time[key] + Total_delay_time_t += (time1 - self.send_time[key]) + else: + pass + else: + if self.recv_time[key] - self.send_time[key] > Max_delay_time: + Max_delay_time = self.recv_time[key] - self.send_time[key] + Total_delay_time_t += (self.recv_time[key] - self.send_time[key]) + Total_delay_time_t += (Total_delay_time_t / len(self.recv_time[key])) + Total_delay_time += Total_delay_time_t + Avg_delay_time = Total_delay_time / len(recv_time_keys) + loss_rate = (len(self.send_time.keys()) - len(self.recv_time.keys())) / len(self.send_time.keys()) + return [Max_delay_time, Avg_delay_time, loss_rate] + pass + +class EntitySendThread(threading.Thread): + def __init__(self, port, behavior, unicast_addr, send_delay, typ, device_mac_list, server_addr, send_recv_time): + threading.Thread.__init__(self) + self.setDaemon(True) + self.recv_data_cache = "" + self.packets_sent = 0 + self.port = port + self.behavior = behavior + self.typ = typ + self.unicast_addr = unicast_addr + self.node_num = len(device_mac_list) + self.device_mac_list = list(device_mac_list) + self.server_addr = server_addr + if typ != "SERVER": + self.device_mac_list.remove(port.device_mac) + self.send_delay = send_delay + self.cache_lock = threading.Lock() + self.exit_event = threading.Event() + self.send_recv_time = send_recv_time + pass + + def data_recv_callback(self, data): + with self.cache_lock: + self.recv_data_cache += data + if self.typ == "SSC": + while True: + if self.recv_data_cache is not None: + match = re.compile(".+\+MSEND1:\d+:OK", re.DOTALL) + res = match.search(self.recv_data_cache) + index = re.search("\+MSEND1:(\d+):OK", self.recv_data_cache) + if index is not None: + time1 = time.time() + index1 = int(index.group(1)) + self.send_recv_time.add_send_time(index1, time1) + #print 'send index:', index1 + process_index = res.group().split("MSEND1") + if len(process_index) > 1: + process_index_t = len(process_index[0]) + len("MSEND1") + self.recv_data_cache = self.recv_data_cache[process_index_t:] + else: + self.recv_data_cache = self.recv_data_cache[len(res.group()):] + else: + break + else: + break + pass + + + def __server_send_packet(self, dst_addr, option_list=None, group_addr=None): + ver = 0x0 + flags = 0x0 + proto = 0x0 + index = random.randint(10000, 999999999) + if group_addr is not None: + len_t = hex(len(group_addr) * 6).split("0x") + if len(group_addr) <= 2: + option_list = "070" + len_t[1] + else: + option_list = "07" + len_t[1] + group = "" + for addr in group_addr: + group += _convert_to_mesh_mac_format(addr) + option_list += group + else: + option_list = None + if self.behavior == "broadcast": + dst_addr = "00:00:00:00:00:00" + elif self.behavior == "unicast": + if self.unicast_addr == "random": + dst_addr = random.choice(self.device_mac_list) + else: + dst_addr = self.unicast_addr + elif self.behavior == "p2p": + proto = 0x2 + if self.unicast_addr == "random": + dst_addr = random.choice(self.device_mac_list) + else: + dst_addr = self.unicast_addr + packet = MeshPort.Packet(ver=ver, flags=flags, proto=proto, + dst_addr=dst_addr, src_addr=self.server_addr, option_list=option_list, data="A" * 100, index=index) + send_data = packet.dumps + try: + self.port.socket.send(send_data) + time2 = time.time() + self.send_recv_time.add_send_time(index, time2) + except StandardError, e: + NativeLog.add_exception_log(e) + return False + + def __server_do_send(self): + if self.behavior == "broadcast": + if self.__server_send_packet(dst_addr="00:00:00:00:00:00", group_addr=None) is True: + self.packets_sent += self.node_num + elif self.behavior == "multicast": + random.shuffle(self.device_mac_list) + group_addr_list = self.device_mac_list[:MULTICAST_GROUP_LEN] + if self.__server_send_packet(dst_addr="01:00:5E:00:00:00", group_addr=group_addr_list) is True: + self.packets_sent += MULTICAST_GROUP_LEN + elif self.behavior == "unicast": + if self.__server_send_packet(dst_addr=random.choice(self.device_mac_list), group_addr=None) is True: + self.packets_sent += 1 + elif self.behavior == "p2p": + if self.__server_send_packet(dst_addr=random.choice(self.device_mac_list), group_addr=None) is True: + self.packets_sent += 1 + else: + NativeLog.add_trace_critical("unsupported behavior [%s]" % self.behavior) + self.exit() + return + + def __node_send_packet(self, dst_addr, group_addr=None): + send_data = "" + ret = False + if group_addr is not None: + len_t = hex(len(group_addr) * 6).split("0x") + if len(group_addr) <= 2: + option_list = "070" + len_t[1] + else: + option_list = "07" + len_t[1] + group = "" + for addr in group_addr: + group += _convert_to_mesh_mac_format(addr) + option_list += group + dst_addr = "01:00:5E:00:00:00" + send_data = "meshsend -S -d %s -o %s -l 100\r\n" % (dst_addr, option_list) + else: + if self.behavior == "broadcast": + dst_addr = "00:00:00:00:00:00" + send_data = "meshsend -S -d %s -l 100\r\n" % dst_addr + elif self.behavior == "unicast": + if self.unicast_addr == "random": + dst_addr = random.choice(self.device_mac_list) + else: + dst_addr = self.unicast_addr + send_data = "meshsend -S -d %s -l 100\r\n" % dst_addr + elif self.behavior == "p2p": + if self.unicast_addr == "random": + dst_addr = random.choice(self.device_mac_list) + else: + dst_addr = self.unicast_addr + send_data = "meshsend -S -d %s -t 1 -l 100\r\n" % dst_addr + try: + self.port.write(send_data) + except StandardError, e: + NativeLog.add_exception_log(e) + pass + for i in range(int(CHECK_TIMEOUT / CHECK_FREQ)): + time.sleep(CHECK_FREQ) + with self.cache_lock: + if self.recv_data_cache.find("+MESHSEND:OK") != -1: + ret = True + break + elif self.recv_data_cache.find("+MESHSEND:ERROR") != -1: + break + return ret + + + def __node_do_send(self): + if self.behavior == "broadcast": + if self.__node_send_packet("00:00:00:00:00:00", group_addr=None) is True: + self.packets_sent += self.node_num + elif self.behavior == "multicast": + random.shuffle(self.device_mac_list) + group_addr_list = self.device_mac_list[:MULTICAST_GROUP_LEN] + if self.__node_send_packet("01:00:5E:00:00:00", group_addr_list) is True: + self.packets_sent += MULTICAST_GROUP_LEN + elif self.behavior == "unicast": + if self.__node_send_packet(random.choice(self.device_mac_list), group_addr=None) is True: + self.packets_sent += 1 + elif self.behavior == "p2p": + if self.__node_send_packet(random.choice(self.device_mac_list), group_addr=None) is True: + self.packets_sent += 1 + else: + NativeLog.add_trace_critical("unsupported behavior [%s]" % self.behavior) + self.exit() + return + + def get_sent_packets(self): + return self.packets_sent + + def exit(self): + self.exit_event.set() + pass + + def run(self): + while self.exit_event.isSet() is False: + if self.typ == "SSC": + self.__node_do_send() + elif self.typ == "SERVER": + self.__server_do_send() + else: + NativeLog.add_trace_critical("type [%s] is neither SSC nor SERVER" % self.typ) + break + time.sleep(self.send_delay) + + pass + + +class EntityRecvThread(threading.Thread): + def __init__(self, port, typ, send_recv_time): + threading.Thread.__init__(self) + self.setDaemon(True) + self.recv_data_cache = "" + self.packets_recv = 0 + self.port = port + self.typ = typ + self.cache_lock = threading.Lock() + self.exit_event = threading.Event() + self.send_recv_time = send_recv_time + pass + + def data_recv_callback(self, data): + # if self.typ == "SERVER": + # NativeLog.add_prompt_trace("[data_recv_callback] server recv len %d" % len(data)) + with self.cache_lock: + self.recv_data_cache += data + pass + + def __server_do_recv(self): + while True: + if self.recv_data_cache: + data_cache = self.recv_data_cache + data_cache_hex = binascii.hexlify(data_cache) + packet_len = int(data_cache_hex[2:6], 16) + if len(self.recv_data_cache) >= packet_len: + time3 = time.time() + data_catch_t = self.recv_data_cache[:packet_len] + packet = binascii.hexlify(data_catch_t) + index3 = int(packet[-8:], 16) + self.send_recv_time.add_recv_time(index3, time3) + self.recv_data_cache = self.recv_data_cache[packet_len:] + else: + break + #self.packets_recv += 1 + else: + break + + def __node_do_recv(self): + with self.cache_lock: + while True: + if self.recv_data_cache: + match = re.search("\+MESHRECV:\d+", self.recv_data_cache) + index = re.search(",(\d+),OK", self.recv_data_cache) + res = re.compile(".+,\d+,OK", re.DOTALL) + res_t = res.search(self.recv_data_cache) + if match is not None: + time4 = time.time() + if index is not None: + index4 = int(index.group(1)) + self.send_recv_time.add_recv_time(index4, time4) + if len(res_t.group()) > 1: + process_index = len(res_t.group(0)) + self.recv_data_cache = self.recv_data_cache[process_index:] + else: + process_index = len(res_t.group()) + self.recv_data_cache = self.recv_data_cache[process_index:] + else: + break + else: + break + # self.packets_recv += 1 + else: + break + pass + + def get_recv_packets(self): + return self.packets_recv + + def exit(self): + self.exit_event.set() + pass + + def run(self): + while self.exit_event.isSet() is False: + if self.typ == "SSC": + self.__node_do_recv() + elif self.typ == "SERVER": + self.__server_do_recv() + else: + NativeLog.add_trace_critical("type [%s] is neither SSC nor SERVER" % self.typ) + break + time.sleep(CHECK_FREQ) + + pass + + +class MeshSendRecv(PerformanceTCBase.PerformanceTCBase): + def __init__(self, name, test_env, cmd_set, timeout, log_path): + PerformanceTCBase.PerformanceTCBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + self.send_config = [] + self.test_time = 0 + self.loss_rate_standard = 0.8 + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy" and cmd_set[i][0] != "": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + # load node send config + for i in range(1, len(cmd_set)): + for j in range(len(cmd_set[i][1])): + if cmd_set[i][1][j] != "": + cmd_string = "self.send_config.extend([" + cmd_set[i][1][j] + "])" + exec cmd_string + node_num = self.get_parameter("node_num") + self.recv_cb = dict.fromkeys(["SSC%s" % (x + 1) for x in range(int(node_num))] + ["GSOC1"]) + self.recv_cb_lock = threading.Lock() + pass + + def register_recv_callback(self, port_name, callback): + with self.recv_cb_lock: + if self.recv_cb[port_name] is None: + self.recv_cb[port_name] = [callback] + else: + self.recv_cb[port_name].append(callback) + pass + + def process(self): + try: + test_time = self.test_time * 60 + send_config = self.send_config + loss_rate_standard = self.loss_rate_standard + node_num = self.get_parameter("node_num") + pc_ip_list = self.get_parameter("pc_ip").split(".") + port = self.get_parameter("test_tcp_port1") + send_recv_time = SendRecvTime() + except StandardError: + return + #create server_addr + server_addr = "" + for i in range(len(pc_ip_list)): + if pc_ip_list[i] in ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]: + server_addr = server_addr + "0" + pc_ip_list[i] + else: + list_t = hex(int(pc_ip_list[i])).split("0x") + server_addr += list_t[1] + port_t = hex(port).split("0x") + port_t_list = list(port_t[1]) + server_addr = server_addr + port_t_list[2] + port_t_list[3] + port_t_list[0] + port_t_list[1] + server_port = self.test_env.get_port_by_name("GSOC1") + if server_port is None: + return + + # create thread dict + thread_dict = dict.fromkeys(["SSC%s" % (x + 1) for x in range(int(node_num))] + ["GSOC1"]) + for port_name in thread_dict: + thread_dict[port_name] = dict(zip(["tx", "rx"], [None, None])) + device_mac_list = [] + # init recv thread & register port for SSC + for port_name in ["SSC%s" % (x + 1) for x in range(int(node_num))]: + port = self.test_env.get_port_by_name(port_name) + thread_dict[port_name]["rx"] = EntityRecvThread(port, "SSC", send_recv_time) + self.register_recv_callback(port_name, thread_dict[port_name]["rx"].data_recv_callback) + device_mac_list.append(port.device_mac) + + thread_dict["GSOC1"]["rx"] = EntityRecvThread(server_port, "SERVER", send_recv_time) + self.register_recv_callback("GSOC1", thread_dict["GSOC1"]["rx"].data_recv_callback) + + # config[0]: target_name; config[1]: behavior; config[2]: destination; config[3]:send_delay; + for config in send_config: + port = self.test_env.get_port_by_name(config[0]) + name = port.name + if config[2] == "GSOC1": + dst = server_addr[:2] + ":" + server_addr[2:4] + ":" + server_addr[4:6] + ":" + server_addr[6:8] + \ + ":" + server_addr[8:10] + ":" + server_addr[10:12] + elif config[2] == "random": + dst = "random" + else: + dst = self.test_env.get_port_by_name(config[2]).device_mac + if name != "GSOC1": + server_addr = None + if config[1] == "broadcast" or config[1] == "multicast": + dst = None + typ = "SSC" if isinstance(port, MeshPort.MeshPort) is False else "SERVER" + thread_dict[name]["tx"] = EntitySendThread(port, config[1], dst, config[3], typ, device_mac_list, + server_addr, send_recv_time) + self.register_recv_callback(name, thread_dict[name]["tx"].data_recv_callback) + pass + + # start all thread + for port_name in thread_dict: + if thread_dict[port_name]["rx"] is not None: + thread_dict[port_name]["rx"].start() + if thread_dict[port_name]["tx"] is not None: + thread_dict[port_name]["tx"].start() + + # wait test time + time.sleep(test_time) + # close all send thread + for port_name in thread_dict: + if thread_dict[port_name]["tx"] is not None: + thread_dict[port_name]["tx"].exit() + thread_dict[port_name]["tx"].join() + # make sure all packet received before close recv thread + time.sleep(10) + # close all recv thread + for port_name in thread_dict: + if thread_dict[port_name]["rx"] is not None: + thread_dict[port_name]["rx"].exit() + thread_dict[port_name]["rx"].join() + + [max_delay_time, avg_delay_time, loss_rate] = send_recv_time.calculate() + + NativeLog.add_trace_critical("[Mesh Send Recv Test] MAX Delay Time is %.3f" % max_delay_time) + NativeLog.add_trace_critical("[Mesh Send Recv Test] Avg Delay Time is %.3f" % avg_delay_time) + NativeLog.add_trace_critical("[Mesh Send Recv Test] loss rate is %.2f%%" % (loss_rate * 100)) + + # set succeed if loss rate higher than required + if loss_rate < loss_rate_standard: + self.set_result("Succeed") + pass + + @Encoding.encode_utf8(3) + def result_check(self, port_name, data): + if port_name in self.recv_cb: + # if port_name == "GSOC1": + # NativeLog.add_prompt_trace("[result_check] recv GSOC1 data len %s" % len(data)) + with self.recv_cb_lock: + callback_list = self.recv_cb[port_name] + if callback_list is not None: + for callback in callback_list: + callback(data) + + # do logging + timestamp = NativeLog.generate_timestamp() + with self.sync_lock: + _formatted_data = HTMLGenerator.process_one_log_item(data, self.log_index, port_name, timestamp) + self.log_index += 1 + + self.append_to_log_file(_formatted_data) + + NativeLog.add_all_tc_log(data, port_name, timestamp) + pass + + +def main(): + pass + + +if __name__ == '__main__': + main() diff --git a/components/test/TestCaseScript/MeshStress/__init__.py b/components/test/TestCaseScript/MeshStress/__init__.py new file mode 100755 index 0000000000..6e94287c45 --- /dev/null +++ b/components/test/TestCaseScript/MeshStress/__init__.py @@ -0,0 +1 @@ +__all__ = ["StableCase1"] \ No newline at end of file diff --git a/components/test/TestCaseScript/SSLTest/Capability.py b/components/test/TestCaseScript/SSLTest/Capability.py new file mode 100755 index 0000000000..efdb6eeb9d --- /dev/null +++ b/components/test/TestCaseScript/SSLTest/Capability.py @@ -0,0 +1,90 @@ + + +class SSLCapability(object): + CAPABILITY_TYPE = ["version", "cipher_suite", "fragment_size", # for hello capability negotiation + "verify_server", "verify_client", # if support verify server/client + "key_algorithm", "key_encoding", "pem_encryption", # what kind of private it supports + "certificate_encoding", "certificate_digest", # what kind of certificate it supports + ] + SSL_TYPE = ("TargetClient", "TargetServer", "PCClient", "PCServer") + + def __init__(self, typ, **kwargs): + assert typ in self.SSL_TYPE + self.type = typ + self.capability = dict.fromkeys(self.CAPABILITY_TYPE, None) + for kw in kwargs: + self.capability[kw] = kwargs[kw] + for kw in self.capability: + assert self.capability[kw] is not None + pass + + def get(self, kw): + return self.capability[kw] + + def set(self, **kwargs): + for kw in kwargs: + self.capability[kw] = kwargs[kw] + pass + + +class TargetSSLCapability(SSLCapability): + DEFAULT_CAPABILITY = { + "version": ["SSLv23_2"], + "cipher_suite": ["TLS_RSA_WITH_AES_128_CBC_SHA", + "TLS_RSA_WITH_AES_256_CBC_SHA", + "TLS_RSA_WITH_RC4_128_SHA", + "TLS_RSA_WITH_RC4_128_MD5"], + "fragment_size": [2048, 4096, 8192], + "verify_server": True, + "verify_client": False, + "key_algorithm": ["RSA512", "RSA1024", "RSA2048", "RSA4096"], + "key_encoding": ["PEM", "DER"], + "pem_encryption": [None, "aes128", "aes256"], + "certificate_encoding": ["PEM", "DER"], + "certificate_digest": ["md5", "sha1", "sha256", "sha384", "sha512"], + } + + def __init__(self, typ, **kwargs): + assert typ == "TargetClient" or typ == "TargetServer" + capability = dict(self.DEFAULT_CAPABILITY) + for kw in kwargs: + capability[kw] = kwargs[kw] + SSLCapability.__init__(self, typ, **capability) + pass + pass + + +class PCSSLCapability(SSLCapability): + DEFAULT_CAPABILITY = { + "version": ["SSLv23", "SSLv20", "SSLv30", "TLSv10", "TLSv11", "TLSv12"], + "cipher_suite": ["TLS_RSA_WITH_AES_128_CBC_SHA", + "TLS_RSA_WITH_AES_256_CBC_SHA", + "TLS_RSA_WITH_RC4_128_SHA", + "TLS_RSA_WITH_RC4_128_MD5", + "TLS_DH_DSS_WITH_AES_128_CBC_SHA", + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"], + "fragment_size": [16384], + "verify_server": True, + "verify_client": True, + "key_algorithm": ["RSA512", "RSA1024", "RSA2048", "RSA4096"], + "key_encoding": ["PEM"], + "pem_encryption": [None], + "certificate_encoding": ["PEM"], + "certificate_digest": ["md5", "sha1", "sha256", "sha384", "sha512"], + } + + def __init__(self, typ): + assert typ == "PCClient" or typ == "PCServer" + SSLCapability.__init__(self, typ, **self.DEFAULT_CAPABILITY) + pass + pass + + +def main(): + pc = PCSSLCapability("PCClient") + target = TargetSSLCapability("TargetClient") + pass + + +if __name__ == '__main__': + main() diff --git a/components/test/TestCaseScript/SSLTest/ConfigUtility.py b/components/test/TestCaseScript/SSLTest/ConfigUtility.py new file mode 100755 index 0000000000..f36fe44fe9 --- /dev/null +++ b/components/test/TestCaseScript/SSLTest/ConfigUtility.py @@ -0,0 +1,333 @@ +from PKI import PKIDict, PKIItem +import Parameter + + +def multiply_2_lists(list1, list2): + def make_list(li): + if not isinstance(li, list): + li = [li] + return li + list1 = make_list(list1) + list2 = make_list(list2) + ret = [] + for a in list1: + for b in list2: + ret.append(make_list(a) + make_list(b)) + return ret + + +def list_multiply(list1, *args): + ret = list1 + for arg in args: + ret = multiply_2_lists(ret, arg) + return ret + + +def list_and(list1, list2): + ret = [] + for item in list1: + if item in list2: + ret.append(item) + return ret + + +class ComputeResult(object): + NEGOTIATION_CONFIG = ["client_version", "client_cipher_suite", "client_fragment_size", + "server_version", "server_cipher_suite", "server_fragment_size"] + CERT_KEY_CONFIG = ["verify_server", "verify_client", + "client_trust_anchor", "client_certificate", "client_key", + "server_trust_anchor", "server_certificate", "server_key"] + + TYPE_CONTEXT = "context" + TYPE_NEGOTIATION = "negotiation" + TYPE_CERT_KEY = "cert_key" + TYPE_SEND_PARAM = "send_param" + + # results + SUCCEED = 0 + CREATE_CONTEXT_FAIL = 1 + HANDSHAKE_FAIL = 2 + CERT_KEY_FAIL = 3 + + def __init__(self, client_capability, server_capability): + self.client_capability = client_capability + self.server_capability = server_capability + pass + + @staticmethod + def __check_cert(cert, capability, check_encoding=True): + ret = True + if cert.name is not None: + if check_encoding is True: + if cert.digest not in capability.get("certificate_digest") \ + or cert.key_algorithm not in capability.get("key_algorithm") \ + or cert.file_encoding not in capability.get("certificate_encoding"): + ret = False + else: + if cert.digest not in capability.get("certificate_digest") \ + or cert.key_algorithm not in capability.get("key_algorithm"): + ret = False + return ret + + @staticmethod + def __check_key(key, capability, check_encoding=True): + ret = True + if key.name is not None: + if check_encoding is True: + if key.algorithm not in capability.get("key_algorithm") \ + or key.file_encoding not in capability.get("key_encoding") \ + or key.file_encryption not in capability.get("pem_encryption"): + ret = False + else: + if key.algorithm not in capability.get("key_algorithm") \ + or key.file_encryption not in capability.get("pem_encryption"): + ret = False + return ret + + # compute result functions + def check_context(self, config): + result = self.SUCCEED + check_list = [(self.__check_cert, PKIItem.Certificate(config["client_trust_anchor"]), + self.client_capability), + (self.__check_cert, PKIItem.Certificate(config["client_certificate"]), + self.client_capability), + (self.__check_key, PKIItem.PrivateKey(config["client_key"]), + self.client_capability), + (self.__check_cert, PKIItem.Certificate(config["server_trust_anchor"]), + self.server_capability), + (self.__check_cert, PKIItem.Certificate(config["server_certificate"]), + self.server_capability), + (self.__check_key, PKIItem.PrivateKey(config["server_key"]), + self.server_capability)] + for _check in check_list: + if _check[0](_check[1], _check[2]) is False: + result = self.CREATE_CONTEXT_FAIL + break + return result + + def check_negotiation_param(self, config): + result = self.SUCCEED + # first check version + while True: + if Parameter.VERSION[config["client_version"]]\ + & Parameter.VERSION[config["server_version"]] == 0: + result = self.HANDSHAKE_FAIL + break + # check cipher suite + supported_cipher_suite = list_and(self.client_capability.get("cipher_suite"), + self.server_capability.get("cipher_suite")) + if config["client_cipher_suite"] not in supported_cipher_suite\ + or config["server_cipher_suite"] not in supported_cipher_suite\ + or config["client_cipher_suite"] != config["server_cipher_suite"]: + result = self.HANDSHAKE_FAIL + break + break + return result + + # check cert key, if it can be supported by both client and server, if it matches + def __check_cert_key_content(self, cert, key): + if self.__check_cert(cert, self.client_capability, check_encoding=False) is True\ + and self.__check_cert(cert, self.server_capability, check_encoding=False) is True \ + and self.__check_key(key, self.client_capability, check_encoding=False) is True \ + and self.__check_key(key, self.server_capability, check_encoding=False) is True \ + and key.name.find(cert.private_key) != -1: + result = True + else: + result = False + return result + + def __verify_ca(self, ca, cert, capability): + result = True + while True: + # if ca supported + if self.__check_cert(ca, capability) is False: + result = False + break + # check if ca in cert chain + try: + index = cert.cert_chain.index(ca.name) + except StandardError: + result = False + break + + # for pem cert, it contains cert chain to issuer, any cert in chain works + # der cert do not contain cert chain + # only der root cert verify L1 cert and root cert works + if cert.file_encoding == "DER": + if len(cert.cert_chain) > 2 and index != len(cert.cert_chain) - 1: + result = False + break + # check if all certs in before trust anchor supported + for cert_name in cert.cert_chain[1:index]: + _cert = PKIItem.Certificate(cert_name + ".pem") + if self.__check_cert(_cert, capability) is False: + result = False + break + break + return result + + def __check_verify_client(self, client_cert, client_key, server_ca): + result = self.__check_cert_key_content(client_cert, client_key) + if result is True: + result = self.__verify_ca(server_ca, client_cert, self.server_capability) + return result + + def __check_verify_server(self, client_ca, server_cert): + return self.__verify_ca(client_ca, server_cert, self.client_capability) + + def check_cert_key(self, config): + result = self.SUCCEED + while True: # break if when anything failed + if (config["verify_server"] is True and self.client_capability.get("verify_server") is False) \ + or (config["verify_client"] is True and + (self.server_capability.get("verify_client") is False or + self.client_capability.get("verify_client") is False)): + result = self.CERT_KEY_FAIL + break + + server_cert = PKIItem.Certificate(config["server_certificate"]) + server_key = PKIItem.PrivateKey(config["server_key"]) + server_ca = PKIItem.Certificate(config["server_trust_anchor"]) + client_cert = PKIItem.Certificate(config["client_certificate"]) + client_key = PKIItem.PrivateKey(config["client_key"]) + client_ca = PKIItem.Certificate(config["client_trust_anchor"]) + # always check server cert key + if self.__check_cert_key_content(server_cert, server_key) is False: + result = self.CERT_KEY_FAIL + break + # if require to verify server + if config["verify_server"] is True: + if self.__check_verify_server(client_ca, server_cert) is False: + result = self.CERT_KEY_FAIL + break + # if require to verify client + if config["verify_client"] is True: + if self.__check_verify_client(client_cert, client_key, server_ca) is False: + result = self.CERT_KEY_FAIL + break + break + return result + + CHECK_FUNC = { + TYPE_CONTEXT: check_context, + TYPE_NEGOTIATION: check_negotiation_param, + TYPE_CERT_KEY: check_cert_key, + } + CONFIG_KEY = { + TYPE_CONTEXT: CERT_KEY_CONFIG, + TYPE_NEGOTIATION: NEGOTIATION_CONFIG, + TYPE_CERT_KEY: CERT_KEY_CONFIG, + } + + def compute_result(self, typ, config_list): + succeed_list = [] + fail_list = [] + for config in config_list: + if self.CHECK_FUNC[typ](self, dict(zip(self.CONFIG_KEY[typ], config))) != self.SUCCEED: + fail_list.append(config) + else: + succeed_list.append(config) + return succeed_list, fail_list + pass + + +class GenerateTestConfig(ComputeResult): + TEST_CONFIG = ComputeResult.NEGOTIATION_CONFIG + \ + ComputeResult.CERT_KEY_CONFIG + + def __init__(self, client_capability, server_capability): + ComputeResult.__init__(self, client_capability, server_capability) + self.key_dict = PKIDict.PKIDict.KEY_DICT + self.cert_dict = PKIDict.PKIDict.CERT_DICT + pass + + def generate_negotiation_config(self): + _config = list_multiply(self.client_capability.get("version"), + self.client_capability.get("cipher_suite"), + self.client_capability.get("fragment_size"), + self.server_capability.get("version"), + self.server_capability.get("cipher_suite"), + self.server_capability.get("fragment_size")) + return self.compute_result(self.TYPE_NEGOTIATION, _config) + + def __choose_cert_key(self, verify_server, verify_client, + client_ca_opt, client_cert_key_opt, + server_ca_opt, server_cert_key_opt): + pass + + # CERT_KEY_CONFIG = ["verify_server", "verify_client", + # "client_trust_anchor", "client_certificate", "client_key", + # "server_trust_anchor", "server_certificate", "server_key"] + def generate_cert_key_config(self): + # first handle not verify certificate case + _config_list = [] + for cert in PKIDict.PKIDict.CERT_DICT: + for key in PKIDict.PKIDict.KEY_DICT: + _config_list.append([False, False, None, None, None, None, cert, key]) + cert_key_succeed, context_fail = self.compute_result(self.TYPE_CONTEXT, _config_list) + cert_key_succeed, cert_key_fail = self.compute_result(self.TYPE_CERT_KEY, cert_key_succeed) + key_cert_pair = [[x[6], x[7]] for x in cert_key_succeed] + # for succeed config, do server cert verify + _config_list = [] + for _config in cert_key_succeed: + for cert in PKIDict.PKIDict.CERT_DICT: + _config_list.append([True, False, cert, None, None, + None, _config[6], _config[7]]) + _cert_key_succeed, _context_fail = self.compute_result(self.TYPE_CONTEXT, _config_list) + context_fail += _context_fail + _cert_key_succeed, _cert_key_fail = self.compute_result(self.TYPE_CERT_KEY, _cert_key_succeed) + cert_key_fail += _cert_key_fail + cert_key_succeed += _cert_key_succeed + # for succeed config, do client verify + _config_list = [] + for _config in _cert_key_succeed: + for key_cert in key_cert_pair: + _config_list.append([True, True, _config[2], key_cert[0], key_cert[1], + key_cert[0], _config[6], _config[7]]) + _cert_key_succeed, _context_fail = self.compute_result(self.TYPE_CONTEXT, _config_list) + context_fail += _context_fail + _cert_key_succeed, _cert_key_fail = self.compute_result(self.TYPE_CERT_KEY, _cert_key_succeed) + cert_key_fail += _cert_key_fail + cert_key_succeed += _cert_key_succeed + # only verify client not verify server + _config_list = [] + for _config in _cert_key_succeed: + _config_list.append([False, True, None, + _config[3], _config[4], _config[5], _config[6], _config[7]]) + _cert_key_succeed, _context_fail = self.compute_result(self.TYPE_CONTEXT, _config_list) + context_fail += _context_fail + _cert_key_succeed, _cert_key_fail = self.compute_result(self.TYPE_CERT_KEY, _cert_key_succeed) + cert_key_fail += _cert_key_fail + cert_key_succeed += _cert_key_succeed + return cert_key_succeed, context_fail, cert_key_fail + + +class ConfigUtility(GenerateTestConfig): + # test config + _TEST_CONFIG_DICT_KEY = ("config", "result") + + def __init__(self, client_capability, server_capability): + GenerateTestConfig.__init__(self, client_capability, server_capability) + pass + + def get_all_test_config(self): + negotiation_succeed, negotiation_fail = self.generate_negotiation_config() + cert_key_succeed, context_fail, cert_key_fail = self.generate_cert_key_config() + succeed_config = list_multiply(negotiation_succeed, cert_key_succeed) + context_fail_config = list_multiply([negotiation_succeed[0]], context_fail) + negotiation_fail_config = list_multiply(negotiation_fail, [cert_key_succeed[0]]) + cert_key_fail_config = list_multiply([negotiation_succeed[0]], cert_key_fail) + return dict(zip(["succeed", "context_fail", "negotiation_fail", "cert_key_fail"], + [[dict(zip(self.TEST_CONFIG, x)) for x in succeed_config], + [dict(zip(self.TEST_CONFIG, x)) for x in context_fail_config], + [dict(zip(self.TEST_CONFIG, x)) for x in negotiation_fail_config], + [dict(zip(self.TEST_CONFIG, x)) for x in cert_key_fail_config]])) + pass + + +def main(): + pass + + +if __name__ == '__main__': + main() diff --git a/components/test/TestCaseScript/SSLTest/Parameter.py b/components/test/TestCaseScript/SSLTest/Parameter.py new file mode 100755 index 0000000000..1670c5fd29 --- /dev/null +++ b/components/test/TestCaseScript/SSLTest/Parameter.py @@ -0,0 +1,56 @@ + + +VERSION = { + "SSLv23": 0x1F, + "SSLv23_2": 0x1C, # current target ssl implementation do not support SSLv20 and TLSv12 + "SSLv20": 0x01, + "SSLv30": 0x02, + "TLSv10": 0x04, + "TLSv11": 0x08, + "TLSv12": 0x10, +} + + +CIPHER_SUITE = { + # supported algorithm + "TLS_RSA_WITH_AES_128_CBC_SHA": "AES128-SHA", + "TLS_RSA_WITH_AES_256_CBC_SHA": "AES256-SHA", + "TLS_RSA_WITH_RC4_128_SHA": "RC4-SHA", + "TLS_RSA_WITH_RC4_128_MD5": "RC4-MD5", + "TLS_DH_DSS_WITH_AES_128_CBC_SHA": "DH-DSS-AES128-SHA", + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256": "ECDHE-RSA-AES128-GCM-SHA256", +} + + +FRAGMENT_SIZE = { + "SIZE_DEFAULT": 0, + "SIZE_512": 512, + "SIZE_1024": 1024, + "SIZE_2048": 2048, + "SIZE_4096": 4096, + "SIZE_8192": 8192, +} + + +VERIFY_OPTION = { + "NOT_VERIFY": "NOT_VERIFY", + "VERIFY": "VERIFY", +} + + +SEND_OPTION = { + "MAX_SEND_SIZE_512": 512, + "MAX_SEND_SIZE_1K": 1024, + "MAX_SEND_SIZE_2K": 2048, + "MAX_SEND_SIZE_4K": 4096, + "MAX_SEND_SIZE_8K": 8192, + "MAX_SEND_SIZE_16K": 16384, +} + + +def main(): + pass + + +if __name__ == '__main__': + main() diff --git a/components/test/TestCaseScript/SSLTest/SSLHandler.py b/components/test/TestCaseScript/SSLTest/SSLHandler.py new file mode 100644 index 0000000000..7fe19b3cef --- /dev/null +++ b/components/test/TestCaseScript/SSLTest/SSLHandler.py @@ -0,0 +1,498 @@ +import socket +import ssl +import os +import re +import time +import threading + +import Parameter +from PKI import PKIDict +from PKI import PKIItem +from NativeLog import NativeLog + + +class SerialPortCheckFail(StandardError): + pass + + +class SSLHandlerFail(StandardError): + pass + + +class PCFail(StandardError): + pass + + +class TargetFail(StandardError): + pass + + +def ssl_handler_wrapper(handler_type): + if handler_type == "PC": + exception_type = PCFail + elif handler_type == "Target": + exception_type = TargetFail + else: + exception_type = None + + def _handle_func(func): + def _handle_args(*args, **kwargs): + try: + ret = func(*args, **kwargs) + except StandardError, e: + NativeLog.add_exception_log(e) + raise exception_type(str(e)) + return ret + return _handle_args + return _handle_func + + +class SerialPort(object): + def __init__(self, tc_action, port_name): + self.tc_action = tc_action + self.port_name = port_name + + def flush(self): + self.tc_action.flush_data(self.port_name) + + def write_line(self, data): + self.tc_action.serial_write_line(self.port_name, data) + + def check(self, condition, timeout=10): + if self.tc_action.check_response(self.port_name, condition, timeout) is False: + raise SerialPortCheckFail("serial port check fail, condition is %s" % condition) + + def read_data(self): + return self.tc_action.serial_read_data(self.port_name) + pass + + +class SSLHandler(object): + # ssl operation timeout is 30 seconds + TIMEOUT = 30 + + def __init__(self, typ, config, serial_port): + self.type = typ + self.config = config + self.timeout = self.TIMEOUT + self.serial_port = serial_port + self.accept_thread = None + self.data_validation = False + + def set_timeout(self, timeout): + self.timeout = timeout + + def init_context(self): + pass + + def connect(self, remote_ip, remote_port, local_ip=0, local_port=0): + pass + + def listen(self, local_port=0, local_ip=0): + pass + + def send(self, size, data): + pass + + def recv(self, length, timeout): + pass + + def set_data_validation(self, validation): + pass + + def close(self): + if self.accept_thread is not None: + self.accept_thread.exit() + self.accept_thread.join(5) + pass + + +class TargetSSLHandler(SSLHandler): + def __init__(self, typ, config, serial_port): + SSLHandler.__init__(self, typ, config, serial_port) + self.ssl_id = None + self.server_id = None + + @ssl_handler_wrapper("Target") + def init_context(self): + self.serial_port.flush() + self.serial_port.write_line("soc -T") + self.serial_port.check("+CLOSEALL") + + if self.type == "client": + version = Parameter.VERSION[self.config["client_version"]] + fragment = self.config["client_fragment_size"] + ca = self.config["client_trust_anchor"] + cert = self.config["client_certificate"] + key = self.config["client_key"] + verify_required = 0x01 if self.config["verify_server"] is True else 0x00 + context_type = 1 + else: + version = Parameter.VERSION[self.config["server_version"]] + fragment = self.config["server_fragment_size"] + ca = self.config["server_trust_anchor"] + cert = self.config["server_certificate"] + key = self.config["server_key"] + verify_required = 0x02 if self.config["verify_client"] is True else 0x00 + context_type = 2 + ssc_cmd = "ssl -I -t %u -r %u -v %u -o %u" % (context_type, fragment, version, verify_required) + + if ca is not None: + _index = PKIDict.PKIDict.CERT_DICT[ca] + ssc_cmd += " -a %d" % _index + if cert is not None: + _index = PKIDict.PKIDict.CERT_DICT[cert] + ssc_cmd += " -c %d" % _index + if key is not None: + _index = PKIDict.PKIDict.KEY_DICT[key] + ssc_cmd += " -k %d" % _index + # write command and check result + self.serial_port.flush() + self.serial_port.write_line(ssc_cmd) + self.serial_port.check(["+SSL:OK", "AND", "!+SSL:ERROR"]) + + @ssl_handler_wrapper("Target") + def connect(self, remote_ip, remote_port, local_ip=0, local_port=0): + self.serial_port.flush() + self.serial_port.write_line("soc -B -t SSL -i %s -p %s" % (local_ip, local_port)) + self.serial_port.check(["OK", "AND", "!ERROR"]) + self.serial_port.flush() + self.serial_port.write_line("soc -C -s 0 -i %s -p %s" % (remote_ip, remote_port)) + self.serial_port.check(["OK", "AND", "!ERROR"], timeout=30) + self.ssl_id = 0 + pass + + def accept_succeed(self): + self.ssl_id = 1 + + class Accept(threading.Thread): + def __init__(self, serial_port, succeed_cb): + threading.Thread.__init__(self) + self.setDaemon(True) + self.serial_port = serial_port + self.succeed_cb = succeed_cb + self.exit_flag = threading.Event() + + def run(self): + while self.exit_flag.isSet() is False: + try: + self.serial_port.check("+ACCEPT:", timeout=1) + self.succeed_cb() + break + except StandardError: + pass + + def exit(self): + self.exit_flag.set() + + @ssl_handler_wrapper("Target") + def listen(self, local_port=0, local_ip=0): + self.serial_port.flush() + self.serial_port.write_line("soc -B -t SSL -i %s -p %s" % (local_ip, local_port)) + self.serial_port.check(["OK", "AND", "!ERROR"]) + self.serial_port.flush() + self.serial_port.write_line("soc -L -s 0") + self.serial_port.check(["OK", "AND", "!ERROR"]) + self.server_id = 0 + self.accept_thread = self.Accept(self.serial_port, self.accept_succeed) + self.accept_thread.start() + pass + + @ssl_handler_wrapper("Target") + def send(self, size=10, data=None): + if data is not None: + size = len(data) + self.serial_port.flush() + self.serial_port.write_line("soc -S -s %s -l %s" % (self.ssl_id, size)) + self.serial_port.check(["OK", "AND", "!ERROR"]) + pass + + @ssl_handler_wrapper("Target") + def recv(self, length, timeout=SSLHandler.TIMEOUT): + pattern = re.compile("\+RECV:\d+,(\d+)\r\n") + data_len = 0 + data = "" + time1 = time.time() + while time.time() - time1 < timeout: + data += self.serial_port.read_data() + if self.data_validation is True: + if "+DATA_ERROR" in data: + raise SSLHandlerFail("target data validation fail") + while True: + match = pattern.search(data) + if match is None: + break + else: + data_len += int(match.group(1)) + data = data[data.find(match.group())+len(match.group()):] + if data_len >= length: + result = True + break + else: + result = False + if result is False: + raise SSLHandlerFail("Target recv fail") + + def set_data_validation(self, validation): + self.data_validation = validation + self.serial_port.flush() + self.serial_port.write_line("soc -V -s %s -o %s" % (self.ssl_id, 1 if validation is True else 0)) + self.serial_port.check(["OK", "AND", "!ERROR"]) + + @ssl_handler_wrapper("Target") + def close(self): + SSLHandler.close(self) + self.serial_port.flush() + self.serial_port.write_line("ssl -D") + self.serial_port.check(["+SSL:OK", "OR", "+SSL:ERROR"]) + self.serial_port.write_line("soc -T") + self.serial_port.check("+CLOSEALL") + pass + + pass + + +def calc_hash(index): + return (index & 0xffffffff) % 83 + (index & 0xffffffff) % 167 + + +def verify_data(data, start_index): + for i, c in enumerate(data): + if ord(c) != calc_hash(start_index + i): + NativeLog.add_trace_critical("[Data Validation Error] target sent data index %u is error." + " Sent data is %x, should be %x" + % (start_index + i, ord(c), calc_hash(start_index + i))) + return False + return True + + +def make_validation_data(length, start_index): + return bytes().join([chr(calc_hash(start_index + i)) for i in range(length)]) + + +class PCSSLHandler(SSLHandler): + PROTOCOL_MAPPING = { + "SSLv23": ssl.PROTOCOL_SSLv23, + "SSLv23_2": ssl.PROTOCOL_SSLv23, + "SSLv20": ssl.PROTOCOL_SSLv2, + "SSLv30": ssl.PROTOCOL_SSLv3, + "TLSv10": ssl.PROTOCOL_TLSv1, + "TLSv11": ssl.PROTOCOL_TLSv1_1, + "TLSv12": ssl.PROTOCOL_TLSv1_2, + } + CERT_FOLDER = os.path.join(".", "PKI", PKIDict.PKIDict.CERT_FOLDER) + KEY_FOLDER = os.path.join(".", "PKI", PKIDict.PKIDict.KEY_FOLDER) + + def __init__(self, typ, config, serial_port): + SSLHandler.__init__(self, typ, config, serial_port) + self.ssl_context = None + self.ssl = None + self.server_sock = None + self.send_index = 0 + self.recv_index = 0 + + class InitContextThread(threading.Thread): + def __init__(self, handler, version, cipher_suite, ca, cert, key, verify_required, remote_cert): + threading.Thread.__init__(self) + self.setDaemon(True) + self.handler = handler + self.version = version + self.cipher_suite = cipher_suite + self.ca = ca + self.cert = cert + self.key = key + self.verify_required = verify_required + self.remote_cert = remote_cert + pass + + @staticmethod + def handle_cert(cert_file, ca_file): + cert = PKIItem.Certificate() + cert.parse_file(cert_file) + ca = PKIItem.Certificate() + ca.parse_file(ca_file) + if cert.file_encoding == "PEM" and ca.name in cert.cert_chain: + cert_chain_t = cert.cert_chain[1:cert.cert_chain.index(ca.name)] + ret = ["%s.pem" % c for c in cert_chain_t] + else: + ret = [] + return ret + + def run(self): + try: + ssl_context = ssl.SSLContext(self.version) + # cipher suite + ssl_context.set_ciphers(self.cipher_suite) + if self.ca is not None: + ssl_context.load_verify_locations(cafile=os.path.join(self.handler.CERT_FOLDER, self.ca)) + # python ssl can't verify cert chain, don't know why + # need to load cert between cert and ca for pem (pem cert contains cert chain) + if self.remote_cert is not None: + cert_chain = self.handle_cert(self.remote_cert, self.ca) + for c in cert_chain: + NativeLog.add_trace_info("load ca chain %s" % c) + ssl_context.load_verify_locations(cafile=os.path.join(self.handler.CERT_FOLDER, c)) + if self.cert is not None: + cert = os.path.join(self.handler.CERT_FOLDER, self.cert) + key = os.path.join(self.handler.KEY_FOLDER, self.key) + ssl_context.load_cert_chain(cert, keyfile=key) + if self.verify_required is True: + ssl_context.verify_mode = ssl.CERT_REQUIRED + else: + ssl_context.verify_mode = ssl.CERT_NONE + self.handler.ssl_context = ssl_context + except StandardError, e: + NativeLog.add_exception_log(e) + pass + pass + + @ssl_handler_wrapper("PC") + def init_context(self): + if self.type == "client": + version = self.PROTOCOL_MAPPING[self.config["client_version"]] + cipher_suite = Parameter.CIPHER_SUITE[self.config["client_cipher_suite"]] + ca = self.config["client_trust_anchor"] + cert = self.config["client_certificate"] + key = self.config["client_key"] + verify_required = self.config["verify_server"] + remote_cert = self.config["server_certificate"] + else: + version = self.PROTOCOL_MAPPING[self.config["server_version"]] + cipher_suite = Parameter.CIPHER_SUITE[self.config["server_cipher_suite"]] + ca = self.config["server_trust_anchor"] + cert = self.config["server_certificate"] + key = self.config["server_key"] + verify_required = self.config["verify_client"] + remote_cert = self.config["client_certificate"] + + _init_context = self.InitContextThread(self, version, cipher_suite, ca, cert, key, verify_required, remote_cert) + _init_context.start() + _init_context.join(5) + if self.ssl_context is None: + raise StandardError("Init Context Fail") + + pass + + @ssl_handler_wrapper("PC") + def connect(self, remote_ip, remote_port, local_ip=0, local_port=0): + sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) + # reuse socket in TIME_WAIT state + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + sock.settimeout(self.timeout) + sock.bind((local_ip, local_port)) + self.ssl = self.ssl_context.wrap_socket(sock) + self.ssl.connect((remote_ip, remote_port)) + pass + + def accept_succeed(self, ssl_new): + ssl_new.settimeout(self.timeout) + self.ssl = ssl_new + + class Accept(threading.Thread): + def __init__(self, server_sock, ssl_context, succeed_cb): + threading.Thread.__init__(self) + self.setDaemon(True) + self.server_sock = server_sock + self.ssl_context = ssl_context + self.succeed_cb = succeed_cb + self.exit_flag = threading.Event() + + def run(self): + while self.exit_flag.isSet() is False: + try: + new_socket, addr = self.server_sock.accept() + ssl_new = self.ssl_context.wrap_socket(new_socket, server_side=True) + self.succeed_cb(ssl_new) + break + except StandardError: + pass + pass + + def exit(self): + self.exit_flag.set() + + @ssl_handler_wrapper("PC") + def listen(self, local_port=0, local_ip=0): + self.server_sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) + # reuse socket in TIME_WAIT state + self.server_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + self.server_sock.settimeout(1) + self.server_sock.bind((local_ip, local_port)) + self.server_sock.listen(5) + self.accept_thread = self.Accept(self.server_sock, self.ssl_context, self.accept_succeed) + self.accept_thread.start() + pass + + @ssl_handler_wrapper("PC") + def send(self, size=10, data=None): + if data is None: + self.ssl.send(make_validation_data(size, self.send_index)) + if self.data_validation is True: + self.send_index += size + else: + self.ssl.send(data) + + @ssl_handler_wrapper("PC") + def recv(self, length, timeout=SSLHandler.TIMEOUT, data_validation=False): + time1 = time.time() + data_len = 0 + while time.time() - time1 < timeout: + data = self.ssl.read() + + if data_validation is True and len(data) > 0: + if verify_data(data, self.recv_index) is False: + raise SSLHandlerFail("PC data validation fail, index is %s" % self.recv_index) + self.recv_index += len(data) + data_len += len(data) + if data_len >= length: + result = True + break + else: + result = False + if result is False: + raise SSLHandlerFail("PC recv fail") + + def set_data_validation(self, validation): + self.data_validation = validation + + @ssl_handler_wrapper("PC") + def close(self): + SSLHandler.close(self) + if self.ssl is not None: + self.ssl.close() + self.ssl = None + if self.server_sock is not None: + self.server_sock.close() + self.server_sock = None + del self.ssl_context + + +def main(): + ssl_context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + # cipher suite + ssl_context.set_ciphers("AES256-SHA") + ssl_context.load_cert_chain("D:\workspace\\auto_test_script\PKI\Certificate\\" + "L2CertRSA512sha1_L1CertRSA512sha1_RootCertRSA512sha1.pem", + keyfile="D:\workspace\\auto_test_script\PKI\Key\PrivateKey2RSA512.pem") + ssl_context.verify_mode = ssl.CERT_NONE + server_sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) + # reuse socket in TIME_WAIT state + server_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + server_sock.settimeout(100) + server_sock.bind(("192.168.111.5", 443)) + server_sock.listen(5) + while True: + try: + new_socket, addr = server_sock.accept() + ssl_new = ssl_context.wrap_socket(new_socket, server_side=True) + print "server connected" + break + except StandardError: + pass + + +pass + + +if __name__ == '__main__': + main() diff --git a/components/test/TestCaseScript/SSLTest/SSLHandshake.py b/components/test/TestCaseScript/SSLTest/SSLHandshake.py new file mode 100755 index 0000000000..5eb68c3503 --- /dev/null +++ b/components/test/TestCaseScript/SSLTest/SSLHandshake.py @@ -0,0 +1,240 @@ +import os +import random +import time +import re + +from TCAction import TCActionBase +from TCAction import PerformanceTCBase +from NativeLog import NativeLog, HTMLGenerator +from Utility import MakeFolder + +import ConfigUtility +import Capability +import SSLHandler + +LOG_FOLDER = os.path.join("AT_LOG", "TEMP") + +HEAP_SIZE_LIMIT = 30000 + + +class SSLHandshake(PerformanceTCBase.PerformanceTCBase): + + def __init__(self, name, test_env, cmd_set, timeout=15, log_path=TCActionBase.LOG_PATH): + PerformanceTCBase.PerformanceTCBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + self.client_type = None + self.server_type = None + self.client_capability = dict() + self.server_capability = dict() + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + timestamp = time.strftime("%d%H%M%S", time.localtime()) + folder = MakeFolder.make_folder(os.path.join(LOG_FOLDER, "SSLHandshake_%s" % timestamp)) + self.tested_log = os.path.join(folder, "SSLHandshakeTested.log") + self.failed_log = os.path.join(folder, "SSLHandshakeFailed.log") + self.memory_track_log = os.path.join(folder, "SSLHandshakeMemTrack.log") + self.succeed_log = os.path.join(folder, "SSLHandshakeSucceed.log") + # store test result for failed config + self.failed_log2 = os.path.join(folder, "SSLHandshakeFailed2.log") + self.succeed_log2 = os.path.join(folder, "SSLHandshakeSucceed2.log") + + self.heap_size_pattern = re.compile("\+FREEHEAP:(\d+)\r\n") + + @staticmethod + def close(client, server): + try: + client.close() + except StandardError: + pass + try: + server.close() + except StandardError: + pass + + def query_heap_size(self, scenario="idle"): + self.flush_data("SSC1") + self.serial_write_line("SSC1", "ram -H") + match = self.check_regular_expression("SSC1", self.heap_size_pattern) + if match is None: + NativeLog.add_trace_critical("No response for SSC ram command") + else: + heap_size = int(match.group(1)) + self.log_memory("[heap size][%s] %s" % (scenario, heap_size)) + if heap_size < HEAP_SIZE_LIMIT and scenario == "idle": + NativeLog.add_trace_critical("[HeapSize] %s" % heap_size) + + pass + + def prepare_handshake_test(self): + # check if connected + self.flush_data("SSC1") + self.serial_write_line("SSC1", "sta -Q") + if self.check_response("SSC1", "+JAP:CONNECTED,") is False: + ap_ssid = self.get_parameter("ap_ssid") + ap_password = self.get_parameter("ap_password") + self.serial_write_line("SSC1", "sta -C -s %s -p %s" % (ap_ssid, ap_password)) + self.check_response("SSC1", "+JAP:CONNECTED,") + self.query_heap_size() + + @staticmethod + def log_data_to_file(file_name, data): + with open(file_name, "ab+") as f: + f.write(data+"\r\n") + + def log_test_config(self, data): + # append to log + with self.sync_lock: + _formatted_data = HTMLGenerator.process_one_log_item(data) + self.append_to_log_file(_formatted_data) + self.log_data_to_file(self.tested_log, data) + + def log_memory(self, data): + self.log_data_to_file(self.memory_track_log, data) + + def log_fail(self, data, log_type="succeed"): + print data + if log_type == "succeed": + self.log_data_to_file(self.failed_log, data) + else: + self.log_data_to_file(self.failed_log2, data) + + def log_succeed(self, data, log_type="succeed"): + if log_type == "succeed": + self.log_data_to_file(self.succeed_log, data) + else: + self.log_data_to_file(self.succeed_log2, data) + + def execute(self): + TCActionBase.TCActionBase.execute(self) + # rewrite the following code + if self.client_type == "PC": + client_capability = Capability.PCSSLCapability("PCClient") + client_handler = SSLHandler.PCSSLHandler + client_ip = self.get_parameter("pc_ip") + else: + client_capability = Capability.TargetSSLCapability("TargetClient", **self.client_capability) + client_handler = SSLHandler.TargetSSLHandler + client_ip = self.get_parameter("target_ip") + if self.server_type == "PC": + server_capability = Capability.PCSSLCapability("PCServer") + server_handler = SSLHandler.PCSSLHandler + server_ip = self.get_parameter("pc_ip") + else: + server_capability = Capability.TargetSSLCapability("TargetServer", **self.server_capability) + server_handler = SSLHandler.TargetSSLHandler + server_ip = self.get_parameter("target_ip") + + serial_port = SSLHandler.SerialPort(self, "SSC1") + # generate config + config_utility = ConfigUtility.ConfigUtility(client_capability, server_capability) + config_list_dict = config_utility.get_all_test_config() + + # succeed + for config in config_list_dict["succeed"]: + self.prepare_handshake_test() + self.log_test_config("[Succeed config] %s" % config) + port = random.randint(500, 50000) + client = client_handler("client", config, serial_port) + server = server_handler("server", config, serial_port) + try: + client.init_context() + server.init_context() + server.listen(local_ip=server_ip, local_port=port) + client.connect(server_ip, port, local_ip=client_ip) + self.query_heap_size(scenario="connected") + self.log_succeed("[Succeed config] %s" % config) + except SSLHandler.TargetFail, e: + NativeLog.add_exception_log(e) + self.log_fail("[Target][%s]\r\n[Failed][Succeed config] %s" % (e, config)) + except SSLHandler.PCFail, e: + NativeLog.add_exception_log(e) + self.log_fail("[PC][%s]\r\n[Failed][Succeed config] %s" % (e, config)) + + self.close(client, server) + + # init context fail + for config in config_list_dict["context_fail"]: + self.prepare_handshake_test() + port = random.randint(500, 50000) + self.log_test_config("[Init context fail config] %s" % config) + client = client_handler("client", config, serial_port) + server = server_handler("server", config, serial_port) + try: + client.init_context() + server.init_context() + server.listen(local_ip=server_ip, local_port=port) + client.connect(server_ip, port, local_ip=client_ip) + self.log_fail("[Target]\r\n[Failed][Init context fail config] %s" % config, log_type="failed") + except StandardError, e: + NativeLog.add_exception_log(e) + self.log_succeed("[init context fail] %s" % config, log_type="failed") + self.close(client, server) + pass + + # negotiation fail + for config in config_list_dict["negotiation_fail"]: + self.prepare_handshake_test() + self.log_test_config("[negotiation_fail] %s" % config) + port = random.randint(500, 50000) + client = client_handler("client", config, serial_port) + server = server_handler("server", config, serial_port) + try: + client.init_context() + server.init_context() + server.listen(local_ip=server_ip, local_port=port) + except SSLHandler.TargetFail, e: + NativeLog.add_exception_log(e) + self.log_fail("[Target][%s]\r\n[Failed][negotiation fail config] %s" % (e, config), log_type="failed") + self.close(client, server) + continue + except SSLHandler.PCFail, e: + NativeLog.add_exception_log(e) + self.log_fail("[PC][%s]\r\n[Failed][negotiation fail config] %s" % (e, config), log_type="failed") + self.close(client, server) + continue + try: + client.connect(server_ip, port, local_ip=client_ip) + self.log_fail("[Target]\r\n[Failed][negotiation fail config] %s" % config, log_type="failed") + except StandardError, e: + NativeLog.add_exception_log(e) + self.log_succeed("[negotiation fail] %s" % config, log_type="failed") + self.close(client, server) + + # cert key fail + for config in config_list_dict["cert_key_fail"]: + self.prepare_handshake_test() + self.log_test_config("[cert_key_fail] %s" % config) + port = random.randint(500, 50000) + client = client_handler("client", config, serial_port) + server = server_handler("server", config, serial_port) + try: + client.init_context() + server.init_context() + server.listen(local_ip=server_ip, local_port=port) + except SSLHandler.TargetFail, e: + NativeLog.add_exception_log(e) + self.log_fail("[Target][%s]\r\n[Failed][cert_key fail config] %s" % (e, config), log_type="failed") + self.close(client, server) + continue + except SSLHandler.PCFail, e: + NativeLog.add_exception_log(e) + self.log_fail("[PC][%s]\r\n[Failed][cert_key fail config] %s" % (e, config), log_type="failed") + self.close(client, server) + continue + try: + client.connect(server_ip, port, local_ip=client_ip) + self.log_fail("[Target][Failed][cert_key fail config] %s" % config, log_type="failed") + except StandardError, e: + NativeLog.add_exception_log(e) + self.log_succeed("[cert_key_fail] %s" % config, log_type="failed") + self.close(client, server) + + +def main(): + pass + +if __name__ == '__main__': + main() diff --git a/components/test/TestCaseScript/SSLTest/SSLLowMem.py b/components/test/TestCaseScript/SSLTest/SSLLowMem.py new file mode 100644 index 0000000000..fdc058f902 --- /dev/null +++ b/components/test/TestCaseScript/SSLTest/SSLLowMem.py @@ -0,0 +1,140 @@ +import os +import random +import time +import re + +from TCAction import TCActionBase +from TCAction import PerformanceTCBase +from NativeLog import NativeLog, HTMLGenerator +from Utility import MakeFolder + +import ConfigUtility +import Capability +import SSLHandler + +LOG_FOLDER = os.path.join("AT_LOG", "TEMP") + +HEAP_SIZE_LIMIT = 30000 + + +class SSLLowMem(PerformanceTCBase.PerformanceTCBase): + + def __init__(self, name, test_env, cmd_set, timeout=15, log_path=TCActionBase.LOG_PATH): + PerformanceTCBase.PerformanceTCBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + self.client_type = None + self.server_type = None + self.client_capability = dict() + self.server_capability = dict() + self.heap_usage_range = (10000, 30000) + self.test_time = 120 + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + timestamp = time.strftime("%d%H%M%S", time.localtime()) + self.heap_size_pattern = re.compile("\+FREEHEAP:(\d+)\r\n") + + @staticmethod + def close(client, server): + try: + client.close() + except StandardError: + pass + try: + server.close() + except StandardError: + pass + + def query_heap_size(self, scenario="idle"): + self.flush_data("SSC1") + self.serial_write_line("SSC1", "ram -H") + match = self.check_regular_expression("SSC1", self.heap_size_pattern) + if match is None: + NativeLog.add_trace_critical("No response for SSC ram command") + else: + heap_size = int(match.group(1)) + if heap_size < HEAP_SIZE_LIMIT and scenario == "idle": + NativeLog.add_trace_critical("[HeapSize] %s" % heap_size) + + pass + + def prepare_handshake_test(self): + # check if connected + self.flush_data("SSC1") + self.serial_write_line("SSC1", "sta -Q") + if self.check_response("SSC1", "+JAP:CONNECTED,") is False: + ap_ssid = self.get_parameter("ap_ssid") + ap_password = self.get_parameter("ap_password") + self.serial_write_line("SSC1", "sta -C -s %s -p %s" % (ap_ssid, ap_password)) + self.check_response("SSC1", "+JAP:CONNECTED,") + # random alloc memory + while True: + memory_size = random.randint(self.heap_usage_range[0], self.heap_usage_range[1]) + self.serial_write_line("SSC1", "soc -M -l %s" % memory_size) + if self.check_response("SSC1", "+SOC_BUFFER:OK", timeout=1) is True: + break + # query size + self.query_heap_size() + + @staticmethod + def log_data_to_file(file_name, data): + with open(file_name, "ab+") as f: + f.write(data+"\r\n") + + def execute(self): + TCActionBase.TCActionBase.execute(self) + # rewrite the following code + if self.client_type == "PC": + client_capability = Capability.PCSSLCapability("PCClient") + client_handler = SSLHandler.PCSSLHandler + client_ip = self.get_parameter("pc_ip") + else: + client_capability = Capability.TargetSSLCapability("TargetClient", **self.client_capability) + client_handler = SSLHandler.TargetSSLHandler + client_ip = self.get_parameter("target_ip") + if self.server_type == "PC": + server_capability = Capability.PCSSLCapability("PCServer") + server_handler = SSLHandler.PCSSLHandler + server_ip = self.get_parameter("pc_ip") + else: + server_capability = Capability.TargetSSLCapability("TargetServer", **self.server_capability) + server_handler = SSLHandler.TargetSSLHandler + server_ip = self.get_parameter("target_ip") + + test_time = self.test_time * 60 # convert test time from minutes to seconds + + serial_port = SSLHandler.SerialPort(self, "SSC1") + # generate config + config_utility = ConfigUtility.ConfigUtility(client_capability, server_capability) + config_list_dict = config_utility.get_all_test_config() + + start_time = time.time() + + # succeed + for config in config_list_dict["succeed"]: + if time.time() - start_time > test_time: + break + self.prepare_handshake_test() + port = random.randint(500, 50000) + client = client_handler("client", config, serial_port) + server = server_handler("server", config, serial_port) + try: + client.init_context() + server.init_context() + server.listen(local_ip=server_ip, local_port=port) + client.connect(server_ip, port, local_ip=client_ip) + self.query_heap_size(scenario="connected") + except SSLHandler.TargetFail, e: + NativeLog.add_exception_log(e) + except SSLHandler.PCFail, e: + NativeLog.add_exception_log(e) + self.close(client, server) + + +def main(): + pass + +if __name__ == '__main__': + main() diff --git a/components/test/TestCaseScript/SSLTest/SSLSendRecv.py b/components/test/TestCaseScript/SSLTest/SSLSendRecv.py new file mode 100644 index 0000000000..13fe0b1529 --- /dev/null +++ b/components/test/TestCaseScript/SSLTest/SSLSendRecv.py @@ -0,0 +1,147 @@ +import random +import time + +from TCAction import TCActionBase +from TCAction import PerformanceTCBase +from NativeLog import NativeLog +import ConfigUtility +import Capability +import SSLHandler + + +class SSLSendRecv(PerformanceTCBase.PerformanceTCBase): + + def __init__(self, name, test_env, cmd_set, timeout=15, log_path=TCActionBase.LOG_PATH): + PerformanceTCBase.PerformanceTCBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + self.target_role = "Client" + self.max_send_len = 2048 + self.test_time = 120 + self.data_validation = False + + self.target_capability = {"version": ["SSLv23"], + "cipher_suite": ["TLS_RSA_WITH_AES_256_CBC_SHA", "TLS_RSA_WITH_AES_128_CBC_SHA"], + "fragment_size": [2048], + "verify_server": False, + "verify_client": False, + "key_algorithm": ["RSA2048"], + "key_encoding": ["PEM"], + "pem_encryption": [None], + "certificate_encoding": ["PEM"], + "certificate_digest": ["sha1"], + } + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + + @staticmethod + def close(client, server): + try: + client.close() + except StandardError: + pass + try: + server.close() + except StandardError: + pass + + def cleanup(self): + self.serial_write_line("SSC1", "ssl -D") + self.check_response("SSC1", "SSL") + + def execute(self): + TCActionBase.TCActionBase.execute(self) + + target_role = self.target_role + max_send_len = self.max_send_len + test_time = self.test_time * 60 + data_validation = self.data_validation + + ssl_port = random.randint(10000, 50000) + NativeLog.add_prompt_trace("SSL port is %s" % ssl_port) + + # make sure ssl context deinit + self.serial_write_line("SSC1", "ssl -D") + self.check_response("SSC1", "SSL") + + # close all sockets and enlarge send buffer + self.serial_write_line("SSC1", "soc -T") + self.check_response("SSC1", "CLOSEALL") + + self.serial_write_line("SSC1", "soc -M -l %s" % max_send_len) + self.check_response("SSC1", "+SOC_BUFFER:OK") + + # rewrite the following code + if target_role == "Server": + client_capability = Capability.PCSSLCapability("PCClient") + client_handler = SSLHandler.PCSSLHandler + client_ip = self.get_parameter("pc_ip") + server_capability = Capability.TargetSSLCapability("TargetServer", **self.target_capability) + server_handler = SSLHandler.TargetSSLHandler + server_ip = self.get_parameter("target_ip") + elif target_role == "Client": + client_capability = Capability.TargetSSLCapability("TargetClient", **self.target_capability) + client_handler = SSLHandler.TargetSSLHandler + client_ip = self.get_parameter("target_ip") + server_capability = Capability.PCSSLCapability("PCServer") + server_handler = SSLHandler.PCSSLHandler + server_ip = self.get_parameter("pc_ip") + else: + raise StandardError("Unsupported target role %s" % target_role) + + serial_port = SSLHandler.SerialPort(self, "SSC1") + + # generate one succeed config + config_utility = ConfigUtility.ConfigUtility(client_capability, server_capability) + config_list_dict = config_utility.get_all_test_config() + + for config in config_list_dict["succeed"]: + try: + # create connection + NativeLog.add_prompt_trace(str(config)) # do print config + client = client_handler("client", config, serial_port) + server = server_handler("server", config, serial_port) + client.init_context() + server.init_context() + server.listen(local_ip=server_ip, local_port=ssl_port) + client.connect(server_ip, ssl_port, local_ip=client_ip) + except StandardError, e: + NativeLog.add_exception_log(e) + return + + # set data validation + client.set_data_validation(data_validation) + server.set_data_validation(data_validation) + + # do send recv + time_start = time.time() + while time.time() - time_start < test_time: + send_len = random.randint(1, max_send_len) + try: + client.send(size=send_len) + client.send(size=send_len) + server.recv(send_len*2) + except StandardError, e: + NativeLog.add_exception_log(e) + NativeLog.add_prompt_trace("client send / server recv fail") + break + try: + # do send twice, try to create a tcp segment with 2 records + server.send(size=send_len) + server.send(size=send_len) + client.recv(send_len*2) + except StandardError, e: + NativeLog.add_exception_log(e) + NativeLog.add_prompt_trace("server send / client recv fail") + break + else: + self.set_result("Succeed") + + +def main(): + pass + +if __name__ == '__main__': + main() diff --git a/components/test/TestCaseScript/SSLTest/__init__.py b/components/test/TestCaseScript/SSLTest/__init__.py new file mode 100755 index 0000000000..98fe3be4a7 --- /dev/null +++ b/components/test/TestCaseScript/SSLTest/__init__.py @@ -0,0 +1 @@ +__all__ = ["Capability", "ConfigUtility", "Parameter", "SSLHandler", "SSLHandshake"] diff --git a/components/test/TestCaseScript/SleepMode/AutoSleep.py b/components/test/TestCaseScript/SleepMode/AutoSleep.py new file mode 100755 index 0000000000..9db70227cf --- /dev/null +++ b/components/test/TestCaseScript/SleepMode/AutoSleep.py @@ -0,0 +1,561 @@ +import random +import os +import time +import string +import re +import threading + +from TCAction import TCActionBase, PerformanceTCBase +from NativeLog import NativeLog +from Utility import MakeFolder +from Utility import MultimeterUtil +from Utility import ShellCmd + +LOG_PATH = os.path.join("AT_LOG", "SLEEP") + +SLEEP_MODE_LIST = ["none_sleep", "light_sleep", "modem_sleep"] +SLEEP_MODE = dict(zip(SLEEP_MODE_LIST, range(len(SLEEP_MODE_LIST)))) + +SAMPLE_RATE_SLEEP_MODE_CHANGE = 0.002 +SAMPLE_NUM_SLEEP_MODE_CHANGE = 256 + +SAMPLE_RATE = 0.002 +SAMPLE_NUM = 512 +MAX_VALUE = 1 +Y_AXIS_LABEL = "Current (mA)" +GPIO_EDGE_DELAY = 120 # 20 ms + +NONE_SLEEP_MIN_CUR = 30 +LIGHT_SLEEP_MIN_CUR = 1.5 +MODEM_SLEEP_MIN_CUR = 20 + +GPIO_WAKE_UP = 15 +GPIO_CHIP_RESET = 14 + +SLEEP_WAKEUP_DELAY = 0.01 + + +class AutoSleep(PerformanceTCBase.PerformanceTCBase): + + def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): + PerformanceTCBase.PerformanceTCBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + self.test_mode = "mode_change" + self.test_count = 100 + self.sleep_mode = SLEEP_MODE_LIST + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + self.log_folder = MakeFolder.make_folder(os.path.join(LOG_PATH, + "AUTO_SLEEP_%s_%s" % (self.test_mode, + time.strftime("%d%H%M%S", + time.localtime())))) + self.multimeter = MultimeterUtil.MultimeterUtil(self.log_folder) + + @staticmethod + def find_min_items(item_list, count): + assert count < len(item_list) + min_items = [] + for i in range(count): + min_val = min(item_list) + min_items.append(min_val) + item_list.remove(min_val) + return min_items + + def sleep_mode_change(self, sleep_mode): + result = True + NativeLog.add_prompt_trace("[AutoSleep][ModeChange] %s start" % sleep_mode) + # choose sleep mode + sleep_mode_enum = SLEEP_MODE[sleep_mode] + # change GPIO to make sure target exit sleep mode, so it can process SSC commands + self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) + time.sleep(SLEEP_WAKEUP_DELAY) + # set sleep mode + self.serial_write_line("SSC1", "sleep -S -t %d" % sleep_mode_enum) + self.check_response("SSC1", "+SLEEP_MODE:OK") + self.check_response("SSC2", "+GPIO_SET:OK") + + NativeLog.add_prompt_trace("[AutoSleep][ModeChange] mode set") + time.sleep(6) + # measure current + current_line = self.multimeter.measure_current(sample_rate=SAMPLE_RATE_SLEEP_MODE_CHANGE, + sample_num=SAMPLE_NUM_SLEEP_MODE_CHANGE, + max_value=MAX_VALUE) + # do check measure + min_items = self.find_min_items(current_line, 10) + average_val = float(0) + for val in min_items: + average_val += val + average_val /= 10 + + NativeLog.add_prompt_trace("[AutoSleep][ModeChange] measure done, average min current %f" % average_val) + + if sleep_mode == "none_sleep": + if average_val < NONE_SLEEP_MIN_CUR: + result = False + elif sleep_mode == "light_sleep": + if average_val > LIGHT_SLEEP_MIN_CUR: + result = False + elif sleep_mode == "modem_sleep": + if average_val > MODEM_SLEEP_MIN_CUR or average_val < LIGHT_SLEEP_MIN_CUR: + result = False + if result is False: + NativeLog.add_trace_critical("[AutoSleep][ModeChange] %s failed" % sleep_mode) + self.multimeter.draw_graph(current_line, SAMPLE_RATE, "%s_fail" % sleep_mode, Y_AXIS_LABEL) + + time.sleep(5) + return result + + def sleep_current_measure(self, sleep_mode): + result = True + + NativeLog.add_prompt_trace("[AutoSleep][CurrentMeasure] %s start" % sleep_mode) + # choose sleep mode + sleep_mode_enum = SLEEP_MODE[sleep_mode] + # change GPIO to make sure target exit sleep mode, so it can process SSC commands + self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) + # set sleep mode + time.sleep(SLEEP_WAKEUP_DELAY) + self.serial_write_line("SSC1", "sleep -S -t %d" % sleep_mode_enum) + self.check_response("SSC1", "+SLEEP_MODE:OK") + self.check_response("SSC2", "+GPIO_SET:OK") + + NativeLog.add_prompt_trace("[AutoSleep][CurrentMeasure] set mode done") + time.sleep(10) + # measure current + current_line = self.multimeter.measure_current(sample_rate=SAMPLE_RATE, + sample_num=SAMPLE_NUM, + max_value=MAX_VALUE) + self.multimeter.draw_graph(current_line, SAMPLE_RATE, sleep_mode, Y_AXIS_LABEL) + NativeLog.add_prompt_trace("[AutoSleep][CurrentMeasure] measure done") + return result + + def light_sleep_wakeup(self): + result = True + NativeLog.add_prompt_trace("[AutoSleep][LightSleepWakeup] start") + + time.sleep(1) + self.serial_write_line("SSC1", "") + time.sleep(1) + # check if respond to uart + self.flush_data("SSC1") + for i in range(60): + self.serial_write("SSC1", "a") + time.sleep(0.043) + time.sleep(0.1) + respond_data = self.serial_read_data("SSC1") + if len(respond_data) >= 60: + NativeLog.add_trace_critical("[AutoSleep][light sleep wakeup] " + "Failed when recving data during sleep, %d" % len(respond_data)) + result = False + + NativeLog.add_prompt_trace("[AutoSleep][LightSleepWakeup] check on sleep mode done") + + self.serial_write_line("SSC1", "") + time.sleep(1) + + # change GPIO to make target wakeup + self.serial_write_line("SSC2", "gpio -L -p %d -t 0" % GPIO_WAKE_UP) + self.check_response("SSC2", "+GPIO_SET:OK") + + self.serial_write_line("SSC1", "") + time.sleep(1) + self.flush_data("SSC1") + for i in range(60): + self.serial_write("SSC1", "a") + time.sleep(0.043) + time.sleep(0.1) + respond_data = self.serial_read_data("SSC1") + if len(respond_data) < 60: + NativeLog.add_trace_critical("[AutoSleep][light sleep wakeup] " + "Failed when recving data during wakeup, %d" % len(respond_data)) + result = False + + NativeLog.add_prompt_trace("[AutoSleep][LightSleepWakeup] check on wakeup mode done") + self.serial_write_line("SSC1", "") + # restore GPIO level + self.serial_write_line("SSC2", "gpio -L -p %d -t 1" % GPIO_WAKE_UP) + self.check_response("SSC2", "+GPIO_SET:OK") + + self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_CHIP_RESET, GPIO_EDGE_DELAY)) + self.check_response("SSC2", "+GPIO_SET:OK") + time.sleep(2) + return result + + def sleep_exit_enter(self, sleep_mode, ssid, password): + result = True + if sleep_mode == "modem_sleep": + max_current_for_sleep = 20 + elif sleep_mode == "light_sleep": + max_current_for_sleep = 5 + else: + raise StandardError("Not supported mode %s" % sleep_mode) + + NativeLog.add_prompt_trace("[AutoSleep][EnterExitSleep] %s start" % sleep_mode) + + ap_ssid = self.get_parameter("ap_ssid") + ap_password = self.get_parameter("ap_password") + + # step A: no STA connect to SoftAP, enter modem sleep mode + self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) + time.sleep(SLEEP_WAKEUP_DELAY) + self.serial_write_line("SSC1", "op -S -o 1") + self.check_response("SSC1", "+MODE:OK") + self.check_response("SSC2", "+GPIO_SET:OK") + + self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) + time.sleep(SLEEP_WAKEUP_DELAY) + self.serial_write_line("SSC1", "sta -C -s %s -p %s" % (ap_ssid, ap_password)) + self.check_response("SSC2", "+GPIO_SET:OK") + self.check_response("SSC1", "+JAP:CONNECTED") + self.check_response("SSC1", "pm open") + + self.serial_write_line("SSC2", "sta -D") + self.check_response("SSC2", "+QAP") + + time.sleep(5) + + current_line = self.multimeter.measure_current(sample_rate=SAMPLE_RATE, + sample_num=SAMPLE_NUM, + max_value=MAX_VALUE) + min_items = self.find_min_items(current_line, 10) + average_val = float(0) + for val in min_items: + average_val += val + average_val /= 10 + if average_val > max_current_for_sleep: + NativeLog.add_trace_critical("[AutoSleep][SleepExitEnter] " + "did not enter %s sleep, %d" % (sleep_mode, average_val)) + self.multimeter.draw_graph(current_line, SAMPLE_RATE, + "%s_sleep_exit_enter_fail_A" % sleep_mode, Y_AXIS_LABEL) + result = False + + NativeLog.add_prompt_trace("[AutoSleep][EnterExitSleep] step A done") + # step B: STA connect to SoftAP, exit modem sleep mode + self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) + time.sleep(SLEEP_WAKEUP_DELAY) + self.serial_write_line("SSC1", "op -S -o 3") + self.check_response("SSC1", "+MODE:OK") + self.check_response("SSC2", "+GPIO_SET:OK") + time.sleep(1) + self.serial_write_line("SSC2", "sta -C -s %s -p %s" % (ssid, password)) + self.check_response("SSC2", "+JAP:CONNECTED") + # self.check_response("SSC1", "pm close") + time.sleep(10) + + current_line = self.multimeter.measure_current(sample_rate=SAMPLE_RATE, + sample_num=SAMPLE_NUM, + max_value=MAX_VALUE) + min_items = self.find_min_items(current_line, 10) + average_val = float(0) + for val in min_items: + average_val += val + average_val /= 10 + if average_val < 30: + NativeLog.add_trace_critical("[AutoSleep][SleepExitEnter] did not exit %s sleep" % sleep_mode) + self.multimeter.draw_graph(current_line, SAMPLE_RATE, + "%s_sleep_exit_enter_fail_B" % sleep_mode, Y_AXIS_LABEL) + result = False + + NativeLog.add_prompt_trace("[AutoSleep][EnterExitSleep] step B done") + # step C: target set to STA mode, enter modem sleep + self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) + time.sleep(SLEEP_WAKEUP_DELAY) + self.serial_write_line("SSC1", "op -S -o 1") + self.check_response("SSC1", "+MODE:OK") + + self.check_response("SSC2", "+GPIO_SET:OK") + # self.check_response("SSC1", "pm open") + time.sleep(15) + + current_line = self.multimeter.measure_current(sample_rate=SAMPLE_RATE, + sample_num=SAMPLE_NUM, + max_value=MAX_VALUE) + min_items = self.find_min_items(current_line, 10) + average_val = float(0) + for val in min_items: + average_val += val + average_val /= 10 + if average_val > max_current_for_sleep: + NativeLog.add_trace_critical("[AutoSleep][SleepExitEnter] did not enter %s sleep" % sleep_mode) + self.multimeter.draw_graph(current_line, SAMPLE_RATE, + "%s_sleep_exit_enter_fail_C" % sleep_mode, Y_AXIS_LABEL) + result = False + + NativeLog.add_prompt_trace("[AutoSleep][EnterExitSleep] step C done") + # step D: target disconnect, exit modem sleep + self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) + time.sleep(SLEEP_WAKEUP_DELAY) + self.serial_write_line("SSC1", "sta -D") + self.check_response("SSC1", "+QAP") + self.check_response("SSC2", "+GPIO_SET:OK") + # self.check_response("SSC1", "pm close") + time.sleep(5) + current_line = self.multimeter.measure_current(sample_rate=SAMPLE_RATE, + sample_num=SAMPLE_NUM, + max_value=MAX_VALUE) + min_items = self.find_min_items(current_line, 10) + average_val = float(0) + for val in min_items: + average_val += val + average_val /= 10 + if average_val < 30: + NativeLog.add_trace_critical("[AutoSleep][SleepExitEnter] did not exit %s sleep" % sleep_mode) + self.multimeter.draw_graph(current_line, SAMPLE_RATE, + "%s_sleep_exit_enter_fail_D" % sleep_mode, Y_AXIS_LABEL) + result = False + + NativeLog.add_prompt_trace("[AutoSleep][EnterExitSleep] step D done") + # step E: target connect to AP, enter modem sleep + self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) + time.sleep(SLEEP_WAKEUP_DELAY) + self.serial_write_line("SSC1", "sta -C -s %s -p %s" % (ap_ssid, ap_password)) + self.check_response("SSC2", "+GPIO_SET:OK") + self.check_response("SSC1", "+JAP:CONNECTED") + self.check_response("SSC1", "pm open") + time.sleep(3) + current_line = self.multimeter.measure_current(sample_rate=SAMPLE_RATE, + sample_num=SAMPLE_NUM, + max_value=MAX_VALUE) + min_items = self.find_min_items(current_line, 10) + average_val = float(0) + for val in min_items: + average_val += val + average_val /= 10 + if average_val > max_current_for_sleep: + NativeLog.add_trace_critical("[AutoSleep][SleepExitEnter] did not enter %s sleep" % sleep_mode) + self.multimeter.draw_graph(current_line, SAMPLE_RATE, + "%s_sleep_exit_enter_fail_E" % sleep_mode, Y_AXIS_LABEL) + result = False + + NativeLog.add_prompt_trace("[AutoSleep][EnterExitSleep] step E done") + # step F: target set to AP mode, exit modem sleep + self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) + time.sleep(SLEEP_WAKEUP_DELAY) + self.serial_write_line("SSC1", "op -S -o 2") + self.check_response("SSC1", "+MODE:OK") + self.check_response("SSC2", "+GPIO_SET:OK") + # self.check_response("SSC1", "pm close") + time.sleep(5) + + current_line = self.multimeter.measure_current(sample_rate=SAMPLE_RATE, + sample_num=SAMPLE_NUM, + max_value=MAX_VALUE) + min_items = self.find_min_items(current_line, 10) + average_val = float(0) + for val in min_items: + average_val += val + average_val /= 10 + if average_val < 30: + NativeLog.add_trace_critical("[AutoSleep][SleepExitEnter] did not exit %s sleep" % sleep_mode) + self.multimeter.draw_graph(current_line, SAMPLE_RATE, + "%s_sleep_exit_enter_fail_F" % sleep_mode, Y_AXIS_LABEL) + result = False + + NativeLog.add_prompt_trace("[AutoSleep][EnterExitSleep] step F done") + return result + + def ping_test(self, sleep_mode): + result = True + NativeLog.add_prompt_trace("[AutoSleep][PingTest] %s start" % sleep_mode) + # choose sleep mode + sleep_mode_enum = SLEEP_MODE[sleep_mode] + if sleep_mode == "modem_sleep": + max_current_for_sleep = MODEM_SLEEP_MIN_CUR + elif sleep_mode == "light_sleep": + max_current_for_sleep = LIGHT_SLEEP_MIN_CUR + else: + raise StandardError("Not supported mode %s" % sleep_mode) + + self.serial_write_line("SSC1", "op -S -o 1") + self.check_response("SSC1", "+MODE:OK") + + # set sleep mode + self.serial_write_line("SSC1", "sleep -S -t %d" % sleep_mode_enum) + self.check_response("SSC1", "+SLEEP_MODE:OK") + NativeLog.add_prompt_trace("[AutoSleep][PingTest] set mode done") + + # connect to AP + ap_ssid = self.get_parameter("ap_ssid") + ap_password = self.get_parameter("ap_password") + target_ip = self.get_parameter("target_ip") + + self.serial_write_line("SSC1", "sta -C -s %s -p %s" % (ap_ssid, ap_password)) + self.check_response("SSC1", "+JAP:CONNECTED") + + time.sleep(10) + # measure current, should be in sleep mode + current_line = self.multimeter.measure_current(sample_rate=SAMPLE_RATE, + sample_num=SAMPLE_NUM, + max_value=MAX_VALUE) + min_items = self.find_min_items(current_line, 10) + average_val = float(0) + for val in min_items: + average_val += val + average_val /= 10 + + if average_val > max_current_for_sleep: + NativeLog.add_trace_critical("[AutoSleep][PingTest] step A did not enter %s sleep, %f" + % (sleep_mode, average_val)) + self.multimeter.draw_graph(current_line, SAMPLE_RATE, + "%s_ping_test_fail_not_enter_sleep" % sleep_mode, Y_AXIS_LABEL) + result = False + else: + NativeLog.add_prompt_trace("[AutoSleep][PingTest] step A enter %s sleep, %f" + % (sleep_mode, average_val)) + + class PingThread(threading.Thread): + def __init__(self, ping_ip): + threading.Thread.__init__(self) + self.setDaemon(True) + self.target_ip = ping_ip + self.exit_event = threading.Event() + + def run(self): + while self.exit_event.isSet() is False: + ShellCmd.shell_check_output("ping %s -w 500" % self.target_ip) + time.sleep(0.1) + pass + + def exit(self): + self.exit_event.set() + + NativeLog.add_prompt_trace("[AutoSleep][PingTest] ping start") + ping_thread = PingThread(target_ip) + ping_thread.start() + time.sleep(5) + + # measure current, should not be in sleep mode + current_line = self.multimeter.measure_current(sample_rate=SAMPLE_RATE, + sample_num=SAMPLE_NUM, + max_value=MAX_VALUE) + min_items = self.find_min_items(current_line, 10) + average_val = float(0) + for val in min_items: + average_val += val + average_val /= 10 + if average_val < 30: + NativeLog.add_trace_critical("[AutoSleep][PingTest] step B did not exit %s sleep, %f" + % (sleep_mode, average_val)) + self.multimeter.draw_graph(current_line, SAMPLE_RATE, + "%s_ping_test_fail_not_exit_sleep" % sleep_mode, Y_AXIS_LABEL) + result = False + else: + NativeLog.add_prompt_trace("[AutoSleep][PingTest] step B exit %s sleep, %f" + % (sleep_mode, average_val)) + + ping_thread.exit() + ping_thread.join(20) + NativeLog.add_prompt_trace("[AutoSleep][PingTest] ping stop") + time.sleep(10) + + # measure current, should not be in sleep mode + current_line = self.multimeter.measure_current(sample_rate=SAMPLE_RATE, + sample_num=SAMPLE_NUM, + max_value=MAX_VALUE) + min_items = self.find_min_items(current_line, 10) + average_val = float(0) + for val in min_items: + average_val += val + average_val /= 10 + if average_val > max_current_for_sleep: + NativeLog.add_trace_critical("[AutoSleep][PingTest] step C did not enter %s" % sleep_mode) + self.multimeter.draw_graph(current_line, SAMPLE_RATE, + "%s_ping_test_fail_not_enter_sleep" % sleep_mode, Y_AXIS_LABEL) + result = False + else: + NativeLog.add_prompt_trace("[AutoSleep][PingTest] step C enter %s sleep" % sleep_mode) + + return result + + def cleanup(self): + self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) + time.sleep(SLEEP_WAKEUP_DELAY) + self.serial_write_line("SSC1", "sleep -S -t %d" % SLEEP_MODE["modem_sleep"]) + self.check_response("SSC1", "OK") + self.check_response("SSC2", "+GPIO_SET:OK") + + def execute(self): + TCActionBase.TCActionBase.execute(self) + + try: + test_mode = self.test_mode + test_count = self.test_count + sleep_mode = self.sleep_mode + except StandardError, e: + return + + # make sure enter modem sleep mode before start test + self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) + time.sleep(SLEEP_WAKEUP_DELAY) + self.serial_write_line("SSC1", "sleep -S -t %d" % SLEEP_MODE["modem_sleep"]) + self.check_response("SSC1", "+SLEEP_MODE:OK") + self.check_response("SSC2", "+GPIO_SET:OK") + self.check_response("SSC1", "pm open", timeout=10) + + self.serial_write_line("SSC1", "gpio -G -p %d" % GPIO_WAKE_UP) + self.check_response("SSC1", "+GPIO_GET") + self.serial_write_line("SSC1", "gpio -G -p %d" % GPIO_CHIP_RESET) + self.check_response("SSC1", "+GPIO_GET") + + # start test + if "mode_change" in test_mode: + for i in range(test_count): + result = self.sleep_mode_change(random.choice(SLEEP_MODE_LIST)) + + elif "measure_current" in test_mode: + for i in range(test_count): + for mode in sleep_mode: + result = self.sleep_current_measure(mode) + pass + elif "gpio_wakeup" in test_mode: + # change GPIO to make sure target exit sleep mode, so it can process SSC commands + self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) + time.sleep(SLEEP_WAKEUP_DELAY) + # set sleep mode + self.serial_write_line("SSC1", "sleep -S -t %d" % SLEEP_MODE["light_sleep"]) + self.check_response("SSC1", "+SLEEP_MODE:OK") + + self.check_response("SSC2", "+GPIO_SET:OK") + for i in range(test_count): + result = self.light_sleep_wakeup() + pass + elif "sleep_exit_enter" in test_mode: + ssid = "".join([random.choice(string.lowercase) for i in range(10)]) + password = "".join([random.choice(string.lowercase) for i in range(10)]) + self.serial_write_line("SSC2", "sta -D") + self.check_response("SSC2", "+QAP") + self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) + time.sleep(SLEEP_WAKEUP_DELAY) + self.serial_write_line("SSC1", "op -S -o 3") + self.check_response("SSC1", "+MODE:OK") + self.check_response("SSC2", "+GPIO_SET:OK") + self.serial_write_line("SSC1", "ap -S -s %s -p %s -t 3" % (ssid, password)) + self.check_response("SSC1", "+SAP:OK") + self.serial_write_line("SSC2", "op -S -o 1") + self.check_response("SSC2", "+MODE:OK") + + for mode in sleep_mode: + self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) + time.sleep(SLEEP_WAKEUP_DELAY) + self.serial_write_line("SSC1", "sleep -S -t %d" % SLEEP_MODE[mode]) + self.check_response("SSC1", "+SLEEP_MODE:OK") + self.check_response("SSC2", "+GPIO_SET:OK") + + for i in range(test_count): + result = self.sleep_exit_enter(mode, ssid, password) + elif "ping" in test_mode: + for mode in sleep_mode: + for i in range(test_count): + result = self.ping_test(mode) + pass + + +def main(): + pass + + +if __name__ == '__main__': + main() diff --git a/components/test/TestCaseScript/SleepMode/DeepSleep.py b/components/test/TestCaseScript/SleepMode/DeepSleep.py new file mode 100755 index 0000000000..252ebb0758 --- /dev/null +++ b/components/test/TestCaseScript/SleepMode/DeepSleep.py @@ -0,0 +1,259 @@ +import random +import os +import time + +from TCAction import TCActionBase, PerformanceTCBase +from Utility import MakeFolder +from Utility import MultimeterUtil +from NativeLog import NativeLog + +LOG_PATH = os.path.join("AT_LOG", "SLEEP") + +DEEP_SLEEP_OPTION_LIST = ["up_to_bin", "normal", "no_rf_calibrate", "rf_off"] +DEEP_SLEEP_OPTION = { + "up_to_bin": 0, + "normal": 1, + "no_rf_calibrate": 2, + "rf_off": 4, +} + +SAMPLE_RATE = 0.001 +SAMPLE_NUM = 512 +MAX_VALUE = 0.1 +Y_AXIS_LABEL = "Current (mA)" + + +MEASURE_FREQ = 3600 + +GPIO_WAKE_UP = 15 +GPIO_CHIP_RESET = 14 +GPIO_EDGE_DELAY = 100 # 20 ms + + +class DeepSleep(PerformanceTCBase.PerformanceTCBase): + + def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): + PerformanceTCBase.PerformanceTCBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + self.test_mode = "mode_change" + self.test_count = 100 + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + self.log_folder = MakeFolder.make_folder(os.path.join(LOG_PATH, + "DEEP_SLEEP_%s_%s" % (self.test_mode, + time.strftime("%d%H%M%S", + time.localtime())))) + self.sleep_time_log = os.path.join(self.log_folder, "deep_sleep_wakeup_time.log") + self.multimeter = MultimeterUtil.MultimeterUtil(self.log_folder) + + def deep_sleep_stable(self): + result = True + RandomTime = random.randint(1, 100) + self.serial_write_line("SSC1", "dsleep -S -t %s" % RandomTime) + if self.check_response("SSC1", "+DSLEEP:OK") is False: + result = False + if self.check_response("SSC1", "ready!!!") is False: + result = False + NativeLog.add_trace_critical("[DeepSleep][Stable] wait ready err") + else: + NativeLog.add_trace_critical("[DeepSleep][Stable] SleepTime:%d" % RandomTime) + time.sleep(1) + + RandomTime = random.randint(100000, 1000000) + self.serial_write_line("SSC1", "dsleep -S -t %s" % RandomTime) + if self.check_response("SSC1", "+DSLEEP:OK") is False: + result = False + if self.check_response("SSC1", "ready!!!") is False: + result = False + NativeLog.add_trace_critical("[DeepSleep][Stable] wait ready err") + else: + NativeLog.add_trace_critical("[DeepSleep][Stable] SleepTime:%d" % RandomTime) + time.sleep(1) + return result + + def deep_sleep_current_measure(self): + result = True + self.serial_write_line("SSC1", "") + self.serial_write_line("SSC1", "dsleep -S -t 10000000") + if self.check_response("SSC1", "+DSLEEP:OK") is False: + result = False + time.sleep(3) + # measure current + current_line = self.multimeter.measure_current(sample_rate=SAMPLE_RATE, + sample_num=SAMPLE_NUM, + max_value=MAX_VALUE) + average_current = float(0) + for current in current_line: + average_current += current + average_current /= SAMPLE_NUM + + self.multimeter.draw_graph(current_line, SAMPLE_RATE, + "deep_sleep_current", Y_AXIS_LABEL) + + if average_current > 1: + NativeLog.add_trace_critical("[DeepSleep][CurrentMeasure] average current %f > 1mA" % average_current) + else: + NativeLog.add_trace_critical("[DeepSleep][CurrentMeasure] dsleep current ok, %f" % average_current) + + if self.check_response("SSC1", "ready!!!") is False: + NativeLog.add_trace_critical("[DeepSleep][CurrentMeasure] CurrentMeasure wait ready err %f" + % average_current) + result = False + + NativeLog.add_trace_critical("[DeepSleep][CurrentMeasure] wait ready ok") + + return result + + ########################################## + # gpio wake up + ########################################## + def deep_sleep_wakeup(self): + result = True + + self.serial_write_line("SSC1", "dsleep -S -t 0") + if self.check_response("SSC1", "+DSLEEP:OK") is False: + result = False + + time.sleep(2) + + # measure current + current_line = self.multimeter.measure_current(sample_rate=SAMPLE_RATE, + sample_num=SAMPLE_NUM, + max_value=MAX_VALUE) + average_current = float(0) + for current in current_line: + average_current += current + average_current /= SAMPLE_NUM + + if average_current > 1: + NativeLog.add_trace_critical("[DeepSleep][Wakeup] average current %f > 1mA" % average_current) + self.multimeter.draw_graph(current_line, SAMPLE_RATE, + "deep_sleep_current", Y_AXIS_LABEL) + + self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_CHIP_RESET, GPIO_EDGE_DELAY)) + self.check_response("SSC2", "+GPIO_SET:OK") + if self.check_response("SSC1", "ready!!!") is False: + NativeLog.add_trace_critical("[DeepSleep][Wakeup] target did not wakeup") + result = False + else: + NativeLog.add_trace_critical("[DeepSleep][Wakeup] target wakeup") + + time.sleep(1) + return result + + ######################################### + #test one hour, Verify RTC Clock timer + ######################################### + def deep_sleep_timeout(self): + result = True + Timeout = 3600 + + start_sleep_time = time.time() + self.serial_write_line("SSC1", "") + self.serial_write_line("SSC1", "dsleep -S -t %d" % (Timeout*1000000)) + if self.check_response("SSC1", "+DSLEEP:OK") is False: + result = False + self.check_response("SSC1", "ready!!!", timeout = Timeout*2) + time_escaped = time.time() - start_sleep_time + NativeLog.add_trace_critical("[DeepSleep][timeout] desired sleep timeout is %s, actual sleep timeout is %s" % (Timeout, time_escaped)) + with open(self.sleep_time_log, "ab+") as f: + f.write("[DeepSleep] desired sleep timeout is %s, actual sleep timeout is %s" % (Timeout, time_escaped)) + return result + + ############################################ + # Capture current map, verify the process of power on + # notice: option = "up_to_bin" up to byte108 in init.bin, + ############################################ + def wake_option(self): + result = True + for option in DEEP_SLEEP_OPTION_LIST: + for i in range(8): + self.serial_write_line("SSC1", "dsleep -O -m %s" % DEEP_SLEEP_OPTION[option]) + if self.check_response("SSC1", "+DSLEEP:OK") is False: + result = False + self.serial_write_line("SSC1", "dsleep -S -t 1200000") + if self.check_response("SSC1", "+DSLEEP:OK") is False: + result = False + + # measure current + current_line = self.multimeter.measure_current(sample_rate=0.002, + sample_num=SAMPLE_NUM, + max_value=1) + self.multimeter.draw_graph(current_line, SAMPLE_RATE, + "deep_sleep_wakeup_option_%s_%d" + % (option, DEEP_SLEEP_OPTION[option]), Y_AXIS_LABEL) + + NativeLog.add_trace_critical("[DeepSleep][wake_option] target wakeup option:%d" + % DEEP_SLEEP_OPTION[option]) + time.sleep(3) + + return result + + def deep_sleep_wakeup_flash_gpio_status(self): + result = True + RandomTime = random.randint(2000000, 2000000) + self.serial_write_line("SSC1", "dsleep -S -t %s" % RandomTime) + if self.check_response("SSC1", "+DSLEEP:OK") is False: + result = False + if self.check_response("SSC1", "ready!!!") is False: + result = False + NativeLog.add_trace_critical("[DeepSleep][Stable] wait ready err") + else: + NativeLog.add_trace_critical("[DeepSleep][Stable] SleepTime:%d" % RandomTime) + + self.serial_write_line("SSC1", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) + self.check_response("SSC1", "+GPIO_SET:OK") + + time.sleep(1) + return result + + def cleanup(self): + self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_CHIP_RESET, GPIO_EDGE_DELAY)) + self.check_response("SSC2", "+GPIO_SET:OK") + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.serial_write_line("SSC2", "sta -D") + self.check_response("SSC2", "+QAP") + self.serial_write_line("SSC1", "sta -D") + self.check_response("SSC1", "+QAP") + try: + test_mode = self.test_mode + test_count = self.test_count + except StandardError, e: + return + + # self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_CHIP_RESET, GPIO_EDGE_DELAY)) + # self.check_response("SSC2", "+GPIO_SET:OK") + # time.sleep(1) + + if "stable" in test_mode: + for i in range(test_count): + # result = self.deep_sleep_wakeup_flash_gpio_status() + result = self.deep_sleep_stable() + elif "measure_current" in test_mode: + for i in range(test_count): + result = self.deep_sleep_current_measure() + elif "timeout" in test_mode: + for i in range(test_count): + result = self.deep_sleep_timeout() + elif "wakeup" in test_mode: + for i in range(test_count): + result = self.deep_sleep_wakeup() + elif "wake_option" in test_mode: + for i in range(test_count): + result = self.wake_option() + + self.set_result("Succeed") + pass + + +def main(): + pass + + +if __name__ == '__main__': + main() diff --git a/components/test/TestCaseScript/SleepMode/ForceSleep.py b/components/test/TestCaseScript/SleepMode/ForceSleep.py new file mode 100755 index 0000000000..4938a97c2a --- /dev/null +++ b/components/test/TestCaseScript/SleepMode/ForceSleep.py @@ -0,0 +1,254 @@ +import random +import os +import time + +from TCAction import TCActionBase, PerformanceTCBase +from Utility import MakeFolder +from Utility import MultimeterUtil +from NativeLog import NativeLog + +LOG_PATH = os.path.join("AT_LOG", "SLEEP") + +SLEEP_MODE_LIST = ["none_sleep", "light_sleep", "modem_sleep"] +SLEEP_MODE = dict(zip(SLEEP_MODE_LIST, range(len(SLEEP_MODE_LIST)))) + +SAMPLE_RATE = 0.002 +SAMPLE_NUM = 512 +MAX_VALUE = 1 +Y_AXIS_LABEL = "Current (mA)" + +MEASURE_FREQ_HOUR = 3600 + +GPIO_WAKE_UP = 15 +GPIO_EDGE_DELAY = 120 # 20 ms +GPIO_CHIP_RESET = 14 +GPIO_CHIP_RESET_DELAY = 100 + +NONE_SLEEP_MIN_CUR = 30 +LIGHT_SLEEP_MIN_CUR = 1.5 +MODEM_SLEEP_MIN_CUR = 20 + +LIGHT_SLEEP_WAKEUP_DELAY = 0.01 + + +class ForceSleep(PerformanceTCBase.PerformanceTCBase): + + def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): + PerformanceTCBase.PerformanceTCBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + self.test_mode = "mode_change" + self.test_count = 100 + self.sleep_mode = SLEEP_MODE_LIST + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + self.log_folder = MakeFolder.make_folder(os.path.join(LOG_PATH, + "FORCE_SLEEP_%s_%s" % (self.test_mode, + time.strftime("%d%H%M%S", + time.localtime())))) + self.multimeter = MultimeterUtil.MultimeterUtil(self.log_folder) + + @staticmethod + def find_min_items(item_list, count): + assert count < len(item_list) + min_items = [] + for i in range(count): + min_val = min(item_list) + min_items.append(min_val) + item_list.remove(min_val) + return min_items + + def sleep_time_boundary_test(self): + result = True + self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) + time.sleep(LIGHT_SLEEP_WAKEUP_DELAY) + self.serial_write_line("SSC1", "op -S -o 0") + self.check_response("SSC2", "+GPIO_SET:OK") + if self.check_response("SSC1", "+MODE:OK") is False: + result = False + self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) + time.sleep(LIGHT_SLEEP_WAKEUP_DELAY) + self.serial_write_line("SSC1", "fsleep -S -t 1") + self.check_response("SSC2", "+GPIO_SET:OK") + if self.check_response("SSC1", "+FSLEEP_MODE:OK") is False: + result = False + self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) + time.sleep(LIGHT_SLEEP_WAKEUP_DELAY) + self.serial_write_line("SSC1", "fsleep -D -d 0") + self.check_response("SSC2", "+GPIO_SET:OK") + # if self.check_response("SSC1", "+FSLEEP_MODE:OK") is False: + # result = False + time.sleep(1) + current_line = self.multimeter.measure_current(sample_rate=SAMPLE_RATE, + sample_num=SAMPLE_NUM, + max_value=MAX_VALUE) + min_items = self.find_min_items(current_line, 10) + average_val = float(0) + for val in min_items: + average_val += val + average_val /= 10 + if average_val > LIGHT_SLEEP_MIN_CUR: + NativeLog.add_trace_critical("[ForceSleep][Boundary] did not enter light sleep %d" % average_val) + result = False + return result + else: + NativeLog.add_trace_critical("[ForceSleep][Boundary] enter light sleep") + + for i in range(3): + time.sleep(MEASURE_FREQ_HOUR) + for j in range(3): + time.sleep(10) + current_line = self.multimeter.measure_current(sample_rate=SAMPLE_RATE, + sample_num=SAMPLE_NUM, + max_value=MAX_VALUE) + self.multimeter.draw_graph(current_line, SAMPLE_RATE, + "light_sleep_boundary_%s_%s" % (i, j), Y_AXIS_LABEL) + pass + + self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) + self.check_response("SSC2", "+GPIO_SET:OK") + time.sleep(1) + self.serial_write_line("SSC1", "reboot") + self.check_response("SSC1", "ready!!!") + self.serial_write_line("SSC1", "fsleep -S -t 1") + if self.check_response("SSC1", "+FSLEEP_MODE:OK") is False: + result = False + self.serial_write_line("SSC1", "") + self.serial_write_line("SSC1", "fsleep -B -t 1") + if self.check_response("SSC1", "+FSLEEP_MODE:OK") is False: + result = False + time.sleep(MEASURE_FREQ_HOUR) + self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_CHIP_RESET,GPIO_CHIP_RESET_DELAY)) + return result + + def force_sleep_current_measure(self, sleep_mode): + result = True + # choose sleep mode + sleep_mode_enum = SLEEP_MODE[sleep_mode] + + self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) + time.sleep(LIGHT_SLEEP_WAKEUP_DELAY) + self.serial_write_line("SSC1", "op -S -o 0") + if self.check_response("SSC1", "+MODE:OK") is False: + result = False + self.check_response("SSC2", "+GPIO_SET:OK") + + # set sleep mode + self.serial_write_line("SSC1", "fsleep -S -t %s" % sleep_mode_enum) + if self.check_response("SSC1", "+FSLEEP_MODE:OK") is False: + result = False + self.serial_write_line("SSC1", "fsleep -D -d 0") + # if self.check_response("SSC1", "+FSLEEP_MODE:OK") is False: + # result = False + + time.sleep(3) + + for i in range(10): + time.sleep(10) + # measure current + current_line = self.multimeter.measure_current(sample_rate=SAMPLE_RATE, + sample_num=SAMPLE_NUM, + max_value=MAX_VALUE) + self.multimeter.draw_graph(current_line, SAMPLE_RATE, + "force_%s_sleep_current_%s" % (sleep_mode, i), Y_AXIS_LABEL) + NativeLog.add_trace_critical("[ForceSleep][current_measure] force_%s_%d"% (sleep_mode,i)) + + # self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP,GPIO_EDGE_DELAY)) + # self.check_response("SSC2", "+GPIO_SET:OK") + # self.serial_write_line("SSC1", "reboot") + # self.check_response("SSC1", "ready!!!") + self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_CHIP_RESET, GPIO_CHIP_RESET_DELAY)) + self.check_response("SSC2", "+GPIO_SET:OK") + if self.check_response("SSC1", "ready!!!") is False: + result = False + time.sleep(1) + return result + + def force_sleep_illegal_enter(self): + result = True + # choose sleep mode + + self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) + time.sleep(LIGHT_SLEEP_WAKEUP_DELAY) + self.serial_write_line("SSC1", "op -S -o 2") + if self.check_response("SSC1", "+MODE:OK") is False: + result = False + self.check_response("SSC2", "+GPIO_SET:OK") + + # set sleep mode + self.serial_write_line("SSC1", "fsleep -D -d 0") + if self.check_response("SSC1", "ready!!!", timeout=10) is False: + result = False + time.sleep(5) + return result + + def force_sleep_stable_test(self): + result = True + # choose sleep mode + + self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) + time.sleep(LIGHT_SLEEP_WAKEUP_DELAY) + self.serial_write_line("SSC1", "fsleep -L") + if self.check_response("SSC1", "+MODE:OK") is False: + result = False + self.check_response("SSC2", "+GPIO_SET:OK") + + time.sleep(3600) + self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_CHIP_RESET, GPIO_CHIP_RESET_DELAY)) + time.sleep(5) + return result + + def cleanup(self): + self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) + time.sleep(LIGHT_SLEEP_WAKEUP_DELAY) + self.serial_write_line("SSC1", "reboot") + self.check_response("SSC1", "ready!!!") + self.check_response("SSC2", "+GPIO_SET:OK") + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.serial_write_line("SSC2", "sta -D") + self.check_response("SSC2", "+QAP") + self.serial_write_line("SSC1", "sta -D") + self.check_response("SSC1", "+QAP") + try: + test_mode = self.test_mode + test_count = self.test_count + sleep_mode = self.sleep_mode + except StandardError, e: + return + + # set gpio to input on sleep target + self.serial_write_line("SSC1", "gpio -G -p %d" % GPIO_WAKE_UP) + self.check_response("SSC1", "+GPIO_GET") + self.serial_write_line("SSC1", "gpio -G -p %d" % GPIO_CHIP_RESET) + self.check_response("SSC1", "+GPIO_GET") + + if test_mode == "boundary_test": + for i in range(test_count): + result = self.sleep_time_boundary_test() + pass + elif test_mode == "measure_current": + for j in range(test_count): + for mode in sleep_mode: + result = self.force_sleep_current_measure(mode) + pass + elif test_mode == "illegal_enter": + for i in range(test_count): + result = self.force_sleep_illegal_enter() + pass + elif test_mode == "stable_test": + for i in range(test_count): + result = self.force_sleep_stable_test() + pass + pass + + +def main(): + pass + + +if __name__ == '__main__': + main() diff --git a/components/test/TestCaseScript/SleepMode/__init__.py b/components/test/TestCaseScript/SleepMode/__init__.py new file mode 100755 index 0000000000..fcd54657f3 --- /dev/null +++ b/components/test/TestCaseScript/SleepMode/__init__.py @@ -0,0 +1 @@ +__all__ = ["AutoSleep", "DeepSleep", "ForceSleep"] diff --git a/components/test/TestCaseScript/StableTest/StableCase1.py b/components/test/TestCaseScript/StableTest/StableCase1.py new file mode 100755 index 0000000000..2554c1499b --- /dev/null +++ b/components/test/TestCaseScript/StableTest/StableCase1.py @@ -0,0 +1,160 @@ +import time +import random +import threading + +from TCAction import TCActionBase +from NativeLog import NativeLog + + +class StableCase1(TCActionBase.CommonTCActionBase): + + def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + self.exit_event = threading.Event() + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + pass + + def check_wifi_status(self, data): + if data.find("+JAP:DISCONNECTED") != -1: + self.exit_event.set() + NativeLog.add_trace_critical("[Wifi] Disconnected") + pass + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + try: + # configurable params + # target role + target_role = self.target_role + # enable tcp send/recv + tcp_enable = self.tcp_enable + # enable udp send/recv + udp_enable = self.udp_enable + # enable ping + ping_enable = self.ping_enable + # delay range + delay_range = self.delay_range + # test time in hours + test_time = self.test_time * 3600 + # configurable params + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for TCPTransparent script, error is %s" % e) + raise StandardError("Error configuration") + + if target_role == "AP": + pc_ip = "" + target_ip = "" + elif target_role == "STA": + pc_ip = "" + target_ip = "" + else: + raise StandardError("target role only support AP or STA") + + # step 1, create UDP socket and TCP server + checker_stings = ["R SSC1 A :BIND:(\d+),OK"] + test_action_string = ["SSC SSC1 soc -B -t UDP -p "] + fail_string = "Fail, Fail to create UDP socket" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["R SSC1 A :BIND:(\d+),OK"] + test_action_string = ["SSC SSC1 soc -B -t TCP -p "] + fail_string = "Fail, Fail to create tcp server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["R SSC1 RE LISTEN:(\d+),OK"] + test_action_string = ["SSC SSC1 soc -L -s "] + fail_string = "Fail, Fail to listen" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step 2, PC connect to 8266 tcp server, PC create UDP socket + checker_stings = ["R SOC_COM C OK"] + test_action_string = ["SOC SOC1 BIND %s" % pc_ip] + fail_string = "Fail, Fail to create udp socket on PC" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["P SSC1 A :ACCEPT:(\d+),\d+", "P SOC_COM C OK"] + test_action_string = ["SOC SOC2 CONNECT %s 0 %s" % (target_ip, pc_ip)] + fail_string = "Fail, Fail to create tcp socket on PC" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + start_time = time.time() + total_test_count = ping_fail_count = tcp_fail_count = udp_fail_count = 0 + + # step 3, start do tcp/udp/ping + while time.time() - start_time < test_time and self.exit_event.isSet() is False: + total_test_count += 1 + if ping_enable is True: + # do ping + checker_stings = ["P PC_COM RE \+PING:\d+ms"] + test_action_string = ["PING %s -n 1 -w 1000" % target_ip] + fail_string = "Fail, Fail to ping target" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + ping_fail_count += 1 + NativeLog.add_prompt_trace("[ping fail] fail/total = %s/%s" + % (ping_fail_count, total_test_count)) + pass + + data_len = random.randint(1, 1460) + + if tcp_enable is True: + # do tcp send/recv + checker_stings = ["P SSC1 SL +%s" % data_len, "P SOC2 RL %s" % data_len] + test_action_string = ["SSC SSC1 soc -S -s -l %s" % data_len, + "SOC SOC2 SEND %s" % data_len] + fail_string = "Fail, Fail to send/recv tcp" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + tcp_fail_count += 1 + NativeLog.add_prompt_trace("[tcp fail] fail/total = %s/%s" + % (tcp_fail_count, total_test_count)) + # tcp fail, break + self.exit_event.set() + pass + + if udp_enable is True: + # do udp send/recv + checker_stings = ["P SSC1 SL +%s" % data_len, "P SOC1 RL %s" % data_len] + test_action_string = ["SSC SSC1 soc -S -s " + "-i %s -p -l %s" % (pc_ip, data_len), + "SOC SOC1 SENDTO %s %s" % (data_len, target_ip)] + fail_string = "Fail, Fail to sendto/recvfrom udp" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, check_time=20) is False: + udp_fail_count += 1 + NativeLog.add_prompt_trace("[udp fail] fail/total = %s/%s" + % (udp_fail_count, total_test_count)) + pass + + # sleep + time.sleep(random.randint(delay_range[0], delay_range[1])) + pass + + # finally, execute done + if self.exit_event.isSet() is False: + self.result_cntx.set_result("Succeed") + + def result_check(self, port_name, data): + self.result_cntx.append_data(port_name, data) + if port_name != "SOC1" and port_name != "SOC2": + # socket received data do not need to be logged + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + if port_name == "SSC1": + self.check_wifi_status(data) + + +def main(): + pass + +if __name__ == '__main__': + main() diff --git a/components/test/TestCaseScript/StableTest/__init__.py b/components/test/TestCaseScript/StableTest/__init__.py new file mode 100755 index 0000000000..be905f816c --- /dev/null +++ b/components/test/TestCaseScript/StableTest/__init__.py @@ -0,0 +1 @@ +__all__ = ["StableCase1"] diff --git a/components/test/TestCaseScript/TCPIPStress/ARPStress.py b/components/test/TestCaseScript/TCPIPStress/ARPStress.py new file mode 100755 index 0000000000..38dcb8fd8b --- /dev/null +++ b/components/test/TestCaseScript/TCPIPStress/ARPStress.py @@ -0,0 +1,121 @@ +import time + +from NativeLog import NativeLog +from TCAction import TCActionBase +from comm.NIC import Adapter + +WARNING_COUNT = 5 + + +class ARPStress(TCActionBase.CommonTCActionBase): + + def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + self.adapter = None + self.target_mode = "STA" + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + pass + + def cleanup(self): + self.adapter.close() + del self.adapter + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + try: + # configurable params + test_time = self.test_time * 60 + # test frequency min should be 0.1s, otherwise reply could be missed + test_freq = self.test_freq if self.test_freq > 0.1 else 0.1 + # test softAP or sta + target_mode = self.target_mode + # configurable params + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for ARPStress script, error is %s" % e) + raise StandardError("Error configuration") + + # get parameters + if target_mode == "STA": + target_ip = self.get_parameter("target_ip") + target_mac = self.get_parameter("target_mac") + pc_mac = self.get_parameter("pc_nic_mac") + pc_nic_name = self.get_parameter("pc_nic") + elif target_mode == "SoftAP": + target_ip = self.get_parameter("target_ap_ip") + target_mac = self.get_parameter("target_ap_mac") + pc_mac = self.get_parameter("pc_wifi_nic_mac") + pc_nic_name = self.get_parameter("pc_wifi_nic") + else: + raise StandardError("Unsupported target mode: %s" % target_mode) + + time_start = time.time() + + # open device + self.adapter = Adapter.Adapter(pc_nic_name, "capture+send") + ret = self.adapter.set_filter("arp and ether src %s and ether dst %s" % (target_mac, pc_mac)) + if ret != "LIBPCAP_SUCCEED": + NativeLog.add_trace_critical("ARP Stress test error: %s" % ret) + return + + ret = self.adapter.start_capture() + if ret != "LIBPCAP_SUCCEED": + NativeLog.add_trace_critical("ARP Stress test error: %s" % ret) + return + + arp_pdu = self.adapter.create_pdu("ARP", self.adapter.create_payload(), + arp_op_code="request", arp_target_proto_addr=target_ip, + ethernet_dst_addr="ff:ff:ff:ff:ff:ff") + + data = arp_pdu.to_bytes() + + total_test_count = total_fail_count = successive_fail_count = most_successive_fail_count = 0 + + while (time.time() - time_start) < test_time: + # send arp req + ret = self.adapter.ether_send(data) + if ret != "LIBNET_SUCCEED": + NativeLog.add_prompt_trace("libnet send fail, %s" % ret) + continue + total_test_count += 1 + # wait for reply + time.sleep(test_freq) + # should get one arp reply + pdu_list = self.adapter.get_packets() + + if len(pdu_list) == 0: + # failed to get arp reply + total_fail_count += 1 + successive_fail_count += 1 + if successive_fail_count > WARNING_COUNT: + NativeLog.add_trace_critical("ARP Fail: successive fail %u times, total tested %u times" + % (successive_fail_count, total_test_count)) + else: + most_successive_fail_count = most_successive_fail_count \ + if most_successive_fail_count > successive_fail_count \ + else successive_fail_count + successive_fail_count = 0 + pass + NativeLog.add_trace_critical("ARP stress test, total %s times, failed %s times, most successive fail count %s" + % (total_test_count, total_fail_count, most_successive_fail_count)) + self.result_cntx.set_result("Succeed") + + # finally, execute done + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + +if __name__ == '__main__': + main() diff --git a/components/test/TestCaseScript/TCPIPStress/PingStress.py b/components/test/TestCaseScript/TCPIPStress/PingStress.py new file mode 100755 index 0000000000..71ab91ce5a --- /dev/null +++ b/components/test/TestCaseScript/TCPIPStress/PingStress.py @@ -0,0 +1,122 @@ +import time + +from NativeLog import NativeLog +from TCAction import TCActionBase +from comm.NIC import Adapter + +WARNING_COUNT = 2 + + +class PingStress(TCActionBase.CommonTCActionBase): + + def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + self.adapter = None + self.target_mode = "STA" + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + pass + + def cleanup(self): + self.adapter.close() + del self.adapter + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + try: + # configurable params + test_time = self.test_time * 60 + # ping data len + ping_len = self.ping_len + # test frequency min should be 0.1s, otherwise reply could be missed + test_freq = self.test_freq if self.test_freq > 0.1 else 0.1 + # target mode + target_mode = self.target_mode + # configurable params + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for PingStress script, error is %s" % e) + raise StandardError("Error configuration") + + if target_mode == "STA": + target_ip = self.get_parameter("target_ip") + target_mac = self.get_parameter("target_mac") + pc_mac = self.get_parameter("pc_nic_mac") + pc_nic_name = self.get_parameter("pc_nic") + elif target_mode == "SoftAP": + target_ip = self.get_parameter("target_ap_ip") + target_mac = self.get_parameter("target_ap_mac") + pc_mac = self.get_parameter("pc_wifi_nic_mac") + pc_nic_name = self.get_parameter("pc_wifi_nic") + else: + raise StandardError("Unsupported target mode: %s" % target_mode) + + time_start = time.time() + # open device + self.adapter = Adapter.Adapter(pc_nic_name, "capture+send") + + ret = self.adapter.set_filter("icmp[icmpcode]=icmp-echoreply and ether src %s and ether dst %s" + % (target_mac, pc_mac)) + if ret != "LIBPCAP_SUCCEED": + NativeLog.add_trace_critical("PING Stress test error: %s" % ret) + return + + ret = self.adapter.start_capture() + if ret != "LIBPCAP_SUCCEED": + NativeLog.add_trace_critical("PING Stress test error: %s" % ret) + return + + total_test_count = total_fail_count = successive_fail_count = most_successive_fail_count = 0 + + while (time.time() - time_start) < test_time: + + ping_pdu = self.adapter.create_pdu("ICMP", self.adapter.create_payload("A" * ping_len), + icmp_type="echo-request", ipv4_protocol="ICMP", + ipv4_dst_ip=target_ip, ethernet_dst_addr=target_mac) + # send ping req + ret = self.adapter.ether_send(ping_pdu.to_bytes()) + if ret != "LIBNET_SUCCEED": + NativeLog.add_prompt_trace("libnet send fail, %s" % ret) + continue + total_test_count += 1 + # wait for reply + time.sleep(test_freq) + # should get one ping reply + pdu_list = self.adapter.get_packets() + + if len(pdu_list) == 0: + # failed to get ping reply + total_fail_count += 1 + successive_fail_count += 1 + if successive_fail_count > WARNING_COUNT: + NativeLog.add_trace_critical("Ping Fail: successive fail %u times, total tested %u times" + % (successive_fail_count, total_test_count)) + pass + else: + most_successive_fail_count = most_successive_fail_count \ + if most_successive_fail_count > successive_fail_count \ + else successive_fail_count + successive_fail_count = 0 + pass + pass + NativeLog.add_trace_critical("Ping stress test, total %s times, failed %s times, most successive fail count %s" + % (total_test_count, total_fail_count, most_successive_fail_count)) + self.result_cntx.set_result("Succeed") + # finally, execute done + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + +if __name__ == '__main__': + main() diff --git a/components/test/TestCaseScript/TCPIPStress/__init__.py b/components/test/TestCaseScript/TCPIPStress/__init__.py new file mode 100755 index 0000000000..25ae689179 --- /dev/null +++ b/components/test/TestCaseScript/TCPIPStress/__init__.py @@ -0,0 +1 @@ +__all__ = ["ARPStress", "PingStress"] diff --git a/components/test/TestCaseScript/TCPStress/TCPAP4STA.py b/components/test/TestCaseScript/TCPStress/TCPAP4STA.py new file mode 100755 index 0000000000..95be6fbe4f --- /dev/null +++ b/components/test/TestCaseScript/TCPStress/TCPAP4STA.py @@ -0,0 +1,168 @@ +from TCAction import TCActionBase +from NativeLog import NativeLog +import copy +import time +import random +import string + + +class TCPAP4STAResultCheckCntx(TCActionBase.ResultCheckContext): + + def __init__(self, test_action, test_env, name): + TCActionBase.ResultCheckContext.__init__(self, test_action, test_env, name) + self.failed_port = [] + pass + + def run(self): + + while True: + exit_flag = self.wait_exit_event(1) + # force exit + if exit_flag is True: + break + try: + self.lock_data() + temp_cache = copy.deepcopy(self.data_cache) + self.data_cache = [] + finally: + self.unlock_data() + + for _cache in temp_cache: + _data = _cache[1] + if _data.find("user_test_tcpclient_recon_cb") != -1 or _data.find("discon") != -1 \ + or _data.find("No heap available") != -1: + self.failed_port.append(_cache[0]) + NativeLog.add_trace_critical("TCPAP4STA failed, failed on %s" % _cache[0]) + pass + if len(self.failed_port) != 0: + # disconnect happen + break + + def get_test_results(self): + return self.failed_port + + +class TCPAP4STA(TCActionBase.CommonTCActionBase): + + def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + pass + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + try: + # configurable params + send_len = self.send_len + # test count + test_count = self.test_count + # server port + server_port = self.server_port + # ap ip + ap_ip = self.ap_ip + # server echo + server_echo = self.server_echo + # station number + sta_number = self.sta_number + # pass standard + pass_standard = self.pass_standard + # send delay + send_delay = self.send_delay + # configurable params + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for TCPTransparent script, error is %s" % e) + raise StandardError("Error configuration") + + # step0 reboot + checker_stings = [] + test_action_string = [] + + for i in range(sta_number+1): + checker_stings.append("P SSC%d C !!!ready!!!" % (i+1)) + test_action_string.append("SSCC SSC%d reboot" % (i+1)) + + fail_string = "Fail, Fail to reboot" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step1 set ap on SSC1, create server + ssid = "".join([random.choice(string.lowercase) for m in range(10)]) + password = "".join([random.choice(string.lowercase) for m in range(10)]) + checker_stings = ["R SSC1 C dhcp%20server%20start"] + test_action_string = ["SSCC SSC1 ap -S -s %s -p %s -n 10 -t 0 -m 8" % (ssid, password)] + fail_string = "Fail, Fail set ap" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["R SSC1 C server%20starts%20at%20port"] + if server_echo is True: + test_action_string = ["SSCC SSC1 tcp -S -p %s -b 1" % server_port] + else: + test_action_string = ["SSCC SSC1 tcp -S -p %s" % server_port] + fail_string = "Fail, Fail create server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step 2, 4 SSC target(SSC2 - SSC5) join SSC1 soft AP + checker_stings = [] + test_action_string = [] + + for i in range(sta_number): + checker_stings.append("P SSC%d C ip C mask C gw C get%%20ip%%20of" % (i+2)) + test_action_string.append("SSCC SSC%d ap -C -s %s -p %s" % (i+2, ssid, password)) + + fail_string = "Fail, Fail to connect to server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + start_time = time.time() + + # step 3, create client on SSC2 - SSC5 + checker_stings = [] + test_action_string = [] + + for i in range(sta_number): + checker_stings.append("P SSC%d C tcp%%20client%%20connect%%20with%%20server" % (i+2)) + test_action_string.append("SSCC SSC%d tcp -W -i %s -p %s -c %s -n 1 -l %s -d %d" + % ((i+2), ap_ip, server_port, test_count, send_len, send_delay)) + + fail_string = "Fail, Fail to connect to server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # switch to new result context + self.result_cntx.stop_thread() + self.result_cntx.join() + self.result_cntx = TCPAP4STAResultCheckCntx(self, self.test_env, self.tc_name) + self.result_cntx.start() + + self.result_cntx.join() + + failed_port = self.result_cntx.get_test_results() + if (time.time() - start_time) > pass_standard: + self.result_cntx.set_result("Succeed") + else: + self.result_cntx.set_result("Failed") + NativeLog.add_trace_critical("Failed port: %s" % failed_port) + + # finally, execute done + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + +if __name__ == '__main__': + main() + diff --git a/components/test/TestCaseScript/TCPStress/TCPAPNSTA.py b/components/test/TestCaseScript/TCPStress/TCPAPNSTA.py new file mode 100755 index 0000000000..6c160a9a00 --- /dev/null +++ b/components/test/TestCaseScript/TCPStress/TCPAPNSTA.py @@ -0,0 +1,209 @@ +from TCAction import TCActionBase +from NativeLog import NativeLog +import time +import random +import string + + +TEST_COUNT_ONE_ROUND = 500 + + +class TCPAPNSTA(TCActionBase.CommonTCActionBase): + + def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + pass + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + try: + # configurable params + send_len = self.send_len + # test count + test_count = self.test_count + # server port + server_port = self.server_port + # ap ip + ap_ip = self.ap_ip + # server echo + server_echo = self.server_echo + # station number + sta_number = self.sta_number + # pass standard + pass_standard = self.pass_standard + # send delay + send_delay = self.send_delay + # configurable params + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for TCPTransparent script, error is %s" % e) + raise StandardError("Error configuration") + + # step0 reboot + checker_stings = [] + test_action_string = [] + + for i in range(sta_number+1): + checker_stings.append("P SSC%d C !!!ready!!!" % (i+1)) + test_action_string.append("SSCC SSC%d reboot" % (i+1)) + + fail_string = "Fail, Fail to reboot" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step1 set ap on SSC1, create server + checker_stings = ["R SSC1 C +MODE:OK"] + test_action_string = ["SSCC SSC1 op -S -o 2"] + fail_string = "Fail, Fail set mode" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + ssid = "".join([random.choice(string.lowercase) for m in range(10)]) + password = "".join([random.choice(string.lowercase) for m in range(10)]) + checker_stings = ["R SSC1 C +SAP:OK"] + test_action_string = ["SSCC SSC1 ap -S -s %s -p %s -n 10 -t 0 -m 8" % (ssid, password)] + fail_string = "Fail, Fail set ap" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["R SSC1 A :BIND:(\d+),OK"] + test_action_string = ["SSCC SSC1 soc -B -t TCP -p %s" % server_port] + fail_string = "Fail, Fail create server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["R SSC1 RE LISTEN:(\d+),OK"] + test_action_string = ["SSCC SSC1 soc -L -s "] + fail_string = "Fail, Fail create server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step 2, 8 SSC target(SSC2 - SSC9) join SSC1 soft AP + checker_stings = [] + test_action_string = [] + for i in range(sta_number): + checker_stings.append("P SSC%d C +MODE:OK" % (i+2)) + test_action_string.append("SSCC SSC%d op -S -o 1" % (i+2)) + fail_string = "Fail, Fail set mode" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = [] + test_action_string = [] + for i in range(sta_number): + checker_stings.append("P SSC%d C +JAP:CONNECTED,%s" % (i+2, ssid)) + test_action_string.append("SSCC SSC%d ap -C -s %s -p %s" % (i+2, ssid, password)) + fail_string = "Fail, Fail to connect to server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + start_time = time.time() + + # step 3, create client on SSC2 - SSC9 + checker_stings = [] + test_action_string = [] + for i in range(sta_number): + checker_stings.append("P SSC%d A :BIND:(\d+),OK" % (i+2, i+2)) + test_action_string.append("SSCC SSC%d soc -B -t TCP" % (i+2)) + fail_string = "Fail, Fail to connect to server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + for i in range(sta_number): + checker_stings = ["P SSC%d RE CONNECT:(\d+),OK" % (i+2), + "P SSC1 A :ACCEPT:(\d+),.+" % (i+2)] + test_action_string = ["SSCC SSC%d soc -C -s -i %s -p %s" % + (i+2, i+2, ap_ip, server_port)] + fail_string = "Fail, Fail to connect to server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step 4, do send/recv + while test_count > 0: + _tmp_count = TEST_COUNT_ONE_ROUND if test_count - TEST_COUNT_ONE_ROUND > 0 else test_count + test_count -= TEST_COUNT_ONE_ROUND + + checker_stings = [] + test_action_string = [] + for i in range(sta_number): + checker_stings.append("P SSC%d RE \+SEND:\d+,OK NC CLOSED" % (i+2)) + test_action_string.append("SSC SSC%d soc -S -s -l %d -n %d -j %d" % + (i+2, i+2, send_len, _tmp_count, send_delay)) + if server_echo is True: + test_action_string.append("SSC SSC1 soc -S -s -l %d -n %d -j %d" % + (i+2, send_len, _tmp_count, send_delay)) + checker_stings.append("P SSC1 RE \"\+SEND:%%%%s,OK\"%%%%() NC CLOSED)" % + (i+2)) + + fail_string = "Fail, Failed to send/recv data" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, + check_freq=1, check_time=300) is False: + break + pass + + if (time.time() - start_time) > pass_standard: + self.result_cntx.set_result("Succeed") + else: + checker_stings = [] + test_action_string = [] + for i in range(sta_number + 1): + checker_stings.append("P SSC%d C CLOSEALL" % (i + 1)) + test_action_string.append("SSCC SSC%d soc -T" % (i + 1)) + fail_string = "Fail, Fail to close socket" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + server_port = random.randint(20000, 30000) + checker_stings = ["R SSC1 A :BIND:(\d+),OK"] + test_action_string = ["SSCC SSC1 soc -B -t TCP -p %s" % server_port] + fail_string = "Fail, Fail to bind socket" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["R SSC1 RE LISTEN:(\d+),OK"] + test_action_string = ["SSCC SSC1 soc -L -s "] + fail_string = "Fail, Fail to listen" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = [] + test_action_string = [] + for i in range(sta_number): + checker_stings.append("P SSC%d A :BIND:(\d+),OK" % (i + 2, i + 2)) + test_action_string.append("SSCC SSC%d soc -B -t TCP" % (i + 2)) + fail_string = "Fail, Fail to connect to server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + for i in range(sta_number): + checker_stings = ["P SSC%d RE CONNECT:(\d+),OK" % (i + 2), + "P SSC1 A :ACCEPT:(\d+),.+" % (i + 2)] + test_action_string = ["SSCC SSC%d soc -C -s -i %s -p %s" % + (i + 2, i + 2, ap_ip, server_port)] + fail_string = "Fail, Fail to connect to server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + self.result_cntx.set_result("Failed") + + # finally, execute done + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + +if __name__ == '__main__': + main() + diff --git a/components/test/TestCaseScript/TCPStress/TCPConnStressTC.py b/components/test/TestCaseScript/TCPStress/TCPConnStressTC.py new file mode 100755 index 0000000000..b04ede6acb --- /dev/null +++ b/components/test/TestCaseScript/TCPStress/TCPConnStressTC.py @@ -0,0 +1,363 @@ +import random +import re +import sys +import threading +import time + +import TCPConnUtility +from NativeLog import NativeLog +from TCAction import TCActionBase + +reload(sys) +sys.setdefaultencoding('iso-8859-1') # # use encoding that with 1 Byte length and contain 256 chars + + +DEFAULT_MAX_CONN_ALLOWED = 5 + + +# complicated design because I want to make this script applied for all TCP connect/close test scenarios +# basic flow: try to create max connections, send/recv data if possible, close all connections +# connect: +# 1. find available (target_link_id, socket_id) list, +# notice that target_link_id maybe not correct if PC is client +# (during that time, some link may timeout and got disconnected from FIN_WAIT or other state) +# 2. choose one method from method set, try to connect +# 3. update state table: a)check result and destination state, b)find real target_link_id, c)update +# send/recv data: +# 1. find channels that are possible to send data on all connections +# 2. send data on possible channels +# disconnect: +# 1. find available connections +# 2. choose one method from disconnect set, try to disconnect +# 3. update state table (phase 1) +# async process: +# listen on AT UART port, record all "x,CONNECT" and "x,CLOSE" command +# for "x,CONNECT", append them to self.target_link_id_list, used when need to find real target_link_id +# for "x,CLOSE", update state table (phase 2), if matching connection is pending on wait state, +# close them and remove from state table +class TCPConnStressTC(TCActionBase.CommonTCActionBase): + + def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + self.__at1_buff = "" + self.max_conn_allowed = test_env.get_variable_by_name("max_conn") + self.enable_log = True + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + + # connection_state_dict: {target_link_id: [socket_id, target_state, socket_state, is_closed]} + # is_closed: found "x,CLOSE" in AT UART port + self.connection_state_dict = dict(zip(range(self.max_conn_allowed), [None] * self.max_conn_allowed)) + self.created_link_id_list = [] + + self.__available_soc_id = range(2, 2+self.max_conn_allowed) + self.__available_link_id = range(self.max_conn_allowed) + + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + self.utility = TCPConnUtility.TCPConnUtility(self) + self.state_lock = threading.Lock() + self.link_id_lock = threading.Lock() + self.available_id_lock = threading.Lock() + pass + + def __add_log(self, log_str): + if self.enable_log is True: + NativeLog.add_trace_info(log_str) + + def __get_created_target_link_id(self): + self.link_id_lock.acquire() + try: + link_id = self.created_link_id_list[-1] + self.created_link_id_list = [] + finally: + self.link_id_lock.release() + return link_id + pass + + def __set_created_target_link_id(self, link_id): + self.link_id_lock.acquire() + try: + self.created_link_id_list.append(link_id) + finally: + self.link_id_lock.release() + pass + + def __find_channel_list(self): + channel_list = [] # # [(socket_id, able_to_send, link_id, able_to_send), ] + self.state_lock.acquire() + try: + for link_id in self.connection_state_dict: + state = self.connection_state_dict[link_id] + if state is not None: + channel_list.append([state[0], self.utility.is_able_to_send_data(state[2]), + link_id, self.utility.is_able_to_send_data(state[1])]) + finally: + self.state_lock.release() + return channel_list + pass + + def __established_connection_list(self): + conn_list = [] # # [(socket_id, link_id), ] + self.state_lock.acquire() + try: + for link_id in self.connection_state_dict: + state = self.connection_state_dict[link_id] + if state is not None: + if self.utility.is_established_connection([state[1], state[2]]) is True: + conn_list.append([state[0], link_id]) + finally: + self.state_lock.release() + return conn_list + pass + + # find free socket_id, target_link_id pair + def __get_available_id_list(self): + self.available_id_lock.acquire() + try: + id_list = zip(self.__available_soc_id, self.__available_link_id) + finally: + self.available_id_lock.release() + return id_list + pass + + def __update_available_id_list(self, soc_id, link_id, action="ADD"): + self.available_id_lock.acquire() + try: + if action == "ADD": + self.__available_link_id.append(link_id) + self.__available_soc_id.append(soc_id) + self.__add_log("[AVAILABLE ID]soc %d link %d is available" % (soc_id, link_id)) + elif action == "REMOVE": + self.__available_link_id.remove(link_id) + self.__available_soc_id.remove(soc_id) + self.__add_log("[AVAILABLE ID]soc %d link %d is used" % (soc_id, link_id)) + finally: + self.available_id_lock.release() + + def __update_connection_state_item(self, target_link_id, socket_id=None, + target_state=None, socket_state=None, is_closed=None): + self.state_lock.acquire() + try: + state = self.connection_state_dict[target_link_id] + if state is None: + state = [None] * 4 + if socket_id is not None: + state[0] = socket_id + if target_state is not None: + state[1] = target_state + if socket_state is not None: + state[2] = socket_state + if is_closed is not None: + state[3] = is_closed + + # remove closed connections + closed = self.utility.is_closed_state(state[1]) and (state[3] is True) + if closed is True: + self.__update_available_id_list(state[0], target_link_id) + state = None + # if new connection created + if self.connection_state_dict[target_link_id] is None: + created = self.utility.is_created_state(state[1]) + if created is True: + self.__update_available_id_list(state[0], target_link_id, "REMOVE") + else: + # connection did not created, do not add them to connection state table + state = None + + # set new connection_state + self.connection_state_dict[target_link_id] = state + self.__add_log("[STATE] link id is %d, state is %s" % (target_link_id, state)) + except StandardError, e: + pass + finally: + self.state_lock.release() + pass + + # update state table: if result is false, return, if result is true: + # for connect, find real link id, update table according to destination state + # for disconnect, if target in SOC_CLOSE_STATE && catch "x,CLOSE" from AT, remove the item + def update_connection_state_table(self, conn_id, destination_state=None): + if isinstance(conn_id, list) is True or isinstance(conn_id, tuple) is True: + socket_id = conn_id[0] + try: + target_link_id = self.__get_created_target_link_id() + except IndexError: + target_link_id = conn_id[1] + self.__add_log("[STATE]fail to get link id, state is %s, %s" + % (destination_state[0], destination_state[1])) + self.__update_connection_state_item(target_link_id, socket_id, + destination_state[0], destination_state[1]) + pass + else: # # called when recv CLOSED + target_link_id = conn_id + self.__update_connection_state_item(target_link_id, is_closed=True) + pass + pass + + def process_at_data(self, data): + pos1 = 0 + pos2 = 0 + connect = re.compile("\d,CONNECT\r\n") + close = re.compile("\d,CLOSED\r\n") + connect_match = connect.findall(data) + close_match = close.findall(data) + close = re.compile("\d,CONNECT FAIL\r\n") + close_match += close.findall(data) + if len(connect_match) != 0: + pos1 = data.find(connect_match[-1]) + 9 + # append last connected link id + self.__set_created_target_link_id(int(connect_match[-1][:1])) + pass + if len(close_match) != 0: + pos2 = data.find(close_match[-1]) + 7 + # update for all closed links + for close_str in close_match: + self.update_connection_state_table(int(close_str[:1])) + pass + pos = pos1 if pos1 > pos2 else pos2 + + return data[pos:] + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + # configurable params + # mandatory params + try: + connect_method_set = self.connect_method_set + test_count = self.test_count + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for TCPConnSingleMode script, error is %s" % e) + raise StandardError("Error configuration") + # optional params + try: + disconn_method_set = self.disconn_method_set + except StandardError: + disconn_method_set = ["D_05"] + pass + try: + delay = self.delay + except StandardError: + delay = 0 + pass + try: + check_data_len = self.check_data_len + except StandardError: + check_data_len = [0, 0] + pass + if isinstance(check_data_len, list) is False: + check_data_len = [check_data_len] * 2 + # configurable params + + # step1 use to create server on both PC and target side + checker_stings = ["SOCP SOC_COM L OK", "ATP AT1 L OK"] + test_action_string = ["SOC SOC1 LISTEN ", "ATC AT1 CIPSERVER 1 "] + fail_string = "Fail, Fail on create server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + for tested_count in xrange(test_count): + # step2 do connect + available_id_list = self.__get_available_id_list() + + for conn_id in available_id_list: + connect_method = random.choice(connect_method_set) + # ret, destination_state = self.utility.execute_tcp_method(connect_method, conn_id) + try: + self.__add_log("[ACTION]connect method is %s, connect id is %s" + % (connect_method, conn_id)) + ret, destination_state = self.utility.execute_tcp_method(connect_method, conn_id) + except StandardError, e: + NativeLog.add_trace_critical("Error in connect, error is %s" % e) + raise StandardError("Exception happen when connect") + if ret is False: + # connect fail, should terminate TC and mark as fail + return + else: + # succeed, append to table + self.update_connection_state_table(conn_id, destination_state) + if delay != 0: + time.sleep(delay) + + # step 3 send/recv test data + # # [(socket_id, able_to_send, link_id, able_to_send)] + self.__add_log("[ACTION]SEND/RECV data") + channel_list = self.__find_channel_list() + for channel in channel_list: + _check_data_len = [0, 0] + if channel[1] is True: + _check_data_len[0] = check_data_len[0] + if channel[3] is True: + _check_data_len[1] = check_data_len[1] + ret = self.utility.send_test_data(channel[0], + channel[2], + _check_data_len) + if ret is False: + # send/recv fail, should terminate TC and mark as fail + return + if delay != 0: + time.sleep(delay) + + # step 4 close all established connections + # (socket_id, link_id) + conn_list = self.__established_connection_list() + for conn_id in conn_list: + disconn_method = random.choice(disconn_method_set) + try: + self.__add_log("[ACTION]disconnect method is %s, connect id is %s" + % (disconn_method, conn_id)) + ret, destination_state = self.utility.execute_tcp_method(disconn_method, conn_id) + except StandardError, e: + NativeLog.add_trace_critical("Error in disconnect, error is %s" % e) + raise StandardError("Exception happen when disconnect") + if ret is False: + # connect fail, should terminate TC and mark as fail + return + else: + # succeed, append to table + self.update_connection_state_table(conn_id, destination_state) + if delay != 0: + time.sleep(delay) + + # finally, execute done + self.result_cntx.set_result("Succeed") + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + # find "x,CONNECT" and "x,CLOSE" + if port_name.find("AT") != -1: + self.__at1_buff += data + self.__at1_buff = self.process_at_data(self.__at1_buff) + + +def main(): + at1_buff = "" + pos1 = 0 + pos2 = 0 + data = "dafgajglajdfg0,CLOSEjdalghalksdg1,CONNECT\r\n\r\n3,CONNECT4,CLOSEadfaasdf" + at1_buff += data + connect = re.compile("\d,CONNECT") + close = re.compile("\d,CLOSE") + connect_match = connect.findall(at1_buff) + close_match = close.findall(at1_buff) + if len(connect_match) != 0: + pos1 = at1_buff.find(connect_match[-1]) + 9 + pass + if len(close_match) != 0: + pos2 = at1_buff.find(close_match[-1]) + 7 + pass + pos = pos1 if pos1 > pos2 else pos2 + + at1_buff = at1_buff[pos:] + + pass + +if __name__ == '__main__': + main() + diff --git a/components/test/TestCaseScript/TCPStress/TCPConnUtility.py b/components/test/TestCaseScript/TCPStress/TCPConnUtility.py new file mode 100755 index 0000000000..3059369010 --- /dev/null +++ b/components/test/TestCaseScript/TCPStress/TCPConnUtility.py @@ -0,0 +1,273 @@ +from NativeLog import NativeLog + +# make sure target do not listen on this port +ERROR_PORT = 23333 + + +def unused_param(param): + return param + + +class TCPUtilError(StandardError): + pass + + +class TCPConnUtility(object): + METHOD_RESULT = {"C_01": ("ESTABLISHED", "ESTABLISHED"), # target TCP peer state, PC TCP peer state + "C_02": ("SYNC_SENT", "CLOSED"), + "C_03": ("CLOSED", "CLOSED"), + "C_04": ("SYN_RCVD", "ESTABLISHED"), + "C_05": ("ESTABLISHED", "ESTABLISHED"), + "C_06": ("CLOSED", "CLOSED"), + "C_07": ("CLOSED", "CLOSED"), + "C_08": ("CLOSED", "CLOSED"), + "D_01": ("TIME_WAIT", "CLOSED"), + "D_02": ("TIME_WAIT", "TIME_WAIT"), + "D_03": ("FIN_WAIT_2", "CLOSE_WAIT"), + "D_04": ("FIN_WAIT_1", "CLOSE_WAIT"), + "D_05": ("CLOSED", "TIME_WAIT"), + "D_06": ("CLOSED", "CLOSED"), + "D_07": ("CLOSE_WAIT", "FIN_WAIT2"), + "D_08": ("TIME_WAIT", "CLOSED"), } + + SOC_CLOSED_STATE = ("FIN_WAIT_1", "FIN_WAIT_2", "CLOSING", "TIME_WAIT", "LAST_ACK", "CLOSED") + SOC_CREATED_STATE = ("SYNC_RCVD", "SYNC_SENT", "ESTABLISHED") + SOC_SEND_DATA_STATE = ("ESTABLISHED", "CLOSE_WAIT") + SOC_ESTABLISHED_STATE = ("ESTABLISHED", ) + + def __init__(self, tc_action): + self.tc_action = tc_action + self.pc_server_port = "" + self.target_server_port = "" + self.pc_ip = "" + self.target_ip = "" + pass + + def config_parameters(self, pc_server_port=None, target_server_port=None, pc_ip=None, target_ip=None): + if pc_ip is not None: + self.pc_ip = pc_ip + if target_ip is not None: + self.target_ip = target_ip + if pc_server_port is not None: + self.pc_server_port = pc_server_port + if target_server_port is not None: + self.target_server_port = target_server_port + pass + + def __connect_c_01(self, conn_id): + checker_stings = ["SOCR SOC1 C +ACCEPT", "ATR AT1 NC CLOSE L OK"] + test_action_strings = ["ATC AT1 CIPSTART %d \"TCP\" %s %s" % + (conn_id[1], self.pc_ip, self.pc_server_port)] + fail_string = "Fail, Target failed on connect to PC server" + ret = self.tc_action.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) + if ret is False: + return ret + + checker_stings = ["SOCR SOC_COM L OK"] + test_action_strings = ["SOC SOC1 ACCEPT SOC%d" % conn_id[0]] + return self.tc_action.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) + pass + + def __connect_c_02(self, conn_id): + checker_stings = ["ATR AT1 C ERROR"] + test_action_strings = ["ATC AT1 CIPSTART %d \"TCP\" %s %s" % + (conn_id[1], self.pc_ip, ERROR_PORT)] + fail_string = "Fail, Target fail on connect to port not listened" + return self.tc_action.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) + pass + + def __connect_c_03(self, conn_id): + pass + + def __connect_c_04(self, conn_id): + pass + + def __connect_c_05(self, conn_id): + checker_stings = ["SOCP SOC_COM OK", "ATP AT1 C CONNECT"] + test_action_strings = ["SOC SOC%d CONNECT %s %s" % + (conn_id[0], self.target_server_port, self.target_ip)] + fail_string = "Fail, PC fail on connect to target server" + return self.tc_action.load_and_exe_one_step(checker_stings, test_action_strings, + fail_string, check_time=200, check_freq=0.01) + pass + + def __connect_c_06(self, conn_id): + pass + + def __connect_c_07(self, conn_id): + # no checker strings, only try to create + # while connect is a blocking function, will return till target reply RST + checker_stings = ["SOCR SOC_COM C CLOSE"] + test_action_strings = ["SOC SOC%d CONNECT %s %s" % + (conn_id[0], ERROR_PORT, self.target_ip)] + fail_string = "Fail, PC fail on connect to target server" + return self.tc_action.load_and_exe_one_step(checker_stings, test_action_strings, + fail_string, check_time=2000, check_freq=0.01) + pass + + def __connect_c_08(self, conn_id): + pass + + def __close_d_01(self, conn_id): + checker_stings = ["ATP AT1 C %d,CLOSED" % conn_id[1], "SOCP SOC_COM C CLOSE"] + test_action_strings = ["SOC SOC%d SETOPT CLOSE_OPT IMM_SEND_FIN" % conn_id[0], + "ATS AT1 AT+CIPCLOSE=%d" % conn_id[1]] + fail_string = "Fail, Fail to close socket using D_01" + return self.tc_action.load_and_exe_one_step(checker_stings, test_action_strings, + fail_string, check_time=200, check_freq=0.01) + pass + + def __close_d_02(self, conn_id): + pass + + def __close_d_03(self, conn_id): + checker_stings = [] + test_action_strings = ["SOC SOC%d SETOPT CLOSE_OPT WAIT_TO" % conn_id[0], + "ATS AT1 AT+CIPCLOSE=%d" % conn_id[1]] + fail_string = "Fail, Fail to close socket using D_01" + return self.tc_action.load_and_exe_one_step(checker_stings, test_action_strings, + fail_string, check_time=500, check_freq=0.01) + pass + + def __close_d_04(self, conn_id): + pass + + def __close_d_05(self, conn_id): + checker_stings = ["ATP AT1 C %d,CLOSED" % conn_id[1]] + test_action_strings = ["SOC SOC%d SETOPT CLOSE_OPT IMM_SEND_FIN" % conn_id[0], + "SOC SOC%d CLOSE" % conn_id[0]] + fail_string = "Fail, Fail to close socket using D_05" + return self.tc_action.load_and_exe_one_step(checker_stings, test_action_strings, + fail_string, check_time=200, check_freq=0.01) + pass + + def __close_d_06(self, conn_id): + # 1. set PC socket close option, stop calling recv; send in target + checker_stings = ["ATP AT1 C >"] + test_action_strings = ["SOC SOC%d STOPRECV" % conn_id[0], + "SOC SOC%d SETOPT CLOSE_OPT IMM_SEND_RST" % conn_id[0], + "ATS AT1 AT+CIPSEND=%d,5" % conn_id[1]] + fail_string = "Fail, Fail to close socket using D_06" + ret = self.tc_action.load_and_exe_one_step(checker_stings, test_action_strings, + fail_string, check_time=200, check_freq=0.01) + if ret is False: + return ret + + # 2. send 5 bytes to socket + checker_stings = ["ATP AT1 C OK"] + test_action_strings = ["ATSN AT1 5"] + fail_string = "Fail, Fail to close socket using D_06" + ret = self.tc_action.load_and_exe_one_step(checker_stings, test_action_strings, + fail_string, check_time=200, check_freq=0.01) + if ret is False: + return ret + + # 3. close socket + checker_stings = ["ATP AT1 OR 2 C %d,CONNECT C %d,CLOSED" % (conn_id[1], conn_id[1])] + test_action_strings = ["SOC SOC%d CLOSE" % conn_id[0]] + fail_string = "Fail, Fail to close socket using D_06" + return self.tc_action.load_and_exe_one_step(checker_stings, test_action_strings, + fail_string, check_time=200, check_freq=0.01) + pass + + def __close_d_07(self, conn_id): + pass + + def __close_d_08(self, conn_id): + pass + + def send_test_data(self, socket_id, target_link_id, check_data_len): + # check_data_len[0] for socket data len, check_data_len[1] for target link data len + fail_string = "Fail, Fail on send and recv data" + + ret = True + + for i in range(1): + if check_data_len[1] != 0: + checker_stings = ["ATP AT1 C >"] + test_action_strings = ["ATS AT1 AT+CIPSEND=%d,%d" % (target_link_id, check_data_len[1])] + if self.tc_action.load_and_exe_one_step(checker_stings, test_action_strings, + fail_string, check_time=20) is False: + NativeLog.add_trace_critical("Fail on target send command for link %d" % target_link_id) + ret = False + break + checker_stings = ["SOCP SOC%d RL %d" % (socket_id, check_data_len[1]), "ATP AT1 C OK"] + test_action_strings = ["ATSN AT1 %d" % check_data_len[1]] + if self.tc_action.load_and_exe_one_step(checker_stings, test_action_strings, + fail_string, check_time=20) is False: + NativeLog.add_trace_critical("Fail on target send for link %d, send or recv error" % target_link_id) + ret = False + break + + if check_data_len[0] != 0: + checker_stings = ["ATP AT1 DL %d+%d" % (target_link_id, check_data_len[0])] + test_action_strings = ["SOC SOC%d SEND %d" % (socket_id, check_data_len[0])] + + if self.tc_action.load_and_exe_one_step(checker_stings, test_action_strings, + fail_string, check_time=20) is False: + NativeLog.add_trace_critical("Fail to receive PC SOC%d sent data" % socket_id) + ret = False + break + + # return ret + # for now do not validate data + return True + + TCP_ACTION_DICT = {"C_01": __connect_c_01, + "C_02": __connect_c_02, + "C_03": __connect_c_03, + "C_04": __connect_c_04, + "C_05": __connect_c_05, + "C_06": __connect_c_06, + "C_07": __connect_c_07, + "C_08": __connect_c_08, + "D_01": __close_d_01, + "D_02": __close_d_02, + "D_03": __close_d_03, + "D_04": __close_d_04, + "D_05": __close_d_05, + "D_06": __close_d_06, + "D_07": __close_d_07, + "D_08": __close_d_08, + } + + def get_method_destination_state(self, method): + return self.METHOD_RESULT[method] + + def execute_tcp_method(self, method, conn_id): + if method in self.METHOD_RESULT: + return self.TCP_ACTION_DICT[method](self, conn_id), self.get_method_destination_state(method) + else: + raise TCPUtilError("Not TCP connection method") + pass + + def is_created_state(self, state): + if state in self.SOC_CREATED_STATE: + return True + else: + return False + + def is_closed_state(self, state): + if state in self.SOC_CLOSED_STATE: + return True + else: + return False + + def is_able_to_send_data(self, state): + if state in self.SOC_SEND_DATA_STATE: + return True + else: + return False + + def is_established_connection(self, state): + if state[0] in self.SOC_ESTABLISHED_STATE and state[1] in self.SOC_ESTABLISHED_STATE: + return True + else: + return False + + +def main(): + pass + +if __name__ == '__main__': + main() diff --git a/components/test/TestCaseScript/TCPStress/TCPConnection.py b/components/test/TestCaseScript/TCPStress/TCPConnection.py new file mode 100755 index 0000000000..8b481c7df8 --- /dev/null +++ b/components/test/TestCaseScript/TCPStress/TCPConnection.py @@ -0,0 +1,321 @@ +import random +import re +import socket +import threading +import time + +import TCPConnectionUtility +from NativeLog import NativeLog +from TCAction import PerformanceTCBase + +DELAY_RANGE = [10, 3000] +CONNECTION_STRUCTURE = ("Connection handler", "PC socket", "Target socket id", + "Target port", "PC port", "PC state", "Target state") + + +class CheckerBase(threading.Thread): + + CHECK_ITEM = ("CONDITION", "NOTIFIER", "ID", "DATA") + SLEEP_TIME = 0.1 # sleep 100ms between each check action + + def __init__(self): + threading.Thread.__init__(self) + self.setDaemon(True) + self.exit_event = threading.Event() + self.sync_lock = threading.Lock() + self.check_item_list = [] + self.check_item_id = 0 + + def run(self): + while self.exit_event.isSet() is False: + self.process() + pass + + def process(self): + pass + + def add_check_item(self, condition, notifier): + with self.sync_lock: + check_item_id = self.check_item_id + self.check_item_id += 1 + self.check_item_list.append(dict(zip(self.CHECK_ITEM, (condition, notifier, check_item_id, str())))) + return check_item_id + + def remove_check_item(self, check_item_id): + ret = None + with self.sync_lock: + check_items = filter(lambda x: x["ID"] == check_item_id, self.check_item_list) + if len(check_items) > 0: + self.check_item_list.remove(check_items[0]) + ret = check_items[0]["DATA"] + return ret + + def exit(self): + self.exit_event.set() + pass + + +# check on serial port +class SerialPortChecker(CheckerBase): + def __init__(self, serial_reader): + CheckerBase.__init__(self) + self.serial_reader = serial_reader + pass + + # check condition for serial is compiled regular expression pattern + @staticmethod + def do_check(check_item, data): + match = check_item["CONDITION"].search(data) + if match is not None: + pos = data.find(match.group()) + len(match.group()) + # notify user + check_item["NOTIFIER"]("serial", match) + else: + pos = -1 + return pos + + def process(self): + # do check + with self.sync_lock: + # read data + new_data = self.serial_reader() + # NativeLog.add_trace_info("[debug][read data] %s" % new_data) + # do check each item + for check_item in self.check_item_list: + # NativeLog.add_trace_info("[debug][read data][ID][%s]" % check_item["ID"]) + check_item["DATA"] += new_data + self.do_check(check_item, check_item["DATA"]) + time.sleep(self.SLEEP_TIME) + + +# handle PC TCP server accept and notify user +class TCPServerChecker(CheckerBase): + def __init__(self, server_sock): + CheckerBase.__init__(self) + self.server_sock = server_sock + server_sock.settimeout(self.SLEEP_TIME) + self.accepted_socket_list = [] + + # check condition for tcp accepted sock is tcp source port + @staticmethod + def do_check(check_item, data): + for sock_addr_pair in data: + addr = sock_addr_pair[1] + if addr[1] == check_item["CONDITION"]: + # same port, so this is the socket that matched, notify and remove it from list + check_item["NOTIFIER"]("tcp", sock_addr_pair[0]) + data.remove(sock_addr_pair) + + def process(self): + # do accept + try: + client_sock, addr = self.server_sock.accept() + self.accepted_socket_list.append((client_sock, addr)) + except socket.error: + pass + # do check + with self.sync_lock: + check_item_list = self.check_item_list + for check_item in check_item_list: + self.do_check(check_item, self.accepted_socket_list) + pass + + +# this thread handles one tcp connection. +class ConnectionHandler(threading.Thread): + CHECK_FREQ = CheckerBase.SLEEP_TIME/2 + + def __init__(self, utility, serial_checker, tcp_checker, connect_method, disconnect_method): + threading.Thread.__init__(self) + self.setDaemon(True) + self.utility = utility + self.connect_method = connect_method + self.disconnect_method = disconnect_method + self.exit_event = threading.Event() + # following members are used in communication with checker threads + self.serial_checker = serial_checker + self.tcp_checker = tcp_checker + self.serial_notify_event = threading.Event() + self.tcp_notify_event = threading.Event() + self.serial_result = None + self.tcp_result = None + self.serial_check_item_id = None + self.tcp_check_item_id = None + self.data_cache = None + pass + + def new_connection_structure(self): + connection = dict.fromkeys(CONNECTION_STRUCTURE, None) + connection["Connection handler"] = self + return connection + + def run(self): + while self.exit_event.isSet() is False: + connection = self.new_connection_structure() + # do connect + connect_method_choice = random.choice(self.connect_method) + self.utility.execute_tcp_method(connect_method_choice, connection) + # check if established + if self.utility.is_established_state(connection) is True: + time.sleep(float(random.randint(DELAY_RANGE[0], DELAY_RANGE[1]))/1000) + # do disconnect if established + disconnect_method_choice = random.choice(self.disconnect_method) + self.utility.execute_tcp_method(disconnect_method_choice, connection) + # make sure target socket closed + self.utility.close_connection(connection) + time.sleep(float(random.randint(DELAY_RANGE[0], DELAY_RANGE[1]))/1000) + pass + + # serial_condition: re string + # tcp_condition: target local port + def add_checkers(self, serial_condition=None, tcp_condition=None): + # cleanup + self.serial_result = None + self.tcp_result = None + self.serial_notify_event.clear() + self.tcp_notify_event.clear() + # serial_checker + if serial_condition is not None: + pattern = re.compile(serial_condition) + self.serial_check_item_id = self.serial_checker.add_check_item(pattern, self.notifier) + else: + # set event so that serial check always pass + self.serial_notify_event.set() + if tcp_condition is not None: + self.tcp_check_item_id = self.tcp_checker.add_check_item(tcp_condition, self.notifier) + else: + # set event so that tcp check always pass + self.tcp_notify_event.set() + # NativeLog.add_trace_info("[Debug] add check item %s, connection is %s" % (self.serial_check_item_id, self)) + pass + + def get_checker_results(self, timeout=5): + time1 = time.time() + while time.time() - time1 < timeout: + # if one type of checker is not set, its event will be set in add_checkers + if self.serial_notify_event.isSet() is True and self.tcp_notify_event.isSet() is True: + break + time.sleep(self.CHECK_FREQ) + # do cleanup + # NativeLog.add_trace_info("[Debug] remove check item %s, connection is %s" % (self.serial_check_item_id, self)) + self.data_cache = self.serial_checker.remove_check_item(self.serial_check_item_id) + self.tcp_checker.remove_check_item(self.tcp_check_item_id) + # self.serial_check_item_id = None + # self.tcp_check_item_id = None + return self.serial_result, self.tcp_result + + def notifier(self, typ, result): + if typ == "serial": + self.serial_notify_event.set() + self.serial_result = result + elif typ == "tcp": + self.tcp_notify_event.set() + self.tcp_result = result + + def exit(self): + self.exit_event.set() + pass + + +class TCPConnection(PerformanceTCBase.PerformanceTCBase): + def __init__(self, name, test_env, cmd_set, timeout=120, log_path=None): + PerformanceTCBase.PerformanceTCBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + self.max_connection = 5 + self.execute_time = 120 # execute time default 120 minutes + self.pc_ip = "pc_ip" + self.target_ip = "target_ip" + self.connect_method = ["C_01"] + self.disconnect_method = ["D_05"] + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + + self.error_event = threading.Event() + self.serial_lock = threading.Lock() + pass + + def serial_reader(self): + return self.serial_read_data("SSC1") + + def send_ssc_command(self, data): + with self.serial_lock: + time.sleep(0.05) + self.serial_write_line("SSC1", data) + + def error_detected(self): + self.error_event.set() + + def process(self): + # parameters + max_connection = self.max_connection + execute_time = self.execute_time * 60 + pc_ip = self.get_parameter(self.pc_ip) + target_ip = self.get_parameter(self.target_ip) + connect_method = self.connect_method + disconnect_method = self.disconnect_method + server_port = random.randint(30000, 50000) + + # step 1, create TCP server on target and PC + # create TCP server on target + self.serial_write_line("SSC1", "soc -B -t TCP -p %s" % server_port) + match = self.check_regular_expression("SSC1", re.compile("BIND:(\d+),OK")) + if match is None: + NativeLog.add_prompt_trace("Failed to create TCP server on target") + return + target_sock_id = match.group(1) + + self.serial_write_line("SSC1", "soc -L -s %s" % target_sock_id) + if self.check_response("SSC1", "+LISTEN:%s,OK" % target_sock_id) is False: + NativeLog.add_prompt_trace("Failed to create TCP server on target") + return + + # create TCP server on PC + try: + server_sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) + server_sock.bind((pc_ip, server_port)) + server_sock.listen(5) + except StandardError: + NativeLog.add_prompt_trace("Failed to create TCP server on PC") + return + + # step 2, create checker + serial_port_checker = SerialPortChecker(self.serial_reader) + tcp_server_checker = TCPServerChecker(server_sock) + serial_port_checker.start() + tcp_server_checker.start() + + # step 3, create 5 thread and do connection + utility = TCPConnectionUtility.Utility(self, server_port, server_port, pc_ip, target_ip) + work_thread = [] + for i in range(max_connection): + t = ConnectionHandler(utility, serial_port_checker, tcp_server_checker, + connect_method, disconnect_method) + work_thread.append(t) + t.start() + + # step 4, wait and exit + self.error_event.wait(execute_time) + # close all threads + for t in work_thread: + t.exit() + t.join() + serial_port_checker.exit() + tcp_server_checker.exit() + serial_port_checker.join() + tcp_server_checker.join() + + if self.error_event.isSet() is False: + # no error detected + self.set_result("Succeed") + pass + + +def main(): + pass + + +if __name__ == '__main__': + main() diff --git a/components/test/TestCaseScript/TCPStress/TCPConnectionUtility.py b/components/test/TestCaseScript/TCPStress/TCPConnectionUtility.py new file mode 100755 index 0000000000..f28218af0b --- /dev/null +++ b/components/test/TestCaseScript/TCPStress/TCPConnectionUtility.py @@ -0,0 +1,251 @@ +import random +import socket +import threading + +from NativeLog import NativeLog + +# from NativeLog import NativeLog + +# make sure target do not listen on this port +ERROR_PORT = 62685 + + +class Utility(object): + METHOD_RESULT = {"C_01": ("ESTABLISHED", "ESTABLISHED"), # target TCP peer state, PC TCP peer state + "C_02": ("SYNC_SENT", "CLOSED"), + "C_03": ("CLOSED", "CLOSED"), + "C_04": ("SYN_RCVD", "ESTABLISHED"), + "C_05": ("ESTABLISHED", "ESTABLISHED"), + "C_06": ("CLOSED", "CLOSED"), + "C_07": ("CLOSED", "CLOSED"), + "C_08": ("CLOSED", "CLOSED"), + "D_01": ("TIME_WAIT", "CLOSED"), + "D_02": ("TIME_WAIT", "TIME_WAIT"), + "D_03": ("FIN_WAIT_2", "CLOSE_WAIT"), + "D_04": ("FIN_WAIT_1", "CLOSE_WAIT"), + "D_05": ("CLOSED", "TIME_WAIT"), + "D_06": ("CLOSED", "CLOSED"), + "D_07": ("CLOSE_WAIT", "FIN_WAIT2"), + "D_08": ("TIME_WAIT", "CLOSED"), } + + SOC_CLOSED_STATE = ("FIN_WAIT_1", "FIN_WAIT_2", "CLOSING", "TIME_WAIT", "LAST_ACK", "CLOSED") + SOC_CREATED_STATE = ("SYNC_RCVD", "ESTABLISHED") + SOC_SEND_DATA_STATE = ("ESTABLISHED", "CLOSE_WAIT") + SOC_ESTABLISHED_STATE = ("ESTABLISHED", ) + + def __init__(self, tc_action, pc_server_port, target_server_port, pc_ip, target_ip): + self.tc_action = tc_action + self.pc_server_port = pc_server_port + self.target_server_port = target_server_port + self.pc_ip = pc_ip + self.target_ip = target_ip + self.pc_close_wait_socket_list = [] + self.sync_lock = threading.Lock() + pass + + # create a tcp socket, return True or False + def __create_tcp_socket(self, connection): + connection_handler = connection["Connection handler"] + connection["Target port"] = random.randint(10000, 60000) + connection_handler.add_checkers("BIND:(\d+),OK,%s,%s" + % (self.target_ip, connection["Target port"])) + self.tc_action.send_ssc_command("soc -B -t TCP -i %s -p %s" % (self.target_ip, connection["Target port"])) + serial_result, tcp_result = connection_handler.get_checker_results() + if serial_result is not None: + connection["Target socket id"] = serial_result.group(1) + return True + else: + return False + + # target do connect, return True or False + def __target_do_connect(self, connection, dest_ip, dest_port, timeout=20): + connection_handler = connection["Connection handler"] + connection_handler.add_checkers("CONNECT:%s,OK" % connection["Target socket id"], + connection["Target port"]) + self.tc_action.send_ssc_command("soc -C -s %s -i %s -p %s" + % (connection["Target socket id"], dest_ip, dest_port)) + serial_result, tcp_result = connection_handler.get_checker_results(timeout) + if serial_result is not None and tcp_result is not None: + connection["PC socket"] = tcp_result + return True + else: + return False + pass + + # pc do connect, return True or False + def __pc_do_connect(self, connection, dest_ip, dest_port, timeout=20): + connection_handler = connection["Connection handler"] + sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) + while True: + connection["PC port"] = random.randint(10000, 60000) + try: + sock.bind((self.pc_ip, connection["PC port"])) + break + except socket.error, e: + if e.errno == 10048: # socket port reuse + continue + sock.settimeout(timeout) + connection["PC socket"] = sock + connection_handler.add_checkers("ACCEPT:(\d+),\d+,%s,%s" + % (self.pc_ip, connection["PC port"])) + try: + sock.connect((dest_ip, dest_port)) + except socket.error: + pass + serial_result, tcp_result = connection_handler.get_checker_results() + if serial_result is not None: + connection["Target socket id"] = serial_result.group(1) + return True + else: + return False + pass + + def connect_c_01(self, connection): + if self.__create_tcp_socket(connection) is True: + return self.__target_do_connect(connection, self.pc_ip, self.pc_server_port) + else: + return False + + def connect_c_02(self, connection): + if self.__create_tcp_socket(connection) is True: + return not self.__target_do_connect(connection, self.pc_ip, ERROR_PORT, timeout=5) + else: + return False + + def connect_c_03(self, connection): + return False + + def connect_c_04(self, connection): + return False + + def connect_c_05(self, connection): + return self.__pc_do_connect(connection, self.target_ip, self.target_server_port) + + def connect_c_06(self, connection): + return False + + def connect_c_07(self, connection): + return not self.__pc_do_connect(connection, self.target_ip, ERROR_PORT) + + def connect_c_08(self, connection): + return False + + def __target_socket_close(self, connection): + connection_handler = connection["Connection handler"] + if connection["Target socket id"] is not None: + connection_handler.add_checkers("CLOSE:%s" % connection["Target socket id"]) + self.tc_action.send_ssc_command("soc -T -s %s" % connection["Target socket id"]) + serial_result, tcp_result = connection_handler.get_checker_results() + connection["Target socket id"] = None + else: + serial_result = None + return True if serial_result is not None else False + + @staticmethod + def __pc_socket_close(connection): + connection_handler = connection["Connection handler"] + if connection["PC socket"] is not None: + connection_handler.add_checkers("CLOSED:%s" % connection["Target socket id"]) + connection["PC socket"].close() + serial_result, tcp_result = connection_handler.get_checker_results() + connection["PC socket"] = None + else: + serial_result = None + return True if serial_result is not None else False + + def close_d_01(self, connection): + connection["PC socket"] = None + return self.__target_socket_close(connection) + + def close_d_02(self, connection): + pass + + def close_d_03(self, connection): + with self.sync_lock: + self.pc_close_wait_socket_list.append(connection["PC socket"]) + return self.__target_socket_close(connection) + pass + + def close_d_04(self, connection): + pass + + def close_d_05(self, connection): + return self.__pc_socket_close(connection) + + def close_d_06(self, connection): + # target send data to PC, PC don't recv and close socket + connection_handler = connection["Connection handler"] + connection_handler.add_checkers("SEND:%s,OK" % connection["Target socket id"]) + self.tc_action.send_ssc_command("soc -S -s %s -l 100" % connection["Target socket id"]) + serial_result, tcp_result = connection_handler.get_checker_results() + if serial_result is None: + return False + return self.__pc_socket_close(connection) + + def close_d_07(self, connection): + # PC shutdown WR + result = False + try: + connection["PC socket"].shutdown(socket.SHUT_WR) + result = True + except StandardError: + pass + return result + + def close_d_08(self, connection): + pass + + def close_connection(self, connection): + self.__target_socket_close(connection) + pass + + TCP_ACTION_DICT = {"C_01": connect_c_01, + "C_02": connect_c_02, + "C_03": connect_c_03, + "C_04": connect_c_04, + "C_05": connect_c_05, + "C_06": connect_c_06, + "C_07": connect_c_07, + "C_08": connect_c_08, + "D_01": close_d_01, + "D_02": close_d_02, + "D_03": close_d_03, + "D_04": close_d_04, + "D_05": close_d_05, + "D_06": close_d_06, + "D_07": close_d_07, + "D_08": close_d_08, + } + + def get_method_destination_state(self, method): + return self.METHOD_RESULT[method] + + def execute_tcp_method(self, method, connection): + if method in self.METHOD_RESULT: + result = self.TCP_ACTION_DICT[method](self, connection) + if result is True: + state = self.get_method_destination_state(method) + connection["Target state"] = state[0] + connection["PC state"] = state[1] + else: + NativeLog.add_prompt_trace("[TCPConnection] tcp method %s fail, connection is %s" + % (method, connection)) + NativeLog.add_trace_info("[TCPConnection][data cache][check item %s] %s" + % (connection["Connection handler"].serial_check_item_id, + connection["Connection handler"].data_cache)) + else: + raise StandardError("Not TCP connection method") + return result + + def is_established_state(self, connection): + return True if connection["Target state"] in self.SOC_CREATED_STATE else False + + def is_closed_state(self, connection): + return True if connection["Target state"] in self.SOC_CLOSED_STATE else False + + +def main(): + pass + +if __name__ == '__main__': + main() diff --git a/components/test/TestCaseScript/TCPStress/TCPDataValidation.py b/components/test/TestCaseScript/TCPStress/TCPDataValidation.py new file mode 100755 index 0000000000..b056af38fa --- /dev/null +++ b/components/test/TestCaseScript/TCPStress/TCPDataValidation.py @@ -0,0 +1,244 @@ +import os +import random +import threading +import socket +import time +import re + +from TCAction import TCActionBase +from TCAction import PerformanceTCBase +from NativeLog import NativeLog + + +LOG_FOLDER = os.path.join("AT_LOG", "Performance", "Throughput") + + +AP_PROP_KEY = ("ssid", "password", "apc") + + +def calc_hash(index): + return (index & 0xffffffff) % 83 + (index & 0xffffffff) % 167 + + +def verify_data(data, start_index): + for i, c in enumerate(data): + if ord(c) != calc_hash(start_index + i): + NativeLog.add_trace_critical("[Data Validation Error] target sent data index %u is error." + " Sent data is %x, should be %x" + % (start_index + i, ord(c), calc_hash(start_index + i))) + return False + return True + + +def make_validation_data(length, start_index): + return bytes().join([chr(calc_hash(start_index + i)) for i in range(length)]) + + +class SendThread(threading.Thread): + def __init__(self, sock, send_len): + threading.Thread.__init__(self) + self.setDaemon(True) + self.sock = sock + self.send_len = send_len + self.exit_event = threading.Event() + pass + + def exit(self): + self.exit_event.set() + + def run(self): + index = 0 + while self.exit_event.isSet() is False: + data = make_validation_data(self.send_len, index) + try: + self.sock.send(data) + index += self.send_len + except StandardError: + # pass but not exit thread + time.sleep(1) + continue + pass + + +class RecvThread(threading.Thread): + def __init__(self, sock): + threading.Thread.__init__(self) + self.setDaemon(True) + self.sock = sock + self.exit_event = threading.Event() + + def exit(self): + self.exit_event.set() + + def run(self): + index = 0 + while self.exit_event.isSet() is False: + if self.sock is not None: + try: + data = self.sock.recv(8*1024) + except StandardError, e: + NativeLog.add_exception_log(e) + NativeLog.add_trace_critical("recv error, connection closed") + break + if verify_data(data, index) is not True: + break + index += len(data) + else: + time.sleep(1) + pass + + +class ValidationThread(threading.Thread): + def __init__(self, tc_action): + threading.Thread.__init__(self) + self.setDaemon(True) + self.tc_action = tc_action + self.exit_event = threading.Event() + + def exit(self): + self.exit_event.set() + + def run(self): + while self.exit_event.isSet() is False: + if self.tc_action.check_response("SSC1", "DATA_ERROR", 5) is True: + NativeLog.add_trace_critical("[Data Validation Error] target recv data error") + break + pass + + +class TCPDataValidation(PerformanceTCBase.PerformanceTCBase): + + def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): + PerformanceTCBase.PerformanceTCBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + self.send_len = 1460 + self.tx_enable = True + self.rx_enable = True + self.conn_num = 1 + self.test_time = 300 + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + pass + + def execute(self): + TCActionBase.TCActionBase.execute(self) + + try: + # configurable params + send_len = self.send_len + tx_enable = self.tx_enable + rx_enable = self.rx_enable + conn_num = self.conn_num + test_time = self.test_time * 60 # convert minutes to seconds + # configurable params + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for TCPThroughput script, error is %s" % e) + raise StandardError("Error configuration") + + # init throughput result data + test_item = "" + if tx_enable is True: + test_item += "Tx" + if rx_enable is True: + test_item += "Rx" + if test_item == "": + raise StandardError("no throughput test item") + + pc_ip = self.get_parameter("pc_ip") + tcp_port = random.randint(10000, 50000) + + # disable recv print during throughput test + self.serial_write_line("SSC1", "soc -R -o 0") + if self.check_response("SSC1", "+RECVPRINT", 2) is False: + NativeLog.add_trace_critical("Fail, Fail to disable recv print") + + # create server + server_sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) + server_sock.bind((pc_ip, tcp_port)) + server_sock.settimeout(5) + server_sock.listen(5) + + sock_id_list = [] + send_thread_list = [] + recv_thread_list = [] + + # step 4 create tcp connection + for i in range(conn_num): + self.serial_write_line("SSC1", "soc -B -t TCP") + match = self.check_regular_expression("SSC1", re.compile("\+BIND:(\d+),OK"), 2) + if match is None: + NativeLog.add_trace_critical("Fail, Fail to bind") + return + else: + sock_id_list.append(int(match.group(1))) + + self.serial_write_line("SSC1", "soc -V -s %s -o 3" % sock_id_list[-1]) + if self.check_regular_expression("SSC1", re.compile("\+DATA_VALIDATION:\d+,OK"), 2) is None: + NativeLog.add_trace_critical("Fail, Failed to enable validation") + return + + self.serial_write_line("SSC1", "soc -C -s %s -i %s -p %s" % (sock_id_list[-1], pc_ip, tcp_port)) + try: + sock, addr = server_sock.accept() + except socket.error, e: + NativeLog.add_trace_critical("%s" % e) + raise e + + if self.check_regular_expression("SSC1", re.compile("\+CONNECT:\d+,OK"), 5) is None: + NativeLog.add_trace_critical("Fail, Failed to connect") + return + + sock.settimeout(10) + + send_thread_list.append(SendThread(sock if rx_enable is True else None, send_len)) + recv_thread_list.append(RecvThread(sock if tx_enable is True else None)) + recv_thread_list[-1].start() + + # step 5 do test + validation_thread = ValidationThread(self) + validation_thread.start() + + for send_thread in send_thread_list: + send_thread.start() + + if tx_enable is True: + # do send from target + for sock_id in sock_id_list: + self.serial_write_line("SSC1", "soc -S -s %s -l %s -n 10000000" % (sock_id, send_len)) + + time1 = time.time() + exit_flag = False + + while time.time() - time1 < test_time and exit_flag is False: + for i in sock_id_list: + send_thread_list[i].join(0.5) + recv_thread_list[i].join(0.5) + validation_thread.join(0.5) + if send_thread_list[i].isAlive() is False \ + or recv_thread_list[i].isAlive() is False \ + or validation_thread.isAlive() is False: + NativeLog.add_trace_critical("validation error found") + exit_flag = True + break + else: + self.set_result("Succeed") + + # exit all thread + for i in sock_id_list: + send_thread_list[i].exit() + recv_thread_list[i].exit() + send_thread_list[i].join() + send_thread_list[i].join() + + validation_thread.exit() + validation_thread.join() + + +def main(): + pass + +if __name__ == '__main__': + main() diff --git a/components/test/TestCaseScript/TCPStress/TCPRandomSend.py b/components/test/TestCaseScript/TCPStress/TCPRandomSend.py new file mode 100755 index 0000000000..5a07a2d965 --- /dev/null +++ b/components/test/TestCaseScript/TCPStress/TCPRandomSend.py @@ -0,0 +1,103 @@ +import os +import time +import random +import threading +import socket +from TCAction import TCActionBase +from NativeLog import NativeLog +from NativeLog import ThroughputResult + + +class TCPRandomSend(TCActionBase.CommonTCActionBase): + + def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + self.send_len_config = range(1460) + self.delay_config = [0, 0.01, 0.1, 0.5, 1] + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + pass + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + try: + # configurable params + send_len_config = self.send_len_config + delay_config = self.delay_config + send_count = self.send_count + test_time = self.test_time * 60 + # configurable params + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for TCPThroughput script, error is %s" % e) + raise StandardError("Error configuration") + + # disable recv print during random send test + checker_stings = ["R SSC1 C +RECVPRINT"] + test_action_string = ["SSC SSC1 soc -R -o 0"] + fail_string = "Fail, Fail to disable recv print" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + pc_ip = self.test_env.get_variable_by_name("pc_ip")[1] + tcp_port = random.randint(50000, 60000) + + # step 0 create tcp connection + + server_sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) + server_sock.bind((pc_ip, tcp_port)) + server_sock.settimeout(1) + server_sock.listen(5) + + checker_stings = ["R SSC1 A :\+BIND:(\d+),OK"] + test_action_string = ["SSC SSC1 soc -B -t TCP"] + fail_string = "Fail, Fail bind" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["P SSC1 RE \+CONNECT:\d+,OK"] + test_action_string = ["SSC SSC1 soc -C -s -i %s -p %s" % (pc_ip, tcp_port)] + fail_string = "Fail, Fail to connect" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + sock, addr = server_sock.accept() + sock.settimeout(10) + # set no delay so that tcp segment will be send as soon as send called + sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) + + # step 1 start send + start_time = time.time() + while time.time() - start_time < test_time: + for delay in delay_config: + for i in xrange(send_count): + send_len = random.choice(send_len_config) + data = "A" * (send_len+1) + try: + sock.send(data) + except socket.error, e: + NativeLog.add_exception_log(e) + return + pass + time.sleep(delay) + + self.result_cntx.set_result("Succeed") + + # finally, execute done + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + +if __name__ == '__main__': + main() diff --git a/components/test/TestCaseScript/TCPStress/TCPSendRecv.py b/components/test/TestCaseScript/TCPStress/TCPSendRecv.py new file mode 100755 index 0000000000..e14d7f04d4 --- /dev/null +++ b/components/test/TestCaseScript/TCPStress/TCPSendRecv.py @@ -0,0 +1,143 @@ +from TCAction import TCActionBase +from NativeLog import NativeLog +import time +import random +import string + +TEST_COUNT_ONE_ROUND = 1000 + + +class TCPSendRecv(TCActionBase.CommonTCActionBase): + + def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + pass + + def cleanup(self): + # step 0 turn on recv print + checker_stings = ["R SSC1 C +RECVPRINT:1"] + test_action_string = ["SSC SSC1 soc -R -o 1"] + fail_string = "Fail, Fail to turn on recv print" + self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) + pass + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + try: + # configurable params + send_len = self.send_len + test_time = self.test_time * 60 + duplex = self.duplex + conn_num = self.conn_num + send_delay = self.send_delay + # configurable params + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for TCPSendRecv script, error is %s" % e) + raise StandardError("Error configuration") + + ssid = "".join([random.choice(string.lowercase) for m in range(10)]) + password = "".join([random.choice(string.lowercase) for m in range(10)]) + + # step 0 set ap + checker_stings = ["R SSC1 C +SAP:OK"] + test_action_string = ["SSC SSC1 ap -S -s %s -p %s -t 3" % (ssid, password)] + fail_string = "Fail, Fail to set ap" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step 1 connect to ap and turn off recv print + checker_stings = ["R SSC2 C +JAP:CONNECTED"] + test_action_string = ["SSC SSC2 sta -C -s %s -p %s" % (ssid, password)] + fail_string = "Fail, Fail to connect to server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, check_time=200) is False: + return + + checker_stings = ["P SSC1 C +RECVPRINT:0", "P SSC2 C +RECVPRINT:0"] + test_action_string = ["SSC SSC1 soc -R -o 0", "SSC SSC2 soc -R -o 0"] + fail_string = "Fail, Fail to turn off recv print" + self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, check_time=200) is False: + return + + # step 2 create server on AP + checker_stings = ["R SSC1 A :\+BIND:(\d+),OK"] + test_action_string = ["SSC SSC1 soc -B -t TCP -p "] + fail_string = "Fail, Fail to create server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["R SSC1 A :\+LISTEN:(\d+),OK"] + test_action_string = ["SSC SSC1 soc -L -s "] + fail_string = "Fail, Fail to create server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step 3 create conn_num tcp connections + for i in range(conn_num): + checker_stings = ["R SSC2 A :\+BIND:(\d+),OK" % i] + test_action_string = ["SSC SSC2 soc -B -t TCP"] + fail_string = "Fail, Fail to bind" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["P SSC1 A :\+ACCEPT:(\d+),\d+" % i, + "P SSC2 RE \+CONNECT:\d+,OK"] + test_action_string = ["SSC SSC2 soc -C -s -i -p " % i] + fail_string = "Fail, Fail to connect" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + start_time = time.time() + # step 4, do send/recv + while time.time()-start_time < test_time: + + checker_stings = ["P SSC1 NC ERROR NC CLOSE"] + for i in range(conn_num): + test_action_string = ["SSC SSC2 soc -S -s -l %d -n %d -j %d" % + (i, send_len, TEST_COUNT_ONE_ROUND, send_delay)] + checker_stings.append("P SSC2 RE \"\+SEND:%%%%s,OK\"%%%%() NC ERROR NC CLOSE" % i) + + if duplex is True: + checker_stings.append("P SSC1 RE \"\+SEND:%%%%s,OK\"%%%%()" % i) + test_action_string.append("SSC SSC1 soc -S -s -l %d -n %d -j %d" % + (i, send_len, TEST_COUNT_ONE_ROUND, send_delay)) + + fail_string = "Fail, Failed on send command" + if self.load_and_exe_one_step([], test_action_string, fail_string) is False: + break + # if self.load_and_exe_one_step([], ["SSC SSC1 ram -H", "SSC SSC2 ram -H"], fail_string) is False: + # break + # time.sleep(0.1) + + fail_string = "Fail, Failed to send/recv data" + if self.load_and_exe_one_step(checker_stings, ["DELAY 0.1"], fail_string, + check_freq=1, check_time=300) is False: + break + pass + + NativeLog.add_prompt_trace("time escape: %s" % (time.time() - start_time)) + self.result_cntx.set_result("Succeed") + + # finally, execute done + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + +if __name__ == '__main__': + main() + + diff --git a/components/test/TestCaseScript/TCPStress/TCPSoftAPSTASendRecv.py b/components/test/TestCaseScript/TCPStress/TCPSoftAPSTASendRecv.py new file mode 100644 index 0000000000..de31bacc11 --- /dev/null +++ b/components/test/TestCaseScript/TCPStress/TCPSoftAPSTASendRecv.py @@ -0,0 +1,318 @@ +from TCAction import TCActionBase +from NativeLog import NativeLog +import time +import random +import string + +TEST_COUNT_ONE_ROUND = 500 + + +class TCPSoftAPSTASendRecv(TCActionBase.CommonTCActionBase): + def __init__(self, name, test_env, cmd_set, timeout=45, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + pass + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + try: + # configurable params + send_len = self.send_len + # test count + test_count = self.test_count + # server port + server_port = self.server_port + server_port_t = self.server_port_2 + # ap ip + # ap_ip = self.ap_ip + # server echo + server_echo = self.server_echo + # station number + sta_number = self.sta_number + # pass standard + pass_standard = self.pass_standard + # send delay + send_delay = self.send_delay + # configurable params + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for TCPTransparent script, error is %s" % e) + raise StandardError("Error configuration") + + # step0 reboot + checker_stings = [] + test_action_string = [] + + for i in range(sta_number + 2): + checker_stings.append("P SSC%d C !!!ready!!!" % (i + 1)) + test_action_string.append("SSCC SSC%d reboot" % (i + 1)) + + fail_string = "Fail, Fail to reboot" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step1, set ap/STA mode on all target + for i in range(sta_number + 2): + checker_stings = ["R SSC%d C +MODE:OK" % (i + 1)] + test_action_string = ["SSCC SSC%d op -S -o 3" % (i + 1)] + fail_string = "Fail, Fail to set mode on SSC%d" % (i + 1) + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # set different getway for SSC1 softAP + checker_stings = ["R SSC1 C +DHCP:AP,OK"] + test_action_string = ["SSCC SSC1 dhcp -E -o 2"] + fail_string = "Fail, SSC1 Fail to disable DHCP" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["R SSC1 C +IP:OK"] + test_action_string = ["SSCC SSC1 ip -S -o 2 -i 192.168.6.1"] + fail_string = "Fail, SSC1 Fail to set IP" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["R SSC1 C +DHCP:AP,OK"] + test_action_string = ["SSCC SSC1 dhcp -S -o 2"] + fail_string = "Fail, SSC1 Fail to enable DHCP" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # set different getway for SSC2 softAP + checker_stings = ["R SSC2 C +DHCP:AP,OK"] + test_action_string = ["SSCC SSC2 dhcp -E -o 2"] + fail_string = "Fail, SSC2 Fail to disable DHCP" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["R SSC2 C +IP:OK"] + test_action_string = ["SSCC SSC2 ip -S -o 2 -i 192.168.5.1"] + fail_string = "Fail, SSC2 Fail to set IP" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["R SSC2 C +DHCP:AP,OK"] + test_action_string = ["SSCC SSC2 dhcp -S -o 2"] + fail_string = "Fail, SSC2 Fail to enable DHCP" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step2, set ssid/password on SSC1 + ssid = "".join([random.choice(string.lowercase) for m in range(10)]) + password = "".join([random.choice(string.lowercase) for m in range(10)]) + checker_stings = ["R SSC1 C +SAP:OK"] + test_action_string = ["SSCC SSC1 ap -S -s %s -p %s -n 10 -t 0 -m 8" % (ssid, password)] + fail_string = "Fail, Fail to set ssid/password on SSC1" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step3, set ssid/password on SSC2 + ssid_1 = "".join([random.choice(string.lowercase) for m in range(10)]) + password_1 = "".join([random.choice(string.lowercase) for m in range(10)]) + checker_stings = ["R SSC2 C +SAP:OK"] + test_action_string = ["SSCC SSC2 ap -S -s %s -p %s -n 10 -t 0 -m 8" % (ssid_1, password_1)] + fail_string = "Fail, Fail to set ap ssid/password on SSC2" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step4, SSC2 join SSC1(soft AP) + checker_stings = [] + test_action_string = [] + checker_stings.append("P SSC2 C +JAP:CONNECTED,%s" % ssid) + test_action_string.append("SSCC SSC2 ap -C -s %s -p %s" % (ssid, password)) + fail_string = "Fail, Fail to connect to SSC1 SoftAP" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + # step5, create server on SSC1 + checker_stings = ["R SSC1 A :BIND:(\d+),OK"] + test_action_string = ["SSCC SSC1 soc -B -t TCP -p %s" % server_port] + fail_string = "Fail, Fail to create server on SSC1 while binding" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["R SSC1 RE LISTEN:(\d+),OK"] + test_action_string = ["SSCC SSC1 soc -L -s "] + fail_string = "Fail, Fail to create server on SSC1 while listening" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step6, create client on SSC2 + checker_stings = [] + test_action_string = [] + checker_stings.append("P SSC2 A :BIND:(\d+),OK") + test_action_string.append("SSCC SSC2 soc -B -t TCP") + fail_string = "Fail, SSC2 Fail to connect to server while binding" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["P SSC2 RE CONNECT:(\d+),OK", "P SSC1 A :ACCEPT:(\d+),.+"] + test_action_string = ["SSCC SSC2 soc -C -s -i %s -p %s" % ("192.168.6.1", server_port)] + fail_string = "Fail, SSC2 Fail to connect to server while connecting" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step7, SSC3 - SSC5 join SSC2 + checker_stings = [] + test_action_string = [] + for i in range(sta_number): + checker_stings.append("P SSC%d C +JAP:CONNECTED,%s" % (i + 3, ssid_1)) + test_action_string.append("SSCC SSC%d ap -C -s %s -p %s" % (i + 3, ssid_1, password_1)) + fail_string = "Fail, SSC%d Fail to connect to SSC2" % (i + 3) + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, check_time=450) is False: + return + + # step8, create server on SSC2 + checker_stings = ["R SSC2 A :BIND:(\d+),OK"] + test_action_string = ["SSCC SSC2 soc -B -t TCP -p %s -i 192.168.5.1" % server_port_t] + fail_string = "Fail, Fail to create server one SSC2 while binding" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["R SSC2 RE LISTEN:(\d+),OK"] + test_action_string = ["SSCC SSC2 soc -L -s "] + fail_string = "Fail, Fail to create server one SSC2 while listening" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step9, create client on SSC3 - SSC5 + checker_stings = [] + test_action_string = [] + for i in range(sta_number): + checker_stings.append("P SSC%d A :BIND:(\d+),OK" % (i + 3, i + 3)) + test_action_string.append("SSCC SSC%d soc -B -t TCP" % (i + 3)) + fail_string = "Fail, Fail to connect to SSC2 server while binding" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + for i in range(sta_number): + checker_stings = ["P SSC%d RE CONNECT:(\d+),OK" % (i + 3), + "P SSC2 A :ACCEPT:(\d+),.+" % (i + 3)] + test_action_string = ["SSCC SSC%d soc -C -s -i %s -p %s" % + (i + 3, i + 3, "192.168.5.1", server_port_t)] + fail_string = "Fail, Fail to connect to SSC2 server while connecting" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + start_time = time.time() + # step 10, do send/recv + while test_count > 0: + _tmp_count = TEST_COUNT_ONE_ROUND if test_count - TEST_COUNT_ONE_ROUND > 0 else test_count + test_count -= TEST_COUNT_ONE_ROUND + + checker_stings = [] + test_action_string = [] + if server_echo is True: + test_action_string.append("SSC SSC1 soc -S -s -l %d -n %d -j %d" % + (send_len, _tmp_count, send_delay)) + checker_stings.append("P SSC1 RE \+SEND:\d+,OK NC CLOSED") + test_action_string.append("SSC SSC2 soc -S -s -l %d -n %d -j %d" % + (send_len, _tmp_count, send_delay)) + checker_stings.append("P SSC2 RE \+SEND:\d+,OK NC CLOSED") + + for i in range(sta_number): + checker_stings.append("P SSC%d RE \+SEND:\d+,OK NC CLOSED" % (i + 3)) + test_action_string.append("SSC SSC%d soc -S -s -l %d -n %d -j %d" % + (i + 3, i + 3, send_len, _tmp_count, send_delay)) + for i in range(sta_number): + test_action_string.append("SSC SSC2 soc -S -s -l %d -n %d -j %d" % + (i + 3, send_len, _tmp_count, send_delay)) + checker_stings.append("P SSC2 RE \+SEND:\d+,OK NC CLOSED") + + fail_string = "Fail, Failed to send/recv data" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, + check_freq=1, check_time=300) is False: + break + pass + + if (time.time() - start_time) > pass_standard: + self.result_cntx.set_result("Succeed") + else: + checker_stings = [] + test_action_string = [] + for i in range(sta_number + 2): + checker_stings.append("P SSC%d C CLOSEALL" % (i + 1)) + test_action_string.append("SSCC SSC%d soc -T" % (i + 1)) + fail_string = "Fail, Fail to close socket" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + # re-set server on SSC1 + server_port = random.randint(20000, 30000) + checker_stings = ["R SSC1 A :BIND:(\d+),OK"] + test_action_string = ["SSCC SSC1 soc -B -t TCP -p %s" % server_port] + fail_string = "Fail, Fail to bind socket" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["R SSC1 RE LISTEN:(\d+),OK"] + test_action_string = ["SSCC SSC1 soc -L -s "] + fail_string = "Fail, Fail to listen" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + # SSC2 connnect SSC1 + checker_stings = [] + test_action_string = [] + checker_stings.append("P SSC2 A :BIND:(\d+),OK") + test_action_string.append("SSCC SSC2 soc -B -t TCP") + fail_string = "Fail, SSC2 Fail to bind sock" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["P SSC2 RE CONNECT:(\d+),OK", "P SSC1 A :ACCEPT:(\d+),.+"] + test_action_string = ["SSCC SSC2 soc -C -s -i %s -p %s" % ("192.168.6.1", server_port)] + fail_string = "Fail, SSC2 Fail to connect to SSC1 server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + #create server on SSC2 + checker_stings = [] + test_action_string = [] + checker_stings.append("P SSC2 A :BIND:(\d+),OK") + test_action_string.append("SSCC SSC2 soc -B -t TCP -p %s -i 192.168.5.1" % server_port_t) + fail_string = "Fail, SSC2 Fail to bind" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + checker_stings = ["R SSC2 RE LISTEN:(\d+),OK"] + test_action_string = ["SSCC SSC2 soc -L -s "] + fail_string = "Fail, SSC2 Fail to listen" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + #create client on SSC3-SSC5 + checker_stings = [] + test_action_string = [] + for i in range(sta_number): + checker_stings.append("P SSC%d A :BIND:(\d+),OK" % (i + 3, i + 3)) + test_action_string.append("SSCC SSC%d soc -B -t TCP" % (i + 3)) + fail_string = "Fail, Fail to connect to SSC2 server while binding" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + for i in range(sta_number): + checker_stings = ["P SSC%d RE CONNECT:(\d+),OK" % (i + 3), + "P SSC2 A :ACCEPT:(\d+),.+" % (i + 3)] + test_action_string = ["SSCC SSC%d soc -C -s -i %s -p %s" % + (i + 3, i + 3, "192.168.5.1", server_port_t)] + fail_string = "Fail, Fail to connect to server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + self.result_cntx.set_result("Failed") + + # finally, execute done + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + + +if __name__ == '__main__': + main() diff --git a/components/test/TestCaseScript/TCPStress/TCPThroughput.py b/components/test/TestCaseScript/TCPStress/TCPThroughput.py new file mode 100755 index 0000000000..0c40603e37 --- /dev/null +++ b/components/test/TestCaseScript/TCPStress/TCPThroughput.py @@ -0,0 +1,315 @@ +import os +import time +import random +import threading +import socket + +from TCAction import TCActionBase +from NativeLog import NativeLog +from NativeLog import ThroughputResult +from Utility import RSSICalibrator +from Utility import MakeFolder + + +LOG_FOLDER = os.path.join("AT_LOG", "Performance", "Throughput") + + +AP_PROP_KEY = ("ssid", "password", "apc") + + +class SendThread(threading.Thread): + def __init__(self, sock, send_len): + threading.Thread.__init__(self) + self.setDaemon(True) + self.sock = sock + self.send_len = send_len + self.exit_event = threading.Event() + self.calc_event = threading.Event() + self.bytes_sent = 0 + pass + + def start_calc(self): + self.calc_event.set() + + def stop_calc(self): + self.calc_event.clear() + self.exit_event.set() + + def run(self): + data = "A" * self.send_len + if self.sock is None: + return + while True: + if self.exit_event.isSet() is True: + break + try: + self.sock.send(data) + except StandardError: + break + if self.calc_event.isSet() is True: + self.bytes_sent += self.send_len + + def get_bytes_sent(self): + return self.bytes_sent + pass + + +class RecvThread(threading.Thread): + def __init__(self, sock): + threading.Thread.__init__(self) + self.setDaemon(True) + self.sock = sock + self.exit_event = threading.Event() + self.calc_event = threading.Event() + self.bytes_recv = 0 + + def start_calc(self): + self.calc_event.set() + + def stop_calc(self): + self.calc_event.clear() + self.exit_event.set() + + def run(self): + if self.sock is None: + return + while True: + if self.exit_event.isSet() is True: + break + try: + data = self.sock.recv(8*1024) + except StandardError: + break + if self.calc_event.isSet() is True: + self.bytes_recv += len(data) + + def get_bytes_recv(self): + return self.bytes_recv + pass + + +class TCPThroughput(TCActionBase.CommonTCActionBase): + + def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + self.att_test_list = range(60) + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + # read AP list + self.ap_list = [] + for i in range(1, len(cmd_set)): + for j in range(len(cmd_set[i][1])): + if cmd_set[i][1][j] != "": + cmd_string = "self.ap_list.append(dict(zip(AP_PROP_KEY, " + cmd_set[i][1][j] + ")))" + exec cmd_string + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + pass + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + try: + # configurable params + ap_list = self.ap_list + send_len = self.send_len + att_test_list = self.att_test_list + tx_enable = self.tx_enable + rx_enable = self.rx_enable + measure_period = self.measure_period + # configurable params + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for TCPThroughput script, error is %s" % e) + raise StandardError("Error configuration") + + # find local ip and generate local port + local_ip_list = socket.gethostbyname_ex(socket.gethostname())[2] + for local_ip in local_ip_list: + if local_ip.find("192.168.1.") != -1: + pc_ip = local_ip + break + else: + raise StandardError("Can't find local IP.") + + tcp_port = random.randint(40000, 50000) + + # init throughput result data + test_item = "" + if tx_enable is True: + test_item += "Tx" + if rx_enable is True: + test_item += "Rx" + if test_item == "": + raise StandardError("no throughput test item") + + folder_path = MakeFolder.make_folder(LOG_FOLDER) + file_name = os.path.join(folder_path, + "TCPThroughput_%s_%s" % (test_item, time.strftime("%d%H%M%S", time.localtime()))) + + result = ThroughputResult.ThroughputResult(file_name, standard_required=True) + + # restart before executing throughput + checker_stings = ["R SSC1 C !!!ready!!!"] + test_action_string = ["SSC SSC1 reboot"] + fail_string = "Fail, Fail to reboot" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # disable recv print during throughput test + checker_stings = ["R SSC1 C +RECVPRINT"] + test_action_string = ["SSC SSC1 soc -R -o 0"] + fail_string = "Fail, Fail to disable recv print" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + for ap_prop in ap_list: + if ap_prop["password"] == "": + # set a default string for open ap + ap_prop["password"] = "1" + + # switch off all outlet, switch on AP outlet + outlet_config_dict = dict.fromkeys(range(1, 9), "OFF") + outlet_config_dict[ap_prop["apc"]] = "ON" + apc_cmd = "APC " + for outlet in outlet_config_dict: + apc_cmd += " %s %s" % (outlet_config_dict[outlet], outlet) + checker_stings = ["P PC_COM L OK"] + fail_string = "Fail, Fail to switch apc" + if self.load_and_exe_one_step(checker_stings, [apc_cmd], fail_string) is False: + return + + # wait AP ready + time.sleep(20) + + # create server + server_sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) + server_sock.bind((pc_ip, tcp_port)) + server_sock.settimeout(5) + server_sock.listen(5) + + if tx_enable is True: + result.add_test_item(ap_prop["ssid"] + "_tx") + if rx_enable is True: + result.add_test_item(ap_prop["ssid"] + "_rx") + + # create RSSI Calibrator + calibrator = RSSICalibrator.Calibrator() + + for att_value in att_test_list: + # step 0 set att value + checker_stings = ["R PC_COM L OK"] + test_action_string = ["ATT %s" % att_value] + fail_string = "Fail, Fail to set att value" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + continue + # step 1 connect to AP + checker_stings = ["R SSC1 C +JAP:CONNECTED"] + test_action_string = ["SSC SSC1 sta -C -s %s -p %s" % (ap_prop["ssid"], ap_prop["password"])] + fail_string = "Fail, Fail to JAP" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, + check_freq=1, check_time=30) is False: + continue + # step 2 get AP RSSI + checker_stings = ["R SSC1 A :\+SCAN:%s,[:\d\w]+,\d+,\d+,([-\d]+)" % ap_prop["ssid"]] + test_action_string = ["SSC SSC1 sta -S -s %s" % ap_prop["ssid"]] + fail_string = "Fail, Fail to scan" + rssi = scan_count = 0 + for i in range(3): + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + continue + rssi += int(self.test_env.get_variable_by_name("rssi")[1]) + scan_count += 1 + + rssi = calibrator.calibrate_rssi(float(rssi)/scan_count if scan_count > 0 else 0, att_value) + + # step 3 close all connections + checker_stings = ["R SSC1 C +CLOSEALL"] + test_action_string = ["SSC SSC1 soc -T"] + fail_string = "Fail, Fail to create server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + continue + + # step 4 create tcp connection + + checker_stings = ["R SSC1 A :\+BIND:(\d+),OK"] + test_action_string = ["SSC SSC1 soc -B -t TCP"] + fail_string = "Fail, Fail bind" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + continue + + checker_stings = ["P SSC1 RE \+CONNECT:\d+,OK"] + test_action_string = ["SSC SSC1 soc -C -s -i %s -p %s" % (pc_ip, tcp_port)] + fail_string = "Fail, Fail to connect" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + continue + + try: + sock, addr = server_sock.accept() + except socket.error, e: + NativeLog.add_trace_critical("%s" % e) + continue + sock.settimeout(measure_period) + + # step 5 do throughput test + send_thread = SendThread(sock if rx_enable is True else None, send_len) + send_thread.start() + + recv_thread = RecvThread(sock if tx_enable is True else None) + recv_thread.start() + + if tx_enable is True: + # do send from target + test_action_string = ["SSC SSC1 soc -S -s -l %s -n 10000000" % send_len] + fail_string = "Fail, Fail to send" + if self.load_and_exe_one_step([], test_action_string, fail_string) is False: + pass + + # start throughput calculate + send_thread.start_calc() + recv_thread.start_calc() + + # sleep for measure period + time.sleep(measure_period) + + # stop throughput calculate + send_thread.stop_calc() + recv_thread.stop_calc() + + send_thread.join() + recv_thread.join() + + sock.close() + + # output throughput result + # in Mbps + if send_thread.get_bytes_sent() > 0: + result.log_throughput(ap_prop["ssid"] + "_rx", rssi, att_value, + float(send_thread.get_bytes_sent() * 8) / (measure_period * 1000000)) + + if recv_thread.get_bytes_recv() > 0: + result.log_throughput(ap_prop["ssid"] + "_tx", rssi, att_value, + float(recv_thread.get_bytes_recv() * 8) / (measure_period * 1000000)) + + result.output_to_file() + pass + + server_sock.close() + + self.result_cntx.set_result("Succeed") + + # finally, execute done + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + +if __name__ == '__main__': + main() diff --git a/components/test/TestCaseScript/TCPStress/__init__.py b/components/test/TestCaseScript/TCPStress/__init__.py new file mode 100755 index 0000000000..049c1b961f --- /dev/null +++ b/components/test/TestCaseScript/TCPStress/__init__.py @@ -0,0 +1 @@ +__all__ = ["TCPConnUtility", "TCPConnSingleMode", "TCPConnMixedMode"] \ No newline at end of file diff --git a/components/test/TestCaseScript/UDPStress/UDPSendRecv.py b/components/test/TestCaseScript/UDPStress/UDPSendRecv.py new file mode 100755 index 0000000000..3a528c6ba7 --- /dev/null +++ b/components/test/TestCaseScript/UDPStress/UDPSendRecv.py @@ -0,0 +1,130 @@ +from TCAction import TCActionBase +from NativeLog import NativeLog +import time +import random +import string + +TEST_COUNT_ONE_ROUND = 1000 + + +class UDPSendRecv(TCActionBase.CommonTCActionBase): + + def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + pass + + def cleanup(self): + # step 0 turn on recv print + checker_stings = ["R SSC1 C +RECVPRINT:1"] + test_action_string = ["SSC SSC1 soc -R -o 1"] + fail_string = "Fail, Fail to turn on recv print" + self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) + pass + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + try: + # configurable params + send_len = self.send_len + test_time = self.test_time * 60 + duplex = self.duplex + conn_num = self.conn_num + send_delay = self.send_delay + # configurable params + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for UDPSendRecv script, error is %s" % e) + raise StandardError("Error configuration") + + ssid = "".join([random.choice(string.lowercase) for m in range(10)]) + password = "".join([random.choice(string.lowercase) for m in range(10)]) + + # step 0 set ap + checker_stings = ["R SSC1 C +SAP:OK"] + test_action_string = ["SSC SSC1 ap -S -s %s -p %s -t 3" % (ssid, password)] + fail_string = "Fail, Fail to set ap" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step 1 connect to ap and turn off recv print + checker_stings = ["R SSC2 C +JAP:CONNECTED"] + test_action_string = ["SSC SSC2 sta -C -s %s -p %s" % (ssid, password)] + fail_string = "Fail, Fail to connect to server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, check_time=200) is False: + return + + checker_stings = ["R SSC2 A :\+STAIP:(\d+\.\d+\.\d+\.\d+)\r"] + test_action_string = ["SSC SSC2 ip -Q -o 1"] + fail_string = "Fail, Fail to connect to server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, check_time=200) is False: + return + + checker_stings = ["P SSC1 C +RECVPRINT:0", "P SSC2 C +RECVPRINT:0"] + test_action_string = ["SSC SSC1 soc -R -o 0", "SSC SSC2 soc -R -o 0"] + fail_string = "Fail, Fail to turn off recv print" + self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, check_time=200) is False: + return + + # step 2 create conn_num udp socket + for i in range(1, conn_num+1): + checker_stings = ["R SSC1 A :\+BIND:(\d+),OK" % i, + "R SSC2 A :\+BIND:(\d+),OK" % i] + test_action_string = ["SSC SSC1 soc -B -t UDP -p " % i, + "SSC SSC2 soc -B -t UDP -p " % i] + fail_string = "Fail, Fail to create socket" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + start_time = time.time() + # step 3, do send/recv + while time.time()-start_time < test_time: + + checker_stings = ["P SSC1 NC ERROR NC CLOSE"] + for i in range(1, conn_num+1): + test_action_string = ["SSC SSC2 soc -S -s -l %d -n %d -j %d " + "-i -p " % + (i, send_len, TEST_COUNT_ONE_ROUND, send_delay, i)] + checker_stings.append("P SSC2 RE \"\+SEND:%%%%s,OK\"%%%%() NC ERROR NC CLOSE" % i) + if duplex is True: + test_action_string.append("SSC SSC1 soc -S -s -l %d -n %d -j %d" + " -i -p " % + (i, send_len, TEST_COUNT_ONE_ROUND, send_delay, i)) + checker_stings.append("P SSC1 RE \"\+SEND:%%%%s,OK\"%%%%()" % i) + + fail_string = "Fail, Failed on send command" + if self.load_and_exe_one_step([], test_action_string, fail_string) is False: + break + time.sleep(1) + + fail_string = "Fail, Failed to send/recv data" + if self.load_and_exe_one_step(checker_stings, ["DELAY 0.1"], fail_string, + check_freq=1, check_time=300) is False: + break + pass + + NativeLog.add_prompt_trace("time escape: %s" % (time.time() - start_time)) + self.result_cntx.set_result("Succeed") + + # finally, execute done + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + +if __name__ == '__main__': + main() + + diff --git a/components/test/TestCaseScript/UDPStress/UDPThroughput.py b/components/test/TestCaseScript/UDPStress/UDPThroughput.py new file mode 100755 index 0000000000..dac7c2206b --- /dev/null +++ b/components/test/TestCaseScript/UDPStress/UDPThroughput.py @@ -0,0 +1,305 @@ +import os +import time +import random +import threading +import socket + +from TCAction import TCActionBase +from NativeLog import NativeLog +from NativeLog import ThroughputResult +from Utility import RSSICalibrator +from Utility import MakeFolder + + +LOG_FOLDER = os.path.join("AT_LOG", "Performance", "Throughput") + + +AP_PROP_KEY = ("ssid", "password", "apc") + + +class SendThread(threading.Thread): + def __init__(self, sock, send_len, target_addr): + threading.Thread.__init__(self) + self.setDaemon(True) + self.sock = sock + self.send_len = send_len + self.target_addr = target_addr + self.exit_event = threading.Event() + pass + + def exit(self): + self.exit_event.set() + + def run(self): + data = "A" * self.send_len + if self.sock is None: + return + while True: + if self.exit_event.isSet() is True: + break + try: + self.sock.sendto(data, self.target_addr) + except StandardError: + break + pass + + +class RecvThread(threading.Thread): + def __init__(self, sock): + threading.Thread.__init__(self) + self.setDaemon(True) + self.sock = sock + self.exit_event = threading.Event() + self.calc_event = threading.Event() + self.bytes_recv = 0 + + def start_calc(self): + self.calc_event.set() + + def stop_calc(self): + self.calc_event.clear() + self.exit_event.set() + + def run(self): + if self.sock is None: + return + while True: + if self.exit_event.isSet() is True: + break + try: + data, addr = self.sock.recvfrom(65535) + except StandardError: + break + if self.calc_event.isSet() is True: + self.bytes_recv += len(data) + + def get_bytes_recv(self): + return self.bytes_recv + pass + + +class UDPThroughput(TCActionBase.CommonTCActionBase): + + def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + self.att_test_list = range(60) + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + # read AP list + self.ap_list = [] + for i in range(1, len(cmd_set)): + for j in range(len(cmd_set[i][1])): + if cmd_set[i][1][j] != "": + cmd_string = "self.ap_list.append(dict(zip(AP_PROP_KEY, " + cmd_set[i][1][j] + ")))" + exec cmd_string + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + pass + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + try: + # configurable params + ap_list = self.ap_list + send_len = self.send_len + att_test_list = self.att_test_list + tx_enable = self.tx_enable + rx_enable = self.rx_enable + measure_period = self.measure_period + # configurable params + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for TCPThroughput script, error is %s" % e) + raise StandardError("Error configuration") + + # find local ip and generate local port + local_ip_list = socket.gethostbyname_ex(socket.gethostname())[2] + for local_ip in local_ip_list: + if local_ip.find("192.168.1.") != -1: + pc_ip = local_ip + break + else: + raise StandardError("Can't find local IP.") + + udp_port = random.randint(40000, 50000) + + # init throughput result data + test_item = "" + if tx_enable is True: + test_item += "Tx" + if rx_enable is True: + test_item += "Rx" + if test_item == "": + raise StandardError("no throughput test item") + + folder_path = MakeFolder.make_folder(LOG_FOLDER) + file_name = os.path.join(folder_path, + "UDPThroughput_%s_%s" % (test_item, time.strftime("%d%H%M%S", time.localtime()))) + + result = ThroughputResult.ThroughputResult(file_name) + + # restart before executing throughput + checker_stings = ["R SSC1 C !!!ready!!!"] + test_action_string = ["SSC SSC1 reboot"] + fail_string = "Fail, Fail to reboot" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # disable recv print during throughput test + checker_stings = ["R SSC1 C +RECVPRINT"] + test_action_string = ["SSC SSC1 soc -R -o 0"] + fail_string = "Fail, Fail to disable recv print" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + for ap_prop in ap_list: + if ap_prop["password"] == "": + # set a default string for open ap + ap_prop["password"] = "1" + + # switch off all outlet, switch on AP outlet + outlet_config_dict = dict.fromkeys(range(1, 9), "OFF") + outlet_config_dict[ap_prop["apc"]] = "ON" + apc_cmd = "APC " + for outlet in outlet_config_dict: + apc_cmd += " %s %s" % (outlet_config_dict[outlet], outlet) + checker_stings = ["P PC_COM L OK"] + fail_string = "Fail, Fail to switch apc" + if self.load_and_exe_one_step(checker_stings, [apc_cmd], fail_string) is False: + return + + # wait AP ready + time.sleep(20) + + # create server + udp_sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM) + udp_sock.bind((pc_ip, udp_port)) + udp_sock.settimeout(1) + + if tx_enable is True: + result.add_test_item(ap_prop["ssid"] + "_tx") + if rx_enable is True: + result.add_test_item(ap_prop["ssid"] + "_rx") + + # create RSSI Calibrator + calibrator = RSSICalibrator.Calibrator() + + for att_value in att_test_list: + # step 0 set att value + checker_stings = ["R PC_COM L OK"] + test_action_string = ["ATT %s" % att_value] + fail_string = "Fail, Fail to set att value" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + continue + # step 1 connect to AP + checker_stings = ["R SSC1 C +JAP:CONNECTED"] + test_action_string = ["SSC SSC1 sta -C -s %s -p %s" % (ap_prop["ssid"], ap_prop["password"])] + fail_string = "Fail, Fail to JAP" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, + check_freq=1, check_time=30) is False: + continue + checker_stings = ["R SSC1 A :STAIP:(\d+\.\d+\.\d+\.\d+)"] + test_action_string = ["SSC SSC1 ip -Q"] + fail_string = "Fail, Fail to get ip" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, + check_freq=1, check_time=30) is False: + continue + target_ip = self.get_parameter("target_ip") + # step 2 get AP RSSI + checker_stings = ["R SSC1 A :\+SCAN:%s,[:\d\w]+,\d+,\d+,([-\d]+)\r" % ap_prop["ssid"]] + test_action_string = ["SSC SSC1 sta -S -s %s" % ap_prop["ssid"]] + fail_string = "Fail, Fail to scan" + rssi = scan_count = 0 + for i in range(3): + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + continue + rssi += int(self.test_env.get_variable_by_name("rssi")[1]) + scan_count += 1 + + rssi = calibrator.calibrate_rssi(float(rssi)/scan_count if scan_count > 0 else 0, att_value) + + # step 3 close all connections + checker_stings = ["R SSC1 C +CLOSEALL"] + test_action_string = ["SSC SSC1 soc -T"] + fail_string = "Fail, Fail to create server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + continue + + # step 4 create UDP socket + checker_stings = ["R SSC1 A :\+BIND:(\d+),OK"] + test_action_string = ["SSC SSC1 soc -B -t UDP -i %s -p %s" % (target_ip, udp_port)] + fail_string = "Fail, Fail bind" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + continue + + # step 5 do throughput test + send_thread = SendThread(udp_sock if rx_enable is True else None, + send_len, (target_ip, udp_port)) + send_thread.start() + + recv_thread = RecvThread(udp_sock if tx_enable is True else None) + recv_thread.start() + + if tx_enable is True: + # do send from target + test_action_string = ["SSC SSC1 soc -S -s -l %s -n 10000000 -i %s -p %s" + % (send_len, pc_ip, udp_port)] + fail_string = "Fail, Fail to send" + if self.load_and_exe_one_step([], test_action_string, fail_string) is False: + pass + + # start throughput calculate + recv_thread.start_calc() + + # sleep for measure period + time.sleep(measure_period) + + # stop throughput calculate + recv_thread.stop_calc() + send_thread.exit() + + send_thread.join() + recv_thread.join() + + # output throughput result + # in Mbps + if rx_enable is True: + # get received data len from PC + self.load_and_exe_one_step(["R SSC1 A :RECVLEN:(\d+)"], + ["SSC SSC1 soc -Q -s -o 1"], + "Fail, Fail to get recv data len") + try: + rx_data_len = int(self.get_parameter("recv_len")) + except StandardError: + rx_data_len = 0 + + result.log_throughput(ap_prop["ssid"] + "_rx", rssi, att_value, + float(rx_data_len * 8) / (measure_period * 1000000)) + + if recv_thread.get_bytes_recv() > 0: + result.log_throughput(ap_prop["ssid"] + "_tx", rssi, att_value, + float(recv_thread.get_bytes_recv() * 8) / (measure_period * 1000000)) + + result.output_to_file() + pass + + udp_sock.close() + + self.result_cntx.set_result("Succeed") + + # finally, execute done + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + +if __name__ == '__main__': + main() diff --git a/components/test/TestCaseScript/UDPStress/__init__.py b/components/test/TestCaseScript/UDPStress/__init__.py new file mode 100755 index 0000000000..d29ee405a4 --- /dev/null +++ b/components/test/TestCaseScript/UDPStress/__init__.py @@ -0,0 +1 @@ +__all__ = ["UDPSendRecv", ] diff --git a/components/test/TestCaseScript/WiFiStress/SoftAPNSTA.py b/components/test/TestCaseScript/WiFiStress/SoftAPNSTA.py new file mode 100755 index 0000000000..70a1169f20 --- /dev/null +++ b/components/test/TestCaseScript/WiFiStress/SoftAPNSTA.py @@ -0,0 +1,178 @@ +import random +import time +import string +import threading + +from TCAction import TCActionBase +from NativeLog import NativeLog +from TCAction import PerformanceTCBase +from Utility import Encoding + + +class STAJAPThread(threading.Thread): + def __init__(self, test_action, port_name, ssid, password, delay1, delay2, change_mac): + threading.Thread.__init__(self) + self.setDaemon(True) + self.test_action = test_action + self.port_name = port_name + self.ssid = ssid + self.password = password + self.delay1 = delay1 + self.delay2 = delay2 + self.change_mac = change_mac + self.exit_flag = threading.Event() + pass + + def exit(self): + self.exit_flag.set() + pass + + def run(self): + total_test_count = 0 + fail_count = 0 + while self.exit_flag.isSet() is False: + # change mac + if self.change_mac is True: + mac = Encoding.generate_random_mac() + self.test_action.serial_write_line(self.port_name, "mac -S -o 1 -m %s" % mac) + self.test_action.check_response(self.port_name, "+MAC:STA,OK") + + time.sleep(1) + + # JAP + total_test_count += 1 + # flush current port data + self.test_action.flush_data(self.port_name) + self.test_action.serial_write_line(self.port_name, "sta -C -s %s -p %s" % (self.ssid, self.password)) + if self.test_action.check_response(self.port_name, "+JAP:CONNECTED", 45) is False: + fail_count += 1 + NativeLog.add_trace_critical("[%s] Failed to JAP, Failed/Total : %d/%d" + % (self.port_name, fail_count, total_test_count)) + continue + time.sleep(random.randint(self.delay1[0], self.delay1[1])) + + # QAP + self.test_action.serial_write_line(self.port_name, "sta -D") + if self.test_action.check_response(self.port_name, "+QAP:OK", 5) is False: + NativeLog.add_trace_critical("[%s] Failed to QAP" % self.port_name) + time.sleep(random.randint(self.delay2[0], self.delay2[1])) + + # make sure quit AP + self.test_action.serial_write_line(self.port_name, "sta -D") + pass + pass + + +class SoftAPNSTA(PerformanceTCBase.PerformanceTCBase): + + def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): + PerformanceTCBase.PerformanceTCBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + self.sta_num = 0 + self.max_sta = 4 + self.test_time = 60 + self.delay1 = [5, 30] + self.delay2 = [5, 10] + self.change_mac = True + self.channel = 11 + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy" and cmd_set[i][0] != "": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + pass + + def process(self): + # configurable parameters + try: + sta_num = self.sta_num + max_sta = self.max_sta + test_time = self.test_time + # delay between JAP succeed and QAP + delay1 = self.delay1 + # delay between QAP and JAP + delay2 = self.delay2 + # if change mac each time before JAP + change_mac = self.change_mac + # channel + channel = self.channel + except StandardError, e: + raise StandardError("miss mandatory parameters") + + # step 0, set op mode and enable dhcp + self.serial_write_line("SSC1", "op -S -o 2") + if self.check_response("SSC1", "+MODE:OK", 2) is False: + NativeLog.add_trace_critical("Failed to set ap mode") + return + self.serial_write_line("SSC1", "dhcp -E -o 2") + if self.check_response("SSC1", "+DHCP:AP,OK", 2) is False: + NativeLog.add_trace_critical("Failed to enable ap dhcp") + return + self.serial_write_line("SSC1", "dhcp -L -s 192.168.4.2 -e 192.168.4.100 -t 1") + if self.check_response("SSC1", "+DHCP:LEASE,OK", 2) is False: + NativeLog.add_trace_critical("Failed to enable ap dhcp") + return + self.serial_write_line("SSC1", "dhcp -S -o 2") + if self.check_response("SSC1", "+DHCP:AP,OK", 2) is False: + NativeLog.add_trace_critical("Failed to enable ap dhcp") + return + + for i in range(sta_num): + self.serial_write_line("SSC%d" % (i+2), "op -S -o 1") + if self.check_response("SSC%d" % (i+2), "+MODE:OK", 2) is False: + NativeLog.add_trace_critical("Failed to set sta mode") + return + self.serial_write_line("SSC%d" % (i+2), "dhcp -S -o 1") + if self.check_response("SSC%d" % (i+2), "+DHCP:STA,OK", 2) is False: + NativeLog.add_trace_critical("Failed to enable sta dhcp") + + # step 1, set ap config and load + ap_ssid = "".join([random.choice(string.uppercase) for m in range(15)]) + ap_password = "".join([random.choice(string.lowercase) for m in range(15)]) + + self.serial_write_line("SSC1", "ap -S -s %s -p %s -t 3 -m %s -n %s" + % (ap_ssid, ap_password, max_sta, channel)) + if self.check_response("SSC1", "+SAP:OK", 2) is False: + NativeLog.add_trace_critical("Failed to set AP") + return + + # step 2, start thread to let STA JAP + sta_thread_list = [] + for i in range(sta_num): + sta_thread_list.append(STAJAPThread(self, "SSC%d" % (i+2), + ap_ssid, ap_password, delay1, delay2, change_mac)) + for sta_thread in sta_thread_list: + sta_thread.start() + + # step 3, sleep for test time + for i in range(test_time): + self.flush_data("SSC1") + time.sleep(60) + + # step 4, close all thread, will disconnect when exit thread + for sta_thread in sta_thread_list: + sta_thread.exit() + for sta_thread in sta_thread_list: + sta_thread.join() + # wait and make sure disconnect done + time.sleep(1) + + # step 5, join AP and check + sta_num_temp = max_sta if sta_num > max_sta else sta_num + + for i in range(sta_num_temp): + self.serial_write_line("SSC%d" % (i+2), "sta -C -s %s -p %s" % (ap_ssid, ap_password)) + if self.check_response("SSC%d" % (i+2), "+JAP:CONNECTED", 45) is False: + self.set_result("Fail") + break + pass + else: + self.set_result("Succeed") + + +def main(): + pass + +if __name__ == '__main__': + main() + diff --git a/components/test/TestCaseScript/WiFiStress/WifiConnUtility.py b/components/test/TestCaseScript/WiFiStress/WifiConnUtility.py new file mode 100755 index 0000000000..24702bfc8d --- /dev/null +++ b/components/test/TestCaseScript/WiFiStress/WifiConnUtility.py @@ -0,0 +1,240 @@ +from NativeLog import NativeLog +import time +import random + + +ERROR_AP_PROP = {"ssid": "123456789012345678901234567890", + "ssid_len": 30, + "pwd": "12345678901234567890", + "pwd_len": 20, + "channel": 10, + "enc": 3, + "apc": 9, # invalid apc count + } + + +class WifiConnUtilError(StandardError): + pass + + +class WifiConnUtility(object): + + def __init__(self, tc_action): + self.tc_action = tc_action + self.target_type = tc_action.target_type + pass + + def set_mode(self, mode): + ret = True + fail_string = "set mode fail" + cmd = [] + checker_stings = [] + for i in range(2): + if self.target_type[0] == "SSC": + cmd.append("SSCC SSC%d op -S -o %d" % (i+1, mode[i])) + checker_stings.append("SSCP SSC%d C +MODE:OK" % (i+1)) + pass + else: + cmd.append("ATC AT%d CWMODE %d" % (i+1, mode[i])) + checker_stings.append("ATP AT%d L OK" % (i+1)) + pass + if self.tc_action.load_and_exe_one_step(checker_stings, cmd, + fail_string, check_time=50) is False: + NativeLog.add_trace_critical("Failed to set mode") + ret = False + return ret + pass + + def _apc_switch(self, outlet_list, action_list): + checker_stings = ["R PC_COM C OK"] + switch_cmd = "APC " + fail_string = "Error when switching APC" + ret = True + + for [_outlet, _action] in zip(action_list, outlet_list): + switch_cmd += " %s %d" % (_action, _outlet) + + if self.tc_action.load_and_exe_one_step(checker_stings, [switch_cmd], + fail_string, check_time=50) is False: + NativeLog.add_trace_critical("Error when switching APC") + ret = False + return ret + pass + + def _set_target_ap(self, ap_prop): + ret = True + fail_string = "set target ap fail, %s, %s" % (ap_prop["ssid"], ap_prop["pwd"]) + if self.target_type[1] == "SSC": + if ap_prop["pwd"] == "": + cmd = ["SSCC SSC2 ap -S -s %s -t %d" % (ap_prop["ssid"], + ap_prop["enc"]) + ] + else: + cmd = ["SSCC SSC2 ap -S -s %s -p %s -t %d" % (ap_prop["ssid"], + ap_prop["pwd"], + ap_prop["enc"]) + ] + checker_stings = ["SSCP SSC2 C +SAP:OK"] + pass + else: + cmd = ["ATC AT2 CWSAP \"%s\" \"%s\" %d %d" % (ap_prop["ssid"], + ap_prop["pwd"], + ap_prop["channel"], + ap_prop["enc"]) + ] + checker_stings = ["ATR AT2 L OK"] + pass + if self.tc_action.load_and_exe_one_step(checker_stings, cmd, + fail_string, check_time=50) is False: + NativeLog.add_trace_critical("set target ap fail") + ret = False + return ret + pass + + def setup_ap(self, ap_type, ap_prop): + if ap_type == "target": + ret = self._set_target_ap(ap_prop) + pass + else: + ret = self._apc_switch(["ON"], [ap_prop["apc"]]) + # delay for 5 seconds, wait AP ready + time.sleep(5) + pass + return ret + + def do_scan(self, ap_prop): + fail_string = "Scan fail" + ret = True + # do not check if the set AP can be scanned + if self.target_type[1] == "SSC": + cmd = ["SSCC SSC1 sta -S"] + checker_stings = ["SSCR SSC1 C +SCANDONE"] + pass + else: + cmd = ["ATS AT1 AT+CWLAP"] + checker_stings = ["ATR AT1 L OK"] + pass + if self.tc_action.load_and_exe_one_step(checker_stings, cmd, + fail_string, check_time=100) is False: + NativeLog.add_trace_critical("Scan fail") + ret = False + return ret + pass + + def _switch_off_target_ap(self, delay): + time.sleep(delay) + self._set_target_ap(ERROR_AP_PROP) + pass + + def _switch_on_target_ap(self, ap_prop, delay): + time.sleep(delay) + self._set_target_ap(ap_prop) + pass + + def _switch_off_ap(self, ap_type, ap_prop, delay_range): + delay = random.randint(delay_range[0]*10, delay_range[1]*10)/10 + if ap_type == "target": + self._switch_off_target_ap(delay) + else: + delay -= 1.5 + time.sleep(delay if delay > 0 else 0) + self._apc_switch(["OFF"], [ap_prop["apc"]]) + pass + + def _switch_on_ap(self, ap_type, ap_prop, delay_range): + delay = random.randint(delay_range[0]*10, delay_range[1]*10)/10 + if ap_type == "target": + self._switch_on_target_ap(ap_prop, delay) + else: + delay -= 1.5 + time.sleep(delay if delay > 0 else 0) + self._apc_switch(["ON"], [ap_prop["apc"]]) + pass + + def _join_ap(self, ap_prop, test_method): + fail_string = "join target ap fail, %s, %s" % (ap_prop["ssid"], ap_prop["pwd"]) + if self.target_type[1] == "SSC": + cmd = ["SSCC SSC1 ap -C -s %s -p %s" % (ap_prop["ssid"], + ap_prop["pwd"],) + ] + checker_stings = ["SSCR SSC1 C +JAP:CONNECTED"] + pass + else: + cmd = ["ATC AT1 CWJAP \"%s\" \"%s\"" % (ap_prop["ssid"], + ap_prop["pwd"]) + ] + checker_stings = ["ATR AT1 NC ERROR NC FAIL L OK"] + pass + if test_method == "Normal": + ret = self.tc_action.load_and_exe_one_step(checker_stings, cmd, + fail_string, check_freq=0.1, check_time=350) + if ret is not False: + ret *= 0.1 + else: + ret = self.tc_action.load_and_exe_one_step([], cmd, fail_string) + return ret + pass + + def _check_join_ap_result(self, ap_prop): + ret = False + fail_string = "join ap fail, %s, %s" % (ap_prop["ssid"], ap_prop["pwd"]) + + if self.target_type[1] == "SSC": + checker_stings = ["SSCR SSC1 C +JAP:CONNECTED"] + ret = self.tc_action.load_and_exe_one_step(checker_stings, ["DELAY 0"], + fail_string, check_freq=1, check_time=120) + pass + else: + cmd = ["ATS AT1 AT+CWJAP?"] + checker_stings = ["ATR AT1 NC busy NC No%20AP C +CWJAP"] + for i in range(3): + ret = self.tc_action.load_and_exe_one_step(checker_stings, cmd, + fail_string, check_freq=1, check_time=2) + if ret is not False: + break + time.sleep(15) + + return ret + pass + + def join_ap(self, join_test_method, ap_type, ap_prop, delay): + + if join_test_method == "WRONG_PROP": + _prop = ERROR_AP_PROP + else: + _prop = ap_prop + + ret = self._join_ap(_prop, join_test_method) + + if join_test_method == "OFF_ON": + self._switch_off_ap(ap_type, ap_prop, delay[0]) + self._switch_on_ap(ap_type, ap_prop, delay[1]) + ret = self._check_join_ap_result(_prop) + pass + elif join_test_method == "OFF": + self._switch_off_ap(ap_type, ap_prop, delay[0]) + time.sleep(25) + pass + + return ret + pass + + def do_reconnect(self, reconnect_test_method, ap_type, ap_prop, delay): + ret = True + if reconnect_test_method == "OFF_ON": + self._switch_off_ap(ap_type, ap_prop, delay[0]) + self._switch_on_ap(ap_type, ap_prop, delay[1]) + ret = self._check_join_ap_result(ap_prop) + pass + elif reconnect_test_method == "OFF": + self._switch_off_ap(ap_type, ap_prop, delay[0]) + pass + return ret + pass + + +def main(): + pass + +if __name__ == '__main__': + main() diff --git a/components/test/TestCaseScript/WiFiStress/WifiJAP.py b/components/test/TestCaseScript/WiFiStress/WifiJAP.py new file mode 100755 index 0000000000..20dd28041e --- /dev/null +++ b/components/test/TestCaseScript/WiFiStress/WifiJAP.py @@ -0,0 +1,218 @@ +import os +import random +import time + +import WifiConnUtility +from NativeLog import NativeLog +from TCAction import TCActionBase +from Utility import Encoding +from Utility import MakeFolder + +STEPS = {"SCAN1": 0x01, "JAP": 0x02, "SCAN2": 0x04, "RECONNECT": 0x08} + +AP_PROP = ("ssid", "ssid_len", "pwd", + "pwd_len", "channel", "enc", "apc") + +JAP_TEST_METHOD = ("Normal", "OFF_ON", "OFF", "WRONG_PROP") + +RECONNECT_TEST_METHOD = ("OFF_ON", "OFF") + +LOG_FOLDER = os.path.join("AT_LOG", "Performance", "JAP") + + +SSID_LEN_RANGE = (1, 32) # in bytes +ENC_TYPE = (0, 2, 3, 4) # do not support WEP for 8266 soft AP +PWD_RANGE = {0: [0, 0], + 1: [5, 5], + 2: [8, 63], + 3: [8, 63], + 4: [8, 63], + } + + +class WifiJAP(TCActionBase.CommonTCActionBase): + + def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + # default value for optional configurable params + self.pwd_len = [8, 64] + self.step_config = [0x03, 0x01, 0x02, 0x0B, 0x0F] + self.join_test_method = ["Normal"] + self.join_delay = [[1.5, 5], [1.5, 5]] + self.reconnect_test_method = ["OFF_ON"] + self.reconnect_delay = [[1.5, 5], [1.5, 6]] + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy" and cmd_set[i][0] != "": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + # read AP list + self.ap_list = [] + for i in range(1, len(cmd_set)): + for j in range(len(cmd_set[i][1])): + if cmd_set[i][1][j] != "": + cmd_string = "self.ap_list.append(dict(zip(AP_PROP, " + cmd_set[i][1][j] + ")))" + exec cmd_string + + folder_path = MakeFolder.make_folder(LOG_FOLDER) + file_name = "JAP_log_%s.log" % (time.strftime("%m%d%H%M%S", time.localtime())) + self._performance_log_file = os.path.join(folder_path, file_name) + + # test statistics + self._succeed_count = self._fail_count = self._time_cost_count = 0 + self._total_time = self._longest_time = 0 + + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + # get target type "SSC" or "AT" + self.target_type = ["SSC" if test_env.get_port_by_name("AT1") is None else "AT"] + self.target_type.append("SSC" if test_env.get_port_by_name("AT2") is None else "AT") + self._utility = WifiConnUtility.WifiConnUtility(self) + pass + + def _generate_random_ap_prop(self): + ap_prop = dict.fromkeys(AP_PROP) + # generate target ap_value + ap_prop["ssid_len"] = random.randint(SSID_LEN_RANGE[0], SSID_LEN_RANGE[1]) + ap_prop["channel"] = random.choice(range(1, 14)) + ap_prop["enc"] = random.choice(ENC_TYPE) + ap_prop["pwd_len"] = random.randint(PWD_RANGE[ap_prop["enc"]][0], PWD_RANGE[ap_prop["enc"]][1]) + # generate string + if self.target_type[0] == self.target_type[1] == "AT": + ap_prop["ssid"] = Encoding.generate_random_utf8_str(ap_prop["ssid_len"]) + ap_prop["pwd"] = Encoding.generate_random_utf8_str(ap_prop["pwd_len"]) + # NativeLog.add_trace_info("ssid hex is : %x" % ap_prop["ssid"]) + # NativeLog.add_trace_info("pwd hex is : %x" % ap_prop["pwd"]) + else: + ap_prop["ssid"] = Encoding.generate_random_printable_str(ap_prop["ssid_len"]) + ap_prop["pwd"] = Encoding.generate_random_printable_str(ap_prop["pwd_len"]) + + return ap_prop + + def _logging_performance(self, ssid, join_method="Normal", time_cost=0): + # log performance to performance log file + with open(self._performance_log_file, "ab+") as f: + # log time and ssid + f.write("\r\n[%s]:\r\n[AP name] %s\r\n" % + (time.strftime("%m-%d %H:%M:%S", time.localtime()), ssid)) + if join_method == "Normal" or join_method == "OFF_ON": + if time_cost is not False: + self._succeed_count += 1 + if join_method == "Normal": + f.write("[Succeed][%f]\r\n" % time_cost) + self._longest_time = (time_cost > self._longest_time and + [time_cost] or [self._longest_time])[0] + self._time_cost_count += 1 + self._total_time += time_cost + else: + f.write("[Succeed][%s]\r\n" % join_method) + else: + self._fail_count += 1 + f.write("[Fail][%s]\r\n" % join_method) + pass + + def _logging_fail_step(self, ssid, step): + with open(self._performance_log_file, "ab+") as f: + f.write("\r\n[%s]:\r\n[AP name] %s\r\n" % + (time.strftime("%m-%d %H:%M:%S", time.localtime()), ssid)) + f.write("[Fail][%s]\r\n" % step) + pass + + def _generate_performance_report(self): + with open(self._performance_log_file, "ab+") as f: + f.write("[Test report] Succeed: %d\r\n" % self._succeed_count) + f.write("[Test report] Failed: %d\r\n" % self._fail_count) + if self._succeed_count > 0 or self._fail_count > 0: + f.write("[Test report] Pass Rate: %f\r\n" % + (self._succeed_count/(self._fail_count+self._succeed_count))) + if self._time_cost_count > 0: + f.write("[Test report] Average time: %f\r\n" % (self._total_time/self._time_cost_count)) + f.write("[Test report] Longest time: %f\r\n" % self._longest_time) + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + # mandatory configurable params + try: + target_ap_num = self.target_ap_num + test_count = self.test_count + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for WifiJAP script, error is %s" % e) + raise StandardError("Error configuration") + + # prepare ap list + _ap_list = [["target", None]] * target_ap_num + for _ap_prop in self.ap_list: + _ap_list.append(["AP", _ap_prop]) + + # set to correct mode first + self._utility.set_mode([1, 2]) + + for i in xrange(test_count): + _ap = random.choice(_ap_list) + # arrange ap + _ap_type = _ap[0] + _ap_prop = _ap[1] + if _ap_type == "target": + _ap_prop = self._generate_random_ap_prop() + pass + + # step 1 : mandatory step, set up AP + if self._utility.setup_ap(_ap_type, _ap_prop) is False: + self._logging_fail_step(_ap_prop["ssid"], "Set AP") + NativeLog.add_prompt_trace("[Step1] setup AP Fail") + continue + step_config = random.choice(self.step_config) + NativeLog.add_prompt_trace("[Step1] setup AP succeed") + + # step 2 : optional step, do scan before connect + if step_config & STEPS["SCAN1"] != 0: # check option + if self._utility.do_scan(_ap_prop) is False: + self._logging_fail_step(_ap_prop["ssid"], "Scan before JAP") + NativeLog.add_prompt_trace("[Step2] Scan Done") + + # step 3 : mandatory step, join AP + if step_config & STEPS["JAP"] != 0: # check option + _join_test_method = random.choice(self.join_test_method) + time_cost = self._utility.join_ap(_join_test_method, _ap_type, _ap_prop, self.join_delay) + # log performance to performance log file + self._logging_performance(_ap_prop["ssid"], _join_test_method, time_cost) + if time_cost is False: + # do scan once to check if AP exist + self._utility.do_scan(_ap_prop) + continue + NativeLog.add_prompt_trace("[Step3] Join AP done") + + # step 4 : optional step, scan after join AP + if step_config & STEPS["SCAN2"] != 0: # check option + if self._utility.do_scan(_ap_prop) is False: + self._logging_fail_step(_ap_prop["ssid"], "Scan after JAP") + NativeLog.add_prompt_trace("[Step4] Scan done") + + # step 5 : optional step, reconnect test + if step_config & STEPS["RECONNECT"] != 0: # check option + _reconnect_test_method = random.choice(self.reconnect_test_method) + if self._utility.do_reconnect(_reconnect_test_method, + _ap_type, _ap_prop, self.reconnect_delay) is False: + self._logging_fail_step(_ap_prop["ssid"], "Reconnect") + + NativeLog.add_prompt_trace("[Step5] Reconnect done") + # continue to next loop + NativeLog.add_prompt_trace("[WifiJAP] Test count %d done" % i) + + # generate report and cleanup + self._generate_performance_report() + + self.result_cntx.set_result("Succeed") + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + +if __name__ == '__main__': + main() diff --git a/components/test/TestCaseScript/WiFiStress/WifiJAPAtt.py b/components/test/TestCaseScript/WiFiStress/WifiJAPAtt.py new file mode 100755 index 0000000000..2c2eadc79d --- /dev/null +++ b/components/test/TestCaseScript/WiFiStress/WifiJAPAtt.py @@ -0,0 +1,173 @@ +import os +import time +from TCAction import TCActionBase +from NativeLog import NativeLog +from Utility import RSSICalibrator +from Utility import MakeFolder + +MAX_RSSI = 0 +MIN_RSSI = -110 +MAX_ATT = 60 +LOG_FOLDER = os.path.join("AT_LOG", "Performance", "JAP") +AP_PROP_KEY = ("ssid", "password", "apc") + + +class Performance(object): + def __init__(self): + self.succeed_rssi = dict.fromkeys(range(MIN_RSSI, MAX_RSSI), 0) + self.failed_rssi = dict.fromkeys(range(MIN_RSSI, MAX_RSSI), 0) + self.failed_att = dict.fromkeys(range(MAX_ATT), 0) + pass + + def log_performance(self, result, att, rssi): + if result == "Succeed": + self.succeed_rssi[rssi] += 1 + else: + if rssi == 0: + self.failed_att[att] += 1 + else: + self.failed_rssi[rssi] += 1 + pass + + def __str__(self): + data = "Succeed:\r\n" + for rssi in self.succeed_rssi: + if self.succeed_rssi[rssi] > 0: + data += "\tRSSI%4d: %2d times\r\n" % (rssi, self.succeed_rssi[rssi]) + + data += "Failed during scan:\r\n" + for att in self.failed_att: + if self.failed_att[att] > 0: + data += "\tATT%3d: %2d times\r\n" % (att, self.failed_att[att]) + + data += "Failed during JAP:\r\n" + for rssi in self.failed_rssi: + if self.failed_rssi[rssi] > 0: + data += "\tRSSI%4d: %2d times\r\n" % (rssi, self.failed_rssi[rssi]) + + return data + pass + + +class WifiJAPAtt(TCActionBase.CommonTCActionBase): + + def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + self.att_test_list = range(60) + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + # read AP list + self.ap_list = [] + for i in range(1, len(cmd_set)): + for j in range(len(cmd_set[i][1])): + if cmd_set[i][1][j] != "": + cmd_string = "self.ap_list.append(dict(zip(AP_PROP_KEY, " + cmd_set[i][1][j] + ")))" + exec cmd_string + + self.performance = dict([(ap_prop["ssid"], Performance()) for ap_prop in self.ap_list]) + # create log file + folder_path = MakeFolder.make_folder(LOG_FOLDER) + self.performance_log = os.path.join(folder_path, + "JAP_Att_%s.log" % time.strftime("%d%H%M%S", time.localtime())) + + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + pass + + def log_performance(self, att, rssi, ssid, result): + NativeLog.add_prompt_trace("[%s][ssid %s] [att %s] [rssi %s]" % (result, ssid, att, rssi)) + data = "" + self.performance[ssid].log_performance(result, att, rssi) + for _ssid in self.performance: + data += "[ssid] %s\r\n%s\r\n" % (_ssid, self.performance[_ssid]) + with open(self.performance_log, "wb+") as f: + f.write(data) + pass + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + try: + # configurable params + ap_list = self.ap_list + att_test_list = self.att_test_list + test_count = self.test_count + # configurable params + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for JAPAtt script, error is %s" % e) + raise StandardError("Error configuration") + + for x in xrange(test_count): + for ap_prop in ap_list: + if ap_prop["password"] == "": + # set a default string for open ap + ap_prop["password"] = "1" + + # switch off all outlet, switch on AP outlet + outlet_config_dict = dict.fromkeys(range(1, 9), "OFF") + outlet_config_dict[ap_prop["apc"]] = "ON" + apc_cmd = "APC " + for outlet in outlet_config_dict: + apc_cmd += " %s %s" % (outlet_config_dict[outlet], outlet) + checker_stings = ["P PC_COM L OK"] + fail_string = "Fail, Fail to switch apc" + if self.load_and_exe_one_step(checker_stings, [apc_cmd], fail_string) is False: + return + + # wait AP ready + time.sleep(20) + + # create RSSI Calibrator + calibrator = RSSICalibrator.Calibrator() + + for att_value in att_test_list: + # step 0 set att value + checker_stings = ["R PC_COM L OK"] + test_action_string = ["ATT %s" % att_value] + fail_string = "Fail, Fail to set att value" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + continue + + # step 1 get AP RSSI + checker_stings = ["R SSC1 A :\+SCAN:%s,[:\d\w]+,\d+,\d+,([-\d]+)" % ap_prop["ssid"]] + test_action_string = ["SSC SSC1 sta -S -s %s" % ap_prop["ssid"]] + fail_string = "Fail, Fail to scan" + rssi = scan_count = 0 + for i in range(3): + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, + check_freq=1, check_time=5) is False: + self.log_performance(att_value, 0, ap_prop["ssid"], "Failed to measure RSSI") + continue + rssi += int(self.test_env.get_variable_by_name("rssi")[1]) + scan_count += 1 + + rssi = calibrator.calibrate_rssi(float(rssi)/scan_count if scan_count > 0 else 0, att_value) + + # step 2 connect to AP + checker_stings = ["R SSC1 C +JAP:CONNECTED"] + test_action_string = ["SSC SSC1 sta -C -s %s -p %s" % (ap_prop["ssid"], ap_prop["password"])] + fail_string = "Fail, Fail to JAP" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, + check_freq=1, check_time=45) is False: + self.log_performance(att_value, rssi, ap_prop["ssid"], "Failed to JAP") + continue + + self.log_performance(att_value, rssi, ap_prop["ssid"], "Succeed") + + # finally, execute done + self.result_cntx.set_result("Succeed") + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + +if __name__ == '__main__': + main() diff --git a/components/test/TestCaseScript/WiFiStress/WifiSmartConfig.py b/components/test/TestCaseScript/WiFiStress/WifiSmartConfig.py new file mode 100755 index 0000000000..3a95a920fb --- /dev/null +++ b/components/test/TestCaseScript/WiFiStress/WifiSmartConfig.py @@ -0,0 +1,273 @@ +import random +import os +import time +import copy + +from TCAction import TCActionBase +from NativeLog import NativeLog +from Utility import Encoding +from Utility import MakeFolder + +AP_PROP = ("ssid", "ssid_len", "pwd", + "pwd_len", "channel", "enc", "apc") + +SMART_TYPE = ("esp-touch", "airkiss") + +TEST_METHOD = ("ssid_broadcast", "ssid_hidden") + +HT = ("ht20", "ht40") + +TEST_STAT = ("total count", "fail count", "total time", "longest time") + +_TEST_STAT_INIT_DICT = {"total count": 0, + "fail count": 0, + "total time": 0, + "longest time": 0, + } + +LOG_FOLDER = os.path.join("AT_LOG", "Performance", "SmartConfig") + + +SSID_LEN_RANGE = (1, 32) # in bytes +ENC_TYPE = (0, 2, 3, 4) # do not support WEP for 8266 soft AP +PWD_RANGE = {0: [0, 0], + 1: [5, 5], + 2: [8, 32], + 3: [8, 32], + 4: [8, 32], + } + + +class WifiSmartConfig(TCActionBase.CommonTCActionBase): + + def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + # default value for optional configurable params + self.test_method = ["ssid_hidden", "ssid_broadcast"] + self.bssid = "ff:ff:ff:ff:ff:ff" + self.ht_ap = dict(zip(HT, [("", ""), + ("", "")])) + self.ap_channel = {"ht20": 1, "ht40": 1} + self.delay_time = 3 # default 3s, wait for scan done + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy" and cmd_set[i][0] != "": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + + folder_path = MakeFolder.make_folder(LOG_FOLDER) + file_name = "SmartConfig_log_%s.log" % (time.strftime("%m%d%H%M%S", time.localtime())) + self._performance_log_file = os.path.join(folder_path, file_name) + + # type + self.target_type = ["SSC" if test_env.get_port_by_name("AT1") is None else "AT"] + self.target_type.append("SSC" if test_env.get_port_by_name("AT2") is None else "AT") + + # test statistics + # better ways to create? + _test_stat = dict.fromkeys(TEST_STAT, 0) + _test_method = dict.fromkeys(TEST_METHOD) + _test_ht = dict.fromkeys(HT) + self.test_stat = dict.fromkeys(SMART_TYPE) + for i in SMART_TYPE: + self.test_stat[i] = copy.deepcopy(_test_ht) + for j in HT: + self.test_stat[i][j] = copy.deepcopy(_test_method) + for k in TEST_METHOD: + self.test_stat[i][j][k] = copy.deepcopy(_test_stat) + + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + pass + + def _generate_random_ap_prop(self, ht_type): + ap_prop = dict.fromkeys(AP_PROP) + # generate target ap_value + ap_prop["ssid_len"] = random.randint(SSID_LEN_RANGE[0], SSID_LEN_RANGE[1]) + ap_prop["channel"] = self.ap_channel[ht_type] + ap_prop["enc"] = random.choice(ENC_TYPE) + ap_prop["pwd_len"] = random.randint(PWD_RANGE[ap_prop["enc"]][0], PWD_RANGE[ap_prop["enc"]][1]) + ap_prop["ssid"] = Encoding.generate_random_printable_str(ap_prop["ssid_len"]) + ap_prop["pwd"] = Encoding.generate_random_printable_str(ap_prop["pwd_len"]) + + return ap_prop + + def _logging_performance(self, time_cost, ssid, password, smart_type, test_method, ht_type): + # update test statistics + stat = self.test_stat[smart_type][ht_type][test_method] + stat["total count"] += 1 + # log performance to performance log file + with open(self._performance_log_file, "ab+") as f: + # log time and ssid + if time_cost is not False: + time_tmp = float(time_cost)/10 + f.write("\r\n[%s]:\r\n[Succeed] [%.2f]\r\n" % + (time.strftime("%m-%d %H:%M:%S", time.localtime()), time_tmp)) + stat["total time"] += time_tmp + stat["longest time"] = time_tmp if time_tmp > stat["longest time"] else stat["longest time"] + else: + f.write("\r\n[%s]:\r\n[Fail]\r\n" % + time.strftime("%m-%d %H:%M:%S", time.localtime())) + stat["fail count"] += 1 + + f.write("[%s] [%s] [%s]\r\n" % + (smart_type, test_method, ht_type)) + f.write("[ssid] %s \r\n[password] %s\r\n" % + (ssid, password)) + pass + + def _generate_performance_report(self): + with open(self._performance_log_file, "ab+") as f: + for i in SMART_TYPE: + for j in HT: + for k in TEST_METHOD: + stat = self.test_stat[i][j][k] + f.write("\r\n[Test report] [%s] [%s] [%s]\r\n" % (i, j, k)) + if stat["total count"] > 0: + f.write("[Total]: %d\r\n" % stat["total count"]) + f.write("[Failed]: %d\r\n" % stat["fail count"]) + f.write("[Fail ratio]: %.2f%%\r\n" % + (float(stat["fail count"])/stat["total count"] * 100)) + f.write("[Longest time cost]: %.2f\r\n" % stat["longest time"]) + if (stat["total count"] - stat["fail count"]) > 0: + f.write("[Average time cost]: %.2f\r\n" % + (stat["total time"]/(stat["total count"]-stat["fail count"]))) + + @staticmethod + def cmd_exception_catcher(e): + raise e + pass + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + # mandatory configurable params + try: + test_count = self.test_count + delay_time = self.delay_time + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for WifiJAP script, error is %s" % e) + raise StandardError("Error configuration") + + # step 0 : set AT1 mode + fail_string = "Fail to restore init condition" + if self.target_type[0] == "AT": + cmd = ["ATS AT1 AT+CWMODE=1"] + checker_stings = ["R AT1 L OK"] + else: + cmd = ["SSC SSC1 op -S -o 1"] + checker_stings = ["R SSC1 C +MODE:OK"] + if self.target_type[1] == "AT": + cmd.append("ATS AT2 AT+CWMODE=2") + checker_stings.append("R AT2 L OK") + else: + cmd.append("SSC SSC2 op -S -o 2") + checker_stings.append("R SSC2 C +MODE:OK") + + if self.load_and_exe_one_step(checker_stings, cmd, + fail_string, check_time=150) is False: + NativeLog.add_trace_critical(fail_string) + return + + for i in xrange(test_count): + _method = random.choice(self.test_method) + _ht = random.choice(self.ht) + _ap_prop = self._generate_random_ap_prop(_ht) + _smart_type = random.choice(self.smart_type) + _ht_ap = self.ht_ap[_ht] + is_hidden = 0 if _method == "ssid_broadcast" else 1 + # get ip and + + # step 1 : restore init condition + fail_string = "Fail to restore init condition" + if self.target_type[0] == "AT": + cmd = ["ATS AT1 AT+CWSTOPSMART", "WIFI CONN %s %s " % (_ht_ap[0], _ht_ap[1])] + checker_stings = ["P AT1 L OK", "P PC_COM L OK"] + else: + cmd = ["SSC SSC1 smart -E", "WIFI CONN %s %s " % (_ht_ap[0], _ht_ap[1])] + checker_stings = ["P SSC1 C +SC:OK", "P PC_COM L OK"] + + if self.load_and_exe_one_step(checker_stings, cmd, + fail_string, check_time=200) is False: + NativeLog.add_trace_critical(fail_string) + continue + NativeLog.add_prompt_trace("Step1 Done") + + # step 2 : test method is ssid_broadcast, then set AP on target 2 + if _method == "ssid_broadcast": + fail_string = "Fail to set AP" + if self.target_type[1] == "AT": + cmd = ["ATS AT2 AT+CWSAP=\"%s\",\"%s\",%d,%d" % (_ap_prop["ssid"], _ap_prop["pwd"], + _ap_prop["channel"], _ap_prop["enc"])] + checker_stings = ["R AT2 L OK"] + else: + cmd = ["SSC SSC2 ap -S -s %s -p %s -n %d -t %d" % (_ap_prop["ssid"], _ap_prop["pwd"], + _ap_prop["channel"], _ap_prop["enc"])] + checker_stings = ["R SSC2 C +SAP:OK"] + + if self.load_and_exe_one_step(checker_stings, cmd, + fail_string, check_time=50) is False: + NativeLog.add_trace_critical(fail_string) + continue + NativeLog.add_prompt_trace("Step2 Done") + + # step 3 : start SMART + fail_string = "Fail to start smart config" + if self.target_type[0] == "AT": + cmd = ["ATS AT1 AT+CWSTARTSMART"] + checker_stings = ["R AT1 L OK"] + else: + cmd = ["SSC SSC1 smart -S -a 0"] + checker_stings = ["R SSC1 C +SC:OK"] + + if self.load_and_exe_one_step(checker_stings, cmd, + fail_string, check_time=50) is False: + NativeLog.add_trace_critical(fail_string) + continue + # sleep for delay_time seconds to wait scan done or simulate delay config situation + time.sleep(delay_time) + NativeLog.add_prompt_trace("Step3 Done") + + # step 4 : do smart config + fail_string = "Fail in smart config" + cmd = ["SMART %s %s %s %s %d" + % (_smart_type, _ap_prop["ssid"], _ap_prop["pwd"], self.bssid, is_hidden)] + if self.target_type[0] == "AT": + checker_stings = ["P AT1 C Smart%20get%20wifi%20info", + "P LOG1 C %s C %s" % (_ap_prop["ssid"], _ap_prop["pwd"])] + else: + checker_stings = ["P SSC1 C %s C %s" % (_ap_prop["ssid"], _ap_prop["pwd"])] + + try: + time_cost = self.load_and_exe_one_step(checker_stings, cmd, + fail_string, check_time=400, + cmd_exception_catcher=self.cmd_exception_catcher) + except StandardError: + NativeLog.add_prompt_trace("Exception occurred during executing cmd") + continue + pass + self._logging_performance(time_cost, _ap_prop["ssid"], _ap_prop["pwd"], + _smart_type, _method, _ht) + if time_cost is False: + NativeLog.add_prompt_trace(fail_string) + continue + + # continue to next loop + NativeLog.add_prompt_trace("[WifiSmartConfig] Test count %d done" % i) + + # generate report and cleanup + self._generate_performance_report() + + self.result_cntx.set_result("Succeed") + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + +if __name__ == '__main__': + main() diff --git a/components/test/TestCaseScript/WiFiStress/__init__.py b/components/test/TestCaseScript/WiFiStress/__init__.py new file mode 100755 index 0000000000..7960a3ce80 --- /dev/null +++ b/components/test/TestCaseScript/WiFiStress/__init__.py @@ -0,0 +1 @@ +__all__ = ["WifiJAP", ] \ No newline at end of file diff --git a/components/test/TestCaseScript/__init__.py b/components/test/TestCaseScript/__init__.py new file mode 100755 index 0000000000..0cc319da70 --- /dev/null +++ b/components/test/TestCaseScript/__init__.py @@ -0,0 +1,2 @@ +__all__ = ['ATFunc', "ATStress", "IOT", "MeshStress", "StableTest", "TCPIPStress" + "TCPStress", "UDPStress", "WiFiStress"] diff --git a/components/test/TestEnvAll.yml b/components/test/TestEnvAll.yml new file mode 100644 index 0000000000..703fafcb60 --- /dev/null +++ b/components/test/TestEnvAll.yml @@ -0,0 +1,275 @@ +test environment: +- {PC OS: '', Special: N, Target Count: 2.0, script path: EnvBase.py, tag: SSC_T2_SmartConfig, + test environment detail: '2 SSC target connect with PC by UART. + + PC has 1 WiFi NIC. + + One HT20 AP and One HT40 AP are placed near target.', test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 2.0, script path: EnvBase.py, tag: AT_T2_SmartConfig, + test environment detail: '2 AT target connect with PC by UART (AT and LOG port). + + PC has 1 WiFi NIC. + + One HT20 AP and One HT40 AP are placed near target.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_IOT1, + test environment detail: 'PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART. + + AP todo IOT test are placed near SSC1.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 2.0, UART ports: 'SSC1 + + SSC2', additional param list: '', basic param list: '', script path: EnvBase.py, + tag: SSC_T2_GPIO3, test environment detail: '[TBD] 2个ESP_8266通过UART连到PC, ESP_8266之间需要测试的Target_GPIO相连', + test script: EnvBase} +- {PC OS: linux, Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: WebServer_T1_1, + test environment detail: 'Web Server target connect with PC by UART. + + PC has 1 wired NIC connected to switch. + + APC, AP also connect with swtich. + + All devices connected with switch use same IP subnet. + + APC control AP power supply.', test script: EnvBase} +- {PC OS: linux, Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: WebServer_T1_2, + test environment detail: 'Web Server target connect with PC by UART. + + 4 PC with WiFi NIC placed near WebServer1.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 2.0, UART ports: 'SSC1 + + SSC2', additional param list: '', basic param list: '', script path: EnvBase.py, + tag: SSC_T2_GPIO1, test environment detail: '[TBD] 2个ESP_8266通过UART连到PC, ESP_8266的 + GPIO_6相连', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_Enterprise, + test environment detail: "AP use WPA2-Etherprise is placed near SSC1. \n1 SSC target\ + \ connect with PC by UART.", test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 2.0, UART ports: 'SSC1 + + SSC2', additional param list: '', basic param list: '', script path: EnvBase.py, + tag: SSC_T2_GPIO2, test environment detail: '[TBD] 1. 2个ESP_8266通过UART连到PC, ESP_8266的 + GPIO_15通过面包板相连 + + 2. 可借助面包板, 将GPIO_15, 以及中断函数被打开的8266板的GPIO_2 相连', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: AT_T1_HighSpeedUART, + test environment detail: 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 AT target connect with PC by high speed UART (AT and LOG port).', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 2.0, script path: EnvBase.py, tag: SSC_T2_ShieldBox, + test environment detail: '2 SSC target connect with PC by UART. + + Put them to Shield box.', test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 1.0, script path: EnvBase.py, tag: AT_T1_3, + test environment detail: 'Able to access WAN after connect to AP. + + 1 AT target connect with PC by UART (AT and LOG port).', test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 1.0, script path: EnvBase.py, tag: AT_T1_2, + test environment detail: 'PC has 1 WiFi NIC. + + 1 AT target connect with PC by UART (AT and LOG port).', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, UART ports: 'SSC1 + + SSC2', additional param list: '', basic param list: '', script path: EnvBase.py, + tag: UART_T1_2, test environment detail: '[TBD] ESP_8266通过UART_0通过USB, UART_1 TXD + 通过 TTLcable 连到PC', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, UART ports: SSC_1, additional param list: '', + basic param list: '', script path: EnvBase.py, tag: UART_T1_1, test environment detail: '[TBD] + 将ESP_8266通过UART连到PC', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: AT_T1_ADC, + test environment detail: 'PC has 1 wired NIC connected to AP. + + Analog input connect to AT1 TOUT. + + Multimeter connect to input, able to measure input voltage. + + 1 AT target connect with PC by UART (AT and LOG port).', test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_WEP, + test environment detail: '1 SSC target connect with PC by UART. + + One WEP share key AP placed near SSC1.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_ADC, + test environment detail: 'PC has 1 wired NIC connected to AP. + + Analog input connect to SSC1 TOUT. + + Multimeter connect to input, able to measure input voltage. + + 1 SSC target connect with PC by UART.', test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_APC, + test environment detail: "PC has 1 wired NIC connected to AP.\nPC has 1 wired NIC\ + \ connected to APC (static IP within the same subnet with APC). \nAPC control\ + \ AP power supply. \nPC has 1 WiFi NIC. \n1 SSC target connect with PC by UART.", + test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_8089, + test environment detail: 'PC has 1 wired NIC connected to AP. + + 1 8089 tablet able to run iperf test placed near SSC1. + + 1 SSC target connect with PC by UART.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 2.0, script path: EnvBase.py, tag: SSC_T1_InitData, + test environment detail: '2 SSC target connect with PC by UART. + + SSC1 use 40M crystal oscillator. + + SSC2 use normal 26M crystal oscillator. + + SSC2 GPIO connect to SSC1 power control pin.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, UART ports: SSC_1, additional param list: '', + basic param list: '', script path: EnvBase.py, tag: SSC_T1_Timer, test environment detail: '[TBD] + 通过串口工具调节Timer, 将GPIO_13端口连接到逻辑分析仪', test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 3.0, script path: EnvBase.py, tag: SSC_T3_PhyMode, + test environment detail: '3 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with (HT20, channel1), (HT20, channel2), (HT40, channel1), (HT40, channel2). + + Put 4 APs near SSC targets.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 2.0, script path: EnvBase.py, tag: AT_T2_JAP, + test environment detail: "Several AP are placed near AT target.\nPC has 1 wired\ + \ NIC connected to APC (static IP within the same subnet with APC).\nAPC control\ + \ power supply for all APs. \n2 AT target connect with PC by UART (AT and LOG\ + \ port).", test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 2.0, script path: EnvBase.py, tag: SSC_T2_PhyMode, + test environment detail: '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_ShieldBox, + test environment detail: 'refer to figure. + + All APs and APC should be set to the same IP subnet. + + PC wired NIC should set static IP address within the same subnet with AP. + + Must use onboard wired NIC.', test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 2.0, script path: EnvBase.py, tag: SSC_T2_1, + test environment detail: 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: TempSensor_T1_1, + test environment detail: 'Tempeture sensor target connect with PC by UART. + + AP support DTIM placed with AT target. + + Multimeter connect with PC via GPIB. + + Series multimeter between GND and VCC of TempSensor1. + + PC has 1 wired NIC connected to switch. + + APC, AP also connect with swtich. + + All devices connected with switch use the same IP subnet. + + APC control AP power supply.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: AT_T1_SmartConfigIOT, + test environment detail: '1 AT target connect with PC by UART (AT and LOG port). + + PC has 1 wired NIC connect to Common AP. + + Several AP are placed near AT target. + + Several smart phone installed test APK are placed near AT target.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 2.0, script path: EnvBase.py, tag: AT_T2_Sleep, + test environment detail: 'AP support DTIM placed with AT target. + + 2 AT target connect with PC by UART (AT and LOG port). + + Multimeter connect with PC via GPIB. + + Series multimeter between GND and VCC of AT1. + + AT1''s light sleep wakeup pin and wakeup indication connect with AT2''s GPIO.', + test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 5.0, script path: EnvBase.py, tag: SSC_T5_1, + test environment detail: 5 SSC target connect with PC by UART., test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_TempBox, + test environment detail: '1 SSC target connect with PC by UART. + + Put SSC target to temperature box.', test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 1.0, script path: EnvBase.py, tag: AT_T1_1, + test environment detail: 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 AT target connect with PC by UART (AT and LOG port).', test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T6_1, + test environment detail: 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 6 SSC target connect with PC by UART.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, UART ports: 'SSC1 + + SSC2', additional param list: '', basic param list: '', script path: EnvBase.py, + tag: IR_T2_1, test environment detail: '[TBD] 本测试为非自动测试, 红外能够做到数据收发吻合即可通过', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_VDD33, + test environment detail: '1 SSC target connect with PC by UART. + + Multimeter connect to VDD33, able to measure voltage.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, UART ports: SSC_1, additional param list: '', + basic param list: '', script path: EnvBase.py, tag: PWM_T1_1, test environment detail: "[TBD]\ + \ 1. PWM OS SDK 以及 Non-OS SDK的测试建议分开进行, 放在不同的文件夹, 防止文件命名混淆\n2. 分析CSV文件的Python脚本只能分析单个channel\ + \ \n3. 如果Init脚本打印\"Network Error\" 检查TCP Server是不是正常发送data", test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 2.0, script path: EnvBase.py, tag: NVS_T1_1, + test environment detail: '1 NVS target connect with PC by UART. + + 1 SSC target connect with PC by UART. + + SSC2 GPIO connect to NVS1 power control pin.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 2.0, script path: EnvBase.py, tag: SSC_T2_Sleep2, + test environment detail: 'AP support DTIM placed with AT target. + + 2 SSC target connect with PC by UART. + + Multimeter connect with PC via GPIB. + + Series multimeter between GND and VCC of SSC1. + + SSC1''s RSTB pin connect with AT2''s GPIO.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 2.0, script path: EnvBase.py, tag: SSC_T2_Sleep1, + test environment detail: 'AP support DTIM placed with AT target. + + 2 SSC target connect with PC by UART. + + Multimeter connect with PC via GPIB. + + Series multimeter between GND and VCC of SSC1. + + SSC1''s light sleep wakeup pin and wakeup indication connect with AT2''s GPIO. + + SSC1''s XPD connect with RSTB.', test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 2.0, script path: EnvBase.py, tag: AT_T2_1, + test environment detail: 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 AT target connect with PC by UART (AT and LOG port).', test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_1, + test environment detail: 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.', test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_2, + test environment detail: 'Able to access WAN after connect to AP. + + 1 SSC target connect with PC by UART.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: AT_T1_APC2, + test environment detail: "Able to access WAN after connect to AP.\nPC has 1 wired\ + \ NIC connected to APC (static IP within the same subnet with APC). \nAPC control\ + \ AP power supply.\nPC has 1 WiFi NIC.\n1 AT target connect with PC by UART (AT\ + \ and LOG port).", test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: AT_T1_APC1, + test environment detail: "PC has 1 wired NIC connected to AP.\nPC has 1 wired NIC\ + \ connected to APC (static IP within the same subnet with APC). \nAPC control\ + \ AP power supply. \nPC has 1 WiFi NIC. \n1 AT target connect with PC by UART\ + \ (AT and LOG port).", test script: EnvBase} From 2fe759ce1d9595e4b273d10b1dc39e782a3eb5b7 Mon Sep 17 00:00:00 2001 From: Yinling Date: Mon, 26 Sep 2016 14:32:58 +0800 Subject: [PATCH 058/343] update CI config file: 1. add night job define (need to set variable in trigger to run night jobs) 2. move auto generated part to the end of file 3. add auto generated CI jobs --- .gitlab-ci.yml | 201 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 162 insertions(+), 39 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e0cea70fa7..0945795753 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -106,46 +106,8 @@ test_build_system: - ./make/test_build_system.sh - -# template for test jobs -.test_template: &test_template - stage: test - when: on_success - only: - - master - - triggers - - variables: - # need user to set SDK_NAME and CONFIG_FILE (may need to set BIN_PATH and APP_NAME later) in before_script - SCRIPT_PATH: /home/gitlab-runner/auto_test_script - BIN_PATH: ${CI_PROJECT_DIR}/SSC/build/ - APP_NAME: ssc - LOG_PATH: $CI_PROJECT_DIR/$CI_BUILD_REF - - artifacts: - when: always - paths: - - $LOG_PATH - expire_in: 6 mos - - script: - - cd $SCRIPT_PATH - - python CIRunner.py -l $LOG_PATH -c $SDK_NAME/$CONFIG_FILE bin_path $APP_NAME $BIN_PATH - -sanity_test: - <<: *test_template - tags: - - ESP32 - - SSC_T1_1 - - SSC_T2_1 - - SSC_T1_WAN - before_script: - - SDK_NAME=ESP32_IDF - - CONFIG_FILE=sanity_test.yml - - push_master_to_github: - before_script: + before_script: - echo "Not setting up GitLab key, not fetching submodules" stage: deploy only: @@ -165,3 +127,164 @@ push_master_to_github: - echo -e "Host github.com\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config - git remote add github git@github.com:espressif/esp-idf.git - git push --follow-tags github HEAD:master + + +# AUTO GENERATED PART START, DO NOT MODIFY CONTENT BELOW +# template for test jobs +.test_template: &test_template + stage: test + when: on_success + only: + - master + - triggers + + variables: + LOCAL_ENV_CONFIG_PATH: "/home/gitlab-runner/LocalConfig/ESP32" + BIN_PATH: "$CI_PROJECT_DIR/SSC/build/" + APP_NAME: "ssc" + LOG_PATH: "$CI_PROJECT_DIR/$CI_BUILD_REF" + # assume it's tests are put in "components/test" + TEST_CASE_FILE_PATH: "components/test" + # jobs MUST set CONFIG_FILE in before_script, and overwrite the variables above if necessary + CONFIG_FILE: "jobs must set this variable" + + artifacts: + when: always + paths: + - $LOG_PATH + expire_in: 6 mos + + script: + # assume that auto_test_script is a sub-module of SDK, otherwise add as submodule here + - git submodule update --init --recursive + - python CIRunner.py -l $LOG_PATH -c $CONFIG_FILE -e $LOCAL_ENV_CONFIG_PATH -t $TEST_CASE_FILE_PATH bin_path $APP_NAME $BIN_PATH + + +# template for overnight test jobs +.test_template_night: &test_template_night + <<: *test_template + only: + # can only be triggered + - triggers + script: + # must be night build triggers, otherwise exit without test + - test $NIGHT_BUILD != "Yes" || exit + # assume that auto_test_script is a sub-module of SDK + - git submodule update --init --recursive + - python CIRunner.py -l $LOG_PATH -c $CONFIG_FILE -e $LOCAL_ENV_CONFIG_PATH -t $TEST_CASE_FILE_PATH bin_path $APP_NAME $BIN_PATH + +Function_SYS_01: + <<: *test_template + tags: + - ESP32_IDF + - SSC_T1_1 + before_script: + - SDK_NAME=ESP32_IDF + - LOCAL_ENV_CONFIG_PATH=/home/gitlab-runner/LocalConfig/ESP32_IDF + - CONFIG_FILE=Function_SYS_01.yml + +Function_WIFI_01: + <<: *test_template + tags: + - ESP32_IDF + - SSC_T1_APC + - SSC_T1_1 + - SSC_T1_WEP + - SSC_T2_1 + before_script: + - SDK_NAME=ESP32_IDF + - LOCAL_ENV_CONFIG_PATH=/home/gitlab-runner/LocalConfig/ESP32_IDF + - CONFIG_FILE=Function_WIFI_01.yml + +Function_WIFI_02: + <<: *test_template + tags: + - ESP32_IDF + - SSC_T1_APC + - SSC_T1_1 + - SSC_T1_WEP + - SSC_T2_1 + before_script: + - SDK_NAME=ESP32_IDF + - LOCAL_ENV_CONFIG_PATH=/home/gitlab-runner/LocalConfig/ESP32_IDF + - CONFIG_FILE=Function_WIFI_02.yml + +Function_TCPIP_01: + <<: *test_template + tags: + - ESP32_IDF + - SSC_T1_1 + - SSC_T1_2 + - SSC_T2_1 + before_script: + - SDK_NAME=ESP32_IDF + - LOCAL_ENV_CONFIG_PATH=/home/gitlab-runner/LocalConfig/ESP32_IDF + - CONFIG_FILE=Function_TCPIP_01.yml + +Function_TCPIP_02: + <<: *test_template + tags: + - ESP32_IDF + - SSC_T1_1 + - SSC_T2_1 + before_script: + - SDK_NAME=ESP32_IDF + - LOCAL_ENV_CONFIG_PATH=/home/gitlab-runner/LocalConfig/ESP32_IDF + - CONFIG_FILE=Function_TCPIP_02.yml + +Function_TCPIP_03: + <<: *test_template + tags: + - ESP32_IDF + - SSC_T1_1 + - SSC_T2_1 + before_script: + - SDK_NAME=ESP32_IDF + - LOCAL_ENV_CONFIG_PATH=/home/gitlab-runner/LocalConfig/ESP32_IDF + - CONFIG_FILE=Function_TCPIP_03.yml + +Function_TCPIP_04: + <<: *test_template + tags: + - ESP32_IDF + - SSC_T1_1 + - SSC_T1_2 + - SSC_T2_1 + before_script: + - SDK_NAME=ESP32_IDF + - LOCAL_ENV_CONFIG_PATH=/home/gitlab-runner/LocalConfig/ESP32_IDF + - CONFIG_FILE=Function_TCPIP_04.yml + +Function_TCPIP_05: + <<: *test_template + tags: + - ESP32_IDF + - SSC_T1_1 + - SSC_T1_2 + - SSC_T2_1 + before_script: + - SDK_NAME=ESP32_IDF + - LOCAL_ENV_CONFIG_PATH=/home/gitlab-runner/LocalConfig/ESP32_IDF + - CONFIG_FILE=Function_TCPIP_05.yml + +Function_TCPIP_06: + <<: *test_template + tags: + - ESP32_IDF + - SSC_T1_1 + - SSC_T2_1 + before_script: + - SDK_NAME=ESP32_IDF + - LOCAL_ENV_CONFIG_PATH=/home/gitlab-runner/LocalConfig/ESP32_IDF + - CONFIG_FILE=Function_TCPIP_06.yml + +Function_TCPIP_07: + <<: *test_template_night + tags: + - ESP32_IDF + - SSC_T1_1 + before_script: + - SDK_NAME=ESP32_IDF + - LOCAL_ENV_CONFIG_PATH=/home/gitlab-runner/LocalConfig/ESP32_IDF + - CONFIG_FILE=Function_TCPIP_07.yml + From e2dd6ebcf08334c6d4bf16f8a3e3056afb3967d3 Mon Sep 17 00:00:00 2001 From: Yinling Date: Mon, 26 Sep 2016 19:24:51 +0800 Subject: [PATCH 059/343] revise .gitlab-ci.yml: 1. remove duplicated code 2. fix path error for config file --- .gitlab-ci.yml | 37 +++++++++++++------------------------ 1 file changed, 13 insertions(+), 24 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0945795753..a0e59d62f4 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -139,14 +139,13 @@ push_master_to_github: - triggers variables: - LOCAL_ENV_CONFIG_PATH: "/home/gitlab-runner/LocalConfig/ESP32" + # LOCAL_ENV_CONFIG_PATH: define LOCAL_ENV_CONFIG in jobs because this variable may need complicated logic to generate BIN_PATH: "$CI_PROJECT_DIR/SSC/build/" APP_NAME: "ssc" LOG_PATH: "$CI_PROJECT_DIR/$CI_BUILD_REF" - # assume it's tests are put in "components/test" - TEST_CASE_FILE_PATH: "components/test" + # assume tests are put in "components/test" + TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/components/test" # jobs MUST set CONFIG_FILE in before_script, and overwrite the variables above if necessary - CONFIG_FILE: "jobs must set this variable" artifacts: when: always @@ -179,9 +178,8 @@ Function_SYS_01: - ESP32_IDF - SSC_T1_1 before_script: - - SDK_NAME=ESP32_IDF - LOCAL_ENV_CONFIG_PATH=/home/gitlab-runner/LocalConfig/ESP32_IDF - - CONFIG_FILE=Function_SYS_01.yml + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_SYS_01.yml Function_WIFI_01: <<: *test_template @@ -192,9 +190,8 @@ Function_WIFI_01: - SSC_T1_WEP - SSC_T2_1 before_script: - - SDK_NAME=ESP32_IDF - LOCAL_ENV_CONFIG_PATH=/home/gitlab-runner/LocalConfig/ESP32_IDF - - CONFIG_FILE=Function_WIFI_01.yml + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_WIFI_01.yml Function_WIFI_02: <<: *test_template @@ -205,9 +202,8 @@ Function_WIFI_02: - SSC_T1_WEP - SSC_T2_1 before_script: - - SDK_NAME=ESP32_IDF - LOCAL_ENV_CONFIG_PATH=/home/gitlab-runner/LocalConfig/ESP32_IDF - - CONFIG_FILE=Function_WIFI_02.yml + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_WIFI_02.yml Function_TCPIP_01: <<: *test_template @@ -217,9 +213,8 @@ Function_TCPIP_01: - SSC_T1_2 - SSC_T2_1 before_script: - - SDK_NAME=ESP32_IDF - LOCAL_ENV_CONFIG_PATH=/home/gitlab-runner/LocalConfig/ESP32_IDF - - CONFIG_FILE=Function_TCPIP_01.yml + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_TCPIP_01.yml Function_TCPIP_02: <<: *test_template @@ -228,9 +223,8 @@ Function_TCPIP_02: - SSC_T1_1 - SSC_T2_1 before_script: - - SDK_NAME=ESP32_IDF - LOCAL_ENV_CONFIG_PATH=/home/gitlab-runner/LocalConfig/ESP32_IDF - - CONFIG_FILE=Function_TCPIP_02.yml + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_TCPIP_02.yml Function_TCPIP_03: <<: *test_template @@ -239,9 +233,8 @@ Function_TCPIP_03: - SSC_T1_1 - SSC_T2_1 before_script: - - SDK_NAME=ESP32_IDF - LOCAL_ENV_CONFIG_PATH=/home/gitlab-runner/LocalConfig/ESP32_IDF - - CONFIG_FILE=Function_TCPIP_03.yml + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_TCPIP_03.yml Function_TCPIP_04: <<: *test_template @@ -251,9 +244,8 @@ Function_TCPIP_04: - SSC_T1_2 - SSC_T2_1 before_script: - - SDK_NAME=ESP32_IDF - LOCAL_ENV_CONFIG_PATH=/home/gitlab-runner/LocalConfig/ESP32_IDF - - CONFIG_FILE=Function_TCPIP_04.yml + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_TCPIP_04.yml Function_TCPIP_05: <<: *test_template @@ -263,9 +255,8 @@ Function_TCPIP_05: - SSC_T1_2 - SSC_T2_1 before_script: - - SDK_NAME=ESP32_IDF - LOCAL_ENV_CONFIG_PATH=/home/gitlab-runner/LocalConfig/ESP32_IDF - - CONFIG_FILE=Function_TCPIP_05.yml + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_TCPIP_05.yml Function_TCPIP_06: <<: *test_template @@ -274,9 +265,8 @@ Function_TCPIP_06: - SSC_T1_1 - SSC_T2_1 before_script: - - SDK_NAME=ESP32_IDF - LOCAL_ENV_CONFIG_PATH=/home/gitlab-runner/LocalConfig/ESP32_IDF - - CONFIG_FILE=Function_TCPIP_06.yml + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_TCPIP_06.yml Function_TCPIP_07: <<: *test_template_night @@ -284,7 +274,6 @@ Function_TCPIP_07: - ESP32_IDF - SSC_T1_1 before_script: - - SDK_NAME=ESP32_IDF - LOCAL_ENV_CONFIG_PATH=/home/gitlab-runner/LocalConfig/ESP32_IDF - - CONFIG_FILE=Function_TCPIP_07.yml + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_TCPIP_07.yml From 99ebc93abb14ee2a6b509bdf8442138472a4ef32 Mon Sep 17 00:00:00 2001 From: Yinling Date: Mon, 26 Sep 2016 19:26:53 +0800 Subject: [PATCH 060/343] modify document to add how to run test locally --- components/test/README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/components/test/README.md b/components/test/README.md index 0e4172d62c..3267e47caf 100644 --- a/components/test/README.md +++ b/components/test/README.md @@ -33,3 +33,15 @@ test --- CIConfigs --- sanity_test1.yml (Runner config files) 2. use [auto_test_script](https://gitlab.espressif.cn:6688/yinling/auto_test_script) to load the modified case and verify the modification 3. create a merge request and assign to HYL (or add comment @yinling for merging test). After review it will be merged to SDK and will be The cases will be synced to database in auto_test_script. + + +## Run test case locally + +1. clone auto_test_script (ssh://git@gitlab.espressif.cn:27227/yinling/auto_test_script.git) from gitlab +2. create test environment: + 1. search test case (search test case ID in components/test/TestCaseAll.yml, get the "test environment" value + 2. goto [test environment list](https://gitlab.espressif.cn:6688/yinling/auto_test_script/blob/master/public/Documents/TestEnvList.md), find the link and goto the environment detail page + 3. create test environment according to figure and description + 4. [config test environment](https://gitlab.espressif.cn:6688/yinling/auto_test_script/blob/master/public/Design/TestEnvConfig.DesignNote.md). All parameters in table "Parameters require config before use" MUST be configured. +3. run test cases with [CIRunner.py](https://gitlab.espressif.cn:6688/yinling/auto_test_script/blob/master/public/Design/RunnerConfigs.DesignNote.md) + From 745ecef2630c468507de04b88d5422bc1bc5264c Mon Sep 17 00:00:00 2001 From: Yinling Date: Tue, 27 Sep 2016 16:22:18 +0800 Subject: [PATCH 061/343] auto_test_script will be cloned from gitlab --- .gitlab-ci.yml | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a0e59d62f4..730e72686b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -154,8 +154,8 @@ push_master_to_github: expire_in: 6 mos script: - # assume that auto_test_script is a sub-module of SDK, otherwise add as submodule here - - git submodule update --init --recursive + - git clone ssh://git@gitlab.espressif.cn:27227/yinling/auto_test_script.git + - cd auto_test_script - python CIRunner.py -l $LOG_PATH -c $CONFIG_FILE -e $LOCAL_ENV_CONFIG_PATH -t $TEST_CASE_FILE_PATH bin_path $APP_NAME $BIN_PATH @@ -168,8 +168,8 @@ push_master_to_github: script: # must be night build triggers, otherwise exit without test - test $NIGHT_BUILD != "Yes" || exit - # assume that auto_test_script is a sub-module of SDK - - git submodule update --init --recursive + - git clone ssh://git@gitlab.espressif.cn:27227/yinling/auto_test_script.git + - cd auto_test_script - python CIRunner.py -l $LOG_PATH -c $CONFIG_FILE -e $LOCAL_ENV_CONFIG_PATH -t $TEST_CASE_FILE_PATH bin_path $APP_NAME $BIN_PATH Function_SYS_01: @@ -185,7 +185,6 @@ Function_WIFI_01: <<: *test_template tags: - ESP32_IDF - - SSC_T1_APC - SSC_T1_1 - SSC_T1_WEP - SSC_T2_1 @@ -197,7 +196,6 @@ Function_WIFI_02: <<: *test_template tags: - ESP32_IDF - - SSC_T1_APC - SSC_T1_1 - SSC_T1_WEP - SSC_T2_1 @@ -277,3 +275,12 @@ Function_TCPIP_07: - LOCAL_ENV_CONFIG_PATH=/home/gitlab-runner/LocalConfig/ESP32_IDF - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_TCPIP_07.yml +Function_WIFI_03: + <<: *test_template + tags: + - ESP32_IDF + - SSC_T1_APC + before_script: + - LOCAL_ENV_CONFIG_PATH=/home/gitlab-runner/LocalConfig/ESP32_IDF + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_WIFI_03.yml + From 4de2054541e9705fbd069676baffd8ad9c146b6c Mon Sep 17 00:00:00 2001 From: Yinling Date: Tue, 27 Sep 2016 16:22:51 +0800 Subject: [PATCH 062/343] fix bugs in config files: 1. filter name is "Add" not "ADD" 2. SSC_T1_APC is special environment 3. remove "debug mode" from config as it will implemented with other ways --- components/test/CIConfigs/Function_SYS_01.yml | 4 +- .../test/CIConfigs/Function_TCPIP_01.yml | 4 +- .../test/CIConfigs/Function_TCPIP_02.yml | 4 +- .../test/CIConfigs/Function_TCPIP_03.yml | 4 +- .../test/CIConfigs/Function_TCPIP_04.yml | 4 +- .../test/CIConfigs/Function_TCPIP_05.yml | 4 +- .../test/CIConfigs/Function_TCPIP_06.yml | 4 +- .../test/CIConfigs/Function_TCPIP_07.yml | 4 +- .../test/CIConfigs/Function_WIFI_01.yml | 14 +- .../test/CIConfigs/Function_WIFI_02.yml | 13 +- .../test/CIConfigs/Function_WIFI_03.yml | 5 + components/test/TestCaseAll.yml | 196 ------------------ components/test/TestEnvAll.yml | 2 +- 13 files changed, 35 insertions(+), 227 deletions(-) create mode 100644 components/test/CIConfigs/Function_WIFI_03.yml diff --git a/components/test/CIConfigs/Function_SYS_01.yml b/components/test/CIConfigs/Function_SYS_01.yml index 501f15f6ba..51a6899029 100644 --- a/components/test/CIConfigs/Function_SYS_01.yml +++ b/components/test/CIConfigs/Function_SYS_01.yml @@ -1,5 +1,5 @@ -Config: {debug mode: false, execute count: 1, execute order: in order} +Config: {execute count: 1, execute order: in order} DUT: [SSC1] Filter: -- ADD: +- Add: ID: [SYS_MISC_0101, SYS_MISC_0201] diff --git a/components/test/CIConfigs/Function_TCPIP_01.yml b/components/test/CIConfigs/Function_TCPIP_01.yml index 9b43ab589b..7eb46ef552 100644 --- a/components/test/CIConfigs/Function_TCPIP_01.yml +++ b/components/test/CIConfigs/Function_TCPIP_01.yml @@ -1,7 +1,7 @@ -Config: {debug mode: false, execute count: 1, execute order: in order} +Config: {execute count: 1, execute order: in order} DUT: [SSC2, SSC1] Filter: -- ADD: +- Add: ID: [TCPIP_ICMP_0101, TCPIP_ARP_0202, ^TCPIP_DHCP_0302, ^TCPIP_DHCP_0301, ^TCPIP_UDP_0113, TCPIP_DHCP_0302, TCPIP_DHCP_0301, TCPIP_ARP_0204, TCPIP_TCP_0412, TCPIP_TCP_0403, TCPIP_TCP_0402, TCPIP_TCP_0401, TCPIP_TCP_0407, TCPIP_TCP_0406, TCPIP_TCP_0404, diff --git a/components/test/CIConfigs/Function_TCPIP_02.yml b/components/test/CIConfigs/Function_TCPIP_02.yml index 7e0a3ead43..0cafa781b9 100644 --- a/components/test/CIConfigs/Function_TCPIP_02.yml +++ b/components/test/CIConfigs/Function_TCPIP_02.yml @@ -1,7 +1,7 @@ -Config: {debug mode: false, execute count: 1, execute order: in order} +Config: {execute count: 1, execute order: in order} DUT: [SSC2, SSC1] Filter: -- ADD: +- Add: ID: [^TCPIP_IGMP_0104, ^TCPIP_UDP_0110, TCPIP_IGMP_0104, TCPIP_IGMP_0103, TCPIP_IGMP_0102, TCPIP_IGMP_0101, ^TCPIP_UDP_0201, ^TCPIP_ICMP_0101, TCPIP_UDP_0108, TCPIP_UDP_0109, TCPIP_UDP_0106, TCPIP_UDP_0107, TCPIP_UDP_0104, TCPIP_UDP_0105, TCPIP_UDP_0102, diff --git a/components/test/CIConfigs/Function_TCPIP_03.yml b/components/test/CIConfigs/Function_TCPIP_03.yml index 33dcd14bea..cdaad25869 100644 --- a/components/test/CIConfigs/Function_TCPIP_03.yml +++ b/components/test/CIConfigs/Function_TCPIP_03.yml @@ -1,7 +1,7 @@ -Config: {debug mode: false, execute count: 1, execute order: in order} +Config: {execute count: 1, execute order: in order} DUT: [SSC2, SSC1] Filter: -- ADD: +- Add: ID: [^TCPIP_UDP_0305, ^TCPIP_UDP_0304, ^TCPIP_TCP_0101, ^TCPIP_TCP_0103, ^TCPIP_TCP_0102, ^TCPIP_TCP_0105, ^TCPIP_TCP_0104, ^TCPIP_TCP_0107, ^TCPIP_TCP_0106, ^TCPIP_DHCP_0210, ^TCPIP_DHCP_0211, TCPIP_TCP_0212, TCPIP_TCP_0210, ^TCPIP_TCP_0210, ^TCPIP_TCP_0212, diff --git a/components/test/CIConfigs/Function_TCPIP_04.yml b/components/test/CIConfigs/Function_TCPIP_04.yml index af2cc7d22f..3476bb7069 100644 --- a/components/test/CIConfigs/Function_TCPIP_04.yml +++ b/components/test/CIConfigs/Function_TCPIP_04.yml @@ -1,7 +1,7 @@ -Config: {debug mode: false, execute count: 1, execute order: in order} +Config: {execute count: 1, execute order: in order} DUT: [SSC2, SSC1] Filter: -- ADD: +- Add: ID: [^TCPIP_IGMP_0203, ^TCPIP_IGMP_0202, ^TCPIP_IGMP_0204, TCPIP_UDP_0114, TCPIP_UDP_0111, TCPIP_UDP_0110, TCPIP_UDP_0113, TCPIP_UDP_0112, ^TCPIP_TCP_0201, ^TCPIP_TCP_0206, ^TCPIP_TCP_0207, TCPIP_TCP_0501, ^TCPIP_DNS_0101, ^TCPIP_DNS_0103, ^TCPIP_DNS_0102, diff --git a/components/test/CIConfigs/Function_TCPIP_05.yml b/components/test/CIConfigs/Function_TCPIP_05.yml index a89ece34cc..85b6e72d8b 100644 --- a/components/test/CIConfigs/Function_TCPIP_05.yml +++ b/components/test/CIConfigs/Function_TCPIP_05.yml @@ -1,7 +1,7 @@ -Config: {debug mode: false, execute count: 1, execute order: in order} +Config: {execute count: 1, execute order: in order} DUT: [SSC2, SSC1] Filter: -- ADD: +- Add: ID: [TCPIP_UDP_0305, TCPIP_UDP_0306, TCPIP_UDP_0307, TCPIP_UDP_0301, TCPIP_UDP_0302, TCPIP_UDP_0303, ^TCPIP_DHCP_0209, ^TCPIP_DHCP_0208, ^TCPIP_DHCP_0207, ^TCPIP_DHCP_0206, ^TCPIP_DHCP_0205, ^TCPIP_DHCP_0204, ^TCPIP_DHCP_0203, ^TCPIP_DHCP_0202, ^TCPIP_DHCP_0201, diff --git a/components/test/CIConfigs/Function_TCPIP_06.yml b/components/test/CIConfigs/Function_TCPIP_06.yml index 929aafd13e..1aceda2b73 100644 --- a/components/test/CIConfigs/Function_TCPIP_06.yml +++ b/components/test/CIConfigs/Function_TCPIP_06.yml @@ -1,7 +1,7 @@ -Config: {debug mode: false, execute count: 1, execute order: in order} +Config: {execute count: 1, execute order: in order} DUT: [SSC2, SSC1] Filter: -- ADD: +- Add: ID: [TCPIP_DHCP_0201, ^TCPIP_TCP_0208, TCPIP_DHCP_0208, TCPIP_DHCP_0209, ^TCPIP_TCP_0412, ^TCPIP_TCP_0411, TCPIP_ARP_0203, ^TCPIP_UDP_0112, ^TCPIP_UDP_0114, ^TCPIP_UDP_0202, ^TCPIP_IGMP_0103, ^TCPIP_IP_0101, TCPIP_ARP_0201, TCPIP_TCP_0115, TCPIP_TCP_0114, diff --git a/components/test/CIConfigs/Function_TCPIP_07.yml b/components/test/CIConfigs/Function_TCPIP_07.yml index d42b5902ad..7cf6279995 100644 --- a/components/test/CIConfigs/Function_TCPIP_07.yml +++ b/components/test/CIConfigs/Function_TCPIP_07.yml @@ -1,5 +1,5 @@ -Config: {debug mode: false, execute count: 1, execute order: in order} +Config: {execute count: 1, execute order: in order} DUT: [SSC1] Filter: -- ADD: +- Add: ID: [TCPIP_TCP_0405, ^TCPIP_TCP_0405] diff --git a/components/test/CIConfigs/Function_WIFI_01.yml b/components/test/CIConfigs/Function_WIFI_01.yml index 594a1fc212..4a6b3e0c17 100644 --- a/components/test/CIConfigs/Function_WIFI_01.yml +++ b/components/test/CIConfigs/Function_WIFI_01.yml @@ -1,11 +1,11 @@ -Config: {debug mode: false, execute count: 1, execute order: in order} +Config: {execute count: 1, execute order: in order} DUT: [SSC2, SSC1] Filter: -- ADD: +- Add: ID: [^WIFI_CONN_0601, ^WIFI_ADDR_0101, ^WIFI_CONN_0903, WIFI_SCAN_0103, WIFI_SCAN_0102, WIFI_SCAN_0101, WIFI_SCAN_0105, WIFI_SCAN_0104, WIFI_CONN_0201, WIFI_CONN_0702, - WIFI_CONN_0703, WIFI_CONN_0701, WIFI_CONN_0904, ^WIFI_CONN_0201, ^WIFI_CONN_0701, - ^WIFI_CONN_0703, ^WIFI_SCAN_0102, ^WIFI_SCAN_0103, ^WIFI_SCAN_0104, ^WIFI_SCAN_0105, - ^WIFI_ADDR_0102, WIFI_CONN_0401, ^WIFI_CONN_0103, WIFI_ADDR_0101, WIFI_ADDR_0102, - WIFI_CONN_0301, ^WIFI_CONN_0801, WIFI_CONN_0104, ^WIFI_CONN_0301, WIFI_CONN_0501, - WIFI_CONN_0502] + WIFI_CONN_0703, WIFI_CONN_0904, ^WIFI_CONN_0201, ^WIFI_CONN_0703, ^WIFI_SCAN_0102, + ^WIFI_SCAN_0103, ^WIFI_SCAN_0104, ^WIFI_SCAN_0105, ^WIFI_ADDR_0102, WIFI_CONN_0401, + ^WIFI_CONN_0103, WIFI_ADDR_0101, WIFI_ADDR_0102, WIFI_CONN_0301, ^WIFI_CONN_0801, + WIFI_CONN_0104, ^WIFI_CONN_0301, WIFI_CONN_0501, WIFI_CONN_0502, ^WIFI_CONN_0401, + WIFI_MODE_0101] diff --git a/components/test/CIConfigs/Function_WIFI_02.yml b/components/test/CIConfigs/Function_WIFI_02.yml index 30735791b7..78ef087b59 100644 --- a/components/test/CIConfigs/Function_WIFI_02.yml +++ b/components/test/CIConfigs/Function_WIFI_02.yml @@ -1,9 +1,8 @@ -Config: {debug mode: false, execute count: 1, execute order: in order} +Config: {execute count: 1, execute order: in order} DUT: [SSC2, SSC1] Filter: -- ADD: - ID: [^WIFI_CONN_0401, WIFI_MODE_0101, WIFI_MODE_0103, WIFI_MODE_0102, ^WIFI_CONN_0904, - ^WIFI_CONN_0902, ^WIFI_CONN_0901, WIFI_CONN_0601, WIFI_CONN_0901, WIFI_CONN_0902, - WIFI_CONN_0903, WIFI_CONN_0503, ^WIFI_CONN_0104, WIFI_CONN_0101, WIFI_CONN_0102, - WIFI_CONN_0103, ^WIFI_CONN_0702, WIFI_CONN_0801, ^WIFI_CONN_0101, ^WIFI_CONN_0503, - ^WIFI_CONN_0502, ^WIFI_CONN_0501, ^WIFI_SCAN_0101] +- Add: + ID: [WIFI_MODE_0103, WIFI_MODE_0102, ^WIFI_CONN_0904, ^WIFI_CONN_0901, WIFI_CONN_0601, + WIFI_CONN_0901, WIFI_CONN_0903, WIFI_CONN_0503, ^WIFI_CONN_0104, WIFI_CONN_0101, + WIFI_CONN_0102, WIFI_CONN_0103, ^WIFI_CONN_0702, WIFI_CONN_0801, ^WIFI_CONN_0101, + ^WIFI_CONN_0503, ^WIFI_CONN_0502, ^WIFI_CONN_0501, ^WIFI_SCAN_0101] diff --git a/components/test/CIConfigs/Function_WIFI_03.yml b/components/test/CIConfigs/Function_WIFI_03.yml new file mode 100644 index 0000000000..1ac97dece3 --- /dev/null +++ b/components/test/CIConfigs/Function_WIFI_03.yml @@ -0,0 +1,5 @@ +Config: {execute count: 1, execute order: in order} +DUT: [SSC1] +Filter: +- Add: + ID: [WIFI_CONN_0701, ^WIFI_CONN_0701, ^WIFI_CONN_0902, WIFI_CONN_0902] diff --git a/components/test/TestCaseAll.yml b/components/test/TestCaseAll.yml index c5e10b794a..cf634005dd 100644 --- a/components/test/TestCaseAll.yml +++ b/components/test/TestCaseAll.yml @@ -2065,64 +2065,6 @@ test cases: test point 1: basic function test point 2: wifi connect status check version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_CONN_0701 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 sta -D - - [R SSC1 C QAP] - - - SSC SSC1 sta -Q - - ['R SSC1 C +STA_STATUS:0'] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:OK'] - - - SSC SSC1 sta -Q - - ['R SSC1 C +STA_STATUS:1', 'R SSC1 C +JAP:CONNECTED'] - - - SSC SSC1 sta -Q - - ['R SSC1 C +STA_STATUS:5'] - - - APC OFF - - [P PC_COM L OK, P SSC1 C bcn_timout] - - - SSC SSC1 sta -Q - - ['R SSC1 C +STA_STATUS:4'] - - - APC ON - - [P PC_COM L OK] - comment: '' - execution time: 0.0 - expected result: '1. idle state - - 2. connecting state - - 3. got IP state - - 4. connect fail state' - initial condition: STAM1 - initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a - TC with initial condition STAAP1 - module: WIFI MAC - steps: '1. sta disconnected, query status - - 2. sta connect to AP, query status - - 3. got IP, query status - - 4. AP power off, query status when beacon timeout' - sub module: WIFI Connect - summary: check wifi status idle, connecting, got ip and connect fail - test environment: SSC_T1_APC - test environment description (auto): "PC has 1 wired NIC connected to AP.\nPC has\ - \ 1 wired NIC connected to APC (static IP within the same subnet with APC). \n\ - APC control AP power supply. \nPC has 1 WiFi NIC. \n1 SSC target connect with\ - \ PC by UART." - test point 1: basic function - test point 2: wifi connect status check - version: v1 (2016-8-15) - CI ready: 'Yes' ID: TCPIP_DNS_0102 SDK: '8266_NonOS @@ -2603,64 +2545,6 @@ test cases: test point 1: basic function test point 2: IGMP API parameter check version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^WIFI_CONN_0701 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 sta -D - - [R SSC1 C QAP] - - - SSC SSC1 sta -Q - - ['R SSC1 C +STA_STATUS:0'] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:OK'] - - - SSC SSC1 sta -Q - - ['R SSC1 C +STA_STATUS:1', 'R SSC1 C +JAP:CONNECTED'] - - - SSC SSC1 sta -Q - - ['R SSC1 C +STA_STATUS:5'] - - - APC OFF - - [P PC_COM L OK, P SSC1 C bcn_timout] - - - SSC SSC1 sta -Q - - ['R SSC1 C +STA_STATUS:4'] - - - APC ON - - [P PC_COM L OK] - comment: '' - execution time: 0.0 - expected result: '1. idle state - - 2. connecting state - - 3. got IP state - - 4. connect fail state' - initial condition: STAAP1 - initial condition description (auto): testing sta on sta + ap mode, quit AP (autogen - by STAM1) - module: WIFI MAC - steps: '1. sta disconnected, query status - - 2. sta connect to AP, query status - - 3. got IP, query status - - 4. AP power off, query status when beacon timeout' - sub module: WIFI Connect - summary: check wifi status idle, connecting, got ip and connect fail - test environment: SSC_T1_APC - test environment description (auto): "PC has 1 wired NIC connected to AP.\nPC has\ - \ 1 wired NIC connected to APC (static IP within the same subnet with APC). \n\ - APC control AP power supply. \nPC has 1 WiFi NIC. \n1 SSC target connect with\ - \ PC by UART." - test point 1: basic function - test point 2: wifi connect status check - version: v1 (2016-8-15) - CI ready: 'Yes' ID: ^WIFI_CONN_0703 SDK: '8266_NonOS @@ -7985,46 +7869,6 @@ test cases: test point 1: basic function test point 2: wifi disconnect reason test version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^WIFI_CONN_0902 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:CONNECTED'] - - - APC OFF - - [P PC_COM L OK, 'R SSC1 C +JAP:DISCONNECTED,1,200'] - - - APC ON - - [P PC_COM L OK] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. disconnect event REASON_BEACON_TIMEOUT' - initial condition: STAAP1 - initial condition description (auto): testing sta on sta + ap mode, quit AP (autogen - by STAM1) - module: WIFI MAC - steps: '1. connect to AP - - 2. AP power off' - sub module: WIFI Connect - summary: test wifi disconnect reason REASON_BEACON_TIMEOUT - test environment: SSC_T1_APC - test environment description (auto): "PC has 1 wired NIC connected to AP.\nPC has\ - \ 1 wired NIC connected to APC (static IP within the same subnet with APC). \n\ - APC control AP power supply. \nPC has 1 WiFi NIC. \n1 SSC target connect with\ - \ PC by UART." - test point 1: basic function - test point 2: wifi disconnect reason test - version: v1 (2016-8-15) - CI ready: 'Yes' ID: ^WIFI_CONN_0901 SDK: '8266_NonOS @@ -12218,46 +12062,6 @@ test cases: test point 1: basic function test point 2: wifi disconnect reason test version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_CONN_0902 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:CONNECTED'] - - - APC OFF - - [P PC_COM L OK, 'R SSC1 C +JAP:DISCONNECTED,1,200'] - - - APC ON - - [P PC_COM L OK] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. disconnect event REASON_BEACON_TIMEOUT' - initial condition: STAM1 - initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a - TC with initial condition STAAP1 - module: WIFI MAC - steps: '1. connect to AP - - 2. AP power off' - sub module: WIFI Connect - summary: test wifi disconnect reason REASON_BEACON_TIMEOUT - test environment: SSC_T1_APC - test environment description (auto): "PC has 1 wired NIC connected to AP.\nPC has\ - \ 1 wired NIC connected to APC (static IP within the same subnet with APC). \n\ - APC control AP power supply. \nPC has 1 WiFi NIC. \n1 SSC target connect with\ - \ PC by UART." - test point 1: basic function - test point 2: wifi disconnect reason test - version: v1 (2016-8-15) - CI ready: 'Yes' ID: TCPIP_ARP_0203 SDK: '8266_NonOS diff --git a/components/test/TestEnvAll.yml b/components/test/TestEnvAll.yml index 703fafcb60..a978f5f73a 100644 --- a/components/test/TestEnvAll.yml +++ b/components/test/TestEnvAll.yml @@ -97,7 +97,7 @@ test environment: Multimeter connect to input, able to measure input voltage. 1 SSC target connect with PC by UART.', test script: EnvBase} -- {PC OS: '', Special: N, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_APC, +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_APC, test environment detail: "PC has 1 wired NIC connected to AP.\nPC has 1 wired NIC\ \ connected to APC (static IP within the same subnet with APC). \nAPC control\ \ AP power supply. \nPC has 1 WiFi NIC. \n1 SSC target connect with PC by UART.", From 024a1ce26060a28d72ec09503d71f60506dafe9a Mon Sep 17 00:00:00 2001 From: Yinling Date: Wed, 28 Sep 2016 19:43:45 +0800 Subject: [PATCH 063/343] add KnownIssues file to test: add known issues to this file so that they will be exculded in CI results --- components/test/KnownIssues | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 components/test/KnownIssues diff --git a/components/test/KnownIssues b/components/test/KnownIssues new file mode 100644 index 0000000000..e69de29bb2 From 59b35eb16ac06f561555c73f2962e70ba257b459 Mon Sep 17 00:00:00 2001 From: Yinling Date: Wed, 28 Sep 2016 19:48:38 +0800 Subject: [PATCH 064/343] sync several changes from auto_test_script: 1. use variable for gitlab server 2. add LOCAL_ENV_CONFIG_PATH to template 2. update jobs with feature "allow fail" --- .gitlab-ci.yml | 142 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 113 insertions(+), 29 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 730e72686b..ad6db4169a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -139,7 +139,8 @@ push_master_to_github: - triggers variables: - # LOCAL_ENV_CONFIG_PATH: define LOCAL_ENV_CONFIG in jobs because this variable may need complicated logic to generate + # LOCAL_ENV_CONFIG_PATH: define in template and jobs can overwrite if required + LOCAL_ENV_CONFIG_PATH: /home/gitlab-runner/LocalConfig/ESP32_IDF BIN_PATH: "$CI_PROJECT_DIR/SSC/build/" APP_NAME: "ssc" LOG_PATH: "$CI_PROJECT_DIR/$CI_BUILD_REF" @@ -154,7 +155,7 @@ push_master_to_github: expire_in: 6 mos script: - - git clone ssh://git@gitlab.espressif.cn:27227/yinling/auto_test_script.git + - git clone $GITLAB_SSH_SERVER/yinling/auto_test_script.git - cd auto_test_script - python CIRunner.py -l $LOG_PATH -c $CONFIG_FILE -e $LOCAL_ENV_CONFIG_PATH -t $TEST_CASE_FILE_PATH bin_path $APP_NAME $BIN_PATH @@ -168,7 +169,7 @@ push_master_to_github: script: # must be night build triggers, otherwise exit without test - test $NIGHT_BUILD != "Yes" || exit - - git clone ssh://git@gitlab.espressif.cn:27227/yinling/auto_test_script.git + - git clone $GITLAB_SSH_SERVER/yinling/auto_test_script.git - cd auto_test_script - python CIRunner.py -l $LOG_PATH -c $CONFIG_FILE -e $LOCAL_ENV_CONFIG_PATH -t $TEST_CASE_FILE_PATH bin_path $APP_NAME $BIN_PATH @@ -178,18 +179,18 @@ Function_SYS_01: - ESP32_IDF - SSC_T1_1 before_script: - - LOCAL_ENV_CONFIG_PATH=/home/gitlab-runner/LocalConfig/ESP32_IDF - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_SYS_01.yml Function_WIFI_01: <<: *test_template tags: - ESP32_IDF + - SSC_T3_PhyMode - SSC_T1_1 - SSC_T1_WEP + - SSC_T2_PhyMode - SSC_T2_1 before_script: - - LOCAL_ENV_CONFIG_PATH=/home/gitlab-runner/LocalConfig/ESP32_IDF - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_WIFI_01.yml Function_WIFI_02: @@ -198,20 +199,28 @@ Function_WIFI_02: - ESP32_IDF - SSC_T1_1 - SSC_T1_WEP + - SSC_T2_PhyMode - SSC_T2_1 before_script: - - LOCAL_ENV_CONFIG_PATH=/home/gitlab-runner/LocalConfig/ESP32_IDF - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_WIFI_02.yml +Function_WIFI_03: + <<: *test_template + tags: + - ESP32_IDF + - SSC_T3_PhyMode + - SSC_T1_1 + - SSC_T2_1 + before_script: + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_WIFI_03.yml + Function_TCPIP_01: <<: *test_template tags: - ESP32_IDF - SSC_T1_1 - - SSC_T1_2 - SSC_T2_1 before_script: - - LOCAL_ENV_CONFIG_PATH=/home/gitlab-runner/LocalConfig/ESP32_IDF - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_TCPIP_01.yml Function_TCPIP_02: @@ -221,7 +230,6 @@ Function_TCPIP_02: - SSC_T1_1 - SSC_T2_1 before_script: - - LOCAL_ENV_CONFIG_PATH=/home/gitlab-runner/LocalConfig/ESP32_IDF - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_TCPIP_02.yml Function_TCPIP_03: @@ -231,7 +239,6 @@ Function_TCPIP_03: - SSC_T1_1 - SSC_T2_1 before_script: - - LOCAL_ENV_CONFIG_PATH=/home/gitlab-runner/LocalConfig/ESP32_IDF - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_TCPIP_03.yml Function_TCPIP_04: @@ -239,10 +246,8 @@ Function_TCPIP_04: tags: - ESP32_IDF - SSC_T1_1 - - SSC_T1_2 - SSC_T2_1 before_script: - - LOCAL_ENV_CONFIG_PATH=/home/gitlab-runner/LocalConfig/ESP32_IDF - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_TCPIP_04.yml Function_TCPIP_05: @@ -250,37 +255,116 @@ Function_TCPIP_05: tags: - ESP32_IDF - SSC_T1_1 - - SSC_T1_2 - SSC_T2_1 before_script: - - LOCAL_ENV_CONFIG_PATH=/home/gitlab-runner/LocalConfig/ESP32_IDF - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_TCPIP_05.yml Function_TCPIP_06: - <<: *test_template - tags: - - ESP32_IDF - - SSC_T1_1 - - SSC_T2_1 - before_script: - - LOCAL_ENV_CONFIG_PATH=/home/gitlab-runner/LocalConfig/ESP32_IDF - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_TCPIP_06.yml - -Function_TCPIP_07: <<: *test_template_night tags: - ESP32_IDF - SSC_T1_1 before_script: - - LOCAL_ENV_CONFIG_PATH=/home/gitlab-runner/LocalConfig/ESP32_IDF - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_TCPIP_07.yml + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_TCPIP_06.yml -Function_WIFI_03: +Function_WIFI_04: <<: *test_template tags: - ESP32_IDF - SSC_T1_APC before_script: - - LOCAL_ENV_CONFIG_PATH=/home/gitlab-runner/LocalConfig/ESP32_IDF - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_WIFI_03.yml + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_WIFI_04.yml + +Function_WIFI_05: + <<: *test_template + tags: + - ESP32_IDF + - SSC_T2_PhyMode + before_script: + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_WIFI_05.yml + +Function_WIFI_06: + <<: *test_template + tags: + - ESP32_IDF + - SSC_T2_PhyMode + before_script: + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_WIFI_06.yml + +Function_WIFI_07: + <<: *test_template + tags: + - ESP32_IDF + - SSC_T2_PhyMode + before_script: + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_WIFI_07.yml + +Function_WIFI_08: + <<: *test_template + tags: + - ESP32_IDF + - SSC_T2_PhyMode + before_script: + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_WIFI_08.yml + +Function_WIFI_09: + <<: *test_template + tags: + - ESP32_IDF + - SSC_T2_PhyMode + before_script: + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_WIFI_09.yml + +Function_TCPIP_07: + <<: *test_template + tags: + - ESP32_IDF + - SSC_T1_1 + - SSC_T1_2 + before_script: + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_TCPIP_07.yml + +Function_TCPIP_08: + <<: *test_template + tags: + - ESP32_IDF + - SSC_T1_1 + - SSC_T2_1 + before_script: + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_TCPIP_08.yml + +Function_TCPIP_09: + <<: *test_template + tags: + - ESP32_IDF + - SSC_T1_1 + before_script: + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_TCPIP_09.yml + +Function_TCPIP_10: + <<: *test_template + tags: + - ESP32_IDF + - SSC_T1_1 + - SSC_T1_2 + - SSC_T2_1 + before_script: + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_TCPIP_10.yml + +Function_TCPIP_11: + <<: *test_template + tags: + - ESP32_IDF + - SSC_T1_1 + before_script: + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_TCPIP_11.yml + +Function_TCPIP_12: + <<: *test_template + tags: + - ESP32_IDF + - SSC_T1_1 + - SSC_T1_2 + before_script: + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_TCPIP_12.yml From d695d4019659927e9afc37e33b4cd656cc6bea2e Mon Sep 17 00:00:00 2001 From: Yinling Date: Wed, 28 Sep 2016 19:52:04 +0800 Subject: [PATCH 065/343] add note that test folder is for internal use. Will move data in readme to wiki except first two notes. --- components/test/README.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/components/test/README.md b/components/test/README.md index 3267e47caf..f23153bca6 100644 --- a/components/test/README.md +++ b/components/test/README.md @@ -1,4 +1,7 @@ -# The test folder in SDK + +# Note: The test cases in this folder are for Espressif internal use. + +# Goto internal project wiki Testing page for detail about this folder. ## File Structure @@ -45,3 +48,14 @@ After review it will be merged to SDK and will be The cases will be synced to da 4. [config test environment](https://gitlab.espressif.cn:6688/yinling/auto_test_script/blob/master/public/Design/TestEnvConfig.DesignNote.md). All parameters in table "Parameters require config before use" MUST be configured. 3. run test cases with [CIRunner.py](https://gitlab.espressif.cn:6688/yinling/auto_test_script/blob/master/public/Design/RunnerConfigs.DesignNote.md) + + +## exclude known issues for CI +the test cases listed in file "KnownIssues" will be excluded by CI when calculating results + +Editing KnownIssues file is very simple, one single line for the ID for each case. +``` +TCPIP_TCP_0101 +TCPIP_TCP_0201 +... +``` \ No newline at end of file From 5fab6c36c887feef3119c635c55b8b46e3b26073 Mon Sep 17 00:00:00 2001 From: Yinling Date: Wed, 28 Sep 2016 19:54:43 +0800 Subject: [PATCH 066/343] update job configs for allow case fail feature --- .../test/CIConfigs/Function_TCPIP_01.yml | 13 +- .../test/CIConfigs/Function_TCPIP_02.yml | 13 +- .../test/CIConfigs/Function_TCPIP_03.yml | 13 +- .../test/CIConfigs/Function_TCPIP_04.yml | 13 +- .../test/CIConfigs/Function_TCPIP_05.yml | 12 +- .../test/CIConfigs/Function_TCPIP_06.yml | 7 +- .../test/CIConfigs/Function_TCPIP_07.yml | 7 +- .../test/CIConfigs/Function_TCPIP_08.yml | 10 + .../test/CIConfigs/Function_TCPIP_09.yml | 10 + .../test/CIConfigs/Function_TCPIP_10.yml | 10 + .../test/CIConfigs/Function_TCPIP_11.yml | 10 + .../test/CIConfigs/Function_TCPIP_12.yml | 6 + .../test/CIConfigs/Function_WIFI_01.yml | 11 +- .../test/CIConfigs/Function_WIFI_02.yml | 10 +- .../test/CIConfigs/Function_WIFI_03.yml | 5 +- .../test/CIConfigs/Function_WIFI_04.yml | 5 + .../test/CIConfigs/Function_WIFI_05.yml | 10 + .../test/CIConfigs/Function_WIFI_06.yml | 10 + .../test/CIConfigs/Function_WIFI_07.yml | 10 + .../test/CIConfigs/Function_WIFI_08.yml | 10 + .../test/CIConfigs/Function_WIFI_09.yml | 10 + components/test/TestCaseAll.yml | 3877 +++++++++++++++++ 22 files changed, 4029 insertions(+), 53 deletions(-) create mode 100644 components/test/CIConfigs/Function_TCPIP_08.yml create mode 100644 components/test/CIConfigs/Function_TCPIP_09.yml create mode 100644 components/test/CIConfigs/Function_TCPIP_10.yml create mode 100644 components/test/CIConfigs/Function_TCPIP_11.yml create mode 100644 components/test/CIConfigs/Function_TCPIP_12.yml create mode 100644 components/test/CIConfigs/Function_WIFI_04.yml create mode 100644 components/test/CIConfigs/Function_WIFI_05.yml create mode 100644 components/test/CIConfigs/Function_WIFI_06.yml create mode 100644 components/test/CIConfigs/Function_WIFI_07.yml create mode 100644 components/test/CIConfigs/Function_WIFI_08.yml create mode 100644 components/test/CIConfigs/Function_WIFI_09.yml diff --git a/components/test/CIConfigs/Function_TCPIP_01.yml b/components/test/CIConfigs/Function_TCPIP_01.yml index 7eb46ef552..29542e9fe3 100644 --- a/components/test/CIConfigs/Function_TCPIP_01.yml +++ b/components/test/CIConfigs/Function_TCPIP_01.yml @@ -2,10 +2,9 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC2, SSC1] Filter: - Add: - ID: [TCPIP_ICMP_0101, TCPIP_ARP_0202, ^TCPIP_DHCP_0302, ^TCPIP_DHCP_0301, ^TCPIP_UDP_0113, - TCPIP_DHCP_0302, TCPIP_DHCP_0301, TCPIP_ARP_0204, TCPIP_TCP_0412, TCPIP_TCP_0403, - TCPIP_TCP_0402, TCPIP_TCP_0401, TCPIP_TCP_0407, TCPIP_TCP_0406, TCPIP_TCP_0404, - TCPIP_TCP_0408, ^TCPIP_TCP_0202, TCPIP_TCP_0110, ^TCPIP_TCP_0203, TCPIP_DHCP_0101, - TCPIP_DHCP_0103, TCPIP_DHCP_0102, ^TCPIP_UDP_0303, ^TCPIP_UDP_0302, ^TCPIP_UDP_0301, - TCPIP_DNS_0102, TCPIP_DNS_0101, TCPIP_IP_0101, TCPIP_IP_0102, ^TCPIP_IGMP_0102, - ^TCPIP_IGMP_0101] + ID: [TCPIP_ARP_0202, ^TCPIP_DHCP_0302, ^TCPIP_DHCP_0301, ^TCPIP_UDP_0113, TCPIP_DHCP_0302, + TCPIP_DHCP_0301, TCPIP_ARP_0204, TCPIP_TCP_0412, TCPIP_TCP_0403, TCPIP_TCP_0402, + TCPIP_TCP_0401, TCPIP_TCP_0407, TCPIP_TCP_0406, TCPIP_TCP_0404, TCPIP_TCP_0408, + ^TCPIP_TCP_0202, TCPIP_TCP_0110, ^TCPIP_TCP_0203, TCPIP_DHCP_0101, TCPIP_DHCP_0103, + TCPIP_DHCP_0102, TCPIP_IP_0101, TCPIP_IP_0102, ^TCPIP_IGMP_0102, ^TCPIP_IGMP_0101, + ^TCPIP_IGMP_0104, TCPIP_IGMP_0104, TCPIP_IGMP_0103, TCPIP_IGMP_0102, TCPIP_IGMP_0101] diff --git a/components/test/CIConfigs/Function_TCPIP_02.yml b/components/test/CIConfigs/Function_TCPIP_02.yml index 0cafa781b9..e40f69db59 100644 --- a/components/test/CIConfigs/Function_TCPIP_02.yml +++ b/components/test/CIConfigs/Function_TCPIP_02.yml @@ -2,10 +2,9 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC2, SSC1] Filter: - Add: - ID: [^TCPIP_IGMP_0104, ^TCPIP_UDP_0110, TCPIP_IGMP_0104, TCPIP_IGMP_0103, TCPIP_IGMP_0102, - TCPIP_IGMP_0101, ^TCPIP_UDP_0201, ^TCPIP_ICMP_0101, TCPIP_UDP_0108, TCPIP_UDP_0109, - TCPIP_UDP_0106, TCPIP_UDP_0107, TCPIP_UDP_0104, TCPIP_UDP_0105, TCPIP_UDP_0102, - TCPIP_UDP_0103, TCPIP_UDP_0101, TCPIP_IGMP_0204, TCPIP_IGMP_0201, TCPIP_IGMP_0202, - TCPIP_IGMP_0203, ^TCPIP_TCP_0404, ^TCPIP_TCP_0406, ^TCPIP_TCP_0407, ^TCPIP_TCP_0401, - ^TCPIP_TCP_0402, ^TCPIP_TCP_0403, ^TCPIP_TCP_0408, TCPIP_UDP_0201, ^TCPIP_UDP_0307, - ^TCPIP_UDP_0306] + ID: [^TCPIP_UDP_0201, TCPIP_UDP_0108, TCPIP_UDP_0106, TCPIP_UDP_0107, TCPIP_UDP_0105, + TCPIP_UDP_0101, TCPIP_IGMP_0204, TCPIP_IGMP_0201, TCPIP_IGMP_0202, TCPIP_IGMP_0203, + ^TCPIP_TCP_0404, ^TCPIP_TCP_0406, ^TCPIP_TCP_0407, ^TCPIP_TCP_0401, ^TCPIP_TCP_0402, + ^TCPIP_TCP_0403, ^TCPIP_TCP_0408, TCPIP_UDP_0201, ^TCPIP_TCP_0101, ^TCPIP_TCP_0103, + ^TCPIP_TCP_0102, ^TCPIP_TCP_0105, ^TCPIP_TCP_0104, ^TCPIP_TCP_0107, ^TCPIP_TCP_0106, + ^TCPIP_DHCP_0210, ^TCPIP_DHCP_0211, TCPIP_TCP_0212, TCPIP_TCP_0210, ^TCPIP_TCP_0210] diff --git a/components/test/CIConfigs/Function_TCPIP_03.yml b/components/test/CIConfigs/Function_TCPIP_03.yml index cdaad25869..79107aca8c 100644 --- a/components/test/CIConfigs/Function_TCPIP_03.yml +++ b/components/test/CIConfigs/Function_TCPIP_03.yml @@ -2,10 +2,9 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC2, SSC1] Filter: - Add: - ID: [^TCPIP_UDP_0305, ^TCPIP_UDP_0304, ^TCPIP_TCP_0101, ^TCPIP_TCP_0103, ^TCPIP_TCP_0102, - ^TCPIP_TCP_0105, ^TCPIP_TCP_0104, ^TCPIP_TCP_0107, ^TCPIP_TCP_0106, ^TCPIP_DHCP_0210, - ^TCPIP_DHCP_0211, TCPIP_TCP_0212, TCPIP_TCP_0210, ^TCPIP_TCP_0210, ^TCPIP_TCP_0212, - TCPIP_DHCP_0211, TCPIP_DHCP_0210, TCPIP_UDP_0202, TCPIP_TCP_0411, ^TCPIP_IP_0102, - ^TCPIP_UDP_0105, ^TCPIP_UDP_0104, ^TCPIP_UDP_0107, ^TCPIP_UDP_0106, ^TCPIP_UDP_0101, - ^TCPIP_UDP_0103, ^TCPIP_UDP_0102, ^TCPIP_DHCP_0102, ^TCPIP_DHCP_0103, ^TCPIP_UDP_0108, - ^TCPIP_IGMP_0201] + ID: [^TCPIP_TCP_0212, TCPIP_DHCP_0211, TCPIP_DHCP_0210, TCPIP_UDP_0202, TCPIP_TCP_0411, + ^TCPIP_IP_0102, ^TCPIP_UDP_0105, ^TCPIP_UDP_0107, ^TCPIP_UDP_0106, ^TCPIP_UDP_0101, + ^TCPIP_DHCP_0102, ^TCPIP_DHCP_0103, ^TCPIP_UDP_0108, ^TCPIP_IGMP_0201, ^TCPIP_IGMP_0203, + ^TCPIP_IGMP_0202, ^TCPIP_IGMP_0204, TCPIP_UDP_0114, TCPIP_UDP_0113, TCPIP_UDP_0112, + ^TCPIP_TCP_0201, ^TCPIP_TCP_0206, ^TCPIP_TCP_0207, TCPIP_TCP_0501, TCPIP_TCP_0106, + TCPIP_TCP_0107, TCPIP_TCP_0104, TCPIP_TCP_0105, TCPIP_TCP_0102, TCPIP_TCP_0103] diff --git a/components/test/CIConfigs/Function_TCPIP_04.yml b/components/test/CIConfigs/Function_TCPIP_04.yml index 3476bb7069..8d20569c1d 100644 --- a/components/test/CIConfigs/Function_TCPIP_04.yml +++ b/components/test/CIConfigs/Function_TCPIP_04.yml @@ -2,10 +2,9 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC2, SSC1] Filter: - Add: - ID: [^TCPIP_IGMP_0203, ^TCPIP_IGMP_0202, ^TCPIP_IGMP_0204, TCPIP_UDP_0114, TCPIP_UDP_0111, - TCPIP_UDP_0110, TCPIP_UDP_0113, TCPIP_UDP_0112, ^TCPIP_TCP_0201, ^TCPIP_TCP_0206, - ^TCPIP_TCP_0207, TCPIP_TCP_0501, ^TCPIP_DNS_0101, ^TCPIP_DNS_0103, ^TCPIP_DNS_0102, - TCPIP_TCP_0106, TCPIP_TCP_0107, TCPIP_TCP_0104, TCPIP_TCP_0105, TCPIP_TCP_0102, - TCPIP_TCP_0103, TCPIP_TCP_0101, ^TCPIP_TCP_0116, ^TCPIP_TCP_0114, ^TCPIP_TCP_0115, - ^TCPIP_TCP_0112, ^TCPIP_TCP_0113, ^TCPIP_TCP_0110, ^TCPIP_TCP_0111, TCPIP_ARP_0101, - TCPIP_UDP_0304] + ID: [TCPIP_TCP_0101, ^TCPIP_TCP_0116, ^TCPIP_TCP_0114, ^TCPIP_TCP_0115, ^TCPIP_TCP_0112, + ^TCPIP_TCP_0113, ^TCPIP_TCP_0110, ^TCPIP_TCP_0111, TCPIP_ARP_0101, ^TCPIP_DHCP_0209, + ^TCPIP_DHCP_0208, ^TCPIP_DHCP_0207, ^TCPIP_DHCP_0206, ^TCPIP_DHCP_0205, ^TCPIP_DHCP_0204, + ^TCPIP_DHCP_0203, ^TCPIP_DHCP_0202, ^TCPIP_DHCP_0201, TCPIP_TCP_0204, TCPIP_TCP_0207, + TCPIP_TCP_0206, TCPIP_TCP_0201, ^TCPIP_DHCP_0101, TCPIP_TCP_0203, TCPIP_TCP_0202, + TCPIP_TCP_0208, TCPIP_DHCP_0206, TCPIP_DHCP_0207, TCPIP_DHCP_0204, TCPIP_DHCP_0205] diff --git a/components/test/CIConfigs/Function_TCPIP_05.yml b/components/test/CIConfigs/Function_TCPIP_05.yml index 85b6e72d8b..7ff1bbf8ce 100644 --- a/components/test/CIConfigs/Function_TCPIP_05.yml +++ b/components/test/CIConfigs/Function_TCPIP_05.yml @@ -2,10 +2,8 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC2, SSC1] Filter: - Add: - ID: [TCPIP_UDP_0305, TCPIP_UDP_0306, TCPIP_UDP_0307, TCPIP_UDP_0301, TCPIP_UDP_0302, - TCPIP_UDP_0303, ^TCPIP_DHCP_0209, ^TCPIP_DHCP_0208, ^TCPIP_DHCP_0207, ^TCPIP_DHCP_0206, - ^TCPIP_DHCP_0205, ^TCPIP_DHCP_0204, ^TCPIP_DHCP_0203, ^TCPIP_DHCP_0202, ^TCPIP_DHCP_0201, - TCPIP_TCP_0204, TCPIP_TCP_0207, TCPIP_TCP_0206, TCPIP_TCP_0201, ^TCPIP_DHCP_0101, - TCPIP_TCP_0203, TCPIP_TCP_0202, TCPIP_TCP_0208, TCPIP_DNS_0103, TCPIP_DHCP_0206, - TCPIP_DHCP_0207, TCPIP_DHCP_0204, TCPIP_DHCP_0205, TCPIP_DHCP_0202, TCPIP_DHCP_0203, - ^TCPIP_TCP_0204] + ID: [TCPIP_DHCP_0202, TCPIP_DHCP_0203, ^TCPIP_TCP_0204, TCPIP_DHCP_0201, ^TCPIP_TCP_0208, + TCPIP_DHCP_0208, TCPIP_DHCP_0209, ^TCPIP_TCP_0412, ^TCPIP_TCP_0411, TCPIP_ARP_0203, + ^TCPIP_UDP_0112, ^TCPIP_UDP_0114, ^TCPIP_UDP_0202, ^TCPIP_IGMP_0103, ^TCPIP_IP_0101, + TCPIP_ARP_0201, TCPIP_TCP_0115, TCPIP_TCP_0114, TCPIP_TCP_0116, TCPIP_TCP_0111, + TCPIP_TCP_0113, TCPIP_TCP_0112] diff --git a/components/test/CIConfigs/Function_TCPIP_06.yml b/components/test/CIConfigs/Function_TCPIP_06.yml index 1aceda2b73..7cf6279995 100644 --- a/components/test/CIConfigs/Function_TCPIP_06.yml +++ b/components/test/CIConfigs/Function_TCPIP_06.yml @@ -1,8 +1,5 @@ Config: {execute count: 1, execute order: in order} -DUT: [SSC2, SSC1] +DUT: [SSC1] Filter: - Add: - ID: [TCPIP_DHCP_0201, ^TCPIP_TCP_0208, TCPIP_DHCP_0208, TCPIP_DHCP_0209, ^TCPIP_TCP_0412, - ^TCPIP_TCP_0411, TCPIP_ARP_0203, ^TCPIP_UDP_0112, ^TCPIP_UDP_0114, ^TCPIP_UDP_0202, - ^TCPIP_IGMP_0103, ^TCPIP_IP_0101, TCPIP_ARP_0201, TCPIP_TCP_0115, TCPIP_TCP_0114, - TCPIP_TCP_0116, TCPIP_TCP_0111, TCPIP_TCP_0113, TCPIP_TCP_0112] + ID: [TCPIP_TCP_0405, ^TCPIP_TCP_0405] diff --git a/components/test/CIConfigs/Function_TCPIP_07.yml b/components/test/CIConfigs/Function_TCPIP_07.yml index 7cf6279995..2a047b8e16 100644 --- a/components/test/CIConfigs/Function_TCPIP_07.yml +++ b/components/test/CIConfigs/Function_TCPIP_07.yml @@ -2,4 +2,9 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC1] Filter: - Add: - ID: [TCPIP_TCP_0405, ^TCPIP_TCP_0405] + ID: [TCPIP_ICMP_0101, TCPIP_ICMP_0101, TCPIP_ICMP_0101, TCPIP_ICMP_0101, TCPIP_ICMP_0101, + ^TCPIP_UDP_0303, ^TCPIP_UDP_0303, ^TCPIP_UDP_0303, ^TCPIP_UDP_0303, ^TCPIP_UDP_0303, + ^TCPIP_UDP_0302, ^TCPIP_UDP_0302, ^TCPIP_UDP_0302, ^TCPIP_UDP_0302, ^TCPIP_UDP_0302, + ^TCPIP_UDP_0301, ^TCPIP_UDP_0301, ^TCPIP_UDP_0301, ^TCPIP_UDP_0301, ^TCPIP_UDP_0301, + TCPIP_DNS_0102, TCPIP_DNS_0102, TCPIP_DNS_0102, TCPIP_DNS_0102, TCPIP_DNS_0102, + TCPIP_DNS_0101, TCPIP_DNS_0101, TCPIP_DNS_0101, TCPIP_DNS_0101, TCPIP_DNS_0101] diff --git a/components/test/CIConfigs/Function_TCPIP_08.yml b/components/test/CIConfigs/Function_TCPIP_08.yml new file mode 100644 index 0000000000..4ada8f3eee --- /dev/null +++ b/components/test/CIConfigs/Function_TCPIP_08.yml @@ -0,0 +1,10 @@ +Config: {execute count: 1, execute order: in order} +DUT: [SSC2, SSC1] +Filter: +- Add: + ID: [^TCPIP_UDP_0110, ^TCPIP_UDP_0110, ^TCPIP_UDP_0110, ^TCPIP_UDP_0110, ^TCPIP_UDP_0110, + ^TCPIP_ICMP_0101, ^TCPIP_ICMP_0101, ^TCPIP_ICMP_0101, ^TCPIP_ICMP_0101, ^TCPIP_ICMP_0101, + TCPIP_UDP_0109, TCPIP_UDP_0109, TCPIP_UDP_0109, TCPIP_UDP_0109, TCPIP_UDP_0109, + TCPIP_UDP_0104, TCPIP_UDP_0104, TCPIP_UDP_0104, TCPIP_UDP_0104, TCPIP_UDP_0104, + TCPIP_UDP_0102, TCPIP_UDP_0102, TCPIP_UDP_0102, TCPIP_UDP_0102, TCPIP_UDP_0102, + TCPIP_UDP_0103, TCPIP_UDP_0103, TCPIP_UDP_0103, TCPIP_UDP_0103, TCPIP_UDP_0103] diff --git a/components/test/CIConfigs/Function_TCPIP_09.yml b/components/test/CIConfigs/Function_TCPIP_09.yml new file mode 100644 index 0000000000..a4c1a51638 --- /dev/null +++ b/components/test/CIConfigs/Function_TCPIP_09.yml @@ -0,0 +1,10 @@ +Config: {execute count: 1, execute order: in order} +DUT: [SSC1] +Filter: +- Add: + ID: [^TCPIP_UDP_0307, ^TCPIP_UDP_0307, ^TCPIP_UDP_0307, ^TCPIP_UDP_0307, ^TCPIP_UDP_0307, + ^TCPIP_UDP_0306, ^TCPIP_UDP_0306, ^TCPIP_UDP_0306, ^TCPIP_UDP_0306, ^TCPIP_UDP_0306, + ^TCPIP_UDP_0305, ^TCPIP_UDP_0305, ^TCPIP_UDP_0305, ^TCPIP_UDP_0305, ^TCPIP_UDP_0305, + ^TCPIP_UDP_0304, ^TCPIP_UDP_0304, ^TCPIP_UDP_0304, ^TCPIP_UDP_0304, ^TCPIP_UDP_0304, + ^TCPIP_UDP_0104, ^TCPIP_UDP_0104, ^TCPIP_UDP_0104, ^TCPIP_UDP_0104, ^TCPIP_UDP_0104, + ^TCPIP_UDP_0103, ^TCPIP_UDP_0103, ^TCPIP_UDP_0103, ^TCPIP_UDP_0103, ^TCPIP_UDP_0103] diff --git a/components/test/CIConfigs/Function_TCPIP_10.yml b/components/test/CIConfigs/Function_TCPIP_10.yml new file mode 100644 index 0000000000..201f95eea0 --- /dev/null +++ b/components/test/CIConfigs/Function_TCPIP_10.yml @@ -0,0 +1,10 @@ +Config: {execute count: 1, execute order: in order} +DUT: [SSC2, SSC1] +Filter: +- Add: + ID: [^TCPIP_UDP_0102, ^TCPIP_UDP_0102, ^TCPIP_UDP_0102, ^TCPIP_UDP_0102, ^TCPIP_UDP_0102, + TCPIP_UDP_0111, TCPIP_UDP_0111, TCPIP_UDP_0111, TCPIP_UDP_0111, TCPIP_UDP_0111, + TCPIP_UDP_0110, TCPIP_UDP_0110, TCPIP_UDP_0110, TCPIP_UDP_0110, TCPIP_UDP_0110, + ^TCPIP_DNS_0101, ^TCPIP_DNS_0101, ^TCPIP_DNS_0101, ^TCPIP_DNS_0101, ^TCPIP_DNS_0101, + ^TCPIP_DNS_0103, ^TCPIP_DNS_0103, ^TCPIP_DNS_0103, ^TCPIP_DNS_0103, ^TCPIP_DNS_0103, + ^TCPIP_DNS_0102, ^TCPIP_DNS_0102, ^TCPIP_DNS_0102, ^TCPIP_DNS_0102, ^TCPIP_DNS_0102] diff --git a/components/test/CIConfigs/Function_TCPIP_11.yml b/components/test/CIConfigs/Function_TCPIP_11.yml new file mode 100644 index 0000000000..1d083887c3 --- /dev/null +++ b/components/test/CIConfigs/Function_TCPIP_11.yml @@ -0,0 +1,10 @@ +Config: {execute count: 1, execute order: in order} +DUT: [SSC1] +Filter: +- Add: + ID: [TCPIP_UDP_0304, TCPIP_UDP_0304, TCPIP_UDP_0304, TCPIP_UDP_0304, TCPIP_UDP_0304, + TCPIP_UDP_0305, TCPIP_UDP_0305, TCPIP_UDP_0305, TCPIP_UDP_0305, TCPIP_UDP_0305, + TCPIP_UDP_0306, TCPIP_UDP_0306, TCPIP_UDP_0306, TCPIP_UDP_0306, TCPIP_UDP_0306, + TCPIP_UDP_0307, TCPIP_UDP_0307, TCPIP_UDP_0307, TCPIP_UDP_0307, TCPIP_UDP_0307, + TCPIP_UDP_0301, TCPIP_UDP_0301, TCPIP_UDP_0301, TCPIP_UDP_0301, TCPIP_UDP_0301, + TCPIP_UDP_0302, TCPIP_UDP_0302, TCPIP_UDP_0302, TCPIP_UDP_0302, TCPIP_UDP_0302] diff --git a/components/test/CIConfigs/Function_TCPIP_12.yml b/components/test/CIConfigs/Function_TCPIP_12.yml new file mode 100644 index 0000000000..e9f5b72a51 --- /dev/null +++ b/components/test/CIConfigs/Function_TCPIP_12.yml @@ -0,0 +1,6 @@ +Config: {execute count: 1, execute order: in order} +DUT: [SSC1] +Filter: +- Add: + ID: [TCPIP_UDP_0303, TCPIP_UDP_0303, TCPIP_UDP_0303, TCPIP_UDP_0303, TCPIP_UDP_0303, + TCPIP_DNS_0103, TCPIP_DNS_0103, TCPIP_DNS_0103, TCPIP_DNS_0103, TCPIP_DNS_0103] diff --git a/components/test/CIConfigs/Function_WIFI_01.yml b/components/test/CIConfigs/Function_WIFI_01.yml index 4a6b3e0c17..9d177e5ee1 100644 --- a/components/test/CIConfigs/Function_WIFI_01.yml +++ b/components/test/CIConfigs/Function_WIFI_01.yml @@ -1,11 +1,10 @@ Config: {execute count: 1, execute order: in order} -DUT: [SSC2, SSC1] +DUT: [SSC3, SSC2, SSC1] Filter: - Add: ID: [^WIFI_CONN_0601, ^WIFI_ADDR_0101, ^WIFI_CONN_0903, WIFI_SCAN_0103, WIFI_SCAN_0102, WIFI_SCAN_0101, WIFI_SCAN_0105, WIFI_SCAN_0104, WIFI_CONN_0201, WIFI_CONN_0702, - WIFI_CONN_0703, WIFI_CONN_0904, ^WIFI_CONN_0201, ^WIFI_CONN_0703, ^WIFI_SCAN_0102, - ^WIFI_SCAN_0103, ^WIFI_SCAN_0104, ^WIFI_SCAN_0105, ^WIFI_ADDR_0102, WIFI_CONN_0401, - ^WIFI_CONN_0103, WIFI_ADDR_0101, WIFI_ADDR_0102, WIFI_CONN_0301, ^WIFI_CONN_0801, - WIFI_CONN_0104, ^WIFI_CONN_0301, WIFI_CONN_0501, WIFI_CONN_0502, ^WIFI_CONN_0401, - WIFI_MODE_0101] + WIFI_CONN_0703, WIFI_PHY_0403, WIFI_CONN_0904, ^WIFI_CONN_0201, ^WIFI_CONN_0703, + ^WIFI_SCAN_0102, ^WIFI_SCAN_0103, ^WIFI_SCAN_0104, ^WIFI_SCAN_0105, ^WIFI_ADDR_0102, + WIFI_CONN_0401, ^WIFI_CONN_0103, WIFI_ADDR_0101, WIFI_ADDR_0102, WIFI_PHY_0502, + WIFI_PHY_0503, WIFI_PHY_0501, WIFI_PHY_0506, WIFI_PHY_0505, WIFI_CONN_0301] diff --git a/components/test/CIConfigs/Function_WIFI_02.yml b/components/test/CIConfigs/Function_WIFI_02.yml index 78ef087b59..c684454880 100644 --- a/components/test/CIConfigs/Function_WIFI_02.yml +++ b/components/test/CIConfigs/Function_WIFI_02.yml @@ -2,7 +2,9 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC2, SSC1] Filter: - Add: - ID: [WIFI_MODE_0103, WIFI_MODE_0102, ^WIFI_CONN_0904, ^WIFI_CONN_0901, WIFI_CONN_0601, - WIFI_CONN_0901, WIFI_CONN_0903, WIFI_CONN_0503, ^WIFI_CONN_0104, WIFI_CONN_0101, - WIFI_CONN_0102, WIFI_CONN_0103, ^WIFI_CONN_0702, WIFI_CONN_0801, ^WIFI_CONN_0101, - ^WIFI_CONN_0503, ^WIFI_CONN_0502, ^WIFI_CONN_0501, ^WIFI_SCAN_0101] + ID: [WIFI_SCAN_0301, WIFI_SCAN_0303, ^WIFI_CONN_0801, WIFI_SCAN_0304, WIFI_CONN_0104, + ^WIFI_CONN_0301, WIFI_CONN_0501, WIFI_CONN_0502, ^WIFI_CONN_0401, WIFI_MODE_0101, + WIFI_MODE_0103, WIFI_MODE_0102, ^WIFI_CONN_0904, ^WIFI_CONN_0901, WIFI_SCAN_0302, + WIFI_CONN_0601, WIFI_CONN_0901, WIFI_CONN_0903, WIFI_SCAN_0201, WIFI_CONN_0503, + WIFI_PHY_0402, WIFI_PHY_0401, WIFI_PHY_0407, WIFI_PHY_0406, WIFI_PHY_0405, WIFI_PHY_0404, + WIFI_PHY_0408, ^WIFI_CONN_0104, WIFI_CONN_0101, WIFI_CONN_0102] diff --git a/components/test/CIConfigs/Function_WIFI_03.yml b/components/test/CIConfigs/Function_WIFI_03.yml index 1ac97dece3..72a9db2deb 100644 --- a/components/test/CIConfigs/Function_WIFI_03.yml +++ b/components/test/CIConfigs/Function_WIFI_03.yml @@ -1,5 +1,6 @@ Config: {execute count: 1, execute order: in order} -DUT: [SSC1] +DUT: [SSC3, SSC2, SSC1] Filter: - Add: - ID: [WIFI_CONN_0701, ^WIFI_CONN_0701, ^WIFI_CONN_0902, WIFI_CONN_0902] + ID: [WIFI_CONN_0103, WIFI_PHY_0504, ^WIFI_CONN_0702, WIFI_CONN_0801, ^WIFI_CONN_0101, + ^WIFI_CONN_0503, ^WIFI_CONN_0502, ^WIFI_CONN_0501, ^WIFI_SCAN_0101] diff --git a/components/test/CIConfigs/Function_WIFI_04.yml b/components/test/CIConfigs/Function_WIFI_04.yml new file mode 100644 index 0000000000..1ac97dece3 --- /dev/null +++ b/components/test/CIConfigs/Function_WIFI_04.yml @@ -0,0 +1,5 @@ +Config: {execute count: 1, execute order: in order} +DUT: [SSC1] +Filter: +- Add: + ID: [WIFI_CONN_0701, ^WIFI_CONN_0701, ^WIFI_CONN_0902, WIFI_CONN_0902] diff --git a/components/test/CIConfigs/Function_WIFI_05.yml b/components/test/CIConfigs/Function_WIFI_05.yml new file mode 100644 index 0000000000..22840fa7af --- /dev/null +++ b/components/test/CIConfigs/Function_WIFI_05.yml @@ -0,0 +1,10 @@ +Config: {execute count: 1, execute order: in order} +DUT: [SSC2, SSC1] +Filter: +- Add: + ID: [WIFI_PHY_0105, WIFI_PHY_0105, WIFI_PHY_0105, WIFI_PHY_0102, WIFI_PHY_0102, + WIFI_PHY_0102, WIFI_PHY_0103, WIFI_PHY_0103, WIFI_PHY_0103, WIFI_PHY_0101, WIFI_PHY_0101, + WIFI_PHY_0101, WIFI_PHY_0313, WIFI_PHY_0313, WIFI_PHY_0313, WIFI_PHY_0312, WIFI_PHY_0312, + WIFI_PHY_0312, WIFI_PHY_0311, WIFI_PHY_0311, WIFI_PHY_0311, WIFI_PHY_0310, WIFI_PHY_0310, + WIFI_PHY_0310, WIFI_PHY_0316, WIFI_PHY_0316, WIFI_PHY_0316, WIFI_PHY_0315, WIFI_PHY_0315, + WIFI_PHY_0315] diff --git a/components/test/CIConfigs/Function_WIFI_06.yml b/components/test/CIConfigs/Function_WIFI_06.yml new file mode 100644 index 0000000000..640330233a --- /dev/null +++ b/components/test/CIConfigs/Function_WIFI_06.yml @@ -0,0 +1,10 @@ +Config: {execute count: 1, execute order: in order} +DUT: [SSC2, SSC1] +Filter: +- Add: + ID: [WIFI_PHY_0314, WIFI_PHY_0314, WIFI_PHY_0314, WIFI_PHY_0308, WIFI_PHY_0308, + WIFI_PHY_0308, WIFI_PHY_0309, WIFI_PHY_0309, WIFI_PHY_0309, WIFI_PHY_0304, WIFI_PHY_0304, + WIFI_PHY_0304, WIFI_PHY_0305, WIFI_PHY_0305, WIFI_PHY_0305, WIFI_PHY_0306, WIFI_PHY_0306, + WIFI_PHY_0306, WIFI_PHY_0307, WIFI_PHY_0307, WIFI_PHY_0307, WIFI_PHY_0301, WIFI_PHY_0301, + WIFI_PHY_0301, WIFI_PHY_0302, WIFI_PHY_0302, WIFI_PHY_0302, WIFI_PHY_0110, WIFI_PHY_0110, + WIFI_PHY_0110] diff --git a/components/test/CIConfigs/Function_WIFI_07.yml b/components/test/CIConfigs/Function_WIFI_07.yml new file mode 100644 index 0000000000..a51560fd60 --- /dev/null +++ b/components/test/CIConfigs/Function_WIFI_07.yml @@ -0,0 +1,10 @@ +Config: {execute count: 1, execute order: in order} +DUT: [SSC2, SSC1] +Filter: +- Add: + ID: [WIFI_PHY_0113, WIFI_PHY_0113, WIFI_PHY_0113, WIFI_PHY_0120, WIFI_PHY_0120, + WIFI_PHY_0120, WIFI_PHY_0119, WIFI_PHY_0119, WIFI_PHY_0119, WIFI_PHY_0118, WIFI_PHY_0118, + WIFI_PHY_0118, WIFI_PHY_0115, WIFI_PHY_0115, WIFI_PHY_0115, WIFI_PHY_0114, WIFI_PHY_0114, + WIFI_PHY_0114, WIFI_PHY_0117, WIFI_PHY_0117, WIFI_PHY_0117, WIFI_PHY_0111, WIFI_PHY_0111, + WIFI_PHY_0111, WIFI_PHY_0112, WIFI_PHY_0112, WIFI_PHY_0112, WIFI_PHY_0205, WIFI_PHY_0205, + WIFI_PHY_0205] diff --git a/components/test/CIConfigs/Function_WIFI_08.yml b/components/test/CIConfigs/Function_WIFI_08.yml new file mode 100644 index 0000000000..f143efb3b0 --- /dev/null +++ b/components/test/CIConfigs/Function_WIFI_08.yml @@ -0,0 +1,10 @@ +Config: {execute count: 1, execute order: in order} +DUT: [SSC2, SSC1] +Filter: +- Add: + ID: [WIFI_PHY_0204, WIFI_PHY_0204, WIFI_PHY_0204, WIFI_PHY_0207, WIFI_PHY_0207, + WIFI_PHY_0207, WIFI_PHY_0206, WIFI_PHY_0206, WIFI_PHY_0206, WIFI_PHY_0201, WIFI_PHY_0201, + WIFI_PHY_0201, WIFI_PHY_0203, WIFI_PHY_0203, WIFI_PHY_0203, WIFI_PHY_0202, WIFI_PHY_0202, + WIFI_PHY_0202, WIFI_PHY_0209, WIFI_PHY_0209, WIFI_PHY_0209, WIFI_PHY_0208, WIFI_PHY_0208, + WIFI_PHY_0208, WIFI_PHY_0116, WIFI_PHY_0116, WIFI_PHY_0116, WIFI_PHY_0303, WIFI_PHY_0303, + WIFI_PHY_0303] diff --git a/components/test/CIConfigs/Function_WIFI_09.yml b/components/test/CIConfigs/Function_WIFI_09.yml new file mode 100644 index 0000000000..f4adf0d2e6 --- /dev/null +++ b/components/test/CIConfigs/Function_WIFI_09.yml @@ -0,0 +1,10 @@ +Config: {execute count: 1, execute order: in order} +DUT: [SSC2, SSC1] +Filter: +- Add: + ID: [WIFI_PHY_0108, WIFI_PHY_0108, WIFI_PHY_0108, WIFI_PHY_0109, WIFI_PHY_0109, + WIFI_PHY_0109, WIFI_PHY_0106, WIFI_PHY_0106, WIFI_PHY_0106, WIFI_PHY_0107, WIFI_PHY_0107, + WIFI_PHY_0107, WIFI_PHY_0214, WIFI_PHY_0214, WIFI_PHY_0214, WIFI_PHY_0212, WIFI_PHY_0212, + WIFI_PHY_0212, WIFI_PHY_0213, WIFI_PHY_0213, WIFI_PHY_0213, WIFI_PHY_0210, WIFI_PHY_0210, + WIFI_PHY_0210, WIFI_PHY_0211, WIFI_PHY_0211, WIFI_PHY_0211, WIFI_PHY_0104, WIFI_PHY_0104, + WIFI_PHY_0104] diff --git a/components/test/TestCaseAll.yml b/components/test/TestCaseAll.yml index cf634005dd..5e72da0f40 100644 --- a/components/test/TestCaseAll.yml +++ b/components/test/TestCaseAll.yml @@ -1,4 +1,151 @@ test cases: +- CI ready: 'Yes' + ID: WIFI_PHY_0105 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 2 -m b + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 40 + - ['R SSC2 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp!)(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. assoc response has no erp/xrates/ht, cap.short_slot_time=1, rates=[1/2/5/5/11] + + 3. radiotap rates in [1/2/5/5/11]' + initial condition: APM1 + initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial + condition APSTA1 + module: WIFI MAC + steps: '1. target set to PHY mode 11b + + 2. ht40 STA connect to SoftAP, capture assoc response + + 3. ping, capture Data' + sub module: Phy Mode + summary: SoftAP set as 11b, ht40 STA connect to AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: SoftAP PHY mode test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0102 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 2 -m b + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m b + - ['R SSC2 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp!)(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. assoc response has no erp/xrates/ht, cap.short_slot_time=1, rates=[1/2/5/5/11] + + 3. radiotap rates in [1/2/5/5/11]' + initial condition: APM1 + initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial + condition APSTA1 + module: WIFI MAC + steps: '1. target set to PHY mode 11b + + 2. 11b STA connect to SoftAP, capture assoc response + + 3. ping, capture Data' + sub module: Phy Mode + summary: SoftAP set as 11b, 11b STA connect to AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: SoftAP PHY mode test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0103 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 2 -m b + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m g + - ['R SSC2 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp!)(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. assoc response has no erp/xrates/ht, cap.short_slot_time=1, rates=[1/2/5/5/11] + + 3. radiotap rates in [1/2/5/5/11]' + initial condition: APM1 + initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial + condition APSTA1 + module: WIFI MAC + steps: '1. target set to PHY mode 11b + + 2. 11bg STA connect to SoftAP, capture assoc response + + 3. ping, capture Data' + sub module: Phy Mode + summary: SoftAP set as 11b, 11g STA connect to AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: SoftAP PHY mode test + version: v1 (2015-8-15) - CI ready: 'Yes' ID: ^WIFI_CONN_0601 SDK: '8266_NonOS @@ -7,6 +154,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -50,6 +198,438 @@ test cases: test point 1: basic function test point 2: list SoftAP connected station version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0101 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 2 -m b + - ['R SSC1 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK', 'R CAP PDU (Wlan.frame_ctrl.type_subtype="Management-Beacon")(Wlan.ie_list.erp!)(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")'] + comment: '' + execution time: 0.0 + expected result: 1. beacon has no erp/xrates/ht, cap.short_slot_time=1, rates=[1/2/5/5/11] + initial condition: APM1 + initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial + condition APSTA1 + module: WIFI MAC + steps: 1. target set to PHY mode 11b, capture beacon + sub module: Phy Mode + summary: SoftAP set as 11b, check beacon + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: SoftAP PHY mode test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0313 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m b + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 40 + - ['R SSC2 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s%20or%20wlan%20addr2%20%%s + + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC1 sta -C -s -p + - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates!)(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities.short_gi_for_40="1")(Wlan.ie_list.ht_operation.second_channel_offset!="0","2")(Wlan.ie_list.ht_operation.sta_channel_width="1")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") + PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. check STA packet + + 3. check SoftAP packet' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. set softAP ht40, STA 11b + + 2. STA connect to ext AP + + 3. ext STA connect to SoftAP' + sub module: Phy Mode + summary: SoftAP ht40, STA 11b, get connected and join AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP PHY mode test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0312 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 20 + - ['R SSC2 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s%20or%20wlan%20addr2%20%%s + + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC1 sta -C -s -p + - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities.short_gi_for_40="1")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") + PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities="")(Wlan.ie_list.ht_operation.second_channel_offset="0")(Wlan.ie_list.ht_operation.sta_channel_width="0")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") + PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. check STA packet + + 3. check SoftAP packet' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. set softAP 11bgn, STA ht40 + + 2. STA connect to ext AP + + 3. ext STA connect to SoftAP' + sub module: Phy Mode + summary: SoftAP 11bgn, STA ht40, get connected and join AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP PHY mode test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0311 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 20 + - ['R SSC2 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s%20or%20wlan%20addr2%20%%s + + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC1 sta -C -s -p + - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities="")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") + PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities="")(Wlan.ie_list.ht_operation.second_channel_offset="0")(Wlan.ie_list.ht_operation.sta_channel_width="0")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") + PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. check STA packet + + 3. check SoftAP packet' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. set softAP 11bgn, STA 11bgn + + 2. STA connect to ext AP + + 3. ext STA connect to SoftAP' + sub module: Phy Mode + summary: SoftAP 11bgn, STA 11bgn, get connected and join AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP PHY mode test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0310 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m g + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 20 + - ['R SSC2 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s%20or%20wlan%20addr2%20%%s + + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC1 sta -C -s -p + - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M")'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities="")(Wlan.ie_list.ht_operation.second_channel_offset="0")(Wlan.ie_list.ht_operation.sta_channel_width="0")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") + PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. check STA packet + + 3. check SoftAP packet' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. set softAP 11bgn, STA 11bg + + 2. STA connect to ext AP + + 3. ext STA connect to SoftAP' + sub module: Phy Mode + summary: SoftAP 11bgn, STA 11bg, get connected and join AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP PHY mode test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0316 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 40 + - ['R SSC2 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s%20or%20wlan%20addr2%20%%s + + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC1 sta -C -s -p + - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities.short_gi_for_40="1")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") + PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities.short_gi_for_40="1")(Wlan.ie_list.ht_operation.second_channel_offset!="0","2")(Wlan.ie_list.ht_operation.sta_channel_width="1")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") + PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. check STA packet + + 3. check SoftAP packet' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. set softAP ht40, STA ht40 + + 2. STA connect to ext AP + + 3. ext STA connect to SoftAP' + sub module: Phy Mode + summary: SoftAP ht40, STA ht40, get connected and join AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP PHY mode test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0315 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 40 + - ['R SSC2 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s%20or%20wlan%20addr2%20%%s + + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC1 sta -C -s -p + - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities="")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") + PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities.short_gi_for_40="1")(Wlan.ie_list.ht_operation.second_channel_offset!="0","2")(Wlan.ie_list.ht_operation.sta_channel_width="1")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") + PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. check STA packet + + 3. check SoftAP packet' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. set softAP ht40, STA 11bgn + + 2. STA connect to ext AP + + 3. ext STA connect to SoftAP' + sub module: Phy Mode + summary: SoftAP ht40, STA 11bgn, get connected and join AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP PHY mode test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0314 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m g + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 40 + - ['R SSC2 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s%20or%20wlan%20addr2%20%%s + + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC1 sta -C -s -p + - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M")'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities.short_gi_for_40="1")(Wlan.ie_list.ht_operation.second_channel_offset!="0","2")(Wlan.ie_list.ht_operation.sta_channel_width="1")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") + PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. check STA packet + + 3. check SoftAP packet' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. set softAP ht40, STA 11bg + + 2. STA connect to ext AP + + 3. ext STA connect to SoftAP' + sub module: Phy Mode + summary: SoftAP ht40, STA 11bg, get connected and join AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP PHY mode test + version: v1 (2015-8-15) - CI ready: 'Yes' ID: TCPIP_ICMP_0101 SDK: '8266_NonOS @@ -58,6 +638,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: 1/5 auto test: 'Yes' category: Function cmd set: @@ -97,6 +678,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -129,6 +711,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -181,6 +764,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -247,6 +831,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -306,6 +891,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -363,6 +949,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -430,6 +1017,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -489,6 +1077,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -525,6 +1114,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -566,6 +1156,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -635,6 +1226,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -690,6 +1282,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -753,6 +1346,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -816,6 +1410,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -870,6 +1465,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -933,6 +1529,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -987,6 +1584,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -1042,6 +1640,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -1073,6 +1672,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -1136,6 +1736,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -1217,6 +1818,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -1280,6 +1882,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -1361,6 +1964,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -1410,6 +2014,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -1479,6 +2084,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -1524,6 +2130,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: 1/5 auto test: 'Yes' category: Function cmd set: @@ -1575,6 +2182,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -1626,6 +2234,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -1665,6 +2274,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -1710,6 +2320,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -1773,6 +2384,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -1836,6 +2448,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: 1/5 auto test: 'Yes' category: Function cmd set: @@ -1893,6 +2506,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: 1/5 auto test: 'Yes' category: Function cmd set: @@ -1950,6 +2564,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -2001,6 +2616,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -2042,6 +2658,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -2065,6 +2682,340 @@ test cases: test point 1: basic function test point 2: wifi connect status check version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0308 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m g + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m g + - ['R SSC2 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s%20or%20wlan%20addr2%20%%s + + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC1 sta -C -s -p + - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities.short_gi_for_40="1")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") + PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. check STA packet + + 3. check SoftAP packet' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. set softAP 11bg, STA ht40 + + 2. STA connect to ext AP + + 3. ext STA connect to SoftAP' + sub module: Phy Mode + summary: SoftAP 11bg, STA ht40, get connected and join AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP PHY mode test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0309 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m b + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 20 + - ['R SSC2 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s%20or%20wlan%20addr2%20%%s + + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC1 sta -C -s -p + - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates!)(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities="")(Wlan.ie_list.ht_operation.second_channel_offset="0")(Wlan.ie_list.ht_operation.sta_channel_width="0")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") + PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. check STA packet + + 3. check SoftAP packet' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. set softAP 11bgn, STA 11b + + 2. STA connect to ext AP + + 3. ext STA connect to SoftAP' + sub module: Phy Mode + summary: SoftAP 11bgn, STA 11b, get connected and join AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP PHY mode test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0304 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m b + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m b + - ['R SSC2 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s%20or%20wlan%20addr2%20%%s + + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC1 sta -C -s -p + - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities.short_gi_for_40="1")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") + PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp!)(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. check STA packet + + 3. check SoftAP packet' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. set softAP 11b, STA ht40 + + 2. STA connect to ext AP + + 3. ext STA connect to SoftAP' + sub module: Phy Mode + summary: SoftAP 11b, STA ht40, get connected and join AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP PHY mode test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0305 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m b + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m g + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m g + - ['R SSC2 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s%20or%20wlan%20addr2%20%%s + + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC1 sta -C -s -p + - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates!)(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. check STA packet + + 3. check SoftAP packet' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. set softAP 11bg, STA 11b + + 2. STA connect to ext AP + + 3. ext STA connect to SoftAP' + sub module: Phy Mode + summary: SoftAP 11bg, STA 11b, get connected and join AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP PHY mode test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0306 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m g + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m g + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m g + - ['R SSC2 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s%20or%20wlan%20addr2%20%%s + + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC1 sta -C -s -p + - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M")'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. check STA packet + + 3. check SoftAP packet' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. set softAP 11bg, STA 11bg + + 2. STA connect to ext AP + + 3. ext STA connect to SoftAP' + sub module: Phy Mode + summary: SoftAP 11bg, STA 11bg, get connected and join AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP PHY mode test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0307 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m g + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m g + - ['R SSC2 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s%20or%20wlan%20addr2%20%%s + + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC1 sta -C -s -p + - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities="")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") + PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. check STA packet + + 3. check SoftAP packet' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. set softAP 11bg, STA 11bgn + + 2. STA connect to ext AP + + 3. ext STA connect to SoftAP' + sub module: Phy Mode + summary: SoftAP 11bg, STA 11bgn, get connected and join AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP PHY mode test + version: v1 (2015-8-15) - CI ready: 'Yes' ID: TCPIP_DNS_0102 SDK: '8266_NonOS @@ -2073,6 +3024,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: 3/5 auto test: 'Yes' category: Function cmd set: @@ -2112,6 +3064,116 @@ test cases: test point 1: basic function test point 2: DNS function test version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0301 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m b + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m b + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m b + - ['R SSC2 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s%20or%20wlan%20addr2%20%%s + + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC1 sta -C -s -p + - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates!)(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp!)(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. check STA packet + + 3. check SoftAP packet' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. set softAP 11b, STA 11b + + 2. STA connect to ext AP + + 3. ext STA connect to SoftAP' + sub module: Phy Mode + summary: SoftAP 11b, STA 11b, get connected and join AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP PHY mode test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0302 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m g + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m b + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m b + - ['R SSC2 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s%20or%20wlan%20addr2%20%%s + + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC1 sta -C -s -p + - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M")'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp!)(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. check STA packet + + 3. check SoftAP packet' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. set softAP 11b, STA 11bg + + 2. STA connect to ext AP + + 3. ext STA connect to SoftAP' + sub module: Phy Mode + summary: SoftAP 11b, STA 11bg, get connected and join AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP PHY mode test + version: v1 (2015-8-15) - CI ready: 'Yes' ID: TCPIP_DNS_0101 SDK: '8266_NonOS @@ -2120,6 +3182,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: 3/5 auto test: 'Yes' category: Function cmd set: @@ -2143,6 +3206,52 @@ test cases: test point 1: basic function test point 2: DNS function test version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0403 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 20 + - ['R SSC2 C +PHY:OK'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC2 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC1 NC +JAP:DISCONNECTED', 'P SSC2 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: 3. SoftAP and STA in channel2, SoftAP 20M, STA 40M, STA not disconnected + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. SoftAP 11n ht20, in channel1, ext AP 11n ht40, in channel2 + + 2. STA connect to ext AP + + 3. AP get connected' + sub module: Phy Mode + summary: SoftAP ext AP in defferent channel, SoftAP 20M, ext AP 40M, STA connect + to AP then Softap get connected + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP initial channel test + version: v1 (2015-8-15) - CI ready: 'Yes' ID: WIFI_CONN_0904 SDK: '8266_NonOS @@ -2151,6 +3260,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -2221,6 +3331,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -2278,6 +3389,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -2333,6 +3445,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -2376,6 +3489,55 @@ test cases: test point 1: basic function test point 2: query JAP status version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0110 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 2 -m g + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 40 + - ['R SSC2 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M")'] + comment: '' + execution time: 0.0 + expected result: '1. beacon has erp/xrates, no ht, cap.short_slot_time=1, rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54] + + 2. assoc response has erp/xrates, no ht, cap.short_slot_time=1, rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54] + + 3. radiotap rates in rates and xrates' + initial condition: APM1 + initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial + condition APSTA1 + module: WIFI MAC + steps: '1. target set to PHY mode 11bg + + 2. ht40 STA connect to SoftAP, capture assoc response + + 3. ping, capture Data' + sub module: Phy Mode + summary: SoftAP set as 11bg, ht40 STA connect to AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: SoftAP PHY mode test + version: v1 (2015-8-15) - CI ready: 'Yes' ID: ^TCPIP_IGMP_0102 SDK: '8266_NonOS @@ -2384,6 +3546,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -2441,6 +3604,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -2488,6 +3652,55 @@ test cases: test point 1: basic function test point 2: IGMP API parameter check version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0113 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 2 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m g + - ['R SSC2 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. assoc response has erp/xrates, no ht, cap.short_slot_time=1, rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54] + + 3. radiotap rates in rates/xrates' + initial condition: APM1 + initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial + condition APSTA1 + module: WIFI MAC + steps: '1. target set to PHY mode 11bgn + + 2. 11bg STA connect to SoftAP, capture assoc response + + 3. ping, capture Data' + sub module: Phy Mode + summary: SoftAP set as 11bgn, 11g STA connect to AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: SoftAP PHY mode test + version: v1 (2015-8-15) - CI ready: 'Yes' ID: ^TCPIP_IGMP_0104 SDK: '8266_NonOS @@ -2496,6 +3709,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -2553,6 +3767,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -2584,6 +3799,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: 1/5 auto test: 'Yes' category: Function cmd set: @@ -2648,6 +3864,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -2686,6 +3903,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -2736,6 +3954,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -2798,6 +4017,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -2860,6 +4080,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -2917,6 +4138,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -2972,6 +4194,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -3029,6 +4252,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -3084,6 +4308,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -3159,6 +4384,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: 1/5 auto test: 'Yes' category: Function cmd set: @@ -3198,6 +4424,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -3265,6 +4492,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -3316,6 +4544,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: 1/5 auto test: 'Yes' category: Function cmd set: @@ -3382,6 +4611,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -3439,6 +4669,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -3478,6 +4709,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: 1/5 auto test: 'Yes' category: Function cmd set: @@ -3547,6 +4779,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -3586,6 +4819,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: 1/5 auto test: 'Yes' category: Function cmd set: @@ -3643,6 +4877,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: 1/5 auto test: 'Yes' category: Function cmd set: @@ -3706,6 +4941,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -3757,6 +4993,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -3804,6 +5041,57 @@ test cases: test point 1: basic function test point 2: IGMP send/recv test version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0120 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 2 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 40 + - ['R SSC2 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities.short_gi_for_40="1")(Wlan.ie_list.ht_operation.second_channel_offset!="0","2")(Wlan.ie_list.ht_operation.sta_channel_width="1")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") + PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed, + + 2. assoc response has erp/ht/xrates, cap.short_slot_time=1, ht_info.2nd_channel_offset=2,sta_channel_width=1, + rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54] + + 3. radiotap rates in rates/xrates/msc0-7' + initial condition: APM1 + initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial + condition APSTA1 + module: WIFI MAC + steps: '1. target set to PHY mode ht40 + + 2. ht40 STA connect to SoftAP, capture assoc response + + 3. ping, capture Data' + sub module: Phy Mode + summary: SoftAP set as ht40, ht40 STA connect to AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: SoftAP PHY mode test + version: v1 (2015-8-15) - CI ready: 'Yes' ID: TCPIP_IGMP_0201 SDK: '8266_NonOS @@ -3812,6 +5100,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -3861,6 +5150,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -3918,6 +5208,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -3967,6 +5258,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -4038,6 +5330,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -4093,6 +5386,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -4147,6 +5441,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -4210,6 +5505,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -4273,6 +5569,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -4336,6 +5633,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -4391,6 +5689,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -4454,6 +5753,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -4529,6 +5829,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: 1/5 auto test: 'Yes' category: Function cmd set: @@ -4588,6 +5889,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: 1/5 auto test: 'Yes' category: Function cmd set: @@ -4647,6 +5949,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: 1/5 auto test: 'Yes' category: Function cmd set: @@ -4698,6 +6001,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: 1/5 auto test: 'Yes' category: Function cmd set: @@ -4749,6 +6053,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -4807,6 +6112,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -4870,6 +6176,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -4945,6 +6252,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -4996,6 +6304,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -5090,6 +6399,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -5177,6 +6487,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -5237,6 +6548,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -5330,6 +6642,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -5391,6 +6704,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -5453,6 +6767,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -5536,6 +6851,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -5605,6 +6921,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -5672,6 +6989,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -5755,6 +7073,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -5818,6 +7137,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -5880,6 +7200,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -5935,6 +7256,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -5995,6 +7317,257 @@ test cases: test point 1: basic function test point 2: mac address function test version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0119 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 2 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 20 + - ['R SSC2 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities="")(Wlan.ie_list.ht_operation.second_channel_offset="0")(Wlan.ie_list.ht_operation.sta_channel_width="0")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") + PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed, + + 2. assoc response has erp/ht/xrates, cap.short_slot_time=1, ht_info.2nd_channel_offset=0,sta_channel_width=0, + rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54] + + 3. radiotap rates in rates/xrates/msc0-7' + initial condition: APM1 + initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial + condition APSTA1 + module: WIFI MAC + steps: '1. target set to PHY mode ht40 + + 2. 11bgn STA connect to SoftAP, capture assoc response + + 3. ping, capture Data' + sub module: Phy Mode + summary: SoftAP set as ht40, 11n STA connect to AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: SoftAP PHY mode test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0118 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 2 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m g + - ['R SSC2 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. assoc response has erp/xrates, no ht, cap.short_slot_time=1, rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54] + + 3. radiotap rates in rates/xrates' + initial condition: APM1 + initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial + condition APSTA1 + module: WIFI MAC + steps: '1. target set to PHY mode ht40 + + 2. 11bg STA connect to SoftAP, capture assoc response + + 3. ping, capture Data' + sub module: Phy Mode + summary: SoftAP set as ht40, 11g STA connect to AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: SoftAP PHY mode test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0115 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 2 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 40 + - ['R SSC2 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities="")(Wlan.ie_list.ht_operation.second_channel_offset="0")(Wlan.ie_list.ht_operation.sta_channel_width="0")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") + PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed, + + 2. assoc response has erp/ht/xrates, cap.short_slot_time=1, ht_info.2nd_channel_offset=0,sta_channel_width=0, + rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54] + + 3. radiotap rates in rates/xrates/msc0-7' + initial condition: APM1 + initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial + condition APSTA1 + module: WIFI MAC + steps: '1. target set to PHY mode 11bgn + + 2. ht40 STA connect to SoftAP, capture assoc response + + 3. ping, capture Data' + sub module: Phy Mode + summary: SoftAP set as 11bgn, ht40 STA connect to AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: SoftAP PHY mode test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0114 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 2 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 20 + - ['R SSC2 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities="")(Wlan.ie_list.ht_operation.second_channel_offset="0")(Wlan.ie_list.ht_operation.sta_channel_width="0")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") + PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed, + + 2. assoc response has erp/ht/xrates, cap.short_slot_time=1, ht_info.2nd_channel_offset=0,sta_channel_width=0, + rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54] + + 3. radiotap rates in rates/xrates/msc0-7' + initial condition: APM1 + initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial + condition APSTA1 + module: WIFI MAC + steps: '1. target set to PHY mode 11bgn + + 2. 11bgn STA connect to SoftAP, capture assoc response + + 3. ping, capture Data' + sub module: Phy Mode + summary: SoftAP set as 11bgn, 11n STA connect to AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: SoftAP PHY mode test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0117 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 2 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m b + - ['R SSC2 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp!)(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. assoc response has no erp/xrates/ht, cap.short_slot_time=1, rates=[1/2/5/5/11] + + 3. radiotap rates in rates' + initial condition: APM1 + initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial + condition APSTA1 + module: WIFI MAC + steps: '1. target set to PHY mode ht40 + + 2. 11b STA connect to SoftAP, capture assoc response + + 3. ping, capture Data' + sub module: Phy Mode + summary: SoftAP set as ht40, 11b STA connect to AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: SoftAP PHY mode test + version: v1 (2015-8-15) - CI ready: 'Yes' ID: TCPIP_UDP_0202 SDK: '8266_NonOS @@ -6003,6 +7576,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -6070,6 +7644,92 @@ test cases: test point 1: abnormal/special use test point 2: use UDP SAP (socket/espconn API) in different state version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0111 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 2 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-Beacon")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities="")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_operation.second_channel_offset="0")(Wlan.ie_list.ht_operation.sta_channel_width="0")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")'] + comment: '' + execution time: 0.0 + expected result: 1. beacon has erp/ht/xrates, cap.short_slot_time=1, ht_info.2nd_channel_offset=0,sta_channel_width=0, + rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54] + initial condition: APM1 + initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial + condition APSTA1 + module: WIFI MAC + steps: 1. target set to PHY mode 11bgn, capture beacon + sub module: Phy Mode + summary: SoftAP set as 11bgn, check beacon + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: SoftAP PHY mode test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0112 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 2 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m b + - ['R SSC2 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp!)(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. assoc response has no erp/xrates/ht, cap.short_slot_time=1, rates=[1/2/5/5/11] + + 3. radiotap rates in rates' + initial condition: APM1 + initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial + condition APSTA1 + module: WIFI MAC + steps: '1. target set to PHY mode 11bgn + + 2. 11b STA connect to SoftAP, capture assoc response + + 3. ping, capture Data' + sub module: Phy Mode + summary: SoftAP set as 11bgn, 11b STA connect to AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: SoftAP PHY mode test + version: v1 (2015-8-15) - CI ready: 'Yes' ID: TCPIP_TCP_0411 SDK: '8266_NonOS @@ -6078,6 +7738,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -6139,6 +7800,281 @@ test cases: test point 1: abnormal/special use test point 2: TCP handling abnormal event version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0502 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC3 sta -C -s -p + - ['R SSC3 C +JAP:CONNECTED'] + - - SSC SSC2 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC2 C +JAP:CONNECTED', 'P SSC[1,3] NC +JAP:DISCONNECTED'] + comment: '' + execution time: 0.0 + expected result: 4. all STA not get disconnected; target 1 SoftAP and STA both in + channel2; SoftAP in 20M, STA in 40M + initial condition: T3_PHY1 + initial condition description (auto): '1. target 1 and target 2 set to AP+STA mode, + target 3 set to STA mode + + 2. all interface of target 2,3 set to 11n ht40 + + 3. config softAP of target 1 and target 2' + module: WIFI MAC + steps: '1. target 1 STA set to 40M, SoftAP set to 20M + + 2. target 2 STA connect to ap_channel1_20 + + 3. target 1/3 STA connect to target 2/1 SoftAP + + 4. target 2 STA connect to ap_channel2_40' + sub module: Phy Mode + summary: SoftAP STA in channel1 20M, STA changed to channel2 40M + test environment: SSC_T3_PhyMode + test environment description (auto): '3 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with (HT20, channel1), (HT20, channel2), (HT40, channel1), (HT40, channel2). + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP dynamic channel switch test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0503 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC3 sta -C -s -p + - ['R SSC3 C +JAP:CONNECTED'] + - - SSC SSC2 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC2 C +JAP:CONNECTED', 'P SSC[1,3] NC +JAP:DISCONNECTED'] + comment: '' + execution time: 0.0 + expected result: 4. all STA not get disconnected; target 1 SoftAP and STA both in + channel2 20M + initial condition: T3_PHY1 + initial condition description (auto): '1. target 1 and target 2 set to AP+STA mode, + target 3 set to STA mode + + 2. all interface of target 2,3 set to 11n ht40 + + 3. config softAP of target 1 and target 2' + module: WIFI MAC + steps: '1. target 1 STA set to 40M, SoftAP set to 20M + + 2. target 2 STA connect to ap_channel1_40 + + 3. target 1/3 STA connect to target 2/1 SoftAP + + 4. target 2 STA connect to ap_channel2_20' + sub module: Phy Mode + summary: SoftAP STA in channel1, SoftAP 20M, STA 40M, STA changed to channel2 20M + test environment: SSC_T3_PhyMode + test environment description (auto): '3 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with (HT20, channel1), (HT20, channel2), (HT40, channel1), (HT40, channel2). + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP dynamic channel switch test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0501 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC3 sta -C -s -p + - ['R SSC3 C +JAP:CONNECTED'] + - - SSC SSC2 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC2 C +JAP:CONNECTED', 'P SSC[1,3] NC +JAP:DISCONNECTED'] + comment: '' + execution time: 0.0 + expected result: 4. all STA not get disconnected; target 1 SoftAP and STA both in + channel2 20M + initial condition: T3_PHY1 + initial condition description (auto): '1. target 1 and target 2 set to AP+STA mode, + target 3 set to STA mode + + 2. all interface of target 2,3 set to 11n ht40 + + 3. config softAP of target 1 and target 2' + module: WIFI MAC + steps: '1. target 1 STA and SoftAP set to 20M + + 2. target 2 STA connect to ap_channel1_20 + + 3. target 1/3 STA connect to target 2/1 SoftAP + + 4. target 2 STA connect to ap_channel2_20' + sub module: Phy Mode + summary: SoftAP STA in channel1 20M, STA changed to channel2 20M + test environment: SSC_T3_PhyMode + test environment description (auto): '3 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with (HT20, channel1), (HT20, channel2), (HT40, channel1), (HT40, channel2). + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP dynamic channel switch test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0506 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC3 sta -C -s -p + - ['R SSC3 C +JAP:CONNECTED'] + - - SSC SSC2 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC2 C +JAP:CONNECTED', 'P SSC[1,3] NC +JAP:DISCONNECTED'] + comment: '' + execution time: 0.0 + expected result: 4. all STA not get disconnected; target 1 SoftAP and STA both in + channel2 40M + initial condition: T3_PHY1 + initial condition description (auto): '1. target 1 and target 2 set to AP+STA mode, + target 3 set to STA mode + + 2. all interface of target 2,3 set to 11n ht40 + + 3. config softAP of target 1 and target 2' + module: WIFI MAC + steps: '1. target 1 STA and SoftAP set to 40M + + 2. target 2 STA connect to ap_channel1_40 + + 3. target 1/3 STA connect to target 2/1 SoftAP + + 4. target 2 STA connect to ap_channel2_40' + sub module: Phy Mode + summary: SoftAP STA in channel1, SoftAP 40M, STA 40M, STA changed to channel2 40M + test environment: SSC_T3_PhyMode + test environment description (auto): '3 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with (HT20, channel1), (HT20, channel2), (HT40, channel1), (HT40, channel2). + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP dynamic channel switch test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0505 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC3 sta -C -s -p + - ['R SSC3 C +JAP:CONNECTED'] + - - SSC SSC2 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC2 C +JAP:CONNECTED', 'P SSC[1,3] NC +JAP:DISCONNECTED'] + comment: '' + execution time: 0.0 + expected result: 4. all STA not get disconnected; target 1 SoftAP and STA both in + channel2; SoftAP in 20M, STA in 40M + initial condition: T3_PHY1 + initial condition description (auto): '1. target 1 and target 2 set to AP+STA mode, + target 3 set to STA mode + + 2. all interface of target 2,3 set to 11n ht40 + + 3. config softAP of target 1 and target 2' + module: WIFI MAC + steps: '1. target 1 STA set to 40M ,SoftAP set to 20M + + 2. target 2 STA connect to ap_channel1_40 + + 3. target 1/3 STA connect to target 2/1 SoftAP + + 4. target 2 STA connect to ap_channel2_20' + sub module: Phy Mode + summary: SoftAP STA in channel1, SoftAP 40M, STA 40M, STA changed to channel2 20M + test environment: SSC_T3_PhyMode + test environment description (auto): '3 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with (HT20, channel1), (HT20, channel2), (HT40, channel1), (HT40, channel2). + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP dynamic channel switch test + version: v1 (2015-8-15) - CI ready: 'Yes' ID: WIFI_CONN_0301 SDK: '8266_NonOS @@ -6147,6 +8083,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -6191,6 +8128,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -6245,6 +8183,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -6284,6 +8223,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: 1/5 auto test: 'Yes' category: Function cmd set: @@ -6353,6 +8293,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -6392,6 +8333,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -6449,6 +8391,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -6500,6 +8443,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: 1/5 auto test: 'Yes' category: Function cmd set: @@ -6563,6 +8507,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: 1/5 auto test: 'Yes' category: Function cmd set: @@ -6612,6 +8557,310 @@ test cases: test point 1: basic function test point 2: use UDP SAP (socket/espconn API) with different parameter version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0205 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m g + - ['R SSC1 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC1 sta -C -s -p + - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. probe-req and assoc-req has xrates, no ht, cap.short_slot_time=1,rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54] + + 4. 20M + + 5. succeed + + 6. data rate in radiotap is in rates or xrates' + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + module: WIFI MAC + steps: '1. target set to PHY mode 11bg + + 2. target connect to 11g AP + + 3. capture probe-req and assoc-req in step2 + + 4. check if config bandwidth correct + + 5. send data from target + + 6. capture data in step5' + sub module: Phy Mode + summary: target STA set as 11bg, join 11g external AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA PHY mode test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0204 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m g + - ['R SSC1 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC1 sta -C -s -p + - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. probe-req has xrates, no ht, cap.short_slot_time=1,rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54]; + + assoc-req has no erp/ht/xrates, cap.short_slot_time=1,rates=[1/2/5.5/11] + + 4. 20M + + 5. succeed + + 6. data rate in radiotap is in [1/2/5.5/11]' + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + module: WIFI MAC + steps: '1. target set to PHY mode 11bg + + 2. target connect to 11b AP + + 3. capture probe-req and assoc-req in step2 + + 4. check if config bandwidth correct + + 5. send data from target + + 6. capture data in step5' + sub module: Phy Mode + summary: target STA set as 11bg, join 11b external AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA PHY mode test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0207 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC1 sta -C -s -p + - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. probe-req has xrates/ht, cap.short_slot_time=1,rates=[1/2/5.5/11/24/36/48/54]; + + assoc-req has no ht/xrates, cap.short_slot_time=1,rates=[1/2/5.5/11] + + 4. 20M + + 5. succeed + + 6. data rate in radiotap is in [1/2/5.5/11]' + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + module: WIFI MAC + steps: '1. target set to PHY mode 11bgn + + 2. target connect to 11b AP + + 3. capture probe-req and assoc-req in step2 + + 4. check if config bandwidth correct + + 5. send data from target + + 6. capture data in step5' + sub module: Phy Mode + summary: target STA set as 11bgn, join 11b external AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA PHY mode test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0206 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m g + - ['R SSC1 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC1 sta -C -s -p + - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. probe-req and assoc-req has xrates, no ht, cap.short_slot_time=1,rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54] + + 4. 20M + + 5. succeed + + 6. data rate in radiotap is in rates or xrates' + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + module: WIFI MAC + steps: '1. target set to PHY mode 11bg + + 2. target connect to 11n AP + + 3. capture probe-req and assoc-req in step2 + + 4. check if config bandwidth correct + + 5. send data from target + + 6. capture data in step5' + sub module: Phy Mode + summary: target STA set as 11bg, join 11n external AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA PHY mode test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0201 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m b + - ['R SSC1 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC1 sta -C -s -p + - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates!)(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. probe-req and assoc-req has no ht/xrates, cap.short_slot_time=1,rates=[1/2/5.5/11] + + 4. 20M + + 5. succeed + + 6. data rate in radiotap is in [1/2/5.5/11]' + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + module: WIFI MAC + steps: '1. target set to PHY mode 11b + + 2. target connect to 11b AP + + 3. capture probe-req and assoc-req in step2 + + 4. check if config bandwidth correct + + 5. send data from target + + 6. capture data in step5' + sub module: Phy Mode + summary: target STA set as 11b, join 11b external AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA PHY mode test + version: v1 (2015-8-15) - CI ready: 'Yes' ID: ^TCPIP_DHCP_0102 SDK: '8266_NonOS @@ -6620,6 +8869,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -6656,6 +8906,126 @@ test cases: test point 1: basic function test point 2: DHCP client function test version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0203 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m b + - ['R SSC1 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC1 sta -C -s -p + - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates!)(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. probe-req and assoc-reqhas no ht/xrates, cap.short_slot_time=1,rates=[1/2/5.5/11] + + 4. 20M + + 5. succeed + + 6. data rate in radiotap is in [1/2/5.5/11]' + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + module: WIFI MAC + steps: '1. target set to PHY mode 11b + + 2. target connect to 11n AP + + 3. capture probe-req and assoc-req in step2 + + 4. check if config bandwidth correct + + 5. send data from target + + 6. capture data in step5' + sub module: Phy Mode + summary: target STA set as 11b, join 11b external AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA PHY mode test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0202 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m b + - ['R SSC1 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC1 sta -C -s -p + - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates!)(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. probe-req and assoc-reqhas no ht/xrates, cap.short_slot_time=1,rates=[1/2/5.5/11] + + 4. 20M + + 5. succeed + + 6. data rate in radiotap is in [1/2/5.5/11]' + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + module: WIFI MAC + steps: '1. target set to PHY mode 11b + + 2. target connect to 11g AP + + 3. capture probe-req and assoc-req in step2 + + 4. check if config bandwidth correct + + 5. send data from target + + 6. capture data in step5' + sub module: Phy Mode + summary: target STA set as 11b, join 11g external AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA PHY mode test + version: v1 (2015-8-15) - CI ready: 'Yes' ID: ^TCPIP_DHCP_0103 SDK: '8266_NonOS @@ -6664,6 +9034,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -6725,6 +9096,216 @@ test cases: test point 1: basic function test point 2: DHCP client function test version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0209 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC1 sta -C -s -p + - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities="")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") + PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. probe-req and assoc-req has xrates/ht, cap.short_slot_time=1,rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54] + + 4. 20M + + 5. succeed + + 6. data rate in radiotap is in rates or xrates or msc0-7' + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + module: WIFI MAC + steps: '1. target set to PHY mode 11bgn + + 2. target connect to 11n AP + + 3. capture probe-req and assoc-req in step2 + + 4. check if config bandwidth correct + + 5. send data from target + + 6. capture data in step5' + sub module: Phy Mode + summary: target STA set as 11bgn, join 11n external AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA PHY mode test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0208 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC1 sta -C -s -p + - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. probe-req has xrates/ht, cap.short_slot_time=1,rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54]; + + assoc-req has xrates no ht, cap.short_slot_time=1,rates=[1/2/5.5/11], xrates=[24/36/48/54]; + + 4. 20M + + 5. succeed + + 6. data rate in radiotap is in rates or xrates' + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + module: WIFI MAC + steps: '1. target set to PHY mode 11bgn + + 2. target connect to 11g AP + + 3. capture probe-req and assoc-req in step2 + + 4. check if config bandwidth correct + + 5. send data from target + + 6. capture data in step5' + sub module: Phy Mode + summary: target STA set as 11bgn, join 11g external AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA PHY mode test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_SCAN_0301 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -S + - [''] + - - SSC SSC1 sta -S + - [P SSC1 C +SCANFAIL, 'P SSC1 P +SCAN:', R SSC1 C +SCANDONE] + comment: '' + execution time: 0.0 + expected result: '1. second scan failed + + 2. first scan succeed' + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + module: WIFI MAC + steps: '1. do all channel scan + + 2. do scan before scan finished' + sub module: WIFI Scan + summary: reject scan request before scan finished + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: interaction + test point 2: Scan interact with other WiFi operation + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_SCAN_0303 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:OK'] + - - SSC SSC1 sta -S + - [P SSC1 C +SCANDONE, 'P SSC1 C +JAP:CONNECTED'] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:OK'] + - - SSC SSC1 sta -S + - [''] + - - SSC SSC1 sta -C -s -p + - [P SSC1 C +SCANDONE, 'P SSC1 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: '2. scan succeed, JAP succeed + + 5. JAP succeed, scan succeed' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. target 1 STA join AP + + 2. target 1 STA scan before JAP succeed + + 3. target 1 quite AP + + 4. target 1 scan + + 5. target 1 JAP before scan succeed' + sub module: WIFI Scan + summary: scan during JAP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: interaction + test point 2: Scan interact with other WiFi operation + version: v1 (2015-8-15) - CI ready: 'Yes' ID: ^WIFI_CONN_0801 SDK: '8266_NonOS @@ -6733,6 +9314,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -6787,6 +9369,55 @@ test cases: test point 1: basic function test point 2: wifi auth changed event test version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_SCAN_0304 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:OK'] + - - SSC SSC1 sta -S + - [P SSC1 C +SCANDONE, 'P SSC2 C +JAP:CONNECTED'] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:OK'] + - - SSC SSC1 sta -S + - [''] + - - SSC SSC2 sta -C -s -p + - [P SSC1 C +SCANDONE, 'P SSC2 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: '2. scan succeed, JAP succeed + + 5. JAP succeed, scan succeed' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. target 2 STA join target 1 SoftAP + + 2. target 1 STA scan before target 2 JAP succeed + + 3. target 2 STA QAP + + 4. target 1 STA scan + + 5. target 2 STA JAP before target 1 STA scan succeed' + sub module: WIFI Scan + summary: scan during ext STA join SoftAP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: interaction + test point 2: Scan interact with other WiFi operation + version: v1 (2015-8-15) - CI ready: 'Yes' ID: ^TCPIP_UDP_0108 SDK: '8266_NonOS @@ -6795,6 +9426,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -6846,6 +9478,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -6899,6 +9532,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -6948,6 +9582,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -6997,6 +9632,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -7054,6 +9690,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -7108,6 +9745,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -7147,6 +9785,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -7186,6 +9825,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: 1/5 auto test: 'Yes' category: Function cmd set: @@ -7260,6 +9900,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: 1/5 auto test: 'Yes' category: Function cmd set: @@ -7324,6 +9965,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -7381,6 +10023,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -7420,6 +10063,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -7497,6 +10141,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -7566,6 +10211,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -7637,6 +10283,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -7700,6 +10347,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -7757,6 +10405,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -7808,6 +10457,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -7877,6 +10527,7 @@ test cases: ESP32_IDF' Test App: basic function + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -7925,6 +10576,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -8024,6 +10676,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -8107,6 +10760,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -8206,6 +10860,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -8242,6 +10897,43 @@ test cases: test point 1: abnormal/special use test point 2: TCP connect and disconnect abnormal case version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0116 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 2 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK', 'R CAP PDU (Wlan.frame_ctrl.type_subtype="Management-Beacon")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities.short_gi_for_40="1")(Wlan.ie_list.ht_operation.second_channel_offset!="0","2")(Wlan.ie_list.ht_operation.sta_channel_width="1")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")'] + comment: '' + execution time: 0.0 + expected result: 1. beacon has erp/ht/xrates, cap.short_slot_time=1, ht_info.2nd_channel_offset=3,sta_channel_width=1, + rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54] + initial condition: APM1 + initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial + condition APSTA1 + module: WIFI MAC + steps: 1. target set to PHY mode ht40, capture beacon + sub module: Phy Mode + summary: SoftAP set as ht40, check beacon + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: SoftAP PHY mode test + version: v1 (2015-8-15) - CI ready: 'Yes' ID: ^TCPIP_DNS_0101 SDK: '8266_NonOS @@ -8250,6 +10942,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: 3/5 auto test: 'Yes' category: Function cmd set: @@ -8281,6 +10974,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: 3/5 auto test: 'Yes' category: Function cmd set: @@ -8324,6 +11018,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: 3/5 auto test: 'Yes' category: Function cmd set: @@ -8371,6 +11066,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -8464,6 +11160,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -8525,6 +11222,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -8612,6 +11310,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -8706,6 +11405,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -8757,6 +11457,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -8832,6 +11533,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -8895,6 +11597,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -8955,6 +11658,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -9049,6 +11753,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -9142,6 +11847,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -9217,6 +11923,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -9304,6 +12011,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -9367,6 +12075,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -9410,6 +12119,61 @@ test cases: test point 1: basic function test point 2: use TCP SAP (socket/espconn API) with different parameter version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_SCAN_0302 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -n 1000000 -j 5 + - [''] + - - SSC SSC2 phy -S -o 1 -m b + - ['R SSC2 C +PHY:OK'] + - - SSC SSC2 sta -S -n + - [R SSC2 P ] + - - SSC SSC2 phy -S -o 1 -m g + - ['R SSC2 C +PHY:OK'] + - - SSC SSC2 sta -S -n + - [R SSC2 P ] + - - SSC SSC2 phy -S -o 1 -m n -b 20 + - ['R SSC2 C +PHY:OK'] + - - SSC SSC2 sta -S -n + - [R SSC2 P ] + - - SSC SSC2 phy -S -o 1 -m n -b 40 + - ['R SSC2 C +PHY:OK'] + - - SSC SSC2 sta -S -n + - [R SSC2 P ] + comment: '' + execution time: 0.0 + expected result: 3. target 2 able to scan AP + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. target 1 connect to AP + + 2. target 1 start sending UDP packets + + 3. target 2 scan in AP channel in 11b.g,n,ht40 mode' + sub module: WIFI Scan + summary: scan in congest channel + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: interaction + test point 2: Scan interact with other WiFi operation + version: v1 (2015-8-15) - CI ready: 'Yes' ID: TCPIP_ARP_0101 SDK: '8266_NonOS @@ -9418,6 +12182,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -9457,6 +12222,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: 1/5 auto test: 'Yes' category: Function cmd set: @@ -9508,6 +12274,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: 1/5 auto test: 'Yes' category: Function cmd set: @@ -9559,6 +12326,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: 1/5 auto test: 'Yes' category: Function cmd set: @@ -9618,6 +12386,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: 1/5 auto test: 'Yes' category: Function cmd set: @@ -9677,6 +12446,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: 1/5 auto test: 'Yes' category: Function cmd set: @@ -9734,6 +12504,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: 1/5 auto test: 'Yes' category: Function cmd set: @@ -9793,6 +12564,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: 1/5 auto test: 'Yes' category: Function cmd set: @@ -9844,6 +12616,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -9896,6 +12669,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -9958,6 +12732,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -10022,6 +12797,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -10094,6 +12870,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -10156,6 +12933,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -10204,6 +12982,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -10284,6 +13063,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -10352,6 +13132,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -10410,6 +13191,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -10467,6 +13249,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -10538,6 +13321,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -10637,6 +13421,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -10720,6 +13505,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -10819,6 +13605,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -10868,6 +13655,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -10949,6 +13737,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -11030,6 +13819,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -11111,6 +13901,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: 3/5 auto test: 'Yes' category: Function cmd set: @@ -11146,6 +13937,62 @@ test cases: test point 1: basic function test point 2: DNS function test version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0303 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m b + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m b + - ['R SSC2 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s%20or%20wlan%20addr2%20%%s + + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC1 sta -C -s -p + - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities="")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") + PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp!)(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. check STA packet + + 3. check SoftAP packet' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. set softAP 11b, STA 11bgn + + 2. STA connect to ext AP + + 3. ext STA connect to SoftAP' + sub module: Phy Mode + summary: SoftAP 11b, STA 11bgn, get connected and join AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP PHY mode test + version: v1 (2015-8-15) - CI ready: 'Yes' ID: TCPIP_DHCP_0206 SDK: '8266_NonOS @@ -11154,6 +14001,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -11217,6 +14065,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -11290,6 +14139,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -11371,6 +14221,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -11420,6 +14271,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -11479,6 +14331,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -11548,6 +14401,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -11617,6 +14471,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -11675,6 +14530,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -11756,6 +14612,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -11821,6 +14678,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -11884,6 +14742,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -11953,6 +14812,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -12022,6 +14882,7 @@ test cases: ESP32_IDF' Test App: basic function + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -12070,6 +14931,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -12116,6 +14978,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -12139,6 +15002,257 @@ test cases: test point 1: basic function test point 2: wifi disconnect reason test version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0108 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 2 -m g + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m g + - ['R SSC2 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. assoc response has erp/xrates, no ht, cap.short_slot_time=1, rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54] + + 3. radiotap rates in rates and xrates' + initial condition: APM1 + initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial + condition APSTA1 + module: WIFI MAC + steps: '1. target set to PHY mode 11bg + + 2. 11bg STA connect to SoftAP, capture assoc response + + 3. ping, capture Data' + sub module: Phy Mode + summary: SoftAP set as 11bg, 11g STA connect to AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: SoftAP PHY mode test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0109 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 2 -m g + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 20 + - ['R SSC2 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. assoc response has erp/xrates, no ht, cap.short_slot_time=1, rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54] + + 3. radiotap rates in rates and xrates' + initial condition: APM1 + initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial + condition APSTA1 + module: WIFI MAC + steps: '1. target set to PHY mode 11bg + + 2. 11bgn STA connect to SoftAP, capture assoc response + + 3. ping, capture Data' + sub module: Phy Mode + summary: SoftAP set as 11bg, 11n STA connect to AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: SoftAP PHY mode test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0106 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 2 -m g + - ['R SSC1 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-Beacon")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")'] + comment: '' + execution time: 0.0 + expected result: 1. beacon has erp/xrates, no ht, cap.short_slot_time=1, rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54] + initial condition: APM1 + initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial + condition APSTA1 + module: WIFI MAC + steps: 1. target set to PHY mode 11bg, capture beacon + sub module: Phy Mode + summary: SoftAP set as 11bg, check beacon + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: SoftAP PHY mode test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0107 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 2 -m g + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m b + - ['R SSC2 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp!)(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.supported_rates=""1/","2/","5.5/","11/")(Wlan.capability.short_slot_time="1")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. assoc response has erp/xrates, no ht, cap.short_slot_time=1, rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54] + + 3. radiotap rates in rates' + initial condition: APM1 + initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial + condition APSTA1 + module: WIFI MAC + steps: '1. target set to PHY mode 11bg + + 2. 11b STA connect to SoftAP, capture assoc response + + 3. ping, capture Data' + sub module: Phy Mode + summary: SoftAP set as 11bg, 11b STA connect to AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: SoftAP PHY mode test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_SCAN_0201 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m b + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 sta -S + - [R SSC1 P P P P ] + - - SSC SSC1 phy -S -o 1 -m g + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 sta -S + - [R SSC1 P P P P ] + - - SSC SSC1 phy -S -o 1 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 sta -S + - [R SSC1 P P P P ] + - - SSC SSC1 phy -S -o 1 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 sta -S + - [R SSC1 P P P P ] + comment: '' + execution time: 0.0 + expected result: '3. find all 3 ext APs + + 5. find all 3 ext APs + + 7. find all 3 ext APs + + 9. find all 3 ext APs' + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + module: WIFI MAC + steps: '1. 3 ext APs in 11b, 11g, 11n mode + + 2. STA in 11b mode + + 3. do all channel scan + + 4. STA in 11g mode + + 5. do all channel scan + + 6. STA in 11n ht20 mode + + 7. do all channel scan + + 8. STA in 11n ht40 mode + + 9. do all channel scan' + sub module: WIFI Scan + summary: STA in differnt PHY mode to scan AP in different PHY mode + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: Scan in different mode and channel + version: v1 (2015-8-15) - CI ready: 'Yes' ID: WIFI_CONN_0503 SDK: '8266_NonOS @@ -12147,6 +15261,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -12196,6 +15311,285 @@ test cases: test point 1: basic function test point 2: reconnect policy test version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0402 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 20 + - ['R SSC2 C +PHY:OK'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC2 NC +JAP:DISCONNECTED', 'P SSC1 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: 3. SoftAP and STA in channel2, both bandwidth 20M, SoftAP not get + disconnected + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. SoftAP 11n ht20, in channel1, ext AP 11n ht20, in channel2 + + 2. AP get connected + + 3. STA connect to ext AP' + sub module: Phy Mode + summary: SoftAP ext AP in defferent channel, both bandwidth 20M, Softap get connected + than STA connect to AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP initial channel test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0401 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 20 + - ['R SSC2 C +PHY:OK'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC2 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC1 NC +JAP:DISCONNECTED', 'P SSC2 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: 3. SoftAP and STA in channel2, both bandwidth 20M, STA not disconnected + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. SoftAP 11n ht20, in channel1, ext AP 11n ht20, in channel2 + + 2. STA connect to ext AP + + 3. AP get connected' + sub module: Phy Mode + summary: SoftAP ext AP in defferent channel, both bandwidth 20M, STA connect to + AP then Softap get connected + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP initial channel test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0407 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 40 + - ['R SSC2 C +PHY:OK'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC2 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC1 NC +JAP:DISCONNECTED', 'P SSC2 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: 3. SoftAP and STA in channel2, SoftAP 40M, STA 20M, STA not disconnected + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. SoftAP 11n ht40, in channel1, ext AP 11n ht20, in channel2 + + 2. STA connect to ext AP + + 3. AP get connected' + sub module: Phy Mode + summary: SoftAP ext AP in defferent channel, SoftAP 40M, ext AP 20M, STA connect + to AP then Softap get connected + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP initial channel test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0406 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 40 + - ['R SSC2 C +PHY:OK'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC2 NC +JAP:DISCONNECTED', 'P SSC1 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: 3. SoftAP and STA in channel2, both bandwidth 40M, SoftAP not get + disconnected + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. SoftAP 11n ht40, in channel1, ext AP 11n ht40, in channel2 + + 2. AP get connected + + 3. STA connect to ext AP' + sub module: Phy Mode + summary: SoftAP ext AP in defferent channel, both bandwidth 40M, Softap get connected + than STA connect to AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP initial channel test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0405 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 40 + - ['R SSC2 C +PHY:OK'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC2 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC1 NC +JAP:DISCONNECTED', 'P SSC2 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: 3. SoftAP and STA in channel2, both bandwidth 40M, STA not disconnected + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. SoftAP 11n ht40, in channel1, ext AP 11n ht40, in channel2 + + 2. STA connect to ext AP + + 3. AP get connected' + sub module: Phy Mode + summary: SoftAP ext AP in defferent channel, both bandwidth 40M, STA connect to + AP then Softap get connected + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP initial channel test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0404 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 20 + - ['R SSC2 C +PHY:OK'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC2 NC +JAP:DISCONNECTED', 'P SSC1 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: 3. SoftAP and STA in channel2, SoftAP 20M, STA 40M, SoftAP not + get disconnected + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. SoftAP 11n ht20, in channel1, ext AP 11n ht40, in channel2 + + 2. AP get connected + + 3. STA connect to ext AP' + sub module: Phy Mode + summary: SoftAP ext AP in defferent channel, SoftAP 20M, ext AP 40M, Softap get + connected than STA connect to AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP initial channel test + version: v1 (2015-8-15) - CI ready: 'Yes' ID: ^TCPIP_UDP_0112 SDK: '8266_NonOS @@ -12204,6 +15598,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -12235,6 +15630,53 @@ test cases: test point 1: basic function test point 2: use UDP SAP (socket/espconn API) with different parameter version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0408 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 40 + - ['R SSC2 C +PHY:OK'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC2 NC +JAP:DISCONNECTED', 'P SSC1 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: 3. SoftAP and STA in channel2, SoftAP 40M, STA 20M, SoftAP not + get disconnected + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. SoftAP 11n ht40, in channel1, ext AP 11n ht20, in channel2 + + 2. AP get connected + + 3. STA connect to ext AP' + sub module: Phy Mode + summary: SoftAP ext AP in defferent channel, SoftAP 40M, ext AP 20M, Softap get + connected than STA connect to AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP initial channel test + version: v1 (2015-8-15) - CI ready: 'Yes' ID: ^TCPIP_UDP_0114 SDK: '8266_NonOS @@ -12243,6 +15685,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -12274,6 +15717,315 @@ test cases: test point 1: basic function test point 2: use UDP SAP (socket/espconn API) with different parameter version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0214 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC1 sta -C -s -p + - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities.short_gi_for_40="1")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") + PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. probe-req and assoc-req has xrates/ht, ht_cap.short_gi40=1, 40width=1, cap.short_slot_time=1,rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54]; + + 4. 40M + + 5. succeed + + 6. data rate in radiotap is in rates or xrates' + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + module: WIFI MAC + steps: '1. target set to PHY mode 11bgn ht40 + + 2. target connect to 11n ht40 AP + + 3. capture probe-req and assoc-req in step2 + + 4. check if config bandwidth correct + + 5. send data from target + + 6. capture data in step5' + sub module: Phy Mode + summary: target STA set as 11bgn ht40,join ht40 external AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA PHY mode test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0212 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC1 sta -C -s -p + - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. probe-req has xrates/ht, ht_cap.short_gi40=1, 40width=1, cap.short_slot_time=1,rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54]; + + assoc-req has xrates no ht, cap.short_slot_time=1,rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54]; + + 4. 20M + + 5. succeed + + 6. data rate in radiotap is in rates or xrates' + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + module: WIFI MAC + steps: '1. target set to PHY mode 11bgn ht40 + + 2. target connect to 11g AP + + 3. capture probe-req and assoc-req in step2 + + 4. check if config bandwidth correct + + 5. send data from target + + 6. capture data in step5' + sub module: Phy Mode + summary: target STA set as 11bgn ht40, join 11g external AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA PHY mode test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0213 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC1 sta -C -s -p + - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities="")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") + PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. probe-req has xrates/ht, ht_cap.short_gi40=1, 40width=1, cap.short_slot_time=1,rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54]; + + assoc-req has xrates/ht, cap.short_slot_time=1,rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54]; + + 4. 20M + + 5. succeed + + 6. data rate in radiotap is in rates or xrates' + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + module: WIFI MAC + steps: '1. target set to PHY mode 11bgn ht40 + + 2. target connect to 11n AP + + 3. capture probe-req and assoc-req in step2 + + 4. check if config bandwidth correct + + 5. send data from target + + 6. capture data in step5' + sub module: Phy Mode + summary: target STA set as 11bgn ht40, join 11n external AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA PHY mode test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0210 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC1 sta -C -s -p + - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities="")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', + 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") + PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. probe-req and assoc-req has xrates/ht, cap.short_slot_time=1,rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54] + + 4. 20M + + 5. succeed + + 6. data rate in radiotap is in rates or xrates or msc0-7' + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + module: WIFI MAC + steps: '1. target set to PHY mode 11bgn + + 2. target connect to 11n ht40 AP + + 3. capture probe-req and assoc-req in step2 + + 4. check if config bandwidth correct + + 5. send data from target + + 6. capture data in step5' + sub module: Phy Mode + summary: target STA set as 11bgn, join ht40 external AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA PHY mode test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0211 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC1 sta -C -s -p + - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. probe-req has xrates/ht, ht_cap.short_gi40=1, 40width=1, cap.short_slot_time=1,rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54]; + + assoc-req has no ht/xrates, cap.short_slot_time=1,rates=[1/2/5.5/11] + + 4. 20M + + 5. succeed + + 6. data rate in radiotap is in [1/2/5.5/11]' + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + module: WIFI MAC + steps: '1. target set to PHY mode 11bgn ht40 + + 2. target connect to 11b AP + + 3. capture probe-req and assoc-req in step2 + + 4. check if config bandwidth correct + + 5. send data from target + + 6. capture data in step5' + sub module: Phy Mode + summary: target STA set as 11bgn ht40, join 11b external AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA PHY mode test + version: v1 (2015-8-15) - CI ready: 'Yes' ID: ^WIFI_CONN_0104 SDK: '8266_NonOS @@ -12282,6 +16034,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -12334,6 +16087,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -12409,6 +16163,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -12464,6 +16219,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -12527,6 +16283,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -12590,6 +16347,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -12641,6 +16399,61 @@ test cases: test point 1: basic function test point 2: SAP/JAP with different config version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0504 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC3 sta -C -s -p + - ['R SSC3 C +JAP:CONNECTED'] + - - SSC SSC2 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC2 C +JAP:CONNECTED', 'P SSC[1,3] NC +JAP:DISCONNECTED'] + comment: '' + execution time: 0.0 + expected result: 4. all STA not get disconnected; target 1 SoftAP and STA both in + channel2 20M + initial condition: T3_PHY1 + initial condition description (auto): '1. target 1 and target 2 set to AP+STA mode, + target 3 set to STA mode + + 2. all interface of target 2,3 set to 11n ht40 + + 3. config softAP of target 1 and target 2' + module: WIFI MAC + steps: '1. target 1 STA and SoftAP set to 40M + + 2. target 2 STA connect to ap_channel1_40 + + 3. target 1/3 STA connect to target 2/1 SoftAP + + 4. target 2 STA connect to ap_channel2_20' + sub module: Phy Mode + summary: SoftAP STA in channel1, SoftAP 20M, STA 40M, STA changed to channel2 40M + test environment: SSC_T3_PhyMode + test environment description (auto): '3 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with (HT20, channel1), (HT20, channel2), (HT40, channel1), (HT40, channel2). + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP dynamic channel switch test + version: v1 (2015-8-15) - CI ready: 'Yes' ID: ^TCPIP_IP_0101 SDK: '8266_NonOS @@ -12649,6 +16462,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -12706,6 +16520,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -12745,6 +16560,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -12808,6 +16624,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -12870,6 +16687,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -12916,6 +16734,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -12971,6 +16790,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -13039,6 +16859,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -13115,6 +16936,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -13208,6 +17030,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -13252,6 +17075,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -13346,6 +17170,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -13407,6 +17232,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -13450,6 +17276,55 @@ test cases: test point 1: basic function test point 2: use TCP SAP (socket/espconn API) with different parameter version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0104 + SDK: ESP32_IDF + Test App: SSC + allow fail: 2/3 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 2 -m b + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 20 + - ['R SSC2 C +PHY:OK'] + - - STRING wlan%20addr2%20%%s + - [R PC_COM C OK] + - - 'NIC CAP START wlan_capture ' + - ['R PC_COM C +NIC_START:OK'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp!)(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', + 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. assoc response has no erp/xrates/ht, cap.short_slot_time=1, rates=[1/2/5/5/11] + + 3. radiotap rates in [1/2/5/5/11]' + initial condition: APM1 + initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial + condition APSTA1 + module: WIFI MAC + steps: '1. target set to PHY mode 11b + + 2. 11bgn STA connect to SoftAP, capture assoc response + + 3. ping, capture Data' + sub module: Phy Mode + summary: SoftAP set as 11b, 11n STA connect to AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: SoftAP PHY mode test + version: v1 (2015-8-15) - CI ready: 'Yes' ID: TCPIP_TCP_0113 SDK: '8266_NonOS @@ -13458,6 +17333,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: @@ -13545,6 +17421,7 @@ test cases: ESP32_IDF' Test App: SSC + allow fail: '' auto test: 'Yes' category: Function cmd set: From 5ba6c1b1b7118bfdb637aea14475f59b56e320cd Mon Sep 17 00:00:00 2001 From: Yinling Date: Thu, 29 Sep 2016 12:07:35 +0800 Subject: [PATCH 067/343] sync test config from test bench: 1. night jobs should exit without error if not triggered 2. remove get wifi connect status cases from IDF 3. use Env tag to check if test environment is special --- .gitlab-ci.yml | 108 +- .../test/CIConfigs/Function_WIFI_01.yml | 12 +- .../test/CIConfigs/Function_WIFI_02.yml | 9 +- .../test/CIConfigs/Function_WIFI_03.yml | 4 +- .../test/CIConfigs/Function_WIFI_04.yml | 2 +- .../test/CIConfigs/Function_WIFI_05.yml | 9 +- .../test/CIConfigs/Function_WIFI_06.yml | 9 +- .../test/CIConfigs/Function_WIFI_07.yml | 12 +- .../test/CIConfigs/Function_WIFI_08.yml | 12 +- .../test/CIConfigs/Function_WIFI_09.yml | 12 +- .../test/CIConfigs/Function_WIFI_10.yml | 10 + .../test/CIConfigs/Function_WIFI_11.yml | 10 + components/test/TestCaseAll.yml | 3885 +---------------- 13 files changed, 116 insertions(+), 3978 deletions(-) create mode 100644 components/test/CIConfigs/Function_WIFI_10.yml create mode 100644 components/test/CIConfigs/Function_WIFI_11.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ad6db4169a..f422f9f250 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -64,28 +64,10 @@ build_ssc: script: - git clone ssh://git@gitlab.espressif.cn:27227/yinling/SSC.git - cd SSC - - git checkout ${CI_BUILD_REF_NAME} || echo "Using SSC default branch..." - make defconfig - chmod +x gen_misc_ng.sh - ./gen_misc_ng.sh -build_examples: - <<: *build_template - artifacts: - paths: - - build_examples/*/*/build/*.bin - - build_examples/*/*/build/*.elf - - build_examples/*/*/build/*.map - - build_examples/*/*/build/bootloader/*.bin - expire_in: 6 mos - - script: - # it's not possible to build 100% out-of-tree and have the "artifacts" - # mechanism work, but this is the next best thing - - mkdir build_examples - - cd build_examples - - ${IDF_PATH}/make/build_examples.sh - test_nvs_on_host: stage: test image: espressif/esp32-ci-env @@ -168,7 +150,7 @@ push_master_to_github: - triggers script: # must be night build triggers, otherwise exit without test - - test $NIGHT_BUILD != "Yes" || exit + - test $NIGHT_BUILD != "Yes" || exit 0 - git clone $GITLAB_SSH_SERVER/yinling/auto_test_script.git - cd auto_test_script - python CIRunner.py -l $LOG_PATH -c $CONFIG_FILE -e $LOCAL_ENV_CONFIG_PATH -t $TEST_CASE_FILE_PATH bin_path $APP_NAME $BIN_PATH @@ -185,10 +167,7 @@ Function_WIFI_01: <<: *test_template tags: - ESP32_IDF - - SSC_T3_PhyMode - SSC_T1_1 - - SSC_T1_WEP - - SSC_T2_PhyMode - SSC_T2_1 before_script: - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_WIFI_01.yml @@ -198,22 +177,10 @@ Function_WIFI_02: tags: - ESP32_IDF - SSC_T1_1 - - SSC_T1_WEP - - SSC_T2_PhyMode - SSC_T2_1 before_script: - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_WIFI_02.yml -Function_WIFI_03: - <<: *test_template - tags: - - ESP32_IDF - - SSC_T3_PhyMode - - SSC_T1_1 - - SSC_T2_1 - before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_WIFI_03.yml - Function_TCPIP_01: <<: *test_template tags: @@ -267,6 +234,14 @@ Function_TCPIP_06: before_script: - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_TCPIP_06.yml +Function_WIFI_03: + <<: *test_template + tags: + - ESP32_IDF + - SSC_T3_PhyMode + before_script: + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_WIFI_03.yml + Function_WIFI_04: <<: *test_template tags: @@ -279,7 +254,7 @@ Function_WIFI_05: <<: *test_template tags: - ESP32_IDF - - SSC_T2_PhyMode + - SSC_T1_WEP before_script: - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_WIFI_05.yml @@ -291,30 +266,6 @@ Function_WIFI_06: before_script: - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_WIFI_06.yml -Function_WIFI_07: - <<: *test_template - tags: - - ESP32_IDF - - SSC_T2_PhyMode - before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_WIFI_07.yml - -Function_WIFI_08: - <<: *test_template - tags: - - ESP32_IDF - - SSC_T2_PhyMode - before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_WIFI_08.yml - -Function_WIFI_09: - <<: *test_template - tags: - - ESP32_IDF - - SSC_T2_PhyMode - before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_WIFI_09.yml - Function_TCPIP_07: <<: *test_template tags: @@ -368,3 +319,42 @@ Function_TCPIP_12: before_script: - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_TCPIP_12.yml +Function_WIFI_07: + <<: *test_template + tags: + - ESP32_IDF + - SSC_T2_PhyMode + before_script: + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_WIFI_07.yml + +Function_WIFI_08: + <<: *test_template + tags: + - ESP32_IDF + - SSC_T2_PhyMode + before_script: + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_WIFI_08.yml + +Function_WIFI_09: + <<: *test_template + tags: + - ESP32_IDF + - SSC_T2_PhyMode + before_script: + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_WIFI_09.yml + +Function_WIFI_10: + <<: *test_template + tags: + - ESP32_IDF + - SSC_T2_PhyMode + before_script: + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_WIFI_10.yml + +Function_WIFI_11: + <<: *test_template + tags: + - ESP32_IDF + - SSC_T2_PhyMode + before_script: + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_WIFI_11.yml diff --git a/components/test/CIConfigs/Function_WIFI_01.yml b/components/test/CIConfigs/Function_WIFI_01.yml index 9d177e5ee1..da9bfecd5d 100644 --- a/components/test/CIConfigs/Function_WIFI_01.yml +++ b/components/test/CIConfigs/Function_WIFI_01.yml @@ -1,10 +1,10 @@ Config: {execute count: 1, execute order: in order} -DUT: [SSC3, SSC2, SSC1] +DUT: [SSC2, SSC1] Filter: - Add: - ID: [^WIFI_CONN_0601, ^WIFI_ADDR_0101, ^WIFI_CONN_0903, WIFI_SCAN_0103, WIFI_SCAN_0102, - WIFI_SCAN_0101, WIFI_SCAN_0105, WIFI_SCAN_0104, WIFI_CONN_0201, WIFI_CONN_0702, - WIFI_CONN_0703, WIFI_PHY_0403, WIFI_CONN_0904, ^WIFI_CONN_0201, ^WIFI_CONN_0703, + ID: [^WIFI_CONN_0601, ^WIFI_ADDR_0101, WIFI_SCAN_0103, WIFI_SCAN_0102, WIFI_SCAN_0101, + WIFI_SCAN_0105, WIFI_SCAN_0104, WIFI_CONN_0201, WIFI_CONN_0904, ^WIFI_CONN_0201, ^WIFI_SCAN_0102, ^WIFI_SCAN_0103, ^WIFI_SCAN_0104, ^WIFI_SCAN_0105, ^WIFI_ADDR_0102, - WIFI_CONN_0401, ^WIFI_CONN_0103, WIFI_ADDR_0101, WIFI_ADDR_0102, WIFI_PHY_0502, - WIFI_PHY_0503, WIFI_PHY_0501, WIFI_PHY_0506, WIFI_PHY_0505, WIFI_CONN_0301] + WIFI_CONN_0401, ^WIFI_CONN_0103, WIFI_ADDR_0101, WIFI_ADDR_0102, WIFI_CONN_0301, + ^WIFI_CONN_0801, WIFI_CONN_0104, ^WIFI_CONN_0301, WIFI_CONN_0501, WIFI_CONN_0502, + ^WIFI_CONN_0401, WIFI_MODE_0101, WIFI_MODE_0103, WIFI_MODE_0102, ^WIFI_CONN_0904] diff --git a/components/test/CIConfigs/Function_WIFI_02.yml b/components/test/CIConfigs/Function_WIFI_02.yml index c684454880..e1b61a20e9 100644 --- a/components/test/CIConfigs/Function_WIFI_02.yml +++ b/components/test/CIConfigs/Function_WIFI_02.yml @@ -2,9 +2,6 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC2, SSC1] Filter: - Add: - ID: [WIFI_SCAN_0301, WIFI_SCAN_0303, ^WIFI_CONN_0801, WIFI_SCAN_0304, WIFI_CONN_0104, - ^WIFI_CONN_0301, WIFI_CONN_0501, WIFI_CONN_0502, ^WIFI_CONN_0401, WIFI_MODE_0101, - WIFI_MODE_0103, WIFI_MODE_0102, ^WIFI_CONN_0904, ^WIFI_CONN_0901, WIFI_SCAN_0302, - WIFI_CONN_0601, WIFI_CONN_0901, WIFI_CONN_0903, WIFI_SCAN_0201, WIFI_CONN_0503, - WIFI_PHY_0402, WIFI_PHY_0401, WIFI_PHY_0407, WIFI_PHY_0406, WIFI_PHY_0405, WIFI_PHY_0404, - WIFI_PHY_0408, ^WIFI_CONN_0104, WIFI_CONN_0101, WIFI_CONN_0102] + ID: [^WIFI_CONN_0901, WIFI_CONN_0601, WIFI_CONN_0901, WIFI_CONN_0503, ^WIFI_CONN_0104, + WIFI_CONN_0101, WIFI_CONN_0102, WIFI_CONN_0103, WIFI_CONN_0801, ^WIFI_CONN_0101, + ^WIFI_CONN_0503, ^WIFI_CONN_0502, ^WIFI_CONN_0501, ^WIFI_SCAN_0101] diff --git a/components/test/CIConfigs/Function_WIFI_03.yml b/components/test/CIConfigs/Function_WIFI_03.yml index 72a9db2deb..0f0b4bbaad 100644 --- a/components/test/CIConfigs/Function_WIFI_03.yml +++ b/components/test/CIConfigs/Function_WIFI_03.yml @@ -2,5 +2,5 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC3, SSC2, SSC1] Filter: - Add: - ID: [WIFI_CONN_0103, WIFI_PHY_0504, ^WIFI_CONN_0702, WIFI_CONN_0801, ^WIFI_CONN_0101, - ^WIFI_CONN_0503, ^WIFI_CONN_0502, ^WIFI_CONN_0501, ^WIFI_SCAN_0101] + ID: [WIFI_PHY_0502, WIFI_PHY_0503, WIFI_PHY_0501, WIFI_PHY_0506, WIFI_PHY_0505, + WIFI_PHY_0504] diff --git a/components/test/CIConfigs/Function_WIFI_04.yml b/components/test/CIConfigs/Function_WIFI_04.yml index 1ac97dece3..50f8707c72 100644 --- a/components/test/CIConfigs/Function_WIFI_04.yml +++ b/components/test/CIConfigs/Function_WIFI_04.yml @@ -2,4 +2,4 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC1] Filter: - Add: - ID: [WIFI_CONN_0701, ^WIFI_CONN_0701, ^WIFI_CONN_0902, WIFI_CONN_0902] + ID: [^WIFI_CONN_0902, WIFI_CONN_0902] diff --git a/components/test/CIConfigs/Function_WIFI_05.yml b/components/test/CIConfigs/Function_WIFI_05.yml index 22840fa7af..3694a698b7 100644 --- a/components/test/CIConfigs/Function_WIFI_05.yml +++ b/components/test/CIConfigs/Function_WIFI_05.yml @@ -1,10 +1,5 @@ Config: {execute count: 1, execute order: in order} -DUT: [SSC2, SSC1] +DUT: [SSC1] Filter: - Add: - ID: [WIFI_PHY_0105, WIFI_PHY_0105, WIFI_PHY_0105, WIFI_PHY_0102, WIFI_PHY_0102, - WIFI_PHY_0102, WIFI_PHY_0103, WIFI_PHY_0103, WIFI_PHY_0103, WIFI_PHY_0101, WIFI_PHY_0101, - WIFI_PHY_0101, WIFI_PHY_0313, WIFI_PHY_0313, WIFI_PHY_0313, WIFI_PHY_0312, WIFI_PHY_0312, - WIFI_PHY_0312, WIFI_PHY_0311, WIFI_PHY_0311, WIFI_PHY_0311, WIFI_PHY_0310, WIFI_PHY_0310, - WIFI_PHY_0310, WIFI_PHY_0316, WIFI_PHY_0316, WIFI_PHY_0316, WIFI_PHY_0315, WIFI_PHY_0315, - WIFI_PHY_0315] + ID: [^WIFI_CONN_0903, WIFI_CONN_0903] diff --git a/components/test/CIConfigs/Function_WIFI_06.yml b/components/test/CIConfigs/Function_WIFI_06.yml index 640330233a..f3db504c9f 100644 --- a/components/test/CIConfigs/Function_WIFI_06.yml +++ b/components/test/CIConfigs/Function_WIFI_06.yml @@ -2,9 +2,6 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC2, SSC1] Filter: - Add: - ID: [WIFI_PHY_0314, WIFI_PHY_0314, WIFI_PHY_0314, WIFI_PHY_0308, WIFI_PHY_0308, - WIFI_PHY_0308, WIFI_PHY_0309, WIFI_PHY_0309, WIFI_PHY_0309, WIFI_PHY_0304, WIFI_PHY_0304, - WIFI_PHY_0304, WIFI_PHY_0305, WIFI_PHY_0305, WIFI_PHY_0305, WIFI_PHY_0306, WIFI_PHY_0306, - WIFI_PHY_0306, WIFI_PHY_0307, WIFI_PHY_0307, WIFI_PHY_0307, WIFI_PHY_0301, WIFI_PHY_0301, - WIFI_PHY_0301, WIFI_PHY_0302, WIFI_PHY_0302, WIFI_PHY_0302, WIFI_PHY_0110, WIFI_PHY_0110, - WIFI_PHY_0110] + ID: [WIFI_PHY_0403, WIFI_SCAN_0301, WIFI_SCAN_0303, WIFI_SCAN_0304, WIFI_SCAN_0302, + WIFI_SCAN_0201, WIFI_PHY_0402, WIFI_PHY_0401, WIFI_PHY_0407, WIFI_PHY_0406, + WIFI_PHY_0405, WIFI_PHY_0404, WIFI_PHY_0408] diff --git a/components/test/CIConfigs/Function_WIFI_07.yml b/components/test/CIConfigs/Function_WIFI_07.yml index a51560fd60..22840fa7af 100644 --- a/components/test/CIConfigs/Function_WIFI_07.yml +++ b/components/test/CIConfigs/Function_WIFI_07.yml @@ -2,9 +2,9 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC2, SSC1] Filter: - Add: - ID: [WIFI_PHY_0113, WIFI_PHY_0113, WIFI_PHY_0113, WIFI_PHY_0120, WIFI_PHY_0120, - WIFI_PHY_0120, WIFI_PHY_0119, WIFI_PHY_0119, WIFI_PHY_0119, WIFI_PHY_0118, WIFI_PHY_0118, - WIFI_PHY_0118, WIFI_PHY_0115, WIFI_PHY_0115, WIFI_PHY_0115, WIFI_PHY_0114, WIFI_PHY_0114, - WIFI_PHY_0114, WIFI_PHY_0117, WIFI_PHY_0117, WIFI_PHY_0117, WIFI_PHY_0111, WIFI_PHY_0111, - WIFI_PHY_0111, WIFI_PHY_0112, WIFI_PHY_0112, WIFI_PHY_0112, WIFI_PHY_0205, WIFI_PHY_0205, - WIFI_PHY_0205] + ID: [WIFI_PHY_0105, WIFI_PHY_0105, WIFI_PHY_0105, WIFI_PHY_0102, WIFI_PHY_0102, + WIFI_PHY_0102, WIFI_PHY_0103, WIFI_PHY_0103, WIFI_PHY_0103, WIFI_PHY_0101, WIFI_PHY_0101, + WIFI_PHY_0101, WIFI_PHY_0313, WIFI_PHY_0313, WIFI_PHY_0313, WIFI_PHY_0312, WIFI_PHY_0312, + WIFI_PHY_0312, WIFI_PHY_0311, WIFI_PHY_0311, WIFI_PHY_0311, WIFI_PHY_0310, WIFI_PHY_0310, + WIFI_PHY_0310, WIFI_PHY_0316, WIFI_PHY_0316, WIFI_PHY_0316, WIFI_PHY_0315, WIFI_PHY_0315, + WIFI_PHY_0315] diff --git a/components/test/CIConfigs/Function_WIFI_08.yml b/components/test/CIConfigs/Function_WIFI_08.yml index f143efb3b0..640330233a 100644 --- a/components/test/CIConfigs/Function_WIFI_08.yml +++ b/components/test/CIConfigs/Function_WIFI_08.yml @@ -2,9 +2,9 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC2, SSC1] Filter: - Add: - ID: [WIFI_PHY_0204, WIFI_PHY_0204, WIFI_PHY_0204, WIFI_PHY_0207, WIFI_PHY_0207, - WIFI_PHY_0207, WIFI_PHY_0206, WIFI_PHY_0206, WIFI_PHY_0206, WIFI_PHY_0201, WIFI_PHY_0201, - WIFI_PHY_0201, WIFI_PHY_0203, WIFI_PHY_0203, WIFI_PHY_0203, WIFI_PHY_0202, WIFI_PHY_0202, - WIFI_PHY_0202, WIFI_PHY_0209, WIFI_PHY_0209, WIFI_PHY_0209, WIFI_PHY_0208, WIFI_PHY_0208, - WIFI_PHY_0208, WIFI_PHY_0116, WIFI_PHY_0116, WIFI_PHY_0116, WIFI_PHY_0303, WIFI_PHY_0303, - WIFI_PHY_0303] + ID: [WIFI_PHY_0314, WIFI_PHY_0314, WIFI_PHY_0314, WIFI_PHY_0308, WIFI_PHY_0308, + WIFI_PHY_0308, WIFI_PHY_0309, WIFI_PHY_0309, WIFI_PHY_0309, WIFI_PHY_0304, WIFI_PHY_0304, + WIFI_PHY_0304, WIFI_PHY_0305, WIFI_PHY_0305, WIFI_PHY_0305, WIFI_PHY_0306, WIFI_PHY_0306, + WIFI_PHY_0306, WIFI_PHY_0307, WIFI_PHY_0307, WIFI_PHY_0307, WIFI_PHY_0301, WIFI_PHY_0301, + WIFI_PHY_0301, WIFI_PHY_0302, WIFI_PHY_0302, WIFI_PHY_0302, WIFI_PHY_0110, WIFI_PHY_0110, + WIFI_PHY_0110] diff --git a/components/test/CIConfigs/Function_WIFI_09.yml b/components/test/CIConfigs/Function_WIFI_09.yml index f4adf0d2e6..a51560fd60 100644 --- a/components/test/CIConfigs/Function_WIFI_09.yml +++ b/components/test/CIConfigs/Function_WIFI_09.yml @@ -2,9 +2,9 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC2, SSC1] Filter: - Add: - ID: [WIFI_PHY_0108, WIFI_PHY_0108, WIFI_PHY_0108, WIFI_PHY_0109, WIFI_PHY_0109, - WIFI_PHY_0109, WIFI_PHY_0106, WIFI_PHY_0106, WIFI_PHY_0106, WIFI_PHY_0107, WIFI_PHY_0107, - WIFI_PHY_0107, WIFI_PHY_0214, WIFI_PHY_0214, WIFI_PHY_0214, WIFI_PHY_0212, WIFI_PHY_0212, - WIFI_PHY_0212, WIFI_PHY_0213, WIFI_PHY_0213, WIFI_PHY_0213, WIFI_PHY_0210, WIFI_PHY_0210, - WIFI_PHY_0210, WIFI_PHY_0211, WIFI_PHY_0211, WIFI_PHY_0211, WIFI_PHY_0104, WIFI_PHY_0104, - WIFI_PHY_0104] + ID: [WIFI_PHY_0113, WIFI_PHY_0113, WIFI_PHY_0113, WIFI_PHY_0120, WIFI_PHY_0120, + WIFI_PHY_0120, WIFI_PHY_0119, WIFI_PHY_0119, WIFI_PHY_0119, WIFI_PHY_0118, WIFI_PHY_0118, + WIFI_PHY_0118, WIFI_PHY_0115, WIFI_PHY_0115, WIFI_PHY_0115, WIFI_PHY_0114, WIFI_PHY_0114, + WIFI_PHY_0114, WIFI_PHY_0117, WIFI_PHY_0117, WIFI_PHY_0117, WIFI_PHY_0111, WIFI_PHY_0111, + WIFI_PHY_0111, WIFI_PHY_0112, WIFI_PHY_0112, WIFI_PHY_0112, WIFI_PHY_0205, WIFI_PHY_0205, + WIFI_PHY_0205] diff --git a/components/test/CIConfigs/Function_WIFI_10.yml b/components/test/CIConfigs/Function_WIFI_10.yml new file mode 100644 index 0000000000..f143efb3b0 --- /dev/null +++ b/components/test/CIConfigs/Function_WIFI_10.yml @@ -0,0 +1,10 @@ +Config: {execute count: 1, execute order: in order} +DUT: [SSC2, SSC1] +Filter: +- Add: + ID: [WIFI_PHY_0204, WIFI_PHY_0204, WIFI_PHY_0204, WIFI_PHY_0207, WIFI_PHY_0207, + WIFI_PHY_0207, WIFI_PHY_0206, WIFI_PHY_0206, WIFI_PHY_0206, WIFI_PHY_0201, WIFI_PHY_0201, + WIFI_PHY_0201, WIFI_PHY_0203, WIFI_PHY_0203, WIFI_PHY_0203, WIFI_PHY_0202, WIFI_PHY_0202, + WIFI_PHY_0202, WIFI_PHY_0209, WIFI_PHY_0209, WIFI_PHY_0209, WIFI_PHY_0208, WIFI_PHY_0208, + WIFI_PHY_0208, WIFI_PHY_0116, WIFI_PHY_0116, WIFI_PHY_0116, WIFI_PHY_0303, WIFI_PHY_0303, + WIFI_PHY_0303] diff --git a/components/test/CIConfigs/Function_WIFI_11.yml b/components/test/CIConfigs/Function_WIFI_11.yml new file mode 100644 index 0000000000..f4adf0d2e6 --- /dev/null +++ b/components/test/CIConfigs/Function_WIFI_11.yml @@ -0,0 +1,10 @@ +Config: {execute count: 1, execute order: in order} +DUT: [SSC2, SSC1] +Filter: +- Add: + ID: [WIFI_PHY_0108, WIFI_PHY_0108, WIFI_PHY_0108, WIFI_PHY_0109, WIFI_PHY_0109, + WIFI_PHY_0109, WIFI_PHY_0106, WIFI_PHY_0106, WIFI_PHY_0106, WIFI_PHY_0107, WIFI_PHY_0107, + WIFI_PHY_0107, WIFI_PHY_0214, WIFI_PHY_0214, WIFI_PHY_0214, WIFI_PHY_0212, WIFI_PHY_0212, + WIFI_PHY_0212, WIFI_PHY_0213, WIFI_PHY_0213, WIFI_PHY_0213, WIFI_PHY_0210, WIFI_PHY_0210, + WIFI_PHY_0210, WIFI_PHY_0211, WIFI_PHY_0211, WIFI_PHY_0211, WIFI_PHY_0104, WIFI_PHY_0104, + WIFI_PHY_0104] diff --git a/components/test/TestCaseAll.yml b/components/test/TestCaseAll.yml index 5e72da0f40..d787017591 100644 --- a/components/test/TestCaseAll.yml +++ b/components/test/TestCaseAll.yml @@ -1,151 +1,4 @@ test cases: -- CI ready: 'Yes' - ID: WIFI_PHY_0105 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 2 -m b - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m n -b 40 - - ['R SSC2 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp!)(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. assoc response has no erp/xrates/ht, cap.short_slot_time=1, rates=[1/2/5/5/11] - - 3. radiotap rates in [1/2/5/5/11]' - initial condition: APM1 - initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial - condition APSTA1 - module: WIFI MAC - steps: '1. target set to PHY mode 11b - - 2. ht40 STA connect to SoftAP, capture assoc response - - 3. ping, capture Data' - sub module: Phy Mode - summary: SoftAP set as 11b, ht40 STA connect to AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: SoftAP PHY mode test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0102 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 2 -m b - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m b - - ['R SSC2 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp!)(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. assoc response has no erp/xrates/ht, cap.short_slot_time=1, rates=[1/2/5/5/11] - - 3. radiotap rates in [1/2/5/5/11]' - initial condition: APM1 - initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial - condition APSTA1 - module: WIFI MAC - steps: '1. target set to PHY mode 11b - - 2. 11b STA connect to SoftAP, capture assoc response - - 3. ping, capture Data' - sub module: Phy Mode - summary: SoftAP set as 11b, 11b STA connect to AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: SoftAP PHY mode test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0103 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 2 -m b - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m g - - ['R SSC2 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp!)(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. assoc response has no erp/xrates/ht, cap.short_slot_time=1, rates=[1/2/5/5/11] - - 3. radiotap rates in [1/2/5/5/11]' - initial condition: APM1 - initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial - condition APSTA1 - module: WIFI MAC - steps: '1. target set to PHY mode 11b - - 2. 11bg STA connect to SoftAP, capture assoc response - - 3. ping, capture Data' - sub module: Phy Mode - summary: SoftAP set as 11b, 11g STA connect to AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: SoftAP PHY mode test - version: v1 (2015-8-15) - CI ready: 'Yes' ID: ^WIFI_CONN_0601 SDK: '8266_NonOS @@ -198,438 +51,6 @@ test cases: test point 1: basic function test point 2: list SoftAP connected station version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0101 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 2 -m b - - ['R SSC1 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK', 'R CAP PDU (Wlan.frame_ctrl.type_subtype="Management-Beacon")(Wlan.ie_list.erp!)(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")'] - comment: '' - execution time: 0.0 - expected result: 1. beacon has no erp/xrates/ht, cap.short_slot_time=1, rates=[1/2/5/5/11] - initial condition: APM1 - initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial - condition APSTA1 - module: WIFI MAC - steps: 1. target set to PHY mode 11b, capture beacon - sub module: Phy Mode - summary: SoftAP set as 11b, check beacon - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: SoftAP PHY mode test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0313 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m b - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m n -b 40 - - ['R SSC2 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s%20or%20wlan%20addr2%20%%s - - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC1 sta -C -s -p - - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates!)(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities.short_gi_for_40="1")(Wlan.ie_list.ht_operation.second_channel_offset!="0","2")(Wlan.ie_list.ht_operation.sta_channel_width="1")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") - PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. check STA packet - - 3. check SoftAP packet' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. set softAP ht40, STA 11b - - 2. STA connect to ext AP - - 3. ext STA connect to SoftAP' - sub module: Phy Mode - summary: SoftAP ht40, STA 11b, get connected and join AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA+SoftAP PHY mode test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0312 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m n -b 20 - - ['R SSC2 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s%20or%20wlan%20addr2%20%%s - - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC1 sta -C -s -p - - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities.short_gi_for_40="1")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") - PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities="")(Wlan.ie_list.ht_operation.second_channel_offset="0")(Wlan.ie_list.ht_operation.sta_channel_width="0")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") - PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. check STA packet - - 3. check SoftAP packet' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. set softAP 11bgn, STA ht40 - - 2. STA connect to ext AP - - 3. ext STA connect to SoftAP' - sub module: Phy Mode - summary: SoftAP 11bgn, STA ht40, get connected and join AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA+SoftAP PHY mode test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0311 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m n -b 20 - - ['R SSC2 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s%20or%20wlan%20addr2%20%%s - - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC1 sta -C -s -p - - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities="")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") - PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities="")(Wlan.ie_list.ht_operation.second_channel_offset="0")(Wlan.ie_list.ht_operation.sta_channel_width="0")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") - PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. check STA packet - - 3. check SoftAP packet' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. set softAP 11bgn, STA 11bgn - - 2. STA connect to ext AP - - 3. ext STA connect to SoftAP' - sub module: Phy Mode - summary: SoftAP 11bgn, STA 11bgn, get connected and join AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA+SoftAP PHY mode test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0310 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m g - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m n -b 20 - - ['R SSC2 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s%20or%20wlan%20addr2%20%%s - - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC1 sta -C -s -p - - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M")'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities="")(Wlan.ie_list.ht_operation.second_channel_offset="0")(Wlan.ie_list.ht_operation.sta_channel_width="0")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") - PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. check STA packet - - 3. check SoftAP packet' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. set softAP 11bgn, STA 11bg - - 2. STA connect to ext AP - - 3. ext STA connect to SoftAP' - sub module: Phy Mode - summary: SoftAP 11bgn, STA 11bg, get connected and join AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA+SoftAP PHY mode test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0316 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m n -b 40 - - ['R SSC2 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s%20or%20wlan%20addr2%20%%s - - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC1 sta -C -s -p - - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities.short_gi_for_40="1")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") - PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities.short_gi_for_40="1")(Wlan.ie_list.ht_operation.second_channel_offset!="0","2")(Wlan.ie_list.ht_operation.sta_channel_width="1")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") - PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. check STA packet - - 3. check SoftAP packet' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. set softAP ht40, STA ht40 - - 2. STA connect to ext AP - - 3. ext STA connect to SoftAP' - sub module: Phy Mode - summary: SoftAP ht40, STA ht40, get connected and join AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA+SoftAP PHY mode test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0315 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m n -b 40 - - ['R SSC2 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s%20or%20wlan%20addr2%20%%s - - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC1 sta -C -s -p - - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities="")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") - PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities.short_gi_for_40="1")(Wlan.ie_list.ht_operation.second_channel_offset!="0","2")(Wlan.ie_list.ht_operation.sta_channel_width="1")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") - PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. check STA packet - - 3. check SoftAP packet' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. set softAP ht40, STA 11bgn - - 2. STA connect to ext AP - - 3. ext STA connect to SoftAP' - sub module: Phy Mode - summary: SoftAP ht40, STA 11bgn, get connected and join AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA+SoftAP PHY mode test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0314 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m g - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m n -b 40 - - ['R SSC2 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s%20or%20wlan%20addr2%20%%s - - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC1 sta -C -s -p - - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M")'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities.short_gi_for_40="1")(Wlan.ie_list.ht_operation.second_channel_offset!="0","2")(Wlan.ie_list.ht_operation.sta_channel_width="1")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") - PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. check STA packet - - 3. check SoftAP packet' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. set softAP ht40, STA 11bg - - 2. STA connect to ext AP - - 3. ext STA connect to SoftAP' - sub module: Phy Mode - summary: SoftAP ht40, STA 11bg, get connected and join AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA+SoftAP PHY mode test - version: v1 (2015-8-15) - CI ready: 'Yes' ID: TCPIP_ICMP_0101 SDK: '8266_NonOS @@ -1632,38 +1053,6 @@ test cases: test point 1: abnormal/special use test point 2: TCP handling abnormal event version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^WIFI_CONN_0903 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 sta -C -s -p bacfd - - ['R SSC1 C +JAP:DISCONNECTED,4,2'] - comment: '' - execution time: 0.0 - expected result: 1. disconect event reason REASON_AUTH_EXPIRE - initial condition: STAAP1 - initial condition description (auto): testing sta on sta + ap mode, quit AP (autogen - by STAM1) - module: WIFI MAC - steps: 1. connect WEP ap with error password (valid wep password) - sub module: WIFI Connect - summary: test wifi disconnect reason REASON_AUTH_EXPIRE - test environment: SSC_T1_WEP - test environment description (auto): '1 SSC target connect with PC by UART. - - One WEP share key AP placed near SSC1.' - test point 1: basic function - test point 2: wifi disconnect reason test - version: v1 (2016-8-15) - CI ready: 'Yes' ID: TCPIP_TCP_0408 SDK: '8266_NonOS @@ -2608,414 +1997,6 @@ test cases: test point 1: basic function test point 2: query JAP status version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_CONN_0702 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:OK', 'R SSC1 C +JAP:DISCONNECTED,3'] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:OK', 'R SSC1 C +JAP:DISCONNECTED,2'] - comment: '' - execution time: 0.0 - expected result: '1. get status AP not exist in disconnect event - - 2. get status wrong password in disconnect event' - initial condition: STAM1 - initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a - TC with initial condition STAAP1 - module: WIFI MAC - steps: '1. sta connect to ap not exist - - 2. sta connect to ap with wrong password - - ' - sub module: WIFI Connect - summary: check wifi status wrong password, no ap found - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: wifi connect status check - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_CONN_0703 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 sta -C -s -p bacfd - - ['R SSC1 C +JAP:DISCONNECTED,4,2'] - comment: '' - execution time: 0.0 - expected result: 1. connect status connect fail in disconnect evnet - initial condition: STAM1 - initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a - TC with initial condition STAAP1 - module: WIFI MAC - steps: 1. connect WEP ap with error password (valid wep password) - sub module: WIFI Connect - summary: check wifi status connect fail - test environment: SSC_T1_WEP - test environment description (auto): '1 SSC target connect with PC by UART. - - One WEP share key AP placed near SSC1.' - test point 1: basic function - test point 2: wifi connect status check - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0308 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m g - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m g - - ['R SSC2 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s%20or%20wlan%20addr2%20%%s - - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC1 sta -C -s -p - - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities.short_gi_for_40="1")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") - PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. check STA packet - - 3. check SoftAP packet' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. set softAP 11bg, STA ht40 - - 2. STA connect to ext AP - - 3. ext STA connect to SoftAP' - sub module: Phy Mode - summary: SoftAP 11bg, STA ht40, get connected and join AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA+SoftAP PHY mode test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0309 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m b - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m n -b 20 - - ['R SSC2 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s%20or%20wlan%20addr2%20%%s - - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC1 sta -C -s -p - - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates!)(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities="")(Wlan.ie_list.ht_operation.second_channel_offset="0")(Wlan.ie_list.ht_operation.sta_channel_width="0")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") - PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. check STA packet - - 3. check SoftAP packet' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. set softAP 11bgn, STA 11b - - 2. STA connect to ext AP - - 3. ext STA connect to SoftAP' - sub module: Phy Mode - summary: SoftAP 11bgn, STA 11b, get connected and join AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA+SoftAP PHY mode test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0304 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m b - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m b - - ['R SSC2 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s%20or%20wlan%20addr2%20%%s - - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC1 sta -C -s -p - - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities.short_gi_for_40="1")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") - PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp!)(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. check STA packet - - 3. check SoftAP packet' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. set softAP 11b, STA ht40 - - 2. STA connect to ext AP - - 3. ext STA connect to SoftAP' - sub module: Phy Mode - summary: SoftAP 11b, STA ht40, get connected and join AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA+SoftAP PHY mode test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0305 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m b - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m g - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m g - - ['R SSC2 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s%20or%20wlan%20addr2%20%%s - - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC1 sta -C -s -p - - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates!)(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. check STA packet - - 3. check SoftAP packet' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. set softAP 11bg, STA 11b - - 2. STA connect to ext AP - - 3. ext STA connect to SoftAP' - sub module: Phy Mode - summary: SoftAP 11bg, STA 11b, get connected and join AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA+SoftAP PHY mode test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0306 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m g - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m g - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m g - - ['R SSC2 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s%20or%20wlan%20addr2%20%%s - - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC1 sta -C -s -p - - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M")'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. check STA packet - - 3. check SoftAP packet' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. set softAP 11bg, STA 11bg - - 2. STA connect to ext AP - - 3. ext STA connect to SoftAP' - sub module: Phy Mode - summary: SoftAP 11bg, STA 11bg, get connected and join AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA+SoftAP PHY mode test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0307 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m g - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m g - - ['R SSC2 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s%20or%20wlan%20addr2%20%%s - - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC1 sta -C -s -p - - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities="")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") - PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. check STA packet - - 3. check SoftAP packet' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. set softAP 11bg, STA 11bgn - - 2. STA connect to ext AP - - 3. ext STA connect to SoftAP' - sub module: Phy Mode - summary: SoftAP 11bg, STA 11bgn, get connected and join AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA+SoftAP PHY mode test - version: v1 (2015-8-15) - CI ready: 'Yes' ID: TCPIP_DNS_0102 SDK: '8266_NonOS @@ -3064,116 +2045,6 @@ test cases: test point 1: basic function test point 2: DNS function test version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0301 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m b - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m b - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m b - - ['R SSC2 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s%20or%20wlan%20addr2%20%%s - - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC1 sta -C -s -p - - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates!)(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp!)(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. check STA packet - - 3. check SoftAP packet' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. set softAP 11b, STA 11b - - 2. STA connect to ext AP - - 3. ext STA connect to SoftAP' - sub module: Phy Mode - summary: SoftAP 11b, STA 11b, get connected and join AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA+SoftAP PHY mode test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0302 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m g - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m b - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m b - - ['R SSC2 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s%20or%20wlan%20addr2%20%%s - - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC1 sta -C -s -p - - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M")'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp!)(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. check STA packet - - 3. check SoftAP packet' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. set softAP 11b, STA 11bg - - 2. STA connect to ext AP - - 3. ext STA connect to SoftAP' - sub module: Phy Mode - summary: SoftAP 11b, STA 11bg, get connected and join AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA+SoftAP PHY mode test - version: v1 (2015-8-15) - CI ready: 'Yes' ID: TCPIP_DNS_0101 SDK: '8266_NonOS @@ -3206,52 +2077,6 @@ test cases: test point 1: basic function test point 2: DNS function test version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0403 - SDK: ESP32_IDF - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m n -b 20 - - ['R SSC2 C +PHY:OK'] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:CONNECTED'] - - - SSC SSC2 sta -C -s -p - - [''] - - - DELAY 10 - - ['P SSC1 NC +JAP:DISCONNECTED', 'P SSC2 C +JAP:CONNECTED'] - comment: '' - execution time: 0.0 - expected result: 3. SoftAP and STA in channel2, SoftAP 20M, STA 40M, STA not disconnected - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. SoftAP 11n ht20, in channel1, ext AP 11n ht40, in channel2 - - 2. STA connect to ext AP - - 3. AP get connected' - sub module: Phy Mode - summary: SoftAP ext AP in defferent channel, SoftAP 20M, ext AP 40M, STA connect - to AP then Softap get connected - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA+SoftAP initial channel test - version: v1 (2015-8-15) - CI ready: 'Yes' ID: WIFI_CONN_0904 SDK: '8266_NonOS @@ -3268,17 +2093,17 @@ test cases: - - SSC SSC1 ap -S -s -p -t 3 -m 1 - ['R SSC1 C +SAP:OK'] - - SSC SSC2 sta -C -s -p 1234567890 - - ['R SSC2 C +JAP:DISCONNECTED,1,204'] + - ['R SSC2 RE JAP:DISCONNECTED,\d+,204'] - - SSC SSC2 sta -D - ['R SSC2 C +QAP:OK'] - - WIFI CONN - ['R PC_COM NC ERROR C +WIFICONN:OK'] - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:DISCONNECTED,1,5'] + - ['R SSC2 RE JAP:DISCONNECTED,\d+,5'] - - WIFI DISCONN - [P PC_COM C OK, 'R SSC2 C +JAP:CONNECTED'] - - SSC SSC1 ap -S -s -p -t 3 -m 1 - - ['P SSC1 C +SAP:OK', 'P SSC2 C +JAP:DISCONNECTED,5,4'] + - ['P SSC1 C +SAP:OK', 'P SSC2 RE JAP:DISCONNECTED,\d+,4'] comment: '' execution time: 0.0 expected result: '1. succeed @@ -3489,55 +2314,6 @@ test cases: test point 1: basic function test point 2: query JAP status version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0110 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 2 -m g - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m n -b 40 - - ['R SSC2 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M")'] - comment: '' - execution time: 0.0 - expected result: '1. beacon has erp/xrates, no ht, cap.short_slot_time=1, rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54] - - 2. assoc response has erp/xrates, no ht, cap.short_slot_time=1, rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54] - - 3. radiotap rates in rates and xrates' - initial condition: APM1 - initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial - condition APSTA1 - module: WIFI MAC - steps: '1. target set to PHY mode 11bg - - 2. ht40 STA connect to SoftAP, capture assoc response - - 3. ping, capture Data' - sub module: Phy Mode - summary: SoftAP set as 11bg, ht40 STA connect to AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: SoftAP PHY mode test - version: v1 (2015-8-15) - CI ready: 'Yes' ID: ^TCPIP_IGMP_0102 SDK: '8266_NonOS @@ -3652,55 +2428,6 @@ test cases: test point 1: basic function test point 2: IGMP API parameter check version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0113 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 2 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m g - - ['R SSC2 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. assoc response has erp/xrates, no ht, cap.short_slot_time=1, rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54] - - 3. radiotap rates in rates/xrates' - initial condition: APM1 - initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial - condition APSTA1 - module: WIFI MAC - steps: '1. target set to PHY mode 11bgn - - 2. 11bg STA connect to SoftAP, capture assoc response - - 3. ping, capture Data' - sub module: Phy Mode - summary: SoftAP set as 11bgn, 11g STA connect to AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: SoftAP PHY mode test - version: v1 (2015-8-15) - CI ready: 'Yes' ID: ^TCPIP_IGMP_0104 SDK: '8266_NonOS @@ -3759,38 +2486,6 @@ test cases: test point 1: basic function test point 2: IGMP API parameter check version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^WIFI_CONN_0703 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 sta -C -s -p bacfd - - ['R SSC1 C +JAP:DISCONNECTED,4,2'] - comment: '' - execution time: 0.0 - expected result: 1. connect status connect fail in disconnect evnet - initial condition: STAAP1 - initial condition description (auto): testing sta on sta + ap mode, quit AP (autogen - by STAM1) - module: WIFI MAC - steps: 1. connect WEP ap with error password (valid wep password) - sub module: WIFI Connect - summary: check wifi status connect fail - test environment: SSC_T1_WEP - test environment description (auto): '1 SSC target connect with PC by UART. - - One WEP share key AP placed near SSC1.' - test point 1: basic function - test point 2: wifi connect status check - version: v1 (2016-8-15) - CI ready: 'Yes' ID: ^TCPIP_UDP_0110 SDK: '8266_NonOS @@ -5041,57 +3736,6 @@ test cases: test point 1: basic function test point 2: IGMP send/recv test version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0120 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 2 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m n -b 40 - - ['R SSC2 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities.short_gi_for_40="1")(Wlan.ie_list.ht_operation.second_channel_offset!="0","2")(Wlan.ie_list.ht_operation.sta_channel_width="1")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") - PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed, - - 2. assoc response has erp/ht/xrates, cap.short_slot_time=1, ht_info.2nd_channel_offset=2,sta_channel_width=1, - rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54] - - 3. radiotap rates in rates/xrates/msc0-7' - initial condition: APM1 - initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial - condition APSTA1 - module: WIFI MAC - steps: '1. target set to PHY mode ht40 - - 2. ht40 STA connect to SoftAP, capture assoc response - - 3. ping, capture Data' - sub module: Phy Mode - summary: SoftAP set as ht40, ht40 STA connect to AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: SoftAP PHY mode test - version: v1 (2015-8-15) - CI ready: 'Yes' ID: TCPIP_IGMP_0201 SDK: '8266_NonOS @@ -7317,257 +5961,6 @@ test cases: test point 1: basic function test point 2: mac address function test version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0119 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 2 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m n -b 20 - - ['R SSC2 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities="")(Wlan.ie_list.ht_operation.second_channel_offset="0")(Wlan.ie_list.ht_operation.sta_channel_width="0")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") - PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed, - - 2. assoc response has erp/ht/xrates, cap.short_slot_time=1, ht_info.2nd_channel_offset=0,sta_channel_width=0, - rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54] - - 3. radiotap rates in rates/xrates/msc0-7' - initial condition: APM1 - initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial - condition APSTA1 - module: WIFI MAC - steps: '1. target set to PHY mode ht40 - - 2. 11bgn STA connect to SoftAP, capture assoc response - - 3. ping, capture Data' - sub module: Phy Mode - summary: SoftAP set as ht40, 11n STA connect to AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: SoftAP PHY mode test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0118 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 2 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m g - - ['R SSC2 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. assoc response has erp/xrates, no ht, cap.short_slot_time=1, rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54] - - 3. radiotap rates in rates/xrates' - initial condition: APM1 - initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial - condition APSTA1 - module: WIFI MAC - steps: '1. target set to PHY mode ht40 - - 2. 11bg STA connect to SoftAP, capture assoc response - - 3. ping, capture Data' - sub module: Phy Mode - summary: SoftAP set as ht40, 11g STA connect to AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: SoftAP PHY mode test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0115 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 2 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m n -b 40 - - ['R SSC2 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities="")(Wlan.ie_list.ht_operation.second_channel_offset="0")(Wlan.ie_list.ht_operation.sta_channel_width="0")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") - PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed, - - 2. assoc response has erp/ht/xrates, cap.short_slot_time=1, ht_info.2nd_channel_offset=0,sta_channel_width=0, - rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54] - - 3. radiotap rates in rates/xrates/msc0-7' - initial condition: APM1 - initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial - condition APSTA1 - module: WIFI MAC - steps: '1. target set to PHY mode 11bgn - - 2. ht40 STA connect to SoftAP, capture assoc response - - 3. ping, capture Data' - sub module: Phy Mode - summary: SoftAP set as 11bgn, ht40 STA connect to AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: SoftAP PHY mode test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0114 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 2 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m n -b 20 - - ['R SSC2 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities="")(Wlan.ie_list.ht_operation.second_channel_offset="0")(Wlan.ie_list.ht_operation.sta_channel_width="0")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") - PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed, - - 2. assoc response has erp/ht/xrates, cap.short_slot_time=1, ht_info.2nd_channel_offset=0,sta_channel_width=0, - rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54] - - 3. radiotap rates in rates/xrates/msc0-7' - initial condition: APM1 - initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial - condition APSTA1 - module: WIFI MAC - steps: '1. target set to PHY mode 11bgn - - 2. 11bgn STA connect to SoftAP, capture assoc response - - 3. ping, capture Data' - sub module: Phy Mode - summary: SoftAP set as 11bgn, 11n STA connect to AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: SoftAP PHY mode test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0117 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 2 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m b - - ['R SSC2 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp!)(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. assoc response has no erp/xrates/ht, cap.short_slot_time=1, rates=[1/2/5/5/11] - - 3. radiotap rates in rates' - initial condition: APM1 - initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial - condition APSTA1 - module: WIFI MAC - steps: '1. target set to PHY mode ht40 - - 2. 11b STA connect to SoftAP, capture assoc response - - 3. ping, capture Data' - sub module: Phy Mode - summary: SoftAP set as ht40, 11b STA connect to AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: SoftAP PHY mode test - version: v1 (2015-8-15) - CI ready: 'Yes' ID: TCPIP_UDP_0202 SDK: '8266_NonOS @@ -7644,92 +6037,6 @@ test cases: test point 1: abnormal/special use test point 2: use UDP SAP (socket/espconn API) in different state version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0111 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 2 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-Beacon")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities="")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_operation.second_channel_offset="0")(Wlan.ie_list.ht_operation.sta_channel_width="0")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")'] - comment: '' - execution time: 0.0 - expected result: 1. beacon has erp/ht/xrates, cap.short_slot_time=1, ht_info.2nd_channel_offset=0,sta_channel_width=0, - rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54] - initial condition: APM1 - initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial - condition APSTA1 - module: WIFI MAC - steps: 1. target set to PHY mode 11bgn, capture beacon - sub module: Phy Mode - summary: SoftAP set as 11bgn, check beacon - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: SoftAP PHY mode test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0112 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 2 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m b - - ['R SSC2 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp!)(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. assoc response has no erp/xrates/ht, cap.short_slot_time=1, rates=[1/2/5/5/11] - - 3. radiotap rates in rates' - initial condition: APM1 - initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial - condition APSTA1 - module: WIFI MAC - steps: '1. target set to PHY mode 11bgn - - 2. 11b STA connect to SoftAP, capture assoc response - - 3. ping, capture Data' - sub module: Phy Mode - summary: SoftAP set as 11bgn, 11b STA connect to AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: SoftAP PHY mode test - version: v1 (2015-8-15) - CI ready: 'Yes' ID: TCPIP_TCP_0411 SDK: '8266_NonOS @@ -7800,281 +6107,6 @@ test cases: test point 1: abnormal/special use test point 2: TCP handling abnormal event version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0502 - SDK: ESP32_IDF - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:CONNECTED'] - - - SSC SSC3 sta -C -s -p - - ['R SSC3 C +JAP:CONNECTED'] - - - SSC SSC2 sta -C -s -p - - [''] - - - DELAY 10 - - ['P SSC2 C +JAP:CONNECTED', 'P SSC[1,3] NC +JAP:DISCONNECTED'] - comment: '' - execution time: 0.0 - expected result: 4. all STA not get disconnected; target 1 SoftAP and STA both in - channel2; SoftAP in 20M, STA in 40M - initial condition: T3_PHY1 - initial condition description (auto): '1. target 1 and target 2 set to AP+STA mode, - target 3 set to STA mode - - 2. all interface of target 2,3 set to 11n ht40 - - 3. config softAP of target 1 and target 2' - module: WIFI MAC - steps: '1. target 1 STA set to 40M, SoftAP set to 20M - - 2. target 2 STA connect to ap_channel1_20 - - 3. target 1/3 STA connect to target 2/1 SoftAP - - 4. target 2 STA connect to ap_channel2_40' - sub module: Phy Mode - summary: SoftAP STA in channel1 20M, STA changed to channel2 40M - test environment: SSC_T3_PhyMode - test environment description (auto): '3 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with (HT20, channel1), (HT20, channel2), (HT40, channel1), (HT40, channel2). - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA+SoftAP dynamic channel switch test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0503 - SDK: ESP32_IDF - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:CONNECTED'] - - - SSC SSC3 sta -C -s -p - - ['R SSC3 C +JAP:CONNECTED'] - - - SSC SSC2 sta -C -s -p - - [''] - - - DELAY 10 - - ['P SSC2 C +JAP:CONNECTED', 'P SSC[1,3] NC +JAP:DISCONNECTED'] - comment: '' - execution time: 0.0 - expected result: 4. all STA not get disconnected; target 1 SoftAP and STA both in - channel2 20M - initial condition: T3_PHY1 - initial condition description (auto): '1. target 1 and target 2 set to AP+STA mode, - target 3 set to STA mode - - 2. all interface of target 2,3 set to 11n ht40 - - 3. config softAP of target 1 and target 2' - module: WIFI MAC - steps: '1. target 1 STA set to 40M, SoftAP set to 20M - - 2. target 2 STA connect to ap_channel1_40 - - 3. target 1/3 STA connect to target 2/1 SoftAP - - 4. target 2 STA connect to ap_channel2_20' - sub module: Phy Mode - summary: SoftAP STA in channel1, SoftAP 20M, STA 40M, STA changed to channel2 20M - test environment: SSC_T3_PhyMode - test environment description (auto): '3 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with (HT20, channel1), (HT20, channel2), (HT40, channel1), (HT40, channel2). - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA+SoftAP dynamic channel switch test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0501 - SDK: ESP32_IDF - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:CONNECTED'] - - - SSC SSC3 sta -C -s -p - - ['R SSC3 C +JAP:CONNECTED'] - - - SSC SSC2 sta -C -s -p - - [''] - - - DELAY 10 - - ['P SSC2 C +JAP:CONNECTED', 'P SSC[1,3] NC +JAP:DISCONNECTED'] - comment: '' - execution time: 0.0 - expected result: 4. all STA not get disconnected; target 1 SoftAP and STA both in - channel2 20M - initial condition: T3_PHY1 - initial condition description (auto): '1. target 1 and target 2 set to AP+STA mode, - target 3 set to STA mode - - 2. all interface of target 2,3 set to 11n ht40 - - 3. config softAP of target 1 and target 2' - module: WIFI MAC - steps: '1. target 1 STA and SoftAP set to 20M - - 2. target 2 STA connect to ap_channel1_20 - - 3. target 1/3 STA connect to target 2/1 SoftAP - - 4. target 2 STA connect to ap_channel2_20' - sub module: Phy Mode - summary: SoftAP STA in channel1 20M, STA changed to channel2 20M - test environment: SSC_T3_PhyMode - test environment description (auto): '3 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with (HT20, channel1), (HT20, channel2), (HT40, channel1), (HT40, channel2). - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA+SoftAP dynamic channel switch test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0506 - SDK: ESP32_IDF - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:CONNECTED'] - - - SSC SSC3 sta -C -s -p - - ['R SSC3 C +JAP:CONNECTED'] - - - SSC SSC2 sta -C -s -p - - [''] - - - DELAY 10 - - ['P SSC2 C +JAP:CONNECTED', 'P SSC[1,3] NC +JAP:DISCONNECTED'] - comment: '' - execution time: 0.0 - expected result: 4. all STA not get disconnected; target 1 SoftAP and STA both in - channel2 40M - initial condition: T3_PHY1 - initial condition description (auto): '1. target 1 and target 2 set to AP+STA mode, - target 3 set to STA mode - - 2. all interface of target 2,3 set to 11n ht40 - - 3. config softAP of target 1 and target 2' - module: WIFI MAC - steps: '1. target 1 STA and SoftAP set to 40M - - 2. target 2 STA connect to ap_channel1_40 - - 3. target 1/3 STA connect to target 2/1 SoftAP - - 4. target 2 STA connect to ap_channel2_40' - sub module: Phy Mode - summary: SoftAP STA in channel1, SoftAP 40M, STA 40M, STA changed to channel2 40M - test environment: SSC_T3_PhyMode - test environment description (auto): '3 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with (HT20, channel1), (HT20, channel2), (HT40, channel1), (HT40, channel2). - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA+SoftAP dynamic channel switch test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0505 - SDK: ESP32_IDF - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:CONNECTED'] - - - SSC SSC3 sta -C -s -p - - ['R SSC3 C +JAP:CONNECTED'] - - - SSC SSC2 sta -C -s -p - - [''] - - - DELAY 10 - - ['P SSC2 C +JAP:CONNECTED', 'P SSC[1,3] NC +JAP:DISCONNECTED'] - comment: '' - execution time: 0.0 - expected result: 4. all STA not get disconnected; target 1 SoftAP and STA both in - channel2; SoftAP in 20M, STA in 40M - initial condition: T3_PHY1 - initial condition description (auto): '1. target 1 and target 2 set to AP+STA mode, - target 3 set to STA mode - - 2. all interface of target 2,3 set to 11n ht40 - - 3. config softAP of target 1 and target 2' - module: WIFI MAC - steps: '1. target 1 STA set to 40M ,SoftAP set to 20M - - 2. target 2 STA connect to ap_channel1_40 - - 3. target 1/3 STA connect to target 2/1 SoftAP - - 4. target 2 STA connect to ap_channel2_20' - sub module: Phy Mode - summary: SoftAP STA in channel1, SoftAP 40M, STA 40M, STA changed to channel2 20M - test environment: SSC_T3_PhyMode - test environment description (auto): '3 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with (HT20, channel1), (HT20, channel2), (HT40, channel1), (HT40, channel2). - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA+SoftAP dynamic channel switch test - version: v1 (2015-8-15) - CI ready: 'Yes' ID: WIFI_CONN_0301 SDK: '8266_NonOS @@ -8557,310 +6589,6 @@ test cases: test point 1: basic function test point 2: use UDP SAP (socket/espconn API) with different parameter version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0205 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m g - - ['R SSC1 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC1 sta -C -s -p - - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 3. probe-req and assoc-req has xrates, no ht, cap.short_slot_time=1,rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54] - - 4. 20M - - 5. succeed - - 6. data rate in radiotap is in rates or xrates' - initial condition: STAM1 - initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a - TC with initial condition STAAP1 - module: WIFI MAC - steps: '1. target set to PHY mode 11bg - - 2. target connect to 11g AP - - 3. capture probe-req and assoc-req in step2 - - 4. check if config bandwidth correct - - 5. send data from target - - 6. capture data in step5' - sub module: Phy Mode - summary: target STA set as 11bg, join 11g external AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA PHY mode test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0204 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m g - - ['R SSC1 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC1 sta -C -s -p - - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 3. probe-req has xrates, no ht, cap.short_slot_time=1,rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54]; - - assoc-req has no erp/ht/xrates, cap.short_slot_time=1,rates=[1/2/5.5/11] - - 4. 20M - - 5. succeed - - 6. data rate in radiotap is in [1/2/5.5/11]' - initial condition: STAM1 - initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a - TC with initial condition STAAP1 - module: WIFI MAC - steps: '1. target set to PHY mode 11bg - - 2. target connect to 11b AP - - 3. capture probe-req and assoc-req in step2 - - 4. check if config bandwidth correct - - 5. send data from target - - 6. capture data in step5' - sub module: Phy Mode - summary: target STA set as 11bg, join 11b external AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA PHY mode test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0207 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC1 sta -C -s -p - - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 3. probe-req has xrates/ht, cap.short_slot_time=1,rates=[1/2/5.5/11/24/36/48/54]; - - assoc-req has no ht/xrates, cap.short_slot_time=1,rates=[1/2/5.5/11] - - 4. 20M - - 5. succeed - - 6. data rate in radiotap is in [1/2/5.5/11]' - initial condition: STAM1 - initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a - TC with initial condition STAAP1 - module: WIFI MAC - steps: '1. target set to PHY mode 11bgn - - 2. target connect to 11b AP - - 3. capture probe-req and assoc-req in step2 - - 4. check if config bandwidth correct - - 5. send data from target - - 6. capture data in step5' - sub module: Phy Mode - summary: target STA set as 11bgn, join 11b external AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA PHY mode test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0206 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m g - - ['R SSC1 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC1 sta -C -s -p - - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 3. probe-req and assoc-req has xrates, no ht, cap.short_slot_time=1,rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54] - - 4. 20M - - 5. succeed - - 6. data rate in radiotap is in rates or xrates' - initial condition: STAM1 - initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a - TC with initial condition STAAP1 - module: WIFI MAC - steps: '1. target set to PHY mode 11bg - - 2. target connect to 11n AP - - 3. capture probe-req and assoc-req in step2 - - 4. check if config bandwidth correct - - 5. send data from target - - 6. capture data in step5' - sub module: Phy Mode - summary: target STA set as 11bg, join 11n external AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA PHY mode test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0201 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m b - - ['R SSC1 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC1 sta -C -s -p - - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates!)(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 3. probe-req and assoc-req has no ht/xrates, cap.short_slot_time=1,rates=[1/2/5.5/11] - - 4. 20M - - 5. succeed - - 6. data rate in radiotap is in [1/2/5.5/11]' - initial condition: STAM1 - initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a - TC with initial condition STAAP1 - module: WIFI MAC - steps: '1. target set to PHY mode 11b - - 2. target connect to 11b AP - - 3. capture probe-req and assoc-req in step2 - - 4. check if config bandwidth correct - - 5. send data from target - - 6. capture data in step5' - sub module: Phy Mode - summary: target STA set as 11b, join 11b external AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA PHY mode test - version: v1 (2015-8-15) - CI ready: 'Yes' ID: ^TCPIP_DHCP_0102 SDK: '8266_NonOS @@ -8906,126 +6634,6 @@ test cases: test point 1: basic function test point 2: DHCP client function test version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0203 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m b - - ['R SSC1 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC1 sta -C -s -p - - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates!)(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 3. probe-req and assoc-reqhas no ht/xrates, cap.short_slot_time=1,rates=[1/2/5.5/11] - - 4. 20M - - 5. succeed - - 6. data rate in radiotap is in [1/2/5.5/11]' - initial condition: STAM1 - initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a - TC with initial condition STAAP1 - module: WIFI MAC - steps: '1. target set to PHY mode 11b - - 2. target connect to 11n AP - - 3. capture probe-req and assoc-req in step2 - - 4. check if config bandwidth correct - - 5. send data from target - - 6. capture data in step5' - sub module: Phy Mode - summary: target STA set as 11b, join 11b external AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA PHY mode test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0202 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m b - - ['R SSC1 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC1 sta -C -s -p - - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates!)(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 3. probe-req and assoc-reqhas no ht/xrates, cap.short_slot_time=1,rates=[1/2/5.5/11] - - 4. 20M - - 5. succeed - - 6. data rate in radiotap is in [1/2/5.5/11]' - initial condition: STAM1 - initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a - TC with initial condition STAAP1 - module: WIFI MAC - steps: '1. target set to PHY mode 11b - - 2. target connect to 11g AP - - 3. capture probe-req and assoc-req in step2 - - 4. check if config bandwidth correct - - 5. send data from target - - 6. capture data in step5' - sub module: Phy Mode - summary: target STA set as 11b, join 11g external AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA PHY mode test - version: v1 (2015-8-15) - CI ready: 'Yes' ID: ^TCPIP_DHCP_0103 SDK: '8266_NonOS @@ -9096,216 +6704,6 @@ test cases: test point 1: basic function test point 2: DHCP client function test version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0209 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC1 sta -C -s -p - - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities="")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") - PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 3. probe-req and assoc-req has xrates/ht, cap.short_slot_time=1,rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54] - - 4. 20M - - 5. succeed - - 6. data rate in radiotap is in rates or xrates or msc0-7' - initial condition: STAM1 - initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a - TC with initial condition STAAP1 - module: WIFI MAC - steps: '1. target set to PHY mode 11bgn - - 2. target connect to 11n AP - - 3. capture probe-req and assoc-req in step2 - - 4. check if config bandwidth correct - - 5. send data from target - - 6. capture data in step5' - sub module: Phy Mode - summary: target STA set as 11bgn, join 11n external AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA PHY mode test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0208 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC1 sta -C -s -p - - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 3. probe-req has xrates/ht, cap.short_slot_time=1,rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54]; - - assoc-req has xrates no ht, cap.short_slot_time=1,rates=[1/2/5.5/11], xrates=[24/36/48/54]; - - 4. 20M - - 5. succeed - - 6. data rate in radiotap is in rates or xrates' - initial condition: STAM1 - initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a - TC with initial condition STAAP1 - module: WIFI MAC - steps: '1. target set to PHY mode 11bgn - - 2. target connect to 11g AP - - 3. capture probe-req and assoc-req in step2 - - 4. check if config bandwidth correct - - 5. send data from target - - 6. capture data in step5' - sub module: Phy Mode - summary: target STA set as 11bgn, join 11g external AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA PHY mode test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_SCAN_0301 - SDK: ESP32_IDF - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 sta -S - - [''] - - - SSC SSC1 sta -S - - [P SSC1 C +SCANFAIL, 'P SSC1 P +SCAN:', R SSC1 C +SCANDONE] - comment: '' - execution time: 0.0 - expected result: '1. second scan failed - - 2. first scan succeed' - initial condition: STAM1 - initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a - TC with initial condition STAAP1 - module: WIFI MAC - steps: '1. do all channel scan - - 2. do scan before scan finished' - sub module: WIFI Scan - summary: reject scan request before scan finished - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: interaction - test point 2: Scan interact with other WiFi operation - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_SCAN_0303 - SDK: ESP32_IDF - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:OK'] - - - SSC SSC1 sta -S - - [P SSC1 C +SCANDONE, 'P SSC1 C +JAP:CONNECTED'] - - - SSC SSC1 sta -D - - ['R SSC1 C +QAP:OK'] - - - SSC SSC1 sta -S - - [''] - - - SSC SSC1 sta -C -s -p - - [P SSC1 C +SCANDONE, 'P SSC1 C +JAP:CONNECTED'] - comment: '' - execution time: 0.0 - expected result: '2. scan succeed, JAP succeed - - 5. JAP succeed, scan succeed' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. target 1 STA join AP - - 2. target 1 STA scan before JAP succeed - - 3. target 1 quite AP - - 4. target 1 scan - - 5. target 1 JAP before scan succeed' - sub module: WIFI Scan - summary: scan during JAP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: interaction - test point 2: Scan interact with other WiFi operation - version: v1 (2015-8-15) - CI ready: 'Yes' ID: ^WIFI_CONN_0801 SDK: '8266_NonOS @@ -9369,55 +6767,6 @@ test cases: test point 1: basic function test point 2: wifi auth changed event test version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_SCAN_0304 - SDK: ESP32_IDF - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:OK'] - - - SSC SSC1 sta -S - - [P SSC1 C +SCANDONE, 'P SSC2 C +JAP:CONNECTED'] - - - SSC SSC2 sta -D - - ['R SSC2 C +QAP:OK'] - - - SSC SSC1 sta -S - - [''] - - - SSC SSC2 sta -C -s -p - - [P SSC1 C +SCANDONE, 'P SSC2 C +JAP:CONNECTED'] - comment: '' - execution time: 0.0 - expected result: '2. scan succeed, JAP succeed - - 5. JAP succeed, scan succeed' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. target 2 STA join target 1 SoftAP - - 2. target 1 STA scan before target 2 JAP succeed - - 3. target 2 STA QAP - - 4. target 1 STA scan - - 5. target 2 STA JAP before target 1 STA scan succeed' - sub module: WIFI Scan - summary: scan during ext STA join SoftAP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: interaction - test point 2: Scan interact with other WiFi operation - version: v1 (2015-8-15) - CI ready: 'Yes' ID: ^TCPIP_UDP_0108 SDK: '8266_NonOS @@ -10465,17 +7814,17 @@ test cases: - - SSC SSC1 ap -S -s -p -t 3 -m 1 - ['R SSC1 C +SAP:OK'] - - SSC SSC2 sta -C -s -p 1234567890 - - ['R SSC2 C +JAP:DISCONNECTED,1,204'] + - ['R SSC2 RE JAP:DISCONNECTED,\d+,204'] - - SSC SSC2 sta -D - ['R SSC2 C +QAP:OK'] - - WIFI CONN - ['R PC_COM NC ERROR C +WIFICONN:OK'] - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:DISCONNECTED,1,5'] + - ['R SSC2 RE JAP:DISCONNECTED,\d+,5'] - - WIFI DISCONN - [P PC_COM C OK, 'R SSC2 C +JAP:CONNECTED'] - - SSC SSC1 ap -S -s -p -t 3 -m 1 - - ['P SSC1 C +SAP:OK', 'P SSC2 C +JAP:DISCONNECTED,5,4'] + - ['P SSC1 C +SAP:OK', 'P SSC2 RE JAP:DISCONNECTED,\d+,4'] comment: '' execution time: 0.0 expected result: '1. succeed @@ -10535,11 +7884,11 @@ test cases: - - SSC SSC1 sta -C -s -p - ['R SSC1 C +JAP:CONNECTED'] - - SSC SSC1 sta -D - - ['R SSC1 C +JAP:DISCONNECTED,0,8'] + - ['R SSC1 RE JAP:DISCONNECTED,\d+,8'] - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:DISCONNECTED,2,15'] + - ['R SSC1 RE JAP:DISCONNECTED,\d+,15'] - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:DISCONNECTED,1,201'] + - ['R SSC1 RE JAP:DISCONNECTED,\d+,201'] comment: '' execution time: 0.0 expected result: '1. disconnect event reason REASON_ASSOC_LEAVE @@ -10897,43 +8246,6 @@ test cases: test point 1: abnormal/special use test point 2: TCP connect and disconnect abnormal case version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0116 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 2 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK', 'R CAP PDU (Wlan.frame_ctrl.type_subtype="Management-Beacon")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities.short_gi_for_40="1")(Wlan.ie_list.ht_operation.second_channel_offset!="0","2")(Wlan.ie_list.ht_operation.sta_channel_width="1")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")'] - comment: '' - execution time: 0.0 - expected result: 1. beacon has erp/ht/xrates, cap.short_slot_time=1, ht_info.2nd_channel_offset=3,sta_channel_width=1, - rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54] - initial condition: APM1 - initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial - condition APSTA1 - module: WIFI MAC - steps: 1. target set to PHY mode ht40, capture beacon - sub module: Phy Mode - summary: SoftAP set as ht40, check beacon - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: SoftAP PHY mode test - version: v1 (2015-8-15) - CI ready: 'Yes' ID: ^TCPIP_DNS_0101 SDK: '8266_NonOS @@ -12119,61 +9431,6 @@ test cases: test point 1: basic function test point 2: use TCP SAP (socket/espconn API) with different parameter version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_SCAN_0302 - SDK: ESP32_IDF - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:CONNECTED'] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -S -s -i -p -n 1000000 -j 5 - - [''] - - - SSC SSC2 phy -S -o 1 -m b - - ['R SSC2 C +PHY:OK'] - - - SSC SSC2 sta -S -n - - [R SSC2 P ] - - - SSC SSC2 phy -S -o 1 -m g - - ['R SSC2 C +PHY:OK'] - - - SSC SSC2 sta -S -n - - [R SSC2 P ] - - - SSC SSC2 phy -S -o 1 -m n -b 20 - - ['R SSC2 C +PHY:OK'] - - - SSC SSC2 sta -S -n - - [R SSC2 P ] - - - SSC SSC2 phy -S -o 1 -m n -b 40 - - ['R SSC2 C +PHY:OK'] - - - SSC SSC2 sta -S -n - - [R SSC2 P ] - comment: '' - execution time: 0.0 - expected result: 3. target 2 able to scan AP - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. target 1 connect to AP - - 2. target 1 start sending UDP packets - - 3. target 2 scan in AP channel in 11b.g,n,ht40 mode' - sub module: WIFI Scan - summary: scan in congest channel - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: interaction - test point 2: Scan interact with other WiFi operation - version: v1 (2015-8-15) - CI ready: 'Yes' ID: TCPIP_ARP_0101 SDK: '8266_NonOS @@ -13937,62 +11194,6 @@ test cases: test point 1: basic function test point 2: DNS function test version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0303 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m b - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m b - - ['R SSC2 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s%20or%20wlan%20addr2%20%%s - - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC1 sta -C -s -p - - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities="")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") - PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp!)(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. check STA packet - - 3. check SoftAP packet' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. set softAP 11b, STA 11bgn - - 2. STA connect to ext AP - - 3. ext STA connect to SoftAP' - sub module: Phy Mode - summary: SoftAP 11b, STA 11bgn, get connected and join AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA+SoftAP PHY mode test - version: v1 (2015-8-15) - CI ready: 'Yes' ID: TCPIP_DHCP_0206 SDK: '8266_NonOS @@ -14890,11 +12091,11 @@ test cases: - - SSC SSC1 sta -C -s -p - ['R SSC1 C +JAP:CONNECTED'] - - SSC SSC1 sta -D - - ['R SSC1 C +JAP:DISCONNECTED,0,8'] + - ['R SSC1 RE JAP:DISCONNECTED,\d+,8'] - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:DISCONNECTED,2,15'] + - ['R SSC1 RE JAP:DISCONNECTED,\d+,15'] - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:DISCONNECTED,1,201'] + - ['R SSC1 RE JAP:DISCONNECTED,\d+,201'] comment: '' execution time: 0.0 expected result: '1. disconnect event reason REASON_ASSOC_LEAVE @@ -14970,289 +12171,6 @@ test cases: test point 1: abnormal/special use test point 2: handling ARP request version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_CONN_0903 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 sta -C -s -p bacfd - - ['R SSC1 C +JAP:DISCONNECTED,4,2'] - comment: '' - execution time: 0.0 - expected result: 1. disconect event reason REASON_AUTH_EXPIRE - initial condition: STAM1 - initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a - TC with initial condition STAAP1 - module: WIFI MAC - steps: 1. connect WEP ap with error password (valid wep password) - sub module: WIFI Connect - summary: test wifi disconnect reason REASON_AUTH_EXPIRE - test environment: SSC_T1_WEP - test environment description (auto): '1 SSC target connect with PC by UART. - - One WEP share key AP placed near SSC1.' - test point 1: basic function - test point 2: wifi disconnect reason test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0108 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 2 -m g - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m g - - ['R SSC2 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. assoc response has erp/xrates, no ht, cap.short_slot_time=1, rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54] - - 3. radiotap rates in rates and xrates' - initial condition: APM1 - initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial - condition APSTA1 - module: WIFI MAC - steps: '1. target set to PHY mode 11bg - - 2. 11bg STA connect to SoftAP, capture assoc response - - 3. ping, capture Data' - sub module: Phy Mode - summary: SoftAP set as 11bg, 11g STA connect to AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: SoftAP PHY mode test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0109 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 2 -m g - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m n -b 20 - - ['R SSC2 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. assoc response has erp/xrates, no ht, cap.short_slot_time=1, rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54] - - 3. radiotap rates in rates and xrates' - initial condition: APM1 - initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial - condition APSTA1 - module: WIFI MAC - steps: '1. target set to PHY mode 11bg - - 2. 11bgn STA connect to SoftAP, capture assoc response - - 3. ping, capture Data' - sub module: Phy Mode - summary: SoftAP set as 11bg, 11n STA connect to AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: SoftAP PHY mode test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0106 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 2 -m g - - ['R SSC1 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-Beacon")(Wlan.ie_list.erp="")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")'] - comment: '' - execution time: 0.0 - expected result: 1. beacon has erp/xrates, no ht, cap.short_slot_time=1, rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54] - initial condition: APM1 - initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial - condition APSTA1 - module: WIFI MAC - steps: 1. target set to PHY mode 11bg, capture beacon - sub module: Phy Mode - summary: SoftAP set as 11bg, check beacon - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: SoftAP PHY mode test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0107 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 2 -m g - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m b - - ['R SSC2 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp!)(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.supported_rates=""1/","2/","5.5/","11/")(Wlan.capability.short_slot_time="1")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. assoc response has erp/xrates, no ht, cap.short_slot_time=1, rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54] - - 3. radiotap rates in rates' - initial condition: APM1 - initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial - condition APSTA1 - module: WIFI MAC - steps: '1. target set to PHY mode 11bg - - 2. 11b STA connect to SoftAP, capture assoc response - - 3. ping, capture Data' - sub module: Phy Mode - summary: SoftAP set as 11bg, 11b STA connect to AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: SoftAP PHY mode test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_SCAN_0201 - SDK: ESP32_IDF - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m b - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 sta -S - - [R SSC1 P P P P ] - - - SSC SSC1 phy -S -o 1 -m g - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 sta -S - - [R SSC1 P P P P ] - - - SSC SSC1 phy -S -o 1 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 sta -S - - [R SSC1 P P P P ] - - - SSC SSC1 phy -S -o 1 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 sta -S - - [R SSC1 P P P P ] - comment: '' - execution time: 0.0 - expected result: '3. find all 3 ext APs - - 5. find all 3 ext APs - - 7. find all 3 ext APs - - 9. find all 3 ext APs' - initial condition: STAM1 - initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a - TC with initial condition STAAP1 - module: WIFI MAC - steps: '1. 3 ext APs in 11b, 11g, 11n mode - - 2. STA in 11b mode - - 3. do all channel scan - - 4. STA in 11g mode - - 5. do all channel scan - - 6. STA in 11n ht20 mode - - 7. do all channel scan - - 8. STA in 11n ht40 mode - - 9. do all channel scan' - sub module: WIFI Scan - summary: STA in differnt PHY mode to scan AP in different PHY mode - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: Scan in different mode and channel - version: v1 (2015-8-15) - CI ready: 'Yes' ID: WIFI_CONN_0503 SDK: '8266_NonOS @@ -15311,285 +12229,6 @@ test cases: test point 1: basic function test point 2: reconnect policy test version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0402 - SDK: ESP32_IDF - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m n -b 20 - - ['R SSC2 C +PHY:OK'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED'] - - - SSC SSC1 sta -C -s -p - - [''] - - - DELAY 10 - - ['P SSC2 NC +JAP:DISCONNECTED', 'P SSC1 C +JAP:CONNECTED'] - comment: '' - execution time: 0.0 - expected result: 3. SoftAP and STA in channel2, both bandwidth 20M, SoftAP not get - disconnected - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. SoftAP 11n ht20, in channel1, ext AP 11n ht20, in channel2 - - 2. AP get connected - - 3. STA connect to ext AP' - sub module: Phy Mode - summary: SoftAP ext AP in defferent channel, both bandwidth 20M, Softap get connected - than STA connect to AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA+SoftAP initial channel test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0401 - SDK: ESP32_IDF - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m n -b 20 - - ['R SSC2 C +PHY:OK'] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:CONNECTED'] - - - SSC SSC2 sta -C -s -p - - [''] - - - DELAY 10 - - ['P SSC1 NC +JAP:DISCONNECTED', 'P SSC2 C +JAP:CONNECTED'] - comment: '' - execution time: 0.0 - expected result: 3. SoftAP and STA in channel2, both bandwidth 20M, STA not disconnected - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. SoftAP 11n ht20, in channel1, ext AP 11n ht20, in channel2 - - 2. STA connect to ext AP - - 3. AP get connected' - sub module: Phy Mode - summary: SoftAP ext AP in defferent channel, both bandwidth 20M, STA connect to - AP then Softap get connected - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA+SoftAP initial channel test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0407 - SDK: ESP32_IDF - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m n -b 40 - - ['R SSC2 C +PHY:OK'] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:CONNECTED'] - - - SSC SSC2 sta -C -s -p - - [''] - - - DELAY 10 - - ['P SSC1 NC +JAP:DISCONNECTED', 'P SSC2 C +JAP:CONNECTED'] - comment: '' - execution time: 0.0 - expected result: 3. SoftAP and STA in channel2, SoftAP 40M, STA 20M, STA not disconnected - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. SoftAP 11n ht40, in channel1, ext AP 11n ht20, in channel2 - - 2. STA connect to ext AP - - 3. AP get connected' - sub module: Phy Mode - summary: SoftAP ext AP in defferent channel, SoftAP 40M, ext AP 20M, STA connect - to AP then Softap get connected - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA+SoftAP initial channel test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0406 - SDK: ESP32_IDF - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m n -b 40 - - ['R SSC2 C +PHY:OK'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED'] - - - SSC SSC1 sta -C -s -p - - [''] - - - DELAY 10 - - ['P SSC2 NC +JAP:DISCONNECTED', 'P SSC1 C +JAP:CONNECTED'] - comment: '' - execution time: 0.0 - expected result: 3. SoftAP and STA in channel2, both bandwidth 40M, SoftAP not get - disconnected - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. SoftAP 11n ht40, in channel1, ext AP 11n ht40, in channel2 - - 2. AP get connected - - 3. STA connect to ext AP' - sub module: Phy Mode - summary: SoftAP ext AP in defferent channel, both bandwidth 40M, Softap get connected - than STA connect to AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA+SoftAP initial channel test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0405 - SDK: ESP32_IDF - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m n -b 40 - - ['R SSC2 C +PHY:OK'] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:CONNECTED'] - - - SSC SSC2 sta -C -s -p - - [''] - - - DELAY 10 - - ['P SSC1 NC +JAP:DISCONNECTED', 'P SSC2 C +JAP:CONNECTED'] - comment: '' - execution time: 0.0 - expected result: 3. SoftAP and STA in channel2, both bandwidth 40M, STA not disconnected - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. SoftAP 11n ht40, in channel1, ext AP 11n ht40, in channel2 - - 2. STA connect to ext AP - - 3. AP get connected' - sub module: Phy Mode - summary: SoftAP ext AP in defferent channel, both bandwidth 40M, STA connect to - AP then Softap get connected - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA+SoftAP initial channel test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0404 - SDK: ESP32_IDF - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m n -b 20 - - ['R SSC2 C +PHY:OK'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED'] - - - SSC SSC1 sta -C -s -p - - [''] - - - DELAY 10 - - ['P SSC2 NC +JAP:DISCONNECTED', 'P SSC1 C +JAP:CONNECTED'] - comment: '' - execution time: 0.0 - expected result: 3. SoftAP and STA in channel2, SoftAP 20M, STA 40M, SoftAP not - get disconnected - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. SoftAP 11n ht20, in channel1, ext AP 11n ht40, in channel2 - - 2. AP get connected - - 3. STA connect to ext AP' - sub module: Phy Mode - summary: SoftAP ext AP in defferent channel, SoftAP 20M, ext AP 40M, Softap get - connected than STA connect to AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA+SoftAP initial channel test - version: v1 (2015-8-15) - CI ready: 'Yes' ID: ^TCPIP_UDP_0112 SDK: '8266_NonOS @@ -15630,53 +12269,6 @@ test cases: test point 1: basic function test point 2: use UDP SAP (socket/espconn API) with different parameter version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0408 - SDK: ESP32_IDF - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m n -b 40 - - ['R SSC2 C +PHY:OK'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED'] - - - SSC SSC1 sta -C -s -p - - [''] - - - DELAY 10 - - ['P SSC2 NC +JAP:DISCONNECTED', 'P SSC1 C +JAP:CONNECTED'] - comment: '' - execution time: 0.0 - expected result: 3. SoftAP and STA in channel2, SoftAP 40M, STA 20M, SoftAP not - get disconnected - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. SoftAP 11n ht40, in channel1, ext AP 11n ht20, in channel2 - - 2. AP get connected - - 3. STA connect to ext AP' - sub module: Phy Mode - summary: SoftAP ext AP in defferent channel, SoftAP 40M, ext AP 20M, Softap get - connected than STA connect to AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA+SoftAP initial channel test - version: v1 (2015-8-15) - CI ready: 'Yes' ID: ^TCPIP_UDP_0114 SDK: '8266_NonOS @@ -15717,315 +12309,6 @@ test cases: test point 1: basic function test point 2: use UDP SAP (socket/espconn API) with different parameter version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0214 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC1 sta -C -s -p - - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities.short_gi_for_40="1")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") - PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 3. probe-req and assoc-req has xrates/ht, ht_cap.short_gi40=1, 40width=1, cap.short_slot_time=1,rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54]; - - 4. 40M - - 5. succeed - - 6. data rate in radiotap is in rates or xrates' - initial condition: STAM1 - initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a - TC with initial condition STAAP1 - module: WIFI MAC - steps: '1. target set to PHY mode 11bgn ht40 - - 2. target connect to 11n ht40 AP - - 3. capture probe-req and assoc-req in step2 - - 4. check if config bandwidth correct - - 5. send data from target - - 6. capture data in step5' - sub module: Phy Mode - summary: target STA set as 11bgn ht40,join ht40 external AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA PHY mode test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0212 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC1 sta -C -s -p - - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 3. probe-req has xrates/ht, ht_cap.short_gi40=1, 40width=1, cap.short_slot_time=1,rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54]; - - assoc-req has xrates no ht, cap.short_slot_time=1,rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54]; - - 4. 20M - - 5. succeed - - 6. data rate in radiotap is in rates or xrates' - initial condition: STAM1 - initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a - TC with initial condition STAAP1 - module: WIFI MAC - steps: '1. target set to PHY mode 11bgn ht40 - - 2. target connect to 11g AP - - 3. capture probe-req and assoc-req in step2 - - 4. check if config bandwidth correct - - 5. send data from target - - 6. capture data in step5' - sub module: Phy Mode - summary: target STA set as 11bgn ht40, join 11g external AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA PHY mode test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0213 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC1 sta -C -s -p - - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities="")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") - PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 3. probe-req has xrates/ht, ht_cap.short_gi40=1, 40width=1, cap.short_slot_time=1,rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54]; - - assoc-req has xrates/ht, cap.short_slot_time=1,rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54]; - - 4. 20M - - 5. succeed - - 6. data rate in radiotap is in rates or xrates' - initial condition: STAM1 - initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a - TC with initial condition STAAP1 - module: WIFI MAC - steps: '1. target set to PHY mode 11bgn ht40 - - 2. target connect to 11n AP - - 3. capture probe-req and assoc-req in step2 - - 4. check if config bandwidth correct - - 5. send data from target - - 6. capture data in step5' - sub module: Phy Mode - summary: target STA set as 11bgn ht40, join 11n external AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA PHY mode test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0210 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC1 sta -C -s -p - - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities="")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")(Wlan.capability.short_slot_time="1")', - 'P CAP OR 2 PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M","6M","9M","12M","18M","24M","36M","48M","54M") - PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.msc="")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 3. probe-req and assoc-req has xrates/ht, cap.short_slot_time=1,rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54] - - 4. 20M - - 5. succeed - - 6. data rate in radiotap is in rates or xrates or msc0-7' - initial condition: STAM1 - initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a - TC with initial condition STAAP1 - module: WIFI MAC - steps: '1. target set to PHY mode 11bgn - - 2. target connect to 11n ht40 AP - - 3. capture probe-req and assoc-req in step2 - - 4. check if config bandwidth correct - - 5. send data from target - - 6. capture data in step5' - sub module: Phy Mode - summary: target STA set as 11bgn, join ht40 external AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA PHY mode test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0211 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC1 sta -C -s -p - - ['P SSC1 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-ProbeReq")(Wlan.ie_list.extended_supported_rates+Wlan.ie_list.supported_rates="24/","36/","48/","54/","1/","2/","5.5/","11/","6/","9/","12/","18/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocReq")(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 3. probe-req has xrates/ht, ht_cap.short_gi40=1, 40width=1, cap.short_slot_time=1,rates+xrates=[1/2/5.5/11/6/9/12/18/24/36/48/54]; - - assoc-req has no ht/xrates, cap.short_slot_time=1,rates=[1/2/5.5/11] - - 4. 20M - - 5. succeed - - 6. data rate in radiotap is in [1/2/5.5/11]' - initial condition: STAM1 - initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a - TC with initial condition STAAP1 - module: WIFI MAC - steps: '1. target set to PHY mode 11bgn ht40 - - 2. target connect to 11b AP - - 3. capture probe-req and assoc-req in step2 - - 4. check if config bandwidth correct - - 5. send data from target - - 6. capture data in step5' - sub module: Phy Mode - summary: target STA set as 11bgn ht40, join 11b external AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA PHY mode test - version: v1 (2015-8-15) - CI ready: 'Yes' ID: ^WIFI_CONN_0104 SDK: '8266_NonOS @@ -16399,61 +12682,6 @@ test cases: test point 1: basic function test point 2: SAP/JAP with different config version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0504 - SDK: ESP32_IDF - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:CONNECTED'] - - - SSC SSC3 sta -C -s -p - - ['R SSC3 C +JAP:CONNECTED'] - - - SSC SSC2 sta -C -s -p - - [''] - - - DELAY 10 - - ['P SSC2 C +JAP:CONNECTED', 'P SSC[1,3] NC +JAP:DISCONNECTED'] - comment: '' - execution time: 0.0 - expected result: 4. all STA not get disconnected; target 1 SoftAP and STA both in - channel2 20M - initial condition: T3_PHY1 - initial condition description (auto): '1. target 1 and target 2 set to AP+STA mode, - target 3 set to STA mode - - 2. all interface of target 2,3 set to 11n ht40 - - 3. config softAP of target 1 and target 2' - module: WIFI MAC - steps: '1. target 1 STA and SoftAP set to 40M - - 2. target 2 STA connect to ap_channel1_40 - - 3. target 1/3 STA connect to target 2/1 SoftAP - - 4. target 2 STA connect to ap_channel2_20' - sub module: Phy Mode - summary: SoftAP STA in channel1, SoftAP 20M, STA 40M, STA changed to channel2 40M - test environment: SSC_T3_PhyMode - test environment description (auto): '3 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with (HT20, channel1), (HT20, channel2), (HT40, channel1), (HT40, channel2). - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA+SoftAP dynamic channel switch test - version: v1 (2015-8-15) - CI ready: 'Yes' ID: ^TCPIP_IP_0101 SDK: '8266_NonOS @@ -16512,46 +12740,6 @@ test cases: test point 1: basic function test point 2: set and query static IP version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^WIFI_CONN_0702 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:OK', 'R SSC1 C +JAP:DISCONNECTED,3'] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:OK', 'R SSC1 C +JAP:DISCONNECTED,2'] - comment: '' - execution time: 0.0 - expected result: '1. get status AP not exist in disconnect event - - 2. get status wrong password in disconnect event' - initial condition: STAAP1 - initial condition description (auto): testing sta on sta + ap mode, quit AP (autogen - by STAM1) - module: WIFI MAC - steps: '1. sta connect to ap not exist - - 2. sta connect to ap with wrong password' - sub module: WIFI Connect - summary: check wifi status wrong password, no ap found - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: wifi connect status check - version: v1 (2016-8-15) - CI ready: 'Yes' ID: WIFI_CONN_0801 SDK: '8266_NonOS @@ -17276,55 +13464,6 @@ test cases: test point 1: basic function test point 2: use TCP SAP (socket/espconn API) with different parameter version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0104 - SDK: ESP32_IDF - Test App: SSC - allow fail: 2/3 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 2 -m b - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m n -b 20 - - ['R SSC2 C +PHY:OK'] - - - STRING wlan%20addr2%20%%s - - [R PC_COM C OK] - - - 'NIC CAP START wlan_capture ' - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED', 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Management-AssocRes")(Wlan.ie_list.erp!)(Wlan.ie_list.ht_capabilities!)(Wlan.ie_list.extended_supported_rates!)(Wlan.capability.short_slot_time="1")(Wlan.ie_list.supported_rates="1/","2/","5.5/","11/")', - 'P CAP PDU (Wlan.frame_ctrl.type_subtype="Data")(Wlan.radiotap.rate<"1M","2M","5.5M","11M")'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. assoc response has no erp/xrates/ht, cap.short_slot_time=1, rates=[1/2/5/5/11] - - 3. radiotap rates in [1/2/5/5/11]' - initial condition: APM1 - initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial - condition APSTA1 - module: WIFI MAC - steps: '1. target set to PHY mode 11b - - 2. 11bgn STA connect to SoftAP, capture assoc response - - 3. ping, capture Data' - sub module: Phy Mode - summary: SoftAP set as 11b, 11n STA connect to AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: SoftAP PHY mode test - version: v1 (2015-8-15) - CI ready: 'Yes' ID: TCPIP_TCP_0113 SDK: '8266_NonOS From d7db3e6a35f3877577ed7eb53c028b321bb59dcc Mon Sep 17 00:00:00 2001 From: He Yin Ling Date: Wed, 28 Sep 2016 20:11:42 +0800 Subject: [PATCH 068/343] build SSC should also use variable for server name --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f422f9f250..a258da418a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -62,7 +62,7 @@ build_ssc: expire_in: 6 mos script: - - git clone ssh://git@gitlab.espressif.cn:27227/yinling/SSC.git + - git clone $GITLAB_SSH_SERVER/yinling/SSC.git - cd SSC - make defconfig - chmod +x gen_misc_ng.sh From 4929534448cbcc711bb180ce29d3ecc8a4df37e4 Mon Sep 17 00:00:00 2001 From: Yinling Date: Thu, 29 Sep 2016 13:38:29 +0800 Subject: [PATCH 069/343] add gitlab key in test template job --- .gitlab-ci.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a258da418a..952cba7d78 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -64,6 +64,7 @@ build_ssc: script: - git clone $GITLAB_SSH_SERVER/yinling/SSC.git - cd SSC + - git checkout ${CI_BUILD_REF_NAME} || echo "Using SSC default branch..." - make defconfig - chmod +x gen_misc_ng.sh - ./gen_misc_ng.sh @@ -137,8 +138,17 @@ push_master_to_github: expire_in: 6 mos script: + # add gitlab ssh key + - mkdir -p ~/.ssh + - chmod 700 ~/.ssh + - echo -n $GITLAB_KEY > ~/.ssh/id_rsa_base64 + - base64 --decode --ignore-garbage ~/.ssh/id_rsa_base64 > ~/.ssh/id_rsa + - chmod 600 ~/.ssh/id_rsa + - echo -e "Host gitlab.espressif.cn\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config + # clone test bench - git clone $GITLAB_SSH_SERVER/yinling/auto_test_script.git - cd auto_test_script + # run test - python CIRunner.py -l $LOG_PATH -c $CONFIG_FILE -e $LOCAL_ENV_CONFIG_PATH -t $TEST_CASE_FILE_PATH bin_path $APP_NAME $BIN_PATH @@ -151,8 +161,17 @@ push_master_to_github: script: # must be night build triggers, otherwise exit without test - test $NIGHT_BUILD != "Yes" || exit 0 + # add gitlab ssh key + - mkdir -p ~/.ssh + - chmod 700 ~/.ssh + - echo -n $GITLAB_KEY > ~/.ssh/id_rsa_base64 + - base64 --decode --ignore-garbage ~/.ssh/id_rsa_base64 > ~/.ssh/id_rsa + - chmod 600 ~/.ssh/id_rsa + - echo -e "Host gitlab.espressif.cn\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config + # clone test bench - git clone $GITLAB_SSH_SERVER/yinling/auto_test_script.git - cd auto_test_script + # run test - python CIRunner.py -l $LOG_PATH -c $CONFIG_FILE -e $LOCAL_ENV_CONFIG_PATH -t $TEST_CASE_FILE_PATH bin_path $APP_NAME $BIN_PATH Function_SYS_01: From 9b72441b450a0320c0ebe5d21e5ffe3c1fd97bc2 Mon Sep 17 00:00:00 2001 From: Yinling Date: Thu, 29 Sep 2016 14:14:19 +0800 Subject: [PATCH 070/343] Test cases use libpcap or libnet are not CI ready now: 1. It need rebuild native lib 2. require root permission --- .gitlab-ci.yml | 40 --- .../test/CIConfigs/Function_TCPIP_01.yml | 12 +- .../test/CIConfigs/Function_TCPIP_02.yml | 12 +- .../test/CIConfigs/Function_TCPIP_03.yml | 12 +- .../test/CIConfigs/Function_TCPIP_04.yml | 12 +- .../test/CIConfigs/Function_TCPIP_05.yml | 7 +- .../test/CIConfigs/Function_WIFI_07.yml | 10 - .../test/CIConfigs/Function_WIFI_08.yml | 10 - .../test/CIConfigs/Function_WIFI_09.yml | 10 - .../test/CIConfigs/Function_WIFI_10.yml | 10 - .../test/CIConfigs/Function_WIFI_11.yml | 10 - components/test/TestCaseAll.yml | 274 ------------------ 12 files changed, 27 insertions(+), 392 deletions(-) delete mode 100644 components/test/CIConfigs/Function_WIFI_07.yml delete mode 100644 components/test/CIConfigs/Function_WIFI_08.yml delete mode 100644 components/test/CIConfigs/Function_WIFI_09.yml delete mode 100644 components/test/CIConfigs/Function_WIFI_10.yml delete mode 100644 components/test/CIConfigs/Function_WIFI_11.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 952cba7d78..89269aa425 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -337,43 +337,3 @@ Function_TCPIP_12: - SSC_T1_2 before_script: - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_TCPIP_12.yml - -Function_WIFI_07: - <<: *test_template - tags: - - ESP32_IDF - - SSC_T2_PhyMode - before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_WIFI_07.yml - -Function_WIFI_08: - <<: *test_template - tags: - - ESP32_IDF - - SSC_T2_PhyMode - before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_WIFI_08.yml - -Function_WIFI_09: - <<: *test_template - tags: - - ESP32_IDF - - SSC_T2_PhyMode - before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_WIFI_09.yml - -Function_WIFI_10: - <<: *test_template - tags: - - ESP32_IDF - - SSC_T2_PhyMode - before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_WIFI_10.yml - -Function_WIFI_11: - <<: *test_template - tags: - - ESP32_IDF - - SSC_T2_PhyMode - before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_WIFI_11.yml diff --git a/components/test/CIConfigs/Function_TCPIP_01.yml b/components/test/CIConfigs/Function_TCPIP_01.yml index 29542e9fe3..e947b0c5c7 100644 --- a/components/test/CIConfigs/Function_TCPIP_01.yml +++ b/components/test/CIConfigs/Function_TCPIP_01.yml @@ -2,9 +2,9 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC2, SSC1] Filter: - Add: - ID: [TCPIP_ARP_0202, ^TCPIP_DHCP_0302, ^TCPIP_DHCP_0301, ^TCPIP_UDP_0113, TCPIP_DHCP_0302, - TCPIP_DHCP_0301, TCPIP_ARP_0204, TCPIP_TCP_0412, TCPIP_TCP_0403, TCPIP_TCP_0402, - TCPIP_TCP_0401, TCPIP_TCP_0407, TCPIP_TCP_0406, TCPIP_TCP_0404, TCPIP_TCP_0408, - ^TCPIP_TCP_0202, TCPIP_TCP_0110, ^TCPIP_TCP_0203, TCPIP_DHCP_0101, TCPIP_DHCP_0103, - TCPIP_DHCP_0102, TCPIP_IP_0101, TCPIP_IP_0102, ^TCPIP_IGMP_0102, ^TCPIP_IGMP_0101, - ^TCPIP_IGMP_0104, TCPIP_IGMP_0104, TCPIP_IGMP_0103, TCPIP_IGMP_0102, TCPIP_IGMP_0101] + ID: [^TCPIP_DHCP_0302, ^TCPIP_DHCP_0301, ^TCPIP_UDP_0113, TCPIP_DHCP_0302, TCPIP_DHCP_0301, + TCPIP_TCP_0412, TCPIP_TCP_0403, TCPIP_TCP_0402, TCPIP_TCP_0401, TCPIP_TCP_0407, + TCPIP_TCP_0406, TCPIP_TCP_0404, TCPIP_TCP_0408, ^TCPIP_TCP_0202, TCPIP_TCP_0110, + ^TCPIP_TCP_0203, TCPIP_DHCP_0101, TCPIP_DHCP_0103, TCPIP_DHCP_0102, TCPIP_IP_0101, + TCPIP_IP_0102, ^TCPIP_IGMP_0102, ^TCPIP_IGMP_0101, ^TCPIP_IGMP_0104, TCPIP_IGMP_0104, + TCPIP_IGMP_0103, TCPIP_IGMP_0102, TCPIP_IGMP_0101, ^TCPIP_UDP_0201, TCPIP_UDP_0108] diff --git a/components/test/CIConfigs/Function_TCPIP_02.yml b/components/test/CIConfigs/Function_TCPIP_02.yml index e40f69db59..6a3cb08d6d 100644 --- a/components/test/CIConfigs/Function_TCPIP_02.yml +++ b/components/test/CIConfigs/Function_TCPIP_02.yml @@ -2,9 +2,9 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC2, SSC1] Filter: - Add: - ID: [^TCPIP_UDP_0201, TCPIP_UDP_0108, TCPIP_UDP_0106, TCPIP_UDP_0107, TCPIP_UDP_0105, - TCPIP_UDP_0101, TCPIP_IGMP_0204, TCPIP_IGMP_0201, TCPIP_IGMP_0202, TCPIP_IGMP_0203, - ^TCPIP_TCP_0404, ^TCPIP_TCP_0406, ^TCPIP_TCP_0407, ^TCPIP_TCP_0401, ^TCPIP_TCP_0402, - ^TCPIP_TCP_0403, ^TCPIP_TCP_0408, TCPIP_UDP_0201, ^TCPIP_TCP_0101, ^TCPIP_TCP_0103, - ^TCPIP_TCP_0102, ^TCPIP_TCP_0105, ^TCPIP_TCP_0104, ^TCPIP_TCP_0107, ^TCPIP_TCP_0106, - ^TCPIP_DHCP_0210, ^TCPIP_DHCP_0211, TCPIP_TCP_0212, TCPIP_TCP_0210, ^TCPIP_TCP_0210] + ID: [TCPIP_UDP_0106, TCPIP_UDP_0107, TCPIP_UDP_0105, TCPIP_UDP_0101, TCPIP_IGMP_0204, + TCPIP_IGMP_0201, TCPIP_IGMP_0202, TCPIP_IGMP_0203, ^TCPIP_TCP_0404, ^TCPIP_TCP_0406, + ^TCPIP_TCP_0407, ^TCPIP_TCP_0401, ^TCPIP_TCP_0402, ^TCPIP_TCP_0403, ^TCPIP_TCP_0408, + TCPIP_UDP_0201, ^TCPIP_TCP_0101, ^TCPIP_TCP_0103, ^TCPIP_TCP_0102, ^TCPIP_TCP_0105, + ^TCPIP_TCP_0104, ^TCPIP_TCP_0107, ^TCPIP_TCP_0106, ^TCPIP_DHCP_0210, ^TCPIP_DHCP_0211, + TCPIP_TCP_0212, TCPIP_TCP_0210, ^TCPIP_TCP_0210, ^TCPIP_TCP_0212, TCPIP_DHCP_0211] diff --git a/components/test/CIConfigs/Function_TCPIP_03.yml b/components/test/CIConfigs/Function_TCPIP_03.yml index 79107aca8c..0c4ac37524 100644 --- a/components/test/CIConfigs/Function_TCPIP_03.yml +++ b/components/test/CIConfigs/Function_TCPIP_03.yml @@ -2,9 +2,9 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC2, SSC1] Filter: - Add: - ID: [^TCPIP_TCP_0212, TCPIP_DHCP_0211, TCPIP_DHCP_0210, TCPIP_UDP_0202, TCPIP_TCP_0411, - ^TCPIP_IP_0102, ^TCPIP_UDP_0105, ^TCPIP_UDP_0107, ^TCPIP_UDP_0106, ^TCPIP_UDP_0101, - ^TCPIP_DHCP_0102, ^TCPIP_DHCP_0103, ^TCPIP_UDP_0108, ^TCPIP_IGMP_0201, ^TCPIP_IGMP_0203, - ^TCPIP_IGMP_0202, ^TCPIP_IGMP_0204, TCPIP_UDP_0114, TCPIP_UDP_0113, TCPIP_UDP_0112, - ^TCPIP_TCP_0201, ^TCPIP_TCP_0206, ^TCPIP_TCP_0207, TCPIP_TCP_0501, TCPIP_TCP_0106, - TCPIP_TCP_0107, TCPIP_TCP_0104, TCPIP_TCP_0105, TCPIP_TCP_0102, TCPIP_TCP_0103] + ID: [TCPIP_DHCP_0210, TCPIP_UDP_0202, TCPIP_TCP_0411, ^TCPIP_IP_0102, ^TCPIP_UDP_0105, + ^TCPIP_UDP_0107, ^TCPIP_UDP_0106, ^TCPIP_UDP_0101, ^TCPIP_DHCP_0102, ^TCPIP_DHCP_0103, + ^TCPIP_UDP_0108, ^TCPIP_IGMP_0201, ^TCPIP_IGMP_0203, ^TCPIP_IGMP_0202, ^TCPIP_IGMP_0204, + TCPIP_UDP_0114, TCPIP_UDP_0113, TCPIP_UDP_0112, ^TCPIP_TCP_0201, ^TCPIP_TCP_0206, + ^TCPIP_TCP_0207, TCPIP_TCP_0106, TCPIP_TCP_0107, TCPIP_TCP_0104, TCPIP_TCP_0105, + TCPIP_TCP_0102, TCPIP_TCP_0103, TCPIP_TCP_0101, ^TCPIP_TCP_0116, ^TCPIP_TCP_0114] diff --git a/components/test/CIConfigs/Function_TCPIP_04.yml b/components/test/CIConfigs/Function_TCPIP_04.yml index 8d20569c1d..f8bdb264b9 100644 --- a/components/test/CIConfigs/Function_TCPIP_04.yml +++ b/components/test/CIConfigs/Function_TCPIP_04.yml @@ -2,9 +2,9 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC2, SSC1] Filter: - Add: - ID: [TCPIP_TCP_0101, ^TCPIP_TCP_0116, ^TCPIP_TCP_0114, ^TCPIP_TCP_0115, ^TCPIP_TCP_0112, - ^TCPIP_TCP_0113, ^TCPIP_TCP_0110, ^TCPIP_TCP_0111, TCPIP_ARP_0101, ^TCPIP_DHCP_0209, - ^TCPIP_DHCP_0208, ^TCPIP_DHCP_0207, ^TCPIP_DHCP_0206, ^TCPIP_DHCP_0205, ^TCPIP_DHCP_0204, - ^TCPIP_DHCP_0203, ^TCPIP_DHCP_0202, ^TCPIP_DHCP_0201, TCPIP_TCP_0204, TCPIP_TCP_0207, - TCPIP_TCP_0206, TCPIP_TCP_0201, ^TCPIP_DHCP_0101, TCPIP_TCP_0203, TCPIP_TCP_0202, - TCPIP_TCP_0208, TCPIP_DHCP_0206, TCPIP_DHCP_0207, TCPIP_DHCP_0204, TCPIP_DHCP_0205] + ID: [^TCPIP_TCP_0115, ^TCPIP_TCP_0112, ^TCPIP_TCP_0113, ^TCPIP_TCP_0110, ^TCPIP_TCP_0111, + ^TCPIP_DHCP_0209, ^TCPIP_DHCP_0208, ^TCPIP_DHCP_0207, ^TCPIP_DHCP_0206, ^TCPIP_DHCP_0205, + ^TCPIP_DHCP_0204, ^TCPIP_DHCP_0203, ^TCPIP_DHCP_0202, ^TCPIP_DHCP_0201, TCPIP_TCP_0204, + TCPIP_TCP_0207, TCPIP_TCP_0206, TCPIP_TCP_0201, ^TCPIP_DHCP_0101, TCPIP_TCP_0203, + TCPIP_TCP_0202, TCPIP_TCP_0208, TCPIP_DHCP_0206, TCPIP_DHCP_0207, TCPIP_DHCP_0204, + TCPIP_DHCP_0205, TCPIP_DHCP_0202, TCPIP_DHCP_0203, ^TCPIP_TCP_0204, TCPIP_DHCP_0201] diff --git a/components/test/CIConfigs/Function_TCPIP_05.yml b/components/test/CIConfigs/Function_TCPIP_05.yml index 7ff1bbf8ce..21b3b7a6d8 100644 --- a/components/test/CIConfigs/Function_TCPIP_05.yml +++ b/components/test/CIConfigs/Function_TCPIP_05.yml @@ -2,8 +2,7 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC2, SSC1] Filter: - Add: - ID: [TCPIP_DHCP_0202, TCPIP_DHCP_0203, ^TCPIP_TCP_0204, TCPIP_DHCP_0201, ^TCPIP_TCP_0208, - TCPIP_DHCP_0208, TCPIP_DHCP_0209, ^TCPIP_TCP_0412, ^TCPIP_TCP_0411, TCPIP_ARP_0203, + ID: [^TCPIP_TCP_0208, TCPIP_DHCP_0208, TCPIP_DHCP_0209, ^TCPIP_TCP_0412, ^TCPIP_TCP_0411, ^TCPIP_UDP_0112, ^TCPIP_UDP_0114, ^TCPIP_UDP_0202, ^TCPIP_IGMP_0103, ^TCPIP_IP_0101, - TCPIP_ARP_0201, TCPIP_TCP_0115, TCPIP_TCP_0114, TCPIP_TCP_0116, TCPIP_TCP_0111, - TCPIP_TCP_0113, TCPIP_TCP_0112] + TCPIP_TCP_0115, TCPIP_TCP_0114, TCPIP_TCP_0116, TCPIP_TCP_0111, TCPIP_TCP_0113, + TCPIP_TCP_0112] diff --git a/components/test/CIConfigs/Function_WIFI_07.yml b/components/test/CIConfigs/Function_WIFI_07.yml deleted file mode 100644 index 22840fa7af..0000000000 --- a/components/test/CIConfigs/Function_WIFI_07.yml +++ /dev/null @@ -1,10 +0,0 @@ -Config: {execute count: 1, execute order: in order} -DUT: [SSC2, SSC1] -Filter: -- Add: - ID: [WIFI_PHY_0105, WIFI_PHY_0105, WIFI_PHY_0105, WIFI_PHY_0102, WIFI_PHY_0102, - WIFI_PHY_0102, WIFI_PHY_0103, WIFI_PHY_0103, WIFI_PHY_0103, WIFI_PHY_0101, WIFI_PHY_0101, - WIFI_PHY_0101, WIFI_PHY_0313, WIFI_PHY_0313, WIFI_PHY_0313, WIFI_PHY_0312, WIFI_PHY_0312, - WIFI_PHY_0312, WIFI_PHY_0311, WIFI_PHY_0311, WIFI_PHY_0311, WIFI_PHY_0310, WIFI_PHY_0310, - WIFI_PHY_0310, WIFI_PHY_0316, WIFI_PHY_0316, WIFI_PHY_0316, WIFI_PHY_0315, WIFI_PHY_0315, - WIFI_PHY_0315] diff --git a/components/test/CIConfigs/Function_WIFI_08.yml b/components/test/CIConfigs/Function_WIFI_08.yml deleted file mode 100644 index 640330233a..0000000000 --- a/components/test/CIConfigs/Function_WIFI_08.yml +++ /dev/null @@ -1,10 +0,0 @@ -Config: {execute count: 1, execute order: in order} -DUT: [SSC2, SSC1] -Filter: -- Add: - ID: [WIFI_PHY_0314, WIFI_PHY_0314, WIFI_PHY_0314, WIFI_PHY_0308, WIFI_PHY_0308, - WIFI_PHY_0308, WIFI_PHY_0309, WIFI_PHY_0309, WIFI_PHY_0309, WIFI_PHY_0304, WIFI_PHY_0304, - WIFI_PHY_0304, WIFI_PHY_0305, WIFI_PHY_0305, WIFI_PHY_0305, WIFI_PHY_0306, WIFI_PHY_0306, - WIFI_PHY_0306, WIFI_PHY_0307, WIFI_PHY_0307, WIFI_PHY_0307, WIFI_PHY_0301, WIFI_PHY_0301, - WIFI_PHY_0301, WIFI_PHY_0302, WIFI_PHY_0302, WIFI_PHY_0302, WIFI_PHY_0110, WIFI_PHY_0110, - WIFI_PHY_0110] diff --git a/components/test/CIConfigs/Function_WIFI_09.yml b/components/test/CIConfigs/Function_WIFI_09.yml deleted file mode 100644 index a51560fd60..0000000000 --- a/components/test/CIConfigs/Function_WIFI_09.yml +++ /dev/null @@ -1,10 +0,0 @@ -Config: {execute count: 1, execute order: in order} -DUT: [SSC2, SSC1] -Filter: -- Add: - ID: [WIFI_PHY_0113, WIFI_PHY_0113, WIFI_PHY_0113, WIFI_PHY_0120, WIFI_PHY_0120, - WIFI_PHY_0120, WIFI_PHY_0119, WIFI_PHY_0119, WIFI_PHY_0119, WIFI_PHY_0118, WIFI_PHY_0118, - WIFI_PHY_0118, WIFI_PHY_0115, WIFI_PHY_0115, WIFI_PHY_0115, WIFI_PHY_0114, WIFI_PHY_0114, - WIFI_PHY_0114, WIFI_PHY_0117, WIFI_PHY_0117, WIFI_PHY_0117, WIFI_PHY_0111, WIFI_PHY_0111, - WIFI_PHY_0111, WIFI_PHY_0112, WIFI_PHY_0112, WIFI_PHY_0112, WIFI_PHY_0205, WIFI_PHY_0205, - WIFI_PHY_0205] diff --git a/components/test/CIConfigs/Function_WIFI_10.yml b/components/test/CIConfigs/Function_WIFI_10.yml deleted file mode 100644 index f143efb3b0..0000000000 --- a/components/test/CIConfigs/Function_WIFI_10.yml +++ /dev/null @@ -1,10 +0,0 @@ -Config: {execute count: 1, execute order: in order} -DUT: [SSC2, SSC1] -Filter: -- Add: - ID: [WIFI_PHY_0204, WIFI_PHY_0204, WIFI_PHY_0204, WIFI_PHY_0207, WIFI_PHY_0207, - WIFI_PHY_0207, WIFI_PHY_0206, WIFI_PHY_0206, WIFI_PHY_0206, WIFI_PHY_0201, WIFI_PHY_0201, - WIFI_PHY_0201, WIFI_PHY_0203, WIFI_PHY_0203, WIFI_PHY_0203, WIFI_PHY_0202, WIFI_PHY_0202, - WIFI_PHY_0202, WIFI_PHY_0209, WIFI_PHY_0209, WIFI_PHY_0209, WIFI_PHY_0208, WIFI_PHY_0208, - WIFI_PHY_0208, WIFI_PHY_0116, WIFI_PHY_0116, WIFI_PHY_0116, WIFI_PHY_0303, WIFI_PHY_0303, - WIFI_PHY_0303] diff --git a/components/test/CIConfigs/Function_WIFI_11.yml b/components/test/CIConfigs/Function_WIFI_11.yml deleted file mode 100644 index f4adf0d2e6..0000000000 --- a/components/test/CIConfigs/Function_WIFI_11.yml +++ /dev/null @@ -1,10 +0,0 @@ -Config: {execute count: 1, execute order: in order} -DUT: [SSC2, SSC1] -Filter: -- Add: - ID: [WIFI_PHY_0108, WIFI_PHY_0108, WIFI_PHY_0108, WIFI_PHY_0109, WIFI_PHY_0109, - WIFI_PHY_0109, WIFI_PHY_0106, WIFI_PHY_0106, WIFI_PHY_0106, WIFI_PHY_0107, WIFI_PHY_0107, - WIFI_PHY_0107, WIFI_PHY_0214, WIFI_PHY_0214, WIFI_PHY_0214, WIFI_PHY_0212, WIFI_PHY_0212, - WIFI_PHY_0212, WIFI_PHY_0213, WIFI_PHY_0213, WIFI_PHY_0213, WIFI_PHY_0210, WIFI_PHY_0210, - WIFI_PHY_0210, WIFI_PHY_0211, WIFI_PHY_0211, WIFI_PHY_0211, WIFI_PHY_0104, WIFI_PHY_0104, - WIFI_PHY_0104] diff --git a/components/test/TestCaseAll.yml b/components/test/TestCaseAll.yml index d787017591..40d1891715 100644 --- a/components/test/TestCaseAll.yml +++ b/components/test/TestCaseAll.yml @@ -124,59 +124,6 @@ test cases: test point 1: basic function test point 2: sw reboot version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_ARP_0202 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - STRING ether%20src%20%%s%20or%20ether%20dst%20%%s - - - [R PC_COM C OK] - - - NIC NIC1 START capture+send+block_arp_ip - - ['R PC_COM C +NIC_START:OK'] - - - NIC NIC1 SEND ARP arp_op_code "request" arp_target_proto_addr "192.168.11.240" - ethernet_len_type "ARP" ethernet_dst_addr "ff:ff:ff:ff:ff:ff" - - [''] - - - DELAY 2 - - [P PC_COM C +DELAYDONE, P NIC1 NPDU (Ethernet.dst_addr=)(Ethernet.len_type="ARP")] - - - NIC NIC1 SEND ARP arp_op_code "request" arp_target_proto_addr arp_sender_hw_addr - "18:18:18:18:18:18" ethernet_len_type "ARP" ethernet_dst_addr "ff:ff:ff:ff:ff:ff" - - [''] - - - DELAY 2 - - [P PC_COM C +DELAYDONE, P NIC1 NPDU (Ethernet.dst_addr=)(Ethernet.len_type="ARP")] - - - NIC NIC1 SEND ARP arp_op_code "request" arp_target_proto_addr arp_sender_proto_addr - ethernet_dst_addr "ff:ff:ff:ff:ff:ff" - - [''] - - - DELAY 2 - - [P PC_COM C +DELAYDONE, P NIC1 NPDU (Ethernet.dst_addr=)(Ethernet.len_type="ARP")] - comment: '' - execution time: 0.0 - expected result: 1. PC can't recv ARP reply from target - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: 1. PC send ARP req with target_hw_addr, sender_hw_addr and sender_proto_addr - not correct - sub module: ARP - summary: PC send invalid ARP request to target 2 - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: handling ARP request - version: v1 (2015-8-15) - CI ready: 'Yes' ID: ^TCPIP_DHCP_0302 SDK: '8266_NonOS @@ -527,48 +474,6 @@ test cases: test point 1: basic function test point 2: 'get heap size ' version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_ARP_0204 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - STRING ether%20src%20%%s%20or%20ether%20dst%20%%s - - - [R PC_COM C OK] - - - NIC NIC1 START capture+send+block_arp_ip - - ['R PC_COM C +NIC_START:OK'] - - - NIC NIC1 SEND ARP arp_op_code 0xFF arp_target_proto_addr ethernet_dst_addr - "ff:ff:ff:ff:ff:ff" - - [''] - - - DELAY 2 - - [P PC_COM C +DELAYDONE, P NIC1 NPDU (Ethernet.dst_addr=)(Ethernet.len_type="ARP")] - comment: '' - execution time: 0.0 - expected result: 1. PC can't recv ARP reply from target - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: 1. PC send ARP with error op_code - sub module: ARP - summary: PC send invalid ARP request to target 4 - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: handling ARP request - version: v1 (2015-8-15) - CI ready: 'Yes' ID: TCPIP_TCP_0412 SDK: '8266_NonOS @@ -8201,51 +8106,6 @@ test cases: test point 1: basic function test point 2: use TCP SAP (socket/espconn API) in different state version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_TCP_0501 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - STRING ether%20src%20%%s%20or%20ether%20dst%20%%s - - - [R PC_COM C OK] - - - NIC NIC1 START capture+block_ip - - ['R PC_COM C +NIC_START:OK'] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - [''] - - - DELAY 10 - - ['R SSC1 RE CONNECT:\d+,ERROR'] - comment: '' - execution time: 0.0 - expected result: 2. connect failed, no exception - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: '1. PC do not reply any IP packet on NIC - - 2. target try to connect to TCP server with PC NIC IP' - sub module: TCP - summary: PC do not reply TCP SYN of target - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: TCP connect and disconnect abnormal case - version: v1 (2015-8-15) - CI ready: 'Yes' ID: ^TCPIP_DNS_0101 SDK: '8266_NonOS @@ -9431,46 +9291,6 @@ test cases: test point 1: basic function test point 2: use TCP SAP (socket/espconn API) with different parameter version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_ARP_0101 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - STRING ether%20src%20%%s%20or%20ether%20dst%20%%s - - - [R PC_COM C OK] - - - NIC NIC1 START capture+send+block_arp_ip - - ['R PC_COM C +NIC_START:OK'] - - - NIC NIC1 SEND ARP arp_op_code "request" arp_target_proto_addr ethernet_dst_addr - "ff:ff:ff:ff:ff:ff" - - ['P PC_COM C +NIC_SEND:OK', P NIC1 PDU (Ethernet.dst_addr=)(ARP.hw_type="Ethernet")(ARP.protocol="IPv4")(ARP.hw_len="6")(ARP.proto_len="4")(ARP.op_code="reply")(ARP.sender_hw_addr=)(ARP.sender_proto_addr=)(ARP.target_hw_addr=)(ARP.target_proto_addr=)] - comment: '' - execution time: 0.0 - expected result: 1. PC recv target valid ARP reply - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: 1. PC send ARP req to target - sub module: ARP - summary: PC send valid ARP request to target - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: handling ARP request - version: v1 (2015-8-15) - CI ready: 'Yes' ID: TCPIP_UDP_0304 SDK: '8266_NonOS @@ -12124,53 +11944,6 @@ test cases: test point 1: basic function test point 2: wifi disconnect reason test version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_ARP_0203 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - STRING ether%20src%20%%s%20or%20ether%20dst%20%%s - - - [R PC_COM C OK] - - - NIC NIC1 START capture+send+block_arp_ip - - ['R PC_COM C +NIC_START:OK'] - - - NIC NIC1 SEND ARP arp_op_code "request" arp_target_proto_addr arp_hw_len - 10 ethernet_dst_addr "ff:ff:ff:ff:ff:ff" - - [''] - - - DELAY 2 - - [P PC_COM C +DELAYDONE, P NIC1 NPDU (Ethernet.dst_addr=)(Ethernet.len_type="ARP")] - - - NIC NIC1 SEND ARP arp_op_code "request" arp_target_proto_addr arp_proto_len - 10 ethernet_dst_addr "ff:ff:ff:ff:ff:ff" - - [''] - - - DELAY 2 - - [P PC_COM C +DELAYDONE, P NIC1 NPDU (Ethernet.dst_addr=)(Ethernet.len_type="ARP")] - comment: '' - execution time: 0.0 - expected result: 1. PC can't recv ARP reply from target - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: 1. PC send ARP req with hw_addr_len and proto_addr_len not correct - sub module: ARP - summary: PC send invalid ARP request to target 3 - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: handling ARP request - version: v1 (2015-8-15) - CI ready: 'Yes' ID: WIFI_CONN_0503 SDK: '8266_NonOS @@ -12867,53 +12640,6 @@ test cases: test point 1: basic function test point 2: SAP/JAP with different config version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_ARP_0201 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - STRING ether%20src%20%%s%20or%20ether%20dst%20%%s - - - [R PC_COM C OK] - - - NIC NIC1 START capture+send+block_arp_ip - - ['R PC_COM C +NIC_START:OK'] - - - NIC NIC1 SEND ARP arp_op_code "request" arp_hw_type 0xF1F1 arp_target_proto_addr - ethernet_dst_addr "ff:ff:ff:ff:ff:ff" - - [''] - - - DELAY 2 - - [P PC_COM C +DELAYDONE, P NIC1 NPDU (Ethernet.dst_addr=)(Ethernet.len_type="ARP")] - - - NIC NIC1 SEND ARP arp_op_code "request" arp_proto_type 0xF1F1 arp_target_proto_addr - ethernet_dst_addr "ff:ff:ff:ff:ff:ff" - - [''] - - - DELAY 2 - - [P PC_COM C +DELAYDONE, P NIC1 NPDU (Ethernet.dst_addr=)(Ethernet.len_type="ARP")] - comment: '' - execution time: 0.0 - expected result: 1. PC can't recv ARP reply from target - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: 1. PC send ARP req with unsupported hw type and protocol type - sub module: ARP - summary: PC send invalid ARP request to target 1 - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: handling ARP request - version: v1 (2015-8-15) - CI ready: 'Yes' ID: ^WIFI_CONN_0503 SDK: '8266_NonOS From 547fb6ed6ca0dc9dd6da222f16762ea26903b54c Mon Sep 17 00:00:00 2001 From: Yinling Date: Thu, 29 Sep 2016 20:20:40 +0800 Subject: [PATCH 071/343] update current known issue for ESP32 IDF test --- components/test/KnownIssues | 66 +++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/components/test/KnownIssues b/components/test/KnownIssues index e69de29bb2..08bc48f185 100644 --- a/components/test/KnownIssues +++ b/components/test/KnownIssues @@ -0,0 +1,66 @@ + +# NOT SUPPORT + +# ICMP send Ping not supported +TCPIP_ICMP_0101 +^TCPIP_ICMP_0101 + +# IGMP cases are not supported for now +TCPIP_IGMP_0101 +TCPIP_IGMP_0102 +TCPIP_IGMP_0103 +TCPIP_IGMP_0104 +TCPIP_IGMP_0201 +TCPIP_IGMP_0202 +TCPIP_IGMP_0203 +TCPIP_IGMP_0204 +^TCPIP_IGMP_0101 +^TCPIP_IGMP_0102 +^TCPIP_IGMP_0103 +^TCPIP_IGMP_0104 +^TCPIP_IGMP_0201 +^TCPIP_IGMP_0202 +^TCPIP_IGMP_0203 +^TCPIP_IGMP_0204 + +# BUG + +# auth change event +WIFI_CONN_0801 + +# disconnect reason +WIFI_CONN_0904 +^WIFI_CONN_0904 +WIFI_CONN_0901 +^WIFI_CONN_0901 + +# Wifi connect issue +WIFI_CONN_0104 +^WIFI_CONN_0104 + +# DHCP issues +^TCPIP_DHCP_0301 +TCPIP_DHCP_0301 +TCPIP_DHCP_0101 +TCPIP_DHCP_0207 +^TCPIP_DHCP_0207 +TCPIP_DHCP_0208 +^TCPIP_DHCP_0208 + +# TCP issue +TCPIP_TCP_0402 +^TCPIP_TCP_0406 +^TCPIP_TCP_0401 +TCPIP_TCP_0210 +^TCPIP_TCP_0210 +TCPIP_TCP_0103 + + +# UDP issue +TCPIP_UDP_0103 +^TCPIP_UDP_0103 +TCPIP_UDP_0110 +^TCPIP_UDP_0110 + + + From 12fa7472ea1bfa3759a47b219054ffce2997c546 Mon Sep 17 00:00:00 2001 From: Yinling Date: Thu, 29 Sep 2016 20:21:33 +0800 Subject: [PATCH 072/343] night jobs should exit succeed if no need to run --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 89269aa425..2b421e77a0 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -160,7 +160,7 @@ push_master_to_github: - triggers script: # must be night build triggers, otherwise exit without test - - test $NIGHT_BUILD != "Yes" || exit 0 + - test $NIGHT_BUILD = "Yes" || exit 0 # add gitlab ssh key - mkdir -p ~/.ssh - chmod 700 ~/.ssh From 64426013333f01838babe444307ddc7511afff8d Mon Sep 17 00:00:00 2001 From: Yinling Date: Thu, 29 Sep 2016 20:22:33 +0800 Subject: [PATCH 073/343] add some missing cases caused by autogen bug --- components/test/TestCaseAll.yml | 1239 +++++++++++++++++++++++++++++++ 1 file changed, 1239 insertions(+) diff --git a/components/test/TestCaseAll.yml b/components/test/TestCaseAll.yml index 40d1891715..7112c87936 100644 --- a/components/test/TestCaseAll.yml +++ b/components/test/TestCaseAll.yml @@ -902,6 +902,72 @@ test cases: test point 1: abnormal/special use test point 2: TCP handling abnormal event version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0405 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - NIC DISABLED + - [R PC_COM C OK] + - - SSC SSC1 soc -S -s -l 1 + - [''] + - - DELAY 5400 + - ['P SSC1 RE CLOSED:\d+,0'] + comment: '' + execution time: 1.5 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.TCP连接断开' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket1 + + 3.target1上使用步骤2创建的socket1,去连接 PC的ip,test_tcp_port1 + + 4.PC与target1创建好TCP 连接,有ACCEPT + + 5.PC 网卡 disable + + 6.target1上使用socket1发送数据,等待 90 分钟' + sub module: TCP + summary: do TCP send after PC NIC disabled + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: TCP handling abnormal event + version: v1 (2016-8-15) - CI ready: 'Yes' ID: TCPIP_TCP_0404 SDK: '8266_NonOS @@ -958,6 +1024,38 @@ test cases: test point 1: abnormal/special use test point 2: TCP handling abnormal event version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^WIFI_CONN_0903 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -C -s -p bacfd + - ['R SSC1 RE JAP:DISCONNECTED,\d+,2'] + comment: '' + execution time: 0.0 + expected result: 1. disconect event reason REASON_AUTH_EXPIRE + initial condition: STAAP1 + initial condition description (auto): testing sta on sta + ap mode, quit AP (autogen + by STAM1) + module: WIFI MAC + steps: 1. connect WEP ap with error password (valid wep password) + sub module: WIFI Connect + summary: test wifi disconnect reason REASON_AUTH_EXPIRE + test environment: SSC_T1_WEP + test environment description (auto): '1 SSC target connect with PC by UART. + + One WEP share key AP placed near SSC1.' + test point 1: basic function + test point 2: wifi disconnect reason test + version: v1 (2016-8-15) - CI ready: 'Yes' ID: TCPIP_TCP_0408 SDK: '8266_NonOS @@ -1982,6 +2080,52 @@ test cases: test point 1: basic function test point 2: DNS function test version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0403 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 20 + - ['R SSC2 C +PHY:OK'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC2 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC1 NC +JAP:DISCONNECTED', 'P SSC2 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: 3. SoftAP and STA in channel2, SoftAP 20M, STA 40M, STA not disconnected + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. SoftAP 11n ht20, in channel1, ext AP 11n ht40, in channel2 + + 2. STA connect to ext AP + + 3. AP get connected' + sub module: Phy Mode + summary: SoftAP ext AP in defferent channel, SoftAP 20M, ext AP 40M, STA connect + to AP then Softap get connected + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP initial channel test + version: v1 (2015-8-15) - CI ready: 'Yes' ID: WIFI_CONN_0904 SDK: '8266_NonOS @@ -3927,6 +4071,72 @@ test cases: test point 1: abnormal/special use test point 2: TCP handling abnormal event version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0405 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - NIC DISABLED + - [R PC_COM C OK] + - - SSC SSC1 soc -S -s -l 1 + - [''] + - - DELAY 5400 + - ['P SSC1 RE CLOSED:\d+,0'] + comment: '' + execution time: 1.5 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.TCP连接断开' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket1 + + 3.target1上使用步骤2创建的socket1,去连接 PC的ip,test_tcp_port1 + + 4.PC与target1创建好TCP 连接,有ACCEPT + + 5.PC 网卡 disable + + 6.target1上使用socket1发送数据,等待 90 分钟' + sub module: TCP + summary: do TCP send after PC NIC disabled + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: TCP handling abnormal event + version: v1 (2016-8-15) - CI ready: 'Yes' ID: ^TCPIP_TCP_0406 SDK: '8266_NonOS @@ -6012,6 +6222,281 @@ test cases: test point 1: abnormal/special use test point 2: TCP handling abnormal event version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0502 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC3 sta -C -s -p + - ['R SSC3 C +JAP:CONNECTED'] + - - SSC SSC2 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC2 C +JAP:CONNECTED', 'P SSC[1,3] NC +JAP:DISCONNECTED'] + comment: '' + execution time: 0.0 + expected result: 4. all STA not get disconnected; target 1 SoftAP and STA both in + channel2; SoftAP in 20M, STA in 40M + initial condition: T3_PHY1 + initial condition description (auto): '1. target 1 and target 2 set to AP+STA mode, + target 3 set to STA mode + + 2. all interface of target 2,3 set to 11n ht40 + + 3. config softAP of target 1 and target 2' + module: WIFI MAC + steps: '1. target 1 STA set to 40M, SoftAP set to 20M + + 2. target 2 STA connect to ap_channel1_20 + + 3. target 1/3 STA connect to target 2/1 SoftAP + + 4. target 2 STA connect to ap_channel2_40' + sub module: Phy Mode + summary: SoftAP STA in channel1 20M, STA changed to channel2 40M + test environment: SSC_T3_PhyMode + test environment description (auto): '3 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with (HT20, channel1), (HT20, channel2), (HT40, channel1), (HT40, channel2). + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP dynamic channel switch test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0503 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC3 sta -C -s -p + - ['R SSC3 C +JAP:CONNECTED'] + - - SSC SSC2 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC2 C +JAP:CONNECTED', 'P SSC[1,3] NC +JAP:DISCONNECTED'] + comment: '' + execution time: 0.0 + expected result: 4. all STA not get disconnected; target 1 SoftAP and STA both in + channel2 20M + initial condition: T3_PHY1 + initial condition description (auto): '1. target 1 and target 2 set to AP+STA mode, + target 3 set to STA mode + + 2. all interface of target 2,3 set to 11n ht40 + + 3. config softAP of target 1 and target 2' + module: WIFI MAC + steps: '1. target 1 STA set to 40M, SoftAP set to 20M + + 2. target 2 STA connect to ap_channel1_40 + + 3. target 1/3 STA connect to target 2/1 SoftAP + + 4. target 2 STA connect to ap_channel2_20' + sub module: Phy Mode + summary: SoftAP STA in channel1, SoftAP 20M, STA 40M, STA changed to channel2 20M + test environment: SSC_T3_PhyMode + test environment description (auto): '3 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with (HT20, channel1), (HT20, channel2), (HT40, channel1), (HT40, channel2). + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP dynamic channel switch test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0501 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC3 sta -C -s -p + - ['R SSC3 C +JAP:CONNECTED'] + - - SSC SSC2 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC2 C +JAP:CONNECTED', 'P SSC[1,3] NC +JAP:DISCONNECTED'] + comment: '' + execution time: 0.0 + expected result: 4. all STA not get disconnected; target 1 SoftAP and STA both in + channel2 20M + initial condition: T3_PHY1 + initial condition description (auto): '1. target 1 and target 2 set to AP+STA mode, + target 3 set to STA mode + + 2. all interface of target 2,3 set to 11n ht40 + + 3. config softAP of target 1 and target 2' + module: WIFI MAC + steps: '1. target 1 STA and SoftAP set to 20M + + 2. target 2 STA connect to ap_channel1_20 + + 3. target 1/3 STA connect to target 2/1 SoftAP + + 4. target 2 STA connect to ap_channel2_20' + sub module: Phy Mode + summary: SoftAP STA in channel1 20M, STA changed to channel2 20M + test environment: SSC_T3_PhyMode + test environment description (auto): '3 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with (HT20, channel1), (HT20, channel2), (HT40, channel1), (HT40, channel2). + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP dynamic channel switch test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0506 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC3 sta -C -s -p + - ['R SSC3 C +JAP:CONNECTED'] + - - SSC SSC2 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC2 C +JAP:CONNECTED', 'P SSC[1,3] NC +JAP:DISCONNECTED'] + comment: '' + execution time: 0.0 + expected result: 4. all STA not get disconnected; target 1 SoftAP and STA both in + channel2 40M + initial condition: T3_PHY1 + initial condition description (auto): '1. target 1 and target 2 set to AP+STA mode, + target 3 set to STA mode + + 2. all interface of target 2,3 set to 11n ht40 + + 3. config softAP of target 1 and target 2' + module: WIFI MAC + steps: '1. target 1 STA and SoftAP set to 40M + + 2. target 2 STA connect to ap_channel1_40 + + 3. target 1/3 STA connect to target 2/1 SoftAP + + 4. target 2 STA connect to ap_channel2_40' + sub module: Phy Mode + summary: SoftAP STA in channel1, SoftAP 40M, STA 40M, STA changed to channel2 40M + test environment: SSC_T3_PhyMode + test environment description (auto): '3 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with (HT20, channel1), (HT20, channel2), (HT40, channel1), (HT40, channel2). + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP dynamic channel switch test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0505 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC3 sta -C -s -p + - ['R SSC3 C +JAP:CONNECTED'] + - - SSC SSC2 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC2 C +JAP:CONNECTED', 'P SSC[1,3] NC +JAP:DISCONNECTED'] + comment: '' + execution time: 0.0 + expected result: 4. all STA not get disconnected; target 1 SoftAP and STA both in + channel2; SoftAP in 20M, STA in 40M + initial condition: T3_PHY1 + initial condition description (auto): '1. target 1 and target 2 set to AP+STA mode, + target 3 set to STA mode + + 2. all interface of target 2,3 set to 11n ht40 + + 3. config softAP of target 1 and target 2' + module: WIFI MAC + steps: '1. target 1 STA set to 40M ,SoftAP set to 20M + + 2. target 2 STA connect to ap_channel1_40 + + 3. target 1/3 STA connect to target 2/1 SoftAP + + 4. target 2 STA connect to ap_channel2_20' + sub module: Phy Mode + summary: SoftAP STA in channel1, SoftAP 40M, STA 40M, STA changed to channel2 20M + test environment: SSC_T3_PhyMode + test environment description (auto): '3 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with (HT20, channel1), (HT20, channel2), (HT40, channel1), (HT40, channel2). + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP dynamic channel switch test + version: v1 (2015-8-15) - CI ready: 'Yes' ID: WIFI_CONN_0301 SDK: '8266_NonOS @@ -6609,6 +7094,93 @@ test cases: test point 1: basic function test point 2: DHCP client function test version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_SCAN_0301 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -S + - [''] + - - SSC SSC1 sta -S + - [P SSC1 C +SCANFAIL, 'P SSC1 P +SCAN:', R SSC1 C +SCANDONE] + comment: '' + execution time: 0.0 + expected result: '1. second scan failed + + 2. first scan succeed' + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + module: WIFI MAC + steps: '1. do all channel scan + + 2. do scan before scan finished' + sub module: WIFI Scan + summary: reject scan request before scan finished + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: interaction + test point 2: Scan interact with other WiFi operation + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_SCAN_0303 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:OK'] + - - SSC SSC1 sta -S + - [P SSC1 C +SCANDONE, 'P SSC1 C +JAP:CONNECTED'] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:OK'] + - - SSC SSC1 sta -S + - [''] + - - SSC SSC1 sta -C -s -p + - [P SSC1 C +SCANDONE, 'P SSC1 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: '2. scan succeed, JAP succeed + + 5. JAP succeed, scan succeed' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. target 1 STA join AP + + 2. target 1 STA scan before JAP succeed + + 3. target 1 quite AP + + 4. target 1 scan + + 5. target 1 JAP before scan succeed' + sub module: WIFI Scan + summary: scan during JAP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: interaction + test point 2: Scan interact with other WiFi operation + version: v1 (2015-8-15) - CI ready: 'Yes' ID: ^WIFI_CONN_0801 SDK: '8266_NonOS @@ -6672,6 +7244,55 @@ test cases: test point 1: basic function test point 2: wifi auth changed event test version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_SCAN_0304 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:OK'] + - - SSC SSC1 sta -S + - [P SSC1 C +SCANDONE, 'P SSC2 C +JAP:CONNECTED'] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:OK'] + - - SSC SSC1 sta -S + - [''] + - - SSC SSC2 sta -C -s -p + - [P SSC1 C +SCANDONE, 'P SSC2 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: '2. scan succeed, JAP succeed + + 5. JAP succeed, scan succeed' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. target 2 STA join target 1 SoftAP + + 2. target 1 STA scan before target 2 JAP succeed + + 3. target 2 STA QAP + + 4. target 1 STA scan + + 5. target 2 STA JAP before target 1 STA scan succeed' + sub module: WIFI Scan + summary: scan during ext STA join SoftAP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: interaction + test point 2: Scan interact with other WiFi operation + version: v1 (2015-8-15) - CI ready: 'Yes' ID: ^TCPIP_UDP_0108 SDK: '8266_NonOS @@ -7773,6 +8394,47 @@ test cases: test point 1: basic function test point 2: wifi disconnect reason test version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^WIFI_CONN_0902 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - APC OFF + - [P PC_COM L OK, 'R SSC1 RE JAP:DISCONNECTED,\d+,200'] + - - APC ON + - [P PC_COM L OK] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. disconnect event REASON_BEACON_TIMEOUT' + initial condition: STAAP1 + initial condition description (auto): testing sta on sta + ap mode, quit AP (autogen + by STAM1) + module: WIFI MAC + steps: '1. connect to AP + + 2. AP power off' + sub module: WIFI Connect + summary: test wifi disconnect reason REASON_BEACON_TIMEOUT + test environment: SSC_T1_APC + test environment description (auto): "PC has 1 wired NIC connected to AP.\nPC has\ + \ 1 wired NIC connected to APC (static IP within the same subnet with APC). \n\ + APC control AP power supply. \nPC has 1 WiFi NIC. \n1 SSC target connect with\ + \ PC by UART." + test point 1: basic function + test point 2: wifi disconnect reason test + version: v1 (2016-8-15) - CI ready: 'Yes' ID: ^WIFI_CONN_0901 SDK: '8266_NonOS @@ -9291,6 +9953,61 @@ test cases: test point 1: basic function test point 2: use TCP SAP (socket/espconn API) with different parameter version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_SCAN_0302 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -n 1000000 -j 5 + - [''] + - - SSC SSC2 phy -S -o 1 -m b + - ['R SSC2 C +PHY:OK'] + - - SSC SSC2 sta -S -n + - [R SSC2 P ] + - - SSC SSC2 phy -S -o 1 -m g + - ['R SSC2 C +PHY:OK'] + - - SSC SSC2 sta -S -n + - [R SSC2 P ] + - - SSC SSC2 phy -S -o 1 -m n -b 20 + - ['R SSC2 C +PHY:OK'] + - - SSC SSC2 sta -S -n + - [R SSC2 P ] + - - SSC SSC2 phy -S -o 1 -m n -b 40 + - ['R SSC2 C +PHY:OK'] + - - SSC SSC2 sta -S -n + - [R SSC2 P ] + comment: '' + execution time: 0.0 + expected result: 3. target 2 able to scan AP + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. target 1 connect to AP + + 2. target 1 start sending UDP packets + + 3. target 2 scan in AP channel in 11b.g,n,ht40 mode' + sub module: WIFI Scan + summary: scan in congest channel + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: interaction + test point 2: Scan interact with other WiFi operation + version: v1 (2015-8-15) - CI ready: 'Yes' ID: TCPIP_UDP_0304 SDK: '8266_NonOS @@ -11944,6 +12661,147 @@ test cases: test point 1: basic function test point 2: wifi disconnect reason test version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_CONN_0902 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - APC OFF + - [P PC_COM L OK, 'R SSC1 RE JAP:DISCONNECTED,\d+,200'] + - - APC ON + - [P PC_COM L OK] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. disconnect event REASON_BEACON_TIMEOUT' + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + module: WIFI MAC + steps: '1. connect to AP + + 2. AP power off' + sub module: WIFI Connect + summary: test wifi disconnect reason REASON_BEACON_TIMEOUT + test environment: SSC_T1_APC + test environment description (auto): "PC has 1 wired NIC connected to AP.\nPC has\ + \ 1 wired NIC connected to APC (static IP within the same subnet with APC). \n\ + APC control AP power supply. \nPC has 1 WiFi NIC. \n1 SSC target connect with\ + \ PC by UART." + test point 1: basic function + test point 2: wifi disconnect reason test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_CONN_0903 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -C -s -p bacfd + - ['R SSC1 RE JAP:DISCONNECTED,\d+,2'] + comment: '' + execution time: 0.0 + expected result: 1. disconect event reason REASON_AUTH_EXPIRE + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + module: WIFI MAC + steps: 1. connect WEP ap with error password (valid wep password) + sub module: WIFI Connect + summary: test wifi disconnect reason REASON_AUTH_EXPIRE + test environment: SSC_T1_WEP + test environment description (auto): '1 SSC target connect with PC by UART. + + One WEP share key AP placed near SSC1.' + test point 1: basic function + test point 2: wifi disconnect reason test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_SCAN_0201 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m b + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 sta -S + - [R SSC1 P P P P ] + - - SSC SSC1 phy -S -o 1 -m g + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 sta -S + - [R SSC1 P P P P ] + - - SSC SSC1 phy -S -o 1 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 sta -S + - [R SSC1 P P P P ] + - - SSC SSC1 phy -S -o 1 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 sta -S + - [R SSC1 P P P P ] + comment: '' + execution time: 0.0 + expected result: '3. find all 3 ext APs + + 5. find all 3 ext APs + + 7. find all 3 ext APs + + 9. find all 3 ext APs' + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + module: WIFI MAC + steps: '1. 3 ext APs in 11b, 11g, 11n mode + + 2. STA in 11b mode + + 3. do all channel scan + + 4. STA in 11g mode + + 5. do all channel scan + + 6. STA in 11n ht20 mode + + 7. do all channel scan + + 8. STA in 11n ht40 mode + + 9. do all channel scan' + sub module: WIFI Scan + summary: STA in differnt PHY mode to scan AP in different PHY mode + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: Scan in different mode and channel + version: v1 (2015-8-15) - CI ready: 'Yes' ID: WIFI_CONN_0503 SDK: '8266_NonOS @@ -12002,6 +12860,285 @@ test cases: test point 1: basic function test point 2: reconnect policy test version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0402 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 20 + - ['R SSC2 C +PHY:OK'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC2 NC +JAP:DISCONNECTED', 'P SSC1 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: 3. SoftAP and STA in channel2, both bandwidth 20M, SoftAP not get + disconnected + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. SoftAP 11n ht20, in channel1, ext AP 11n ht20, in channel2 + + 2. AP get connected + + 3. STA connect to ext AP' + sub module: Phy Mode + summary: SoftAP ext AP in defferent channel, both bandwidth 20M, Softap get connected + than STA connect to AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP initial channel test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0401 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 20 + - ['R SSC2 C +PHY:OK'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC2 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC1 NC +JAP:DISCONNECTED', 'P SSC2 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: 3. SoftAP and STA in channel2, both bandwidth 20M, STA not disconnected + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. SoftAP 11n ht20, in channel1, ext AP 11n ht20, in channel2 + + 2. STA connect to ext AP + + 3. AP get connected' + sub module: Phy Mode + summary: SoftAP ext AP in defferent channel, both bandwidth 20M, STA connect to + AP then Softap get connected + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP initial channel test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0407 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 40 + - ['R SSC2 C +PHY:OK'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC2 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC1 NC +JAP:DISCONNECTED', 'P SSC2 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: 3. SoftAP and STA in channel2, SoftAP 40M, STA 20M, STA not disconnected + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. SoftAP 11n ht40, in channel1, ext AP 11n ht20, in channel2 + + 2. STA connect to ext AP + + 3. AP get connected' + sub module: Phy Mode + summary: SoftAP ext AP in defferent channel, SoftAP 40M, ext AP 20M, STA connect + to AP then Softap get connected + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP initial channel test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0406 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 40 + - ['R SSC2 C +PHY:OK'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC2 NC +JAP:DISCONNECTED', 'P SSC1 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: 3. SoftAP and STA in channel2, both bandwidth 40M, SoftAP not get + disconnected + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. SoftAP 11n ht40, in channel1, ext AP 11n ht40, in channel2 + + 2. AP get connected + + 3. STA connect to ext AP' + sub module: Phy Mode + summary: SoftAP ext AP in defferent channel, both bandwidth 40M, Softap get connected + than STA connect to AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP initial channel test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0405 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 40 + - ['R SSC2 C +PHY:OK'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC2 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC1 NC +JAP:DISCONNECTED', 'P SSC2 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: 3. SoftAP and STA in channel2, both bandwidth 40M, STA not disconnected + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. SoftAP 11n ht40, in channel1, ext AP 11n ht40, in channel2 + + 2. STA connect to ext AP + + 3. AP get connected' + sub module: Phy Mode + summary: SoftAP ext AP in defferent channel, both bandwidth 40M, STA connect to + AP then Softap get connected + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP initial channel test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0404 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 20 + - ['R SSC2 C +PHY:OK'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC2 NC +JAP:DISCONNECTED', 'P SSC1 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: 3. SoftAP and STA in channel2, SoftAP 20M, STA 40M, SoftAP not + get disconnected + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. SoftAP 11n ht20, in channel1, ext AP 11n ht40, in channel2 + + 2. AP get connected + + 3. STA connect to ext AP' + sub module: Phy Mode + summary: SoftAP ext AP in defferent channel, SoftAP 20M, ext AP 40M, Softap get + connected than STA connect to AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP initial channel test + version: v1 (2015-8-15) - CI ready: 'Yes' ID: ^TCPIP_UDP_0112 SDK: '8266_NonOS @@ -12042,6 +13179,53 @@ test cases: test point 1: basic function test point 2: use UDP SAP (socket/espconn API) with different parameter version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0408 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 40 + - ['R SSC2 C +PHY:OK'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC2 NC +JAP:DISCONNECTED', 'P SSC1 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: 3. SoftAP and STA in channel2, SoftAP 40M, STA 20M, SoftAP not + get disconnected + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + module: WIFI MAC + steps: '1. SoftAP 11n ht40, in channel1, ext AP 11n ht20, in channel2 + + 2. AP get connected + + 3. STA connect to ext AP' + sub module: Phy Mode + summary: SoftAP ext AP in defferent channel, SoftAP 40M, ext AP 20M, Softap get + connected than STA connect to AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP initial channel test + version: v1 (2015-8-15) - CI ready: 'Yes' ID: ^TCPIP_UDP_0114 SDK: '8266_NonOS @@ -12455,6 +13639,61 @@ test cases: test point 1: basic function test point 2: SAP/JAP with different config version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0504 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC3 sta -C -s -p + - ['R SSC3 C +JAP:CONNECTED'] + - - SSC SSC2 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC2 C +JAP:CONNECTED', 'P SSC[1,3] NC +JAP:DISCONNECTED'] + comment: '' + execution time: 0.0 + expected result: 4. all STA not get disconnected; target 1 SoftAP and STA both in + channel2 20M + initial condition: T3_PHY1 + initial condition description (auto): '1. target 1 and target 2 set to AP+STA mode, + target 3 set to STA mode + + 2. all interface of target 2,3 set to 11n ht40 + + 3. config softAP of target 1 and target 2' + module: WIFI MAC + steps: '1. target 1 STA and SoftAP set to 40M + + 2. target 2 STA connect to ap_channel1_40 + + 3. target 1/3 STA connect to target 2/1 SoftAP + + 4. target 2 STA connect to ap_channel2_20' + sub module: Phy Mode + summary: SoftAP STA in channel1, SoftAP 20M, STA 40M, STA changed to channel2 40M + test environment: SSC_T3_PhyMode + test environment description (auto): '3 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with (HT20, channel1), (HT20, channel2), (HT40, channel1), (HT40, channel2). + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP dynamic channel switch test + version: v1 (2015-8-15) - CI ready: 'Yes' ID: ^TCPIP_IP_0101 SDK: '8266_NonOS From fbb654fa686ccce365af7317a1cf76db578b921e Mon Sep 17 00:00:00 2001 From: Yinling Date: Thu, 29 Sep 2016 20:47:31 +0800 Subject: [PATCH 074/343] move content from readme to wiki --- components/test/README.md | 57 --------------------------------------- 1 file changed, 57 deletions(-) diff --git a/components/test/README.md b/components/test/README.md index f23153bca6..1d0c4cfbd1 100644 --- a/components/test/README.md +++ b/components/test/README.md @@ -2,60 +2,3 @@ # Note: The test cases in this folder are for Espressif internal use. # Goto internal project wiki Testing page for detail about this folder. - -## File Structure - -``` -test --- CIConfigs --- sanity_test1.yml (Runner config files) - | |-- stress_test1.yml - |-- TestCaseAll.yml (TestCaseFiles) - |-- TestEnvAll.yml (TestCaseFiles) - |-- InitialConditionAll.yml (TestCaseFiles) - |-- TestCaseScript --- ... (Test case scripts) -``` - -1. CIConfigs folder - * config for CI config files are put in this folder - * CI config files configs the cases and some other options for the CI job with same name -1. Test case files - * TestCaseAll.yml (test cases) - * InitialConditionAll.yml (initial conditions) - * TestEnvAll.yml (test environments) - * [how to modify test cases](https://gitlab.espressif.cn:6688/yinling/auto_test_script/blob/master/public/Design/TestCaseFiles.DesignNote.md) -1. Test case scripts - * some cases are implemented by specified script. those scripts are put in this folder. - - -## Modify test cases - -1. check if the "SDK" of the test case only contain the current SDK - * if Yes, then just modify the test case behavior - * if No: - 1. then remove current SDK name from "SDK" of the test case - 2. Add a new test case, and set "SDK" only support current SDK name -2. use [auto_test_script](https://gitlab.espressif.cn:6688/yinling/auto_test_script) to load the modified case and verify the modification -3. create a merge request and assign to HYL (or add comment @yinling for merging test). -After review it will be merged to SDK and will be The cases will be synced to database in auto_test_script. - - -## Run test case locally - -1. clone auto_test_script (ssh://git@gitlab.espressif.cn:27227/yinling/auto_test_script.git) from gitlab -2. create test environment: - 1. search test case (search test case ID in components/test/TestCaseAll.yml, get the "test environment" value - 2. goto [test environment list](https://gitlab.espressif.cn:6688/yinling/auto_test_script/blob/master/public/Documents/TestEnvList.md), find the link and goto the environment detail page - 3. create test environment according to figure and description - 4. [config test environment](https://gitlab.espressif.cn:6688/yinling/auto_test_script/blob/master/public/Design/TestEnvConfig.DesignNote.md). All parameters in table "Parameters require config before use" MUST be configured. -3. run test cases with [CIRunner.py](https://gitlab.espressif.cn:6688/yinling/auto_test_script/blob/master/public/Design/RunnerConfigs.DesignNote.md) - - - -## exclude known issues for CI -the test cases listed in file "KnownIssues" will be excluded by CI when calculating results - -Editing KnownIssues file is very simple, one single line for the ID for each case. -``` -TCPIP_TCP_0101 -TCPIP_TCP_0201 -... -``` \ No newline at end of file From 19ca66c96824d3205fb178021064093b61f43972 Mon Sep 17 00:00:00 2001 From: Yinling Date: Fri, 30 Sep 2016 13:58:02 +0800 Subject: [PATCH 075/343] add job to generate test report --- .gitlab-ci.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2b421e77a0..bd6e3ce5a4 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -88,6 +88,30 @@ test_build_system: script: - ./make/test_build_system.sh +test_report: + stage: deploy + only: + - master + - triggers + tags: + - test_report + variables: + LOG_PATH: "$CI_PROJECT_DIR/$CI_BUILD_REF" + TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/components/test" + REPORT_PATH: "$CI_PROJECT_DIR/CI_Test_Report" + artifacts: + when: always + paths: + - $REPORT_PATH + expire_in: 6 mos + script: + - ls $LOG_PATH + # clone test bench + - git clone $GITLAB_SSH_SERVER/yinling/auto_test_script.git + - cd auto_test_script + # generate report + - python CITestReport.py -l $LOG_PATH -t $TEST_CASE_FILE_PATH -p $REPORT_PATH + push_master_to_github: before_script: From e5b8854d96ee155c7509ed5edffa2139b33467f6 Mon Sep 17 00:00:00 2001 From: He Yin Ling Date: Fri, 30 Sep 2016 15:34:17 +0800 Subject: [PATCH 076/343] can not put test report to deploy stage, otherwise if test fails it won't generate test report. --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index bd6e3ce5a4..775a13b476 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -89,7 +89,7 @@ test_build_system: - ./make/test_build_system.sh test_report: - stage: deploy + stage: test only: - master - triggers From 1447cd4136f251099cec0fe60a98d1a9881e21fe Mon Sep 17 00:00:00 2001 From: Yinling Date: Fri, 30 Sep 2016 16:11:24 +0800 Subject: [PATCH 077/343] fix issue on test report job: 1. test report job should be put to deploy stage, otherwise it can't get logs from test stage 2. allow test fail so that test report job will be executed for failed test --- .gitlab-ci.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 775a13b476..ef28489077 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -89,12 +89,13 @@ test_build_system: - ./make/test_build_system.sh test_report: - stage: test + stage: deploy only: - master - triggers tags: - test_report + allow_failure: true variables: LOG_PATH: "$CI_PROJECT_DIR/$CI_BUILD_REF" TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/components/test" @@ -144,6 +145,7 @@ push_master_to_github: only: - master - triggers + allow_failure: true variables: # LOCAL_ENV_CONFIG_PATH: define in template and jobs can overwrite if required From 685c1084ba276e4ff9e39e28fe796ed0a347eac0 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 11 Oct 2016 16:41:05 +1100 Subject: [PATCH 078/343] Reinstate build_examples gitlab CI case Had been removed in 42e31116 --- .gitlab-ci.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ef28489077..7834707fef 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -69,6 +69,23 @@ build_ssc: - chmod +x gen_misc_ng.sh - ./gen_misc_ng.sh +build_examples: + <<: *build_template + artifacts: + paths: + - build_examples/*/*/build/*.bin + - build_examples/*/*/build/*.elf + - build_examples/*/*/build/*.map + - build_examples/*/*/build/bootloader/*.bin + expire_in: 6 mos + + script: + # it's not possible to build 100% out-of-tree and have the "artifacts" + # mechanism work, but this is the next best thing + - mkdir build_examples + - cd build_examples + - ${IDF_PATH}/make/build_examples.sh + test_nvs_on_host: stage: test image: espressif/esp32-ci-env From b72d22041ca922792c3648806e5abdc187055ba8 Mon Sep 17 00:00:00 2001 From: Yinling Date: Wed, 12 Oct 2016 11:17:56 +0800 Subject: [PATCH 079/343] rename components/test to idf_test: 1. test will be categorized by test level 2. add test level as attribute to test cases 3. will select TestCaseScript by the test cases added to CI (currently no test case uses test case script) 4. adding test level to test jobs 5. update .gitlab-ci.yml, each job need to set its test case file path 6. update .gitlab-ci.yml, test case path for test report is changed to idf_test --- .gitlab-ci.yml | 141 +- components/idf_test/README.md | 61 + .../CIConfigs/IT_Function_SYS_01.yml} | 0 .../CIConfigs/IT_Function_TCPIP_01.yml | 10 + .../CIConfigs/IT_Function_TCPIP_02.yml | 10 + .../CIConfigs/IT_Function_TCPIP_03.yml | 10 + .../CIConfigs/IT_Function_TCPIP_04.yml | 10 + .../CIConfigs/IT_Function_TCPIP_05.yml | 8 + .../CIConfigs/IT_Function_TCPIP_06.yml} | 0 .../CIConfigs/IT_Function_TCPIP_07.yml} | 8 +- .../CIConfigs/IT_Function_TCPIP_08.yml} | 8 +- .../CIConfigs/IT_Function_TCPIP_09.yml | 10 + .../CIConfigs/IT_Function_TCPIP_10.yml} | 6 +- .../CIConfigs/IT_Function_TCPIP_11.yml} | 6 +- .../CIConfigs/IT_Function_TCPIP_12.yml | 6 + .../CIConfigs/IT_Function_WIFI_01.yml | 10 + .../CIConfigs/IT_Function_WIFI_02.yml | 7 + .../CIConfigs/IT_Function_WIFI_03.yml} | 0 .../CIConfigs/IT_Function_WIFI_04.yml} | 0 .../CIConfigs/IT_Function_WIFI_05.yml} | 0 .../CIConfigs/IT_Function_WIFI_06.yml | 7 + .../integration_test}/InitialConditionAll.yml | 3650 +-- .../integration_test}/KnownIssues | 0 .../integration_test}/TestCaseAll.yml | 24339 ++++++++-------- .../integration_test}/TestEnvAll.yml | 388 +- .../uint_test/InitialConditionAll.yml | 2935 ++ components/idf_test/uint_test/TestCaseAll.yml | 1 + components/idf_test/uint_test/TestEnvAll.yml | 275 + .../test/CIConfigs/Function_TCPIP_01.yml | 10 - .../test/CIConfigs/Function_TCPIP_02.yml | 10 - .../test/CIConfigs/Function_TCPIP_03.yml | 10 - .../test/CIConfigs/Function_TCPIP_04.yml | 10 - .../test/CIConfigs/Function_TCPIP_05.yml | 8 - .../test/CIConfigs/Function_TCPIP_07.yml | 10 - .../test/CIConfigs/Function_TCPIP_12.yml | 6 - .../test/CIConfigs/Function_WIFI_01.yml | 10 - .../test/CIConfigs/Function_WIFI_02.yml | 7 - .../test/CIConfigs/Function_WIFI_06.yml | 7 - components/test/README.md | 4 - .../TestCaseScript/ATFunc/CmdInterruptTest.py | 130 - components/test/TestCaseScript/ATFunc/LAP.py | 64 - .../ATFunc/SendDataValidation.py | 161 - .../test/TestCaseScript/ATFunc/UARTTest.py | 164 - .../test/TestCaseScript/ATFunc/__init__.py | 2 - .../TestCaseScript/ATStress/ATPassThrough.py | 179 - .../test/TestCaseScript/ATStress/ATSleep.py | 251 - .../TestCaseScript/ATStress/SoftAPServer.py | 308 - .../TestCaseScript/ATStress/TCPClientMulti.py | 116 - .../ATStress/TCPClientSingle.py | 123 - .../TestCaseScript/ATStress/TCPSendPerf.py | 148 - .../TestCaseScript/ATStress/TCPServerMulti.py | 126 - .../TestCaseScript/ATStress/TCPTransparent.py | 280 - .../test/TestCaseScript/ATStress/UDPMulti.py | 113 - .../test/TestCaseScript/ATStress/UDPSingle.py | 105 - .../TestCaseScript/ATStress/UDPTransparent.py | 262 - .../test/TestCaseScript/ATStress/__init__.py | 2 - components/test/TestCaseScript/IOT/SCIOT.py | 357 - .../test/TestCaseScript/IOT/SCUDPServer.py | 378 - .../TestCaseScript/IOT/WifiConnUtility.py | 244 - components/test/TestCaseScript/IOT/WifiJAP.py | 183 - .../test/TestCaseScript/IOT/__init__.py | 1 - .../TestCaseScript/MeshStress/MeshSendRecv.py | 525 - .../TestCaseScript/MeshStress/__init__.py | 1 - .../test/TestCaseScript/SSLTest/Capability.py | 90 - .../TestCaseScript/SSLTest/ConfigUtility.py | 333 - .../test/TestCaseScript/SSLTest/Parameter.py | 56 - .../test/TestCaseScript/SSLTest/SSLHandler.py | 498 - .../TestCaseScript/SSLTest/SSLHandshake.py | 240 - .../test/TestCaseScript/SSLTest/SSLLowMem.py | 140 - .../TestCaseScript/SSLTest/SSLSendRecv.py | 147 - .../test/TestCaseScript/SSLTest/__init__.py | 1 - .../TestCaseScript/SleepMode/AutoSleep.py | 561 - .../TestCaseScript/SleepMode/DeepSleep.py | 259 - .../TestCaseScript/SleepMode/ForceSleep.py | 254 - .../test/TestCaseScript/SleepMode/__init__.py | 1 - .../TestCaseScript/StableTest/StableCase1.py | 160 - .../TestCaseScript/StableTest/__init__.py | 1 - .../TestCaseScript/TCPIPStress/ARPStress.py | 121 - .../TestCaseScript/TCPIPStress/PingStress.py | 122 - .../TestCaseScript/TCPIPStress/__init__.py | 1 - .../TestCaseScript/TCPStress/TCPAP4STA.py | 168 - .../TestCaseScript/TCPStress/TCPAPNSTA.py | 209 - .../TCPStress/TCPConnStressTC.py | 363 - .../TCPStress/TCPConnUtility.py | 273 - .../TestCaseScript/TCPStress/TCPConnection.py | 321 - .../TCPStress/TCPConnectionUtility.py | 251 - .../TCPStress/TCPDataValidation.py | 244 - .../TestCaseScript/TCPStress/TCPRandomSend.py | 103 - .../TestCaseScript/TCPStress/TCPSendRecv.py | 143 - .../TCPStress/TCPSoftAPSTASendRecv.py | 318 - .../TestCaseScript/TCPStress/TCPThroughput.py | 315 - .../test/TestCaseScript/TCPStress/__init__.py | 1 - .../TestCaseScript/UDPStress/UDPSendRecv.py | 130 - .../TestCaseScript/UDPStress/UDPThroughput.py | 305 - .../test/TestCaseScript/UDPStress/__init__.py | 1 - .../TestCaseScript/WiFiStress/SoftAPNSTA.py | 178 - .../WiFiStress/WifiConnUtility.py | 240 - .../test/TestCaseScript/WiFiStress/WifiJAP.py | 218 - .../TestCaseScript/WiFiStress/WifiJAPAtt.py | 173 - .../WiFiStress/WifiSmartConfig.py | 273 - .../TestCaseScript/WiFiStress/__init__.py | 1 - components/test/TestCaseScript/__init__.py | 2 - 102 files changed, 17710 insertions(+), 25726 deletions(-) create mode 100644 components/idf_test/README.md rename components/{test/CIConfigs/Function_SYS_01.yml => idf_test/integration_test/CIConfigs/IT_Function_SYS_01.yml} (100%) create mode 100644 components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_01.yml create mode 100644 components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_02.yml create mode 100644 components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_03.yml create mode 100644 components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_04.yml create mode 100644 components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_05.yml rename components/{test/CIConfigs/Function_TCPIP_06.yml => idf_test/integration_test/CIConfigs/IT_Function_TCPIP_06.yml} (100%) rename components/{test/CIConfigs/Function_TCPIP_08.yml => idf_test/integration_test/CIConfigs/IT_Function_TCPIP_07.yml} (53%) rename components/{test/CIConfigs/Function_TCPIP_09.yml => idf_test/integration_test/CIConfigs/IT_Function_TCPIP_08.yml} (51%) create mode 100644 components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_09.yml rename components/{test/CIConfigs/Function_TCPIP_10.yml => idf_test/integration_test/CIConfigs/IT_Function_TCPIP_10.yml} (66%) rename components/{test/CIConfigs/Function_TCPIP_11.yml => idf_test/integration_test/CIConfigs/IT_Function_TCPIP_11.yml} (67%) create mode 100644 components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_12.yml create mode 100644 components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_01.yml create mode 100644 components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_02.yml rename components/{test/CIConfigs/Function_WIFI_03.yml => idf_test/integration_test/CIConfigs/IT_Function_WIFI_03.yml} (100%) rename components/{test/CIConfigs/Function_WIFI_04.yml => idf_test/integration_test/CIConfigs/IT_Function_WIFI_04.yml} (100%) rename components/{test/CIConfigs/Function_WIFI_05.yml => idf_test/integration_test/CIConfigs/IT_Function_WIFI_05.yml} (100%) create mode 100644 components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_06.yml rename components/{test => idf_test/integration_test}/InitialConditionAll.yml (96%) rename components/{test => idf_test/integration_test}/KnownIssues (100%) rename components/{test => idf_test/integration_test}/TestCaseAll.yml (98%) rename components/{test => idf_test/integration_test}/TestEnvAll.yml (100%) create mode 100644 components/idf_test/uint_test/InitialConditionAll.yml create mode 100644 components/idf_test/uint_test/TestCaseAll.yml create mode 100644 components/idf_test/uint_test/TestEnvAll.yml delete mode 100644 components/test/CIConfigs/Function_TCPIP_01.yml delete mode 100644 components/test/CIConfigs/Function_TCPIP_02.yml delete mode 100644 components/test/CIConfigs/Function_TCPIP_03.yml delete mode 100644 components/test/CIConfigs/Function_TCPIP_04.yml delete mode 100644 components/test/CIConfigs/Function_TCPIP_05.yml delete mode 100644 components/test/CIConfigs/Function_TCPIP_07.yml delete mode 100644 components/test/CIConfigs/Function_TCPIP_12.yml delete mode 100644 components/test/CIConfigs/Function_WIFI_01.yml delete mode 100644 components/test/CIConfigs/Function_WIFI_02.yml delete mode 100644 components/test/CIConfigs/Function_WIFI_06.yml delete mode 100644 components/test/README.md delete mode 100755 components/test/TestCaseScript/ATFunc/CmdInterruptTest.py delete mode 100644 components/test/TestCaseScript/ATFunc/LAP.py delete mode 100755 components/test/TestCaseScript/ATFunc/SendDataValidation.py delete mode 100644 components/test/TestCaseScript/ATFunc/UARTTest.py delete mode 100755 components/test/TestCaseScript/ATFunc/__init__.py delete mode 100755 components/test/TestCaseScript/ATStress/ATPassThrough.py delete mode 100644 components/test/TestCaseScript/ATStress/ATSleep.py delete mode 100755 components/test/TestCaseScript/ATStress/SoftAPServer.py delete mode 100755 components/test/TestCaseScript/ATStress/TCPClientMulti.py delete mode 100755 components/test/TestCaseScript/ATStress/TCPClientSingle.py delete mode 100755 components/test/TestCaseScript/ATStress/TCPSendPerf.py delete mode 100755 components/test/TestCaseScript/ATStress/TCPServerMulti.py delete mode 100755 components/test/TestCaseScript/ATStress/TCPTransparent.py delete mode 100755 components/test/TestCaseScript/ATStress/UDPMulti.py delete mode 100755 components/test/TestCaseScript/ATStress/UDPSingle.py delete mode 100755 components/test/TestCaseScript/ATStress/UDPTransparent.py delete mode 100755 components/test/TestCaseScript/ATStress/__init__.py delete mode 100755 components/test/TestCaseScript/IOT/SCIOT.py delete mode 100755 components/test/TestCaseScript/IOT/SCUDPServer.py delete mode 100755 components/test/TestCaseScript/IOT/WifiConnUtility.py delete mode 100755 components/test/TestCaseScript/IOT/WifiJAP.py delete mode 100755 components/test/TestCaseScript/IOT/__init__.py delete mode 100755 components/test/TestCaseScript/MeshStress/MeshSendRecv.py delete mode 100755 components/test/TestCaseScript/MeshStress/__init__.py delete mode 100755 components/test/TestCaseScript/SSLTest/Capability.py delete mode 100755 components/test/TestCaseScript/SSLTest/ConfigUtility.py delete mode 100755 components/test/TestCaseScript/SSLTest/Parameter.py delete mode 100644 components/test/TestCaseScript/SSLTest/SSLHandler.py delete mode 100755 components/test/TestCaseScript/SSLTest/SSLHandshake.py delete mode 100644 components/test/TestCaseScript/SSLTest/SSLLowMem.py delete mode 100644 components/test/TestCaseScript/SSLTest/SSLSendRecv.py delete mode 100755 components/test/TestCaseScript/SSLTest/__init__.py delete mode 100755 components/test/TestCaseScript/SleepMode/AutoSleep.py delete mode 100755 components/test/TestCaseScript/SleepMode/DeepSleep.py delete mode 100755 components/test/TestCaseScript/SleepMode/ForceSleep.py delete mode 100755 components/test/TestCaseScript/SleepMode/__init__.py delete mode 100755 components/test/TestCaseScript/StableTest/StableCase1.py delete mode 100755 components/test/TestCaseScript/StableTest/__init__.py delete mode 100755 components/test/TestCaseScript/TCPIPStress/ARPStress.py delete mode 100755 components/test/TestCaseScript/TCPIPStress/PingStress.py delete mode 100755 components/test/TestCaseScript/TCPIPStress/__init__.py delete mode 100755 components/test/TestCaseScript/TCPStress/TCPAP4STA.py delete mode 100755 components/test/TestCaseScript/TCPStress/TCPAPNSTA.py delete mode 100755 components/test/TestCaseScript/TCPStress/TCPConnStressTC.py delete mode 100755 components/test/TestCaseScript/TCPStress/TCPConnUtility.py delete mode 100755 components/test/TestCaseScript/TCPStress/TCPConnection.py delete mode 100755 components/test/TestCaseScript/TCPStress/TCPConnectionUtility.py delete mode 100755 components/test/TestCaseScript/TCPStress/TCPDataValidation.py delete mode 100755 components/test/TestCaseScript/TCPStress/TCPRandomSend.py delete mode 100755 components/test/TestCaseScript/TCPStress/TCPSendRecv.py delete mode 100644 components/test/TestCaseScript/TCPStress/TCPSoftAPSTASendRecv.py delete mode 100755 components/test/TestCaseScript/TCPStress/TCPThroughput.py delete mode 100755 components/test/TestCaseScript/TCPStress/__init__.py delete mode 100755 components/test/TestCaseScript/UDPStress/UDPSendRecv.py delete mode 100755 components/test/TestCaseScript/UDPStress/UDPThroughput.py delete mode 100755 components/test/TestCaseScript/UDPStress/__init__.py delete mode 100755 components/test/TestCaseScript/WiFiStress/SoftAPNSTA.py delete mode 100755 components/test/TestCaseScript/WiFiStress/WifiConnUtility.py delete mode 100755 components/test/TestCaseScript/WiFiStress/WifiJAP.py delete mode 100755 components/test/TestCaseScript/WiFiStress/WifiJAPAtt.py delete mode 100755 components/test/TestCaseScript/WiFiStress/WifiSmartConfig.py delete mode 100755 components/test/TestCaseScript/WiFiStress/__init__.py delete mode 100755 components/test/TestCaseScript/__init__.py diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7834707fef..42dc78e9ee 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -115,7 +115,7 @@ test_report: allow_failure: true variables: LOG_PATH: "$CI_PROJECT_DIR/$CI_BUILD_REF" - TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/components/test" + TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/components/idf_test" REPORT_PATH: "$CI_PROJECT_DIR/CI_Test_Report" artifacts: when: always @@ -170,8 +170,8 @@ push_master_to_github: BIN_PATH: "$CI_PROJECT_DIR/SSC/build/" APP_NAME: "ssc" LOG_PATH: "$CI_PROJECT_DIR/$CI_BUILD_REF" - # assume tests are put in "components/test" - TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/components/test" + # append test level folder to TEST_CASE_FILE_PATH in before_script of test job + TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/components/idf_test" # jobs MUST set CONFIG_FILE in before_script, and overwrite the variables above if necessary artifacts: @@ -217,144 +217,131 @@ push_master_to_github: # run test - python CIRunner.py -l $LOG_PATH -c $CONFIG_FILE -e $LOCAL_ENV_CONFIG_PATH -t $TEST_CASE_FILE_PATH bin_path $APP_NAME $BIN_PATH -Function_SYS_01: +IT_Function_SYS_01: <<: *test_template tags: - ESP32_IDF - SSC_T1_1 before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_SYS_01.yml + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_SYS_01.yml + - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test -Function_WIFI_01: +IT_Function_WIFI_01: <<: *test_template tags: - ESP32_IDF - SSC_T1_1 - SSC_T2_1 before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_WIFI_01.yml + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_01.yml + - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test -Function_WIFI_02: +IT_Function_WIFI_02: <<: *test_template tags: - ESP32_IDF - SSC_T1_1 - SSC_T2_1 before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_WIFI_02.yml + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_02.yml + - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test -Function_TCPIP_01: +IT_Function_TCPIP_01: <<: *test_template tags: - ESP32_IDF - SSC_T1_1 - SSC_T2_1 before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_TCPIP_01.yml + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_01.yml + - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test -Function_TCPIP_02: +IT_Function_TCPIP_02: <<: *test_template tags: - ESP32_IDF - SSC_T1_1 - SSC_T2_1 before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_TCPIP_02.yml + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_02.yml + - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test -Function_TCPIP_03: +IT_Function_TCPIP_03: <<: *test_template tags: - ESP32_IDF - SSC_T1_1 - SSC_T2_1 before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_TCPIP_03.yml + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_03.yml + - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test -Function_TCPIP_04: +IT_Function_TCPIP_04: <<: *test_template tags: - ESP32_IDF - SSC_T1_1 - SSC_T2_1 before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_TCPIP_04.yml + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_04.yml + - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test -Function_TCPIP_05: +IT_Function_TCPIP_05: <<: *test_template tags: - ESP32_IDF - SSC_T1_1 - SSC_T2_1 before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_TCPIP_05.yml + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_05.yml + - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test -Function_TCPIP_06: +IT_Function_TCPIP_06: <<: *test_template_night tags: - ESP32_IDF - SSC_T1_1 before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_TCPIP_06.yml + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_06.yml + - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test -Function_WIFI_03: +IT_Function_WIFI_03: <<: *test_template tags: - ESP32_IDF - SSC_T3_PhyMode before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_WIFI_03.yml + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_03.yml + - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test -Function_WIFI_04: +IT_Function_WIFI_04: <<: *test_template tags: - ESP32_IDF - SSC_T1_APC before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_WIFI_04.yml + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_04.yml + - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test -Function_WIFI_05: +IT_Function_WIFI_05: <<: *test_template tags: - ESP32_IDF - SSC_T1_WEP before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_WIFI_05.yml + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_05.yml + - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test -Function_WIFI_06: +IT_Function_WIFI_06: <<: *test_template tags: - ESP32_IDF - SSC_T2_PhyMode before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_WIFI_06.yml + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_06.yml + - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test -Function_TCPIP_07: - <<: *test_template - tags: - - ESP32_IDF - - SSC_T1_1 - - SSC_T1_2 - before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_TCPIP_07.yml - -Function_TCPIP_08: - <<: *test_template - tags: - - ESP32_IDF - - SSC_T1_1 - - SSC_T2_1 - before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_TCPIP_08.yml - -Function_TCPIP_09: - <<: *test_template - tags: - - ESP32_IDF - - SSC_T1_1 - before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_TCPIP_09.yml - -Function_TCPIP_10: +IT_Function_TCPIP_07: <<: *test_template tags: - ESP32_IDF @@ -362,21 +349,53 @@ Function_TCPIP_10: - SSC_T1_2 - SSC_T2_1 before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_TCPIP_10.yml + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_07.yml + - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test -Function_TCPIP_11: +IT_Function_TCPIP_08: <<: *test_template tags: - ESP32_IDF - SSC_T1_1 before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_TCPIP_11.yml + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_08.yml + - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test -Function_TCPIP_12: +IT_Function_TCPIP_09: + <<: *test_template + tags: + - ESP32_IDF + - SSC_T1_1 + before_script: + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_09.yml + - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test + +IT_Function_TCPIP_10: + <<: *test_template + tags: + - ESP32_IDF + - SSC_T1_1 + - SSC_T1_2 + - SSC_T2_1 + before_script: + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_10.yml + - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test + +IT_Function_TCPIP_11: + <<: *test_template + tags: + - ESP32_IDF + - SSC_T1_1 + before_script: + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_11.yml + - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test + +IT_Function_TCPIP_12: <<: *test_template tags: - ESP32_IDF - SSC_T1_1 - SSC_T1_2 before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/Function_TCPIP_12.yml + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_12.yml + - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test diff --git a/components/idf_test/README.md b/components/idf_test/README.md new file mode 100644 index 0000000000..f23153bca6 --- /dev/null +++ b/components/idf_test/README.md @@ -0,0 +1,61 @@ + +# Note: The test cases in this folder are for Espressif internal use. + +# Goto internal project wiki Testing page for detail about this folder. + +## File Structure + +``` +test --- CIConfigs --- sanity_test1.yml (Runner config files) + | |-- stress_test1.yml + |-- TestCaseAll.yml (TestCaseFiles) + |-- TestEnvAll.yml (TestCaseFiles) + |-- InitialConditionAll.yml (TestCaseFiles) + |-- TestCaseScript --- ... (Test case scripts) +``` + +1. CIConfigs folder + * config for CI config files are put in this folder + * CI config files configs the cases and some other options for the CI job with same name +1. Test case files + * TestCaseAll.yml (test cases) + * InitialConditionAll.yml (initial conditions) + * TestEnvAll.yml (test environments) + * [how to modify test cases](https://gitlab.espressif.cn:6688/yinling/auto_test_script/blob/master/public/Design/TestCaseFiles.DesignNote.md) +1. Test case scripts + * some cases are implemented by specified script. those scripts are put in this folder. + + +## Modify test cases + +1. check if the "SDK" of the test case only contain the current SDK + * if Yes, then just modify the test case behavior + * if No: + 1. then remove current SDK name from "SDK" of the test case + 2. Add a new test case, and set "SDK" only support current SDK name +2. use [auto_test_script](https://gitlab.espressif.cn:6688/yinling/auto_test_script) to load the modified case and verify the modification +3. create a merge request and assign to HYL (or add comment @yinling for merging test). +After review it will be merged to SDK and will be The cases will be synced to database in auto_test_script. + + +## Run test case locally + +1. clone auto_test_script (ssh://git@gitlab.espressif.cn:27227/yinling/auto_test_script.git) from gitlab +2. create test environment: + 1. search test case (search test case ID in components/test/TestCaseAll.yml, get the "test environment" value + 2. goto [test environment list](https://gitlab.espressif.cn:6688/yinling/auto_test_script/blob/master/public/Documents/TestEnvList.md), find the link and goto the environment detail page + 3. create test environment according to figure and description + 4. [config test environment](https://gitlab.espressif.cn:6688/yinling/auto_test_script/blob/master/public/Design/TestEnvConfig.DesignNote.md). All parameters in table "Parameters require config before use" MUST be configured. +3. run test cases with [CIRunner.py](https://gitlab.espressif.cn:6688/yinling/auto_test_script/blob/master/public/Design/RunnerConfigs.DesignNote.md) + + + +## exclude known issues for CI +the test cases listed in file "KnownIssues" will be excluded by CI when calculating results + +Editing KnownIssues file is very simple, one single line for the ID for each case. +``` +TCPIP_TCP_0101 +TCPIP_TCP_0201 +... +``` \ No newline at end of file diff --git a/components/test/CIConfigs/Function_SYS_01.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_SYS_01.yml similarity index 100% rename from components/test/CIConfigs/Function_SYS_01.yml rename to components/idf_test/integration_test/CIConfigs/IT_Function_SYS_01.yml diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_01.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_01.yml new file mode 100644 index 0000000000..25a3ccda99 --- /dev/null +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_01.yml @@ -0,0 +1,10 @@ +Config: {execute count: 1, execute order: in order} +DUT: [SSC2, SSC1] +Filter: +- Add: + ID: [^TCPIP_DHCP_0302, TCPIP_DHCP_0302, TCPIP_DHCP_0301, TCPIP_TCP_0403, TCPIP_TCP_0402, + TCPIP_TCP_0401, TCPIP_TCP_0407, TCPIP_TCP_0406, ^TCPIP_TCP_0411, TCPIP_TCP_0404, + TCPIP_TCP_0408, TCPIP_TCP_0110, TCPIP_TCP_0115, TCPIP_IP_0101, TCPIP_IP_0102, + ^TCPIP_IGMP_0102, ^TCPIP_IGMP_0101, ^TCPIP_IGMP_0104, TCPIP_IGMP_0104, TCPIP_IGMP_0103, + TCPIP_IGMP_0102, TCPIP_IGMP_0101, TCPIP_UDP_0108, TCPIP_UDP_0106, TCPIP_UDP_0107, + TCPIP_UDP_0105, TCPIP_UDP_0101, TCPIP_IGMP_0204, TCPIP_IGMP_0201, TCPIP_IGMP_0202] diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_02.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_02.yml new file mode 100644 index 0000000000..61adea9821 --- /dev/null +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_02.yml @@ -0,0 +1,10 @@ +Config: {execute count: 1, execute order: in order} +DUT: [SSC2, SSC1] +Filter: +- Add: + ID: [TCPIP_IGMP_0203, ^TCPIP_TCP_0403, ^TCPIP_TCP_0408, TCPIP_UDP_0201, TCPIP_UDP_0202, + ^TCPIP_DHCP_0301, ^TCPIP_TCP_0101, ^TCPIP_TCP_0103, ^TCPIP_TCP_0105, ^TCPIP_TCP_0104, + ^TCPIP_TCP_0107, ^TCPIP_TCP_0106, ^TCPIP_DHCP_0210, ^TCPIP_DHCP_0211, ^TCPIP_TCP_0404, + TCPIP_TCP_0212, TCPIP_TCP_0210, ^TCPIP_TCP_0406, ^TCPIP_TCP_0407, ^TCPIP_TCP_0401, + ^TCPIP_TCP_0210, ^TCPIP_TCP_0212, TCPIP_DHCP_0211, TCPIP_DHCP_0210, TCPIP_DHCP_0101, + TCPIP_DHCP_0103, TCPIP_DHCP_0102, TCPIP_DHCP_0206, TCPIP_DHCP_0207, ^TCPIP_IP_0102] diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_03.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_03.yml new file mode 100644 index 0000000000..9d64630e9c --- /dev/null +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_03.yml @@ -0,0 +1,10 @@ +Config: {execute count: 1, execute order: in order} +DUT: [SSC2, SSC1] +Filter: +- Add: + ID: [^TCPIP_UDP_0105, ^TCPIP_UDP_0107, ^TCPIP_UDP_0106, ^TCPIP_UDP_0101, TCPIP_TCP_0203, + TCPIP_TCP_0202, ^TCPIP_UDP_0108, ^TCPIP_IGMP_0201, ^TCPIP_IGMP_0203, ^TCPIP_IGMP_0202, + ^TCPIP_IGMP_0103, TCPIP_UDP_0114, TCPIP_UDP_0113, TCPIP_UDP_0112, TCPIP_DHCP_0205, + TCPIP_DHCP_0202, TCPIP_DHCP_0203, ^TCPIP_TCP_0102, TCPIP_TCP_0106, TCPIP_TCP_0107, + TCPIP_TCP_0104, TCPIP_TCP_0105, TCPIP_TCP_0102, TCPIP_TCP_0103, TCPIP_TCP_0101, + ^TCPIP_TCP_0116, ^TCPIP_TCP_0114, ^TCPIP_TCP_0115, ^TCPIP_TCP_0112, ^TCPIP_TCP_0113] diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_04.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_04.yml new file mode 100644 index 0000000000..6be01f698c --- /dev/null +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_04.yml @@ -0,0 +1,10 @@ +Config: {execute count: 1, execute order: in order} +DUT: [SSC2, SSC1] +Filter: +- Add: + ID: [^TCPIP_TCP_0110, ^TCPIP_TCP_0111, TCPIP_DHCP_0209, ^TCPIP_DHCP_0209, ^TCPIP_DHCP_0207, + ^TCPIP_DHCP_0206, ^TCPIP_DHCP_0205, ^TCPIP_DHCP_0204, ^TCPIP_DHCP_0203, ^TCPIP_DHCP_0202, + ^TCPIP_DHCP_0201, TCPIP_TCP_0204, TCPIP_TCP_0207, TCPIP_TCP_0206, TCPIP_TCP_0201, + ^TCPIP_DHCP_0101, ^TCPIP_DHCP_0102, ^TCPIP_DHCP_0103, ^TCPIP_DHCP_0208, TCPIP_TCP_0208, + ^TCPIP_TCP_0202, ^TCPIP_TCP_0203, TCPIP_DHCP_0204, ^TCPIP_TCP_0201, ^TCPIP_TCP_0206, + ^TCPIP_TCP_0207, ^TCPIP_TCP_0204, TCPIP_DHCP_0201, ^TCPIP_TCP_0208, TCPIP_DHCP_0208] diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_05.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_05.yml new file mode 100644 index 0000000000..627d67c408 --- /dev/null +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_05.yml @@ -0,0 +1,8 @@ +Config: {execute count: 1, execute order: in order} +DUT: [SSC2, SSC1] +Filter: +- Add: + ID: [^TCPIP_IGMP_0204, ^TCPIP_TCP_0412, TCPIP_TCP_0411, TCPIP_TCP_0412, ^TCPIP_UDP_0112, + ^TCPIP_UDP_0113, ^TCPIP_UDP_0114, ^TCPIP_UDP_0202, ^TCPIP_UDP_0201, ^TCPIP_IP_0101, + ^TCPIP_TCP_0402, TCPIP_TCP_0114, TCPIP_TCP_0116, TCPIP_TCP_0111, TCPIP_TCP_0113, + TCPIP_TCP_0112] diff --git a/components/test/CIConfigs/Function_TCPIP_06.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_06.yml similarity index 100% rename from components/test/CIConfigs/Function_TCPIP_06.yml rename to components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_06.yml diff --git a/components/test/CIConfigs/Function_TCPIP_08.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_07.yml similarity index 53% rename from components/test/CIConfigs/Function_TCPIP_08.yml rename to components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_07.yml index 4ada8f3eee..9b3d943fed 100644 --- a/components/test/CIConfigs/Function_TCPIP_08.yml +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_07.yml @@ -2,9 +2,9 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC2, SSC1] Filter: - Add: - ID: [^TCPIP_UDP_0110, ^TCPIP_UDP_0110, ^TCPIP_UDP_0110, ^TCPIP_UDP_0110, ^TCPIP_UDP_0110, + ID: [TCPIP_ICMP_0101, TCPIP_ICMP_0101, TCPIP_ICMP_0101, TCPIP_ICMP_0101, TCPIP_ICMP_0101, + TCPIP_DNS_0102, TCPIP_DNS_0102, TCPIP_DNS_0102, TCPIP_DNS_0102, TCPIP_DNS_0102, + TCPIP_DNS_0101, TCPIP_DNS_0101, TCPIP_DNS_0101, TCPIP_DNS_0101, TCPIP_DNS_0101, ^TCPIP_ICMP_0101, ^TCPIP_ICMP_0101, ^TCPIP_ICMP_0101, ^TCPIP_ICMP_0101, ^TCPIP_ICMP_0101, TCPIP_UDP_0109, TCPIP_UDP_0109, TCPIP_UDP_0109, TCPIP_UDP_0109, TCPIP_UDP_0109, - TCPIP_UDP_0104, TCPIP_UDP_0104, TCPIP_UDP_0104, TCPIP_UDP_0104, TCPIP_UDP_0104, - TCPIP_UDP_0102, TCPIP_UDP_0102, TCPIP_UDP_0102, TCPIP_UDP_0102, TCPIP_UDP_0102, - TCPIP_UDP_0103, TCPIP_UDP_0103, TCPIP_UDP_0103, TCPIP_UDP_0103, TCPIP_UDP_0103] + TCPIP_UDP_0104, TCPIP_UDP_0104, TCPIP_UDP_0104, TCPIP_UDP_0104, TCPIP_UDP_0104] diff --git a/components/test/CIConfigs/Function_TCPIP_09.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_08.yml similarity index 51% rename from components/test/CIConfigs/Function_TCPIP_09.yml rename to components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_08.yml index a4c1a51638..a2f8f0df07 100644 --- a/components/test/CIConfigs/Function_TCPIP_09.yml +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_08.yml @@ -2,9 +2,9 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC1] Filter: - Add: - ID: [^TCPIP_UDP_0307, ^TCPIP_UDP_0307, ^TCPIP_UDP_0307, ^TCPIP_UDP_0307, ^TCPIP_UDP_0307, + ID: [TCPIP_UDP_0102, TCPIP_UDP_0102, TCPIP_UDP_0102, TCPIP_UDP_0102, TCPIP_UDP_0102, + TCPIP_UDP_0103, TCPIP_UDP_0103, TCPIP_UDP_0103, TCPIP_UDP_0103, TCPIP_UDP_0103, + ^TCPIP_UDP_0307, ^TCPIP_UDP_0307, ^TCPIP_UDP_0307, ^TCPIP_UDP_0307, ^TCPIP_UDP_0307, ^TCPIP_UDP_0306, ^TCPIP_UDP_0306, ^TCPIP_UDP_0306, ^TCPIP_UDP_0306, ^TCPIP_UDP_0306, ^TCPIP_UDP_0305, ^TCPIP_UDP_0305, ^TCPIP_UDP_0305, ^TCPIP_UDP_0305, ^TCPIP_UDP_0305, - ^TCPIP_UDP_0304, ^TCPIP_UDP_0304, ^TCPIP_UDP_0304, ^TCPIP_UDP_0304, ^TCPIP_UDP_0304, - ^TCPIP_UDP_0104, ^TCPIP_UDP_0104, ^TCPIP_UDP_0104, ^TCPIP_UDP_0104, ^TCPIP_UDP_0104, - ^TCPIP_UDP_0103, ^TCPIP_UDP_0103, ^TCPIP_UDP_0103, ^TCPIP_UDP_0103, ^TCPIP_UDP_0103] + ^TCPIP_UDP_0304, ^TCPIP_UDP_0304, ^TCPIP_UDP_0304, ^TCPIP_UDP_0304, ^TCPIP_UDP_0304] diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_09.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_09.yml new file mode 100644 index 0000000000..146b98cf7d --- /dev/null +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_09.yml @@ -0,0 +1,10 @@ +Config: {execute count: 1, execute order: in order} +DUT: [SSC1] +Filter: +- Add: + ID: [^TCPIP_UDP_0303, ^TCPIP_UDP_0303, ^TCPIP_UDP_0303, ^TCPIP_UDP_0303, ^TCPIP_UDP_0303, + ^TCPIP_UDP_0302, ^TCPIP_UDP_0302, ^TCPIP_UDP_0302, ^TCPIP_UDP_0302, ^TCPIP_UDP_0302, + ^TCPIP_UDP_0301, ^TCPIP_UDP_0301, ^TCPIP_UDP_0301, ^TCPIP_UDP_0301, ^TCPIP_UDP_0301, + ^TCPIP_UDP_0104, ^TCPIP_UDP_0104, ^TCPIP_UDP_0104, ^TCPIP_UDP_0104, ^TCPIP_UDP_0104, + ^TCPIP_UDP_0103, ^TCPIP_UDP_0103, ^TCPIP_UDP_0103, ^TCPIP_UDP_0103, ^TCPIP_UDP_0103, + ^TCPIP_UDP_0102, ^TCPIP_UDP_0102, ^TCPIP_UDP_0102, ^TCPIP_UDP_0102, ^TCPIP_UDP_0102] diff --git a/components/test/CIConfigs/Function_TCPIP_10.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_10.yml similarity index 66% rename from components/test/CIConfigs/Function_TCPIP_10.yml rename to components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_10.yml index 201f95eea0..44b7bd1893 100644 --- a/components/test/CIConfigs/Function_TCPIP_10.yml +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_10.yml @@ -2,9 +2,9 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC2, SSC1] Filter: - Add: - ID: [^TCPIP_UDP_0102, ^TCPIP_UDP_0102, ^TCPIP_UDP_0102, ^TCPIP_UDP_0102, ^TCPIP_UDP_0102, - TCPIP_UDP_0111, TCPIP_UDP_0111, TCPIP_UDP_0111, TCPIP_UDP_0111, TCPIP_UDP_0111, + ID: [TCPIP_UDP_0111, TCPIP_UDP_0111, TCPIP_UDP_0111, TCPIP_UDP_0111, TCPIP_UDP_0111, TCPIP_UDP_0110, TCPIP_UDP_0110, TCPIP_UDP_0110, TCPIP_UDP_0110, TCPIP_UDP_0110, ^TCPIP_DNS_0101, ^TCPIP_DNS_0101, ^TCPIP_DNS_0101, ^TCPIP_DNS_0101, ^TCPIP_DNS_0101, ^TCPIP_DNS_0103, ^TCPIP_DNS_0103, ^TCPIP_DNS_0103, ^TCPIP_DNS_0103, ^TCPIP_DNS_0103, - ^TCPIP_DNS_0102, ^TCPIP_DNS_0102, ^TCPIP_DNS_0102, ^TCPIP_DNS_0102, ^TCPIP_DNS_0102] + ^TCPIP_DNS_0102, ^TCPIP_DNS_0102, ^TCPIP_DNS_0102, ^TCPIP_DNS_0102, ^TCPIP_DNS_0102, + TCPIP_UDP_0304, TCPIP_UDP_0304, TCPIP_UDP_0304, TCPIP_UDP_0304, TCPIP_UDP_0304] diff --git a/components/test/CIConfigs/Function_TCPIP_11.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_11.yml similarity index 67% rename from components/test/CIConfigs/Function_TCPIP_11.yml rename to components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_11.yml index 1d083887c3..86690db67c 100644 --- a/components/test/CIConfigs/Function_TCPIP_11.yml +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_11.yml @@ -2,9 +2,9 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC1] Filter: - Add: - ID: [TCPIP_UDP_0304, TCPIP_UDP_0304, TCPIP_UDP_0304, TCPIP_UDP_0304, TCPIP_UDP_0304, - TCPIP_UDP_0305, TCPIP_UDP_0305, TCPIP_UDP_0305, TCPIP_UDP_0305, TCPIP_UDP_0305, + ID: [TCPIP_UDP_0305, TCPIP_UDP_0305, TCPIP_UDP_0305, TCPIP_UDP_0305, TCPIP_UDP_0305, TCPIP_UDP_0306, TCPIP_UDP_0306, TCPIP_UDP_0306, TCPIP_UDP_0306, TCPIP_UDP_0306, TCPIP_UDP_0307, TCPIP_UDP_0307, TCPIP_UDP_0307, TCPIP_UDP_0307, TCPIP_UDP_0307, TCPIP_UDP_0301, TCPIP_UDP_0301, TCPIP_UDP_0301, TCPIP_UDP_0301, TCPIP_UDP_0301, - TCPIP_UDP_0302, TCPIP_UDP_0302, TCPIP_UDP_0302, TCPIP_UDP_0302, TCPIP_UDP_0302] + TCPIP_UDP_0302, TCPIP_UDP_0302, TCPIP_UDP_0302, TCPIP_UDP_0302, TCPIP_UDP_0302, + TCPIP_UDP_0303, TCPIP_UDP_0303, TCPIP_UDP_0303, TCPIP_UDP_0303, TCPIP_UDP_0303] diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_12.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_12.yml new file mode 100644 index 0000000000..4e0495e44d --- /dev/null +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_12.yml @@ -0,0 +1,6 @@ +Config: {execute count: 1, execute order: in order} +DUT: [SSC1] +Filter: +- Add: + ID: [TCPIP_DNS_0103, TCPIP_DNS_0103, TCPIP_DNS_0103, TCPIP_DNS_0103, TCPIP_DNS_0103, + ^TCPIP_UDP_0110, ^TCPIP_UDP_0110, ^TCPIP_UDP_0110, ^TCPIP_UDP_0110, ^TCPIP_UDP_0110] diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_01.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_01.yml new file mode 100644 index 0000000000..c22bc59bd8 --- /dev/null +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_01.yml @@ -0,0 +1,10 @@ +Config: {execute count: 1, execute order: in order} +DUT: [SSC2, SSC1] +Filter: +- Add: + ID: [^WIFI_CONN_0601, ^WIFI_ADDR_0101, WIFI_SCAN_0103, WIFI_SCAN_0102, WIFI_SCAN_0101, + WIFI_SCAN_0105, WIFI_SCAN_0104, ^WIFI_CONN_0103, WIFI_CONN_0201, WIFI_CONN_0904, + ^WIFI_SCAN_0102, ^WIFI_SCAN_0103, ^WIFI_SCAN_0104, ^WIFI_SCAN_0105, WIFI_CONN_0401, + WIFI_ADDR_0101, WIFI_ADDR_0102, WIFI_CONN_0301, ^WIFI_CONN_0801, ^WIFI_CONN_0301, + WIFI_CONN_0501, WIFI_CONN_0502, ^WIFI_CONN_0401, WIFI_MODE_0101, WIFI_MODE_0103, + WIFI_MODE_0102, ^WIFI_CONN_0904, ^WIFI_CONN_0901, WIFI_CONN_0601, ^WIFI_CONN_0201] diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_02.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_02.yml new file mode 100644 index 0000000000..049054dbac --- /dev/null +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_02.yml @@ -0,0 +1,7 @@ +Config: {execute count: 1, execute order: in order} +DUT: [SSC2, SSC1] +Filter: +- Add: + ID: [^WIFI_ADDR_0102, WIFI_CONN_0901, WIFI_CONN_0801, ^WIFI_CONN_0104, WIFI_CONN_0104, + WIFI_CONN_0101, WIFI_CONN_0102, WIFI_CONN_0103, ^WIFI_SCAN_0101, ^WIFI_CONN_0101, + ^WIFI_CONN_0502, ^WIFI_CONN_0501] diff --git a/components/test/CIConfigs/Function_WIFI_03.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_03.yml similarity index 100% rename from components/test/CIConfigs/Function_WIFI_03.yml rename to components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_03.yml diff --git a/components/test/CIConfigs/Function_WIFI_04.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_04.yml similarity index 100% rename from components/test/CIConfigs/Function_WIFI_04.yml rename to components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_04.yml diff --git a/components/test/CIConfigs/Function_WIFI_05.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_05.yml similarity index 100% rename from components/test/CIConfigs/Function_WIFI_05.yml rename to components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_05.yml diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_06.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_06.yml new file mode 100644 index 0000000000..9d639f9121 --- /dev/null +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_06.yml @@ -0,0 +1,7 @@ +Config: {execute count: 1, execute order: in order} +DUT: [SSC2, SSC1] +Filter: +- Add: + ID: [WIFI_SCAN_0301, WIFI_SCAN_0303, WIFI_SCAN_0304, WIFI_SCAN_0302, WIFI_SCAN_0201, + WIFI_PHY_0403, WIFI_PHY_0402, WIFI_PHY_0401, WIFI_PHY_0407, WIFI_PHY_0406, WIFI_PHY_0405, + WIFI_PHY_0404, WIFI_PHY_0408] diff --git a/components/test/InitialConditionAll.yml b/components/idf_test/integration_test/InitialConditionAll.yml similarity index 96% rename from components/test/InitialConditionAll.yml rename to components/idf_test/integration_test/InitialConditionAll.yml index 797ccad550..ba06af9f87 100644 --- a/components/test/InitialConditionAll.yml +++ b/components/idf_test/integration_test/InitialConditionAll.yml @@ -1,135 +1,195 @@ initial condition: - check cmd set: - '' - - - ASSERT - - [dummy] - - - SSC SSC[1-] mesh -Q -t 4 - - ['R SSC[1-] T '] - - - MESHTREE - - ['R PC_COM RE "MESHTREE:%%s%20nodes"%%()'] + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:2'] + - - SSC SSC1 ap -Q + - ['R SSC1 RE "\+APCONFIG:%%s,%%s,\d+,\d+,\d+,4,"%%(,)'] + - - SSC SSC1 dhcp -Q -o 2 + - ['R SSC1 C +DHCP:AP,STARTED'] + - - SSC SSC1 mac -Q -o 2 + - [R SSC1 P ] force restore cmd set: - '' - - - SSC SSC[1-] reboot - - ['P SSC[1-] C !!!ready!!!'] - - - SSC SSC[1-] mesh -I -g -a 4 -k -i - -p -h 5 - - ['P SSC[1-] C ENCRYPTION,OK C GROUP,OK C SERVER,OK C HOP,OK'] - - - SSC SSC1 mesh -A -s -k - - ['P SSC1 C +MESHINIT:AP,OK'] - - - SSC SSC1 mesh -E -o 1 -t 1 - - ['P SSC1 C +MESH:ENABLED'] - - - SSC SSC[2-] mesh -E -o 1 -t 2 - - [''] - - - DELAY 60 - - ['P SSC[2-] C +MESH:ENABLED'] - - - SSC SSC[1-] mesh -C - - ['P SSC[1-] C +MESH:CONNECTED'] - - - SSC SSC[1-] mesh -Q -t 4 - - ['R SSC[1-] T '] - - - MESHTREE - - ['R PC_COM RE "MESHTREE:%%s%20nodes"%%()'] - initial condition detail: root as LOCAL, rest node as ONLINE, mesh network established + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + initial condition detail: AP mode, DHCP on, will autogen a TC with initial condition + APSTA1 restore cmd set: - '' - - - SSC SSC[1-] mesh -E -o 0 - - ['P SSC[1-] C +MESH:DISABLED'] - - - SSC SSC[1-] mesh -I -g -a 4 -k -i - -p -h 5 - - ['P SSC[1-] C ENCRYPTION,OK C GROUP,OK C SERVER,OK C HOP,OK'] - - - SSC SSC1 mesh -A -s -k - - ['P SSC1 C +MESHINIT:AP,OK'] - - - SSC SSC1 mesh -E -o 1 -t 1 - - ['P SSC1 C +MESH:ENABLED'] - - - SSC SSC[2-] mesh -E -o 1 -t 2 - - [''] - - - DELAY 60 - - ['P SSC[2-] C +MESH:ENABLED'] - - - SSC SSC[1-] mesh -C - - ['P SSC[1-] C +MESH:CONNECTED'] - - - SSC SSC[1-] mesh -Q -t 4 - - ['R SSC[1-] T '] - - - MESHTREE - - ['R PC_COM RE "MESHTREE:%%s%20nodes"%%()'] + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] restore post cmd set: - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] - - SSC SSC1 ram - - ['R SSC1 A :(\d+)'] + - ['R SSC1 C +FREEHEAP:'] script path: InitCondBase.py - start: 24.0 - tag: ENABLED_2 + start: 31.0 + tag: APM1 test script: InitCondBase - check cmd set: - '' - - - ASSERT - - [dummy] - - - SSC SSC[1-] mesh -Q -t 4 - - ['R SSC[1-] T '] - - - MESHTREE - - ['R PC_COM RE "MESHTREE:%%s%20nodes"%%()'] + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:2'] + - - SSC SSC1 ap -Q + - ['R SSC1 RE "\+APCONFIG:%%s,%%s,\d+,\d+,\d+,4,"%%(,)'] + - - SSC SSC1 ap -L + - ['R SSC1 RE "\+LSTA:.+,%%s"%%()'] + - - SSC SSC1 dhcp -Q -o 2 + - ['R SSC1 C +DHCP:AP,STARTED'] + - - SSC SSC1 mac -Q -o 2 + - [R SSC1 P ] force restore cmd set: - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC[1-] mesh -E -o 0 - - ['P SSC[1-] C +MESH:DISABLED'] - - - SSC SSC[1-] mesh -I -g -a 4 -k -i - -p -h 5 - - ['P SSC[1-] C ENCRYPTION,OK C GROUP,OK C SERVER,OK C HOP,OK'] - - - SSC SSC[1-] mesh -A -s -k - - ['P SSC[1-] C +MESHINIT:AP,OK'] - - - SSC SSC1 mesh -E -o 1 -t 2 - - ['P SSC1 C +MESH:ENABLED'] - - - SOC SOC1 MACCEPT GSOC1 - - [R SOC_COM L OK] - - - SSC SSC[2-] mesh -E -o 1 -t 2 - - ['P SSC[2-] C +MESH:ENABLED'] - - - DELAY 60 - - [''] - - - SSC SSC[1-] mesh -C - - ['P SSC[1-] C +MESH:CONNECTED'] - - - SSC SSC[1-] mesh -Q -t 4 - - ['R SSC[1-] T '] - - - MESHTREE - - ['R PC_COM RE "MESHTREE:%%s%20nodes"%%()'] - - - SSC SSC[1-] mesh -O -t 1 -o 1 - - ['P SSC[1-] C +MESH:OK'] - initial condition detail: all mesh node enabled as ONLINE, mesh network established + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - WIFI CONN + + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + initial condition detail: AP mode, PC join AP, DHCP on, will autogen a TC with initial + condition APSTA2 restore cmd set: - '' - - - SSC SSC[1-] reboot - - ['P SSC[1-] C !!!ready!!!'] - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC[1-] mesh -E -o 0 - - ['P SSC[1-] C +MESH:DISABLED'] - - - SSC SSC[1-] mesh -I -g -a 4 -k -i - -p -h 5 - - ['P SSC[1-] C ENCRYPTION,OK C GROUP,OK C SERVER,OK C HOP,OK'] - - - SSC SSC[1-] mesh -A -s -k - - ['P SSC[1-] C +MESHINIT:AP,OK'] - - - SSC SSC1 mesh -E -o 1 -t 2 - - ['P SSC1 C +MESH:ENABLED'] - - - SOC SOC1 MACCEPT GSOC1 - - [R SOC_COM L OK] - - - SSC SSC[2-] mesh -E -o 1 -t 2 - - ['P SSC[2-] C +MESH:ENABLED'] - - - DELAY 60 - - [''] - - - SSC SSC[1-] mesh -C - - ['P SSC[1-] C +MESH:CONNECTED'] - - - SSC SSC[1-] mesh -Q -t 4 - - ['R SSC[1-] T '] - - - MESHTREE - - ['R PC_COM RE "MESHTREE:%%s%20nodes"%%()'] - - - SSC SSC[1-] mesh -O -t 1 -o 1 - - ['P SSC[1-] C +MESH:OK'] + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - WIFI CONN + + - ['R PC_COM NC ERROR C +WIFICONN:OK'] restore post cmd set: - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] - - SSC SSC1 ram - - ['R SSC1 A :(\d+)'] + - ['R SSC1 C +FREEHEAP:'] script path: InitCondBase.py - start: 17.0 - tag: ENABLED_1 + start: 38.0 + tag: APM2 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:2'] + - - SSC SSC1 ap -Q + - ['R SSC1 RE "\+APCONFIG:%%s,%%s,\d+,\d+,\d+,4,"%%(,)'] + - - SSC SSC1 dhcp -Q -o 2 + - ['R SSC1 C +DHCP:AP,STARTED'] + - - SSC SSC1 mac -Q -o 2 + - [R SSC1 P ] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + initial condition detail: AP mode, will NOT autogen a TC with initial condition + APSTA1 + restore cmd set: + - '' + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 ram + - ['R SSC1 C +FREEHEAP:'] + script path: InitCondBase.py + start: 31.0 + tag: APO1 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:2'] + - - SSC SSC1 ap -Q + - ['R SSC1 RE "\+APCONFIG:%%s,%%s,\d+,\d+,\d+,4,"%%(,)'] + - - SSC SSC1 ap -L + - ['R SSC1 RE "\+LSTA:.+,%%s"%%()'] + - - SSC SSC1 dhcp -Q -o 2 + - ['R SSC1 C +DHCP:AP,STARTED'] + - - SSC SSC1 mac -Q -o 2 + - [R SSC1 P ] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - WIFI CONN + + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + initial condition detail: AP mode, will NOT autogen a TC with initial condition + APSTA2 + restore cmd set: + - '' + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - WIFI CONN + + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 ram + - ['R SSC1 C +FREEHEAP:'] + script path: InitCondBase.py + start: 38.0 + tag: APO2 test script: InitCondBase - check cmd set: - '' @@ -137,17 +197,13 @@ initial condition: - ['R SSC1 C BIN_ID,0'] - - SSC SSC1 upgrade -Q -t 2 -b 0 - ['R SSC1 C BIN_INFO,0'] - - - SSC SSC1 op -S -o 3 + - - SSC SSC1 op -S -o 2 - ['R SSC1 C +MODE:OK'] - - - SSC SSC1 dhcp -S -o 1 - - [R SSC1 C +DHCP] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] force restore cmd set: - '' - - SSC SSC1 upgrade -R -r 1 -s - [R SSC1 NC ERROR C !!!ready!!!] - - - SSC SSC1 op -S -o 3 + - - SSC SSC1 op -S -o 1 - ['R SSC1 C +MODE:OK'] - - SSC SSC1 dhcp -S -o 1 - [R SSC1 C +DHCP] @@ -163,24 +219,17 @@ initial condition: - ['P SSC1 C +UPGRADE:SUCCEED'] - - SSC SSC1 upgrade -R -b 0 - [R SSC1 C !!!ready!!!] - - - SSC SSC1 dhcp -S -o 1 - - [R SSC1 C +DHCP] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] - initial condition detail: APSTA mode, connected to AP, running BIN0 (located on - flash id 0) + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + initial condition detail: AP only mode, running BIN0 (located on flash id 0) restore cmd set: - '' - - SSC SSC1 upgrade -Q -t 2 -b 0 - ['R SSC1 C BIN_INFO,0'] - - SSC SSC1 upgrade -R -b 0 - [R SSC1 C !!!ready!!!] - - - SSC SSC1 op -S -o 3 + - - SSC SSC1 op -S -o 2 - ['R SSC1 C +MODE:OK'] - - - SSC SSC1 dhcp -S -o 1 - - [R SSC1 C +DHCP] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] restore post cmd set: - '' - - SSC SSC1 upgrade -D @@ -188,8 +237,51 @@ initial condition: - - SSC SSC1 ram - ['R SSC1 A :(\d+)'] script path: InitCondBase.py - start: 24.0 - tag: STAAPBIN0 + start: 31.0 + tag: APOBIN0 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:3'] + - - SSC SSC1 ap -Q + - ['R SSC1 RE "\+APCONFIG:%%s,%%s,\d+,\d+,\d+,4,"%%(,)'] + - - SSC SSC1 dhcp -Q -o 2 + - ['R SSC1 C +DHCP:AP,STARTED'] + - - SSC SSC1 mac -Q -o 2 + - [R SSC1 P ] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + initial condition detail: testing ap on sta + ap mode (autogen by APM1) + restore cmd set: + - '' + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 ram + - ['R SSC1 C +FREEHEAP:'] + script path: InitCondBase.py + start: 59.0 + tag: APSTA1 test script: InitCondBase - check cmd set: - '' @@ -209,204 +301,46 @@ initial condition: - [R SSC1 C !!!ready!!!] - - SSC SSC1 op -S -o 3 - ['R SSC1 C +MODE:OK'] - - - SSC SSC1 ap -S -s -p -t 3 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC1 dhcp -S -o 2 - - [R SSC1 C +DHCP] - - SSC SSC1 mac -S -o 2 -m - ['R SSC1 C +MAC:AP,OK'] - - - WIFI CONN + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - WIFI CONN + - ['R PC_COM NC ERROR C +WIFICONN:OK'] - initial condition detail: testing ap on sta + ap mode, PC join AP (autogen) + initial condition detail: testing ap on sta + ap mode, PC join AP (autogen by APM2) restore cmd set: - '' - - SSC SSC1 op -S -o 3 - ['R SSC1 C +MODE:OK'] - - - SSC SSC1 ap -S -s -p -t 3 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC1 dhcp -S -o 2 - - [R SSC1 C +DHCP] - - SSC SSC1 mac -S -o 2 -m - ['R SSC1 C +MAC:AP,OK'] - - - WIFI CONN + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - WIFI CONN + - ['R PC_COM NC ERROR C +WIFICONN:OK'] restore post cmd set: - '' - - SSC SSC1 soc -T - [R SSC1 C +CLOSEALL] - - SSC SSC1 ram - - ['R SSC1 A :(\d+)'] + - ['R SSC1 C +FREEHEAP:'] script path: InitCondBase.py start: 66.0 tag: APSTA2 test script: InitCondBase -- check cmd set: - - '' - - - SSC SSC1 op -Q - - ['R SSC1 C +CURMODE:3'] - - - SSC SSC1 ap -Q - - ['R SSC1 RE "\+APCONFIG:%%s,%%s,\d+,\d+,\d+,4,"%%(,)'] - - - SSC SSC1 dhcp -Q -o 2 - - ['R SSC1 C +DHCP:AP,STARTED'] - - - SSC SSC1 mac -Q -o 2 - - [R SSC1 P ] - force restore cmd set: - - '' - - - SSC SSC1 reboot - - [R SSC1 C !!!ready!!!] - - - SSC SSC1 op -S -o 3 - - ['R SSC1 C +MODE:OK'] - - - SSC SSC1 ap -S -s -p -t 3 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC1 dhcp -S -o 2 - - [R SSC1 C +DHCP] - - - SSC SSC1 mac -S -o 2 -m - - ['R SSC1 C +MAC:AP,OK'] - initial condition detail: testing ap on sta + ap mode (autogen) - restore cmd set: - - '' - - - SSC SSC1 op -S -o 3 - - ['R SSC1 C +MODE:OK'] - - - SSC SSC1 ap -S -s -p -t 3 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC1 dhcp -S -o 2 - - [R SSC1 C +DHCP] - - - SSC SSC1 mac -S -o 2 -m - - ['R SSC1 C +MAC:AP,OK'] - restore post cmd set: - - '' - - - SSC SSC1 soc -T - - [R SSC1 C +CLOSEALL] - - - SSC SSC1 ram - - ['R SSC1 A :(\d+)'] - script path: InitCondBase.py - start: 59.0 - tag: APSTA1 - test script: InitCondBase -- check cmd set: - - '' - - - SSC SSC1 op -Q - - ['R SSC1 C +CURMODE:3'] - - - SSC SSC1 sta -D - - ['R SSC1 C +QAP:'] - - - SSC SSC1 dhcp -Q -o 1 - - ['R SSC1 C +DHCP:STA,STARTED'] - - - SSC SSC1 mac -Q -o 1 - - [R SSC1 P ] - force restore cmd set: - - '' - - - SSC SSC1 reboot - - [R SSC1 C !!!ready!!!] - - - SSC SSC1 op -S -o 3 - - ['R SSC1 C +MODE:OK'] - - - SSC SSC1 sta -D - - ['R SSC1 C +QAP:'] - - - SSC SSC1 dhcp -S -o 1 - - [R SSC1 C +DHCP] - - - SSC SSC1 mac -S -o 1 -m - - ['R SSC1 C +MAC:STA,OK'] - initial condition detail: testing sta on sta + ap mode, quit AP (autogen) - restore cmd set: - - '' - - - SSC SSC1 op -S -o 3 - - ['R SSC1 C +MODE:OK'] - - - SSC SSC1 sta -D - - ['R SSC1 C +QAP:'] - - - SSC SSC1 dhcp -S -o 1 - - [R SSC1 C +DHCP] - - - SSC SSC1 mac -S -o 1 -m - - ['R SSC1 C +MAC:STA,OK'] - restore post cmd set: - - '' - - - SSC SSC1 soc -T - - [R SSC1 C +CLOSEALL] - - - SSC SSC1 ram - - ['R SSC1 A :(\d+)'] - script path: InitCondBase.py - start: 45.0 - tag: STAAP1 - test script: InitCondBase -- check cmd set: - - '' - - - DELAY 0.1 - - [dummy] - force restore cmd set: - - '' - - - DELAY 0.1 - - [dummy] - initial condition detail: none 2 - restore cmd set: - - '' - - - DELAY 0.1 - - [dummy] - restore post cmd set: - - '' - - - ATS AT1 AT+CWSTOPSMART - - [R AT1 R *] - - - ATS AT1 AT+SAVETRANSLINK=0 - - [R AT1 R *] - - - AT+SYSRAM - - ['R AT1 A :(\d+)'] - script path: InitCondBase.py - start: 108.0 - tag: ATNone2 - test script: InitCondBase -- check cmd set: - - '' - - - SSC SSC1 op -Q - - ['R SSC1 C +CURMODE:3'] - - - SSC SSC1 sta -Q - - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] - - - SSC SSC1 dhcp -Q -o 1 - - ['R SSC1 C +DHCP:STA,STARTED'] - - - SSC SSC1 mac -Q -o 1 - - [R SSC1 P ] - force restore cmd set: - - '' - - - SSC SSC1 reboot - - [R SSC1 C !!!ready!!!] - - - SSC SSC1 op -S -o 3 - - ['R SSC1 C +MODE:OK'] - - - SSC SSC1 dhcp -S -o 1 - - [R SSC1 C +DHCP] - - - SSC SSC1 mac -S -o 1 -m - - ['R SSC1 C +MAC:STA,OK'] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] - initial condition detail: testing sta on sta + ap mode, join AP, DHCP on (autogen) - restore cmd set: - - '' - - - SSC SSC1 op -S -o 3 - - ['R SSC1 C +MODE:OK'] - - - SSC SSC1 dhcp -S -o 1 - - [R SSC1 C +DHCP] - - - SSC SSC1 mac -S -o 1 -m - - ['R SSC1 C +MAC:STA,OK'] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] - restore post cmd set: - - '' - - - SSC SSC1 soc -T - - [R SSC1 C +CLOSEALL] - - - SSC SSC1 ram - - ['R SSC1 A :(\d+)'] - script path: InitCondBase.py - start: 52.0 - tag: STAAP2 - test script: InitCondBase - check cmd set: - '' - - ATS AT1 AT+CWMODE_CUR? - ['R AT1 L +CWMODE_CUR:3'] - - - ATS AT1 AT+CWJAP_CUR? - - ['R AT1 C +CWJAP_CUR:', R AT1 P ] - - - ATS AT1 AT+CIPMUX? - - ['R AT1 L +CIPMUX:1'] - - - ATS AT1 AT+CWDHCP_CUR? - - ['R AT1 C DHCP:3'] - - - ATS AT1 AT+CIPSERVER=0 - - [R AT1 R *] - - - ATC AT1 CIPCLOSE + - - ATS AT1 AT+CWLIF + - [R AT1 P ] + - - ATS AT1 AT+CWDHCP_DEF=2,1 - [R AT1 R *] force restore cmd set: - '' @@ -414,23 +348,18 @@ initial condition: - [R AT1 C ready] - - ATS AT1 AT+CWMODE_DEF=3 - [R AT1 L OK] - - - ATS AT1 AT+CWDHCP_DEF=2,1 - - [R AT1 R *] - - - ATC AT1 CWJAP_DEF + - - DELAY 5 + - [''] + - - ATC AT1 CWSAP_DEF - [R AT1 L OK] - - ATS AT1 AT+CWDHCP_DEF=2,1 - [R AT1 R *] - - - ATS AT1 AT+CIPCLOSE - - [R AT1 R *] - - - ATS AT1 AT+CIPMUX=1 - - [R AT1 L OK] - - - ATS AT1 AT+CIPSERVER=0 - - [R AT1 R *] - - - ATC AT1 CIPCLOSE - - [R AT1 R *] - - - ATS AT1 AT+CWDHCP_DEF=2,1 - - [R AT1 R *] - initial condition detail: StationSoftAP mode, connected to AP, multi link, use dhcp + - - WIFI CONN + + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - ATS AT1 AT+CWLIF + - [R AT1 P ] + initial condition detail: StationSoftAP mode restore cmd set: - '' - - ATSO AT1 +++ @@ -441,20 +370,10 @@ initial condition: - [R AT1 R *] - - ATS AT1 AT+CWMODE_DEF=3 - [R AT1 L OK] + - - ATS AT1 AT+CWLIF + - [R AT1 P ] - - ATS AT1 AT+CWDHCP_DEF=2,1 - [R AT1 R *] - - - ATC AT1 CWJAP_DEF - - [R AT1 L OK] - - - ATS AT1 AT+CIPCLOSE - - [R AT1 R *] - - - ATS AT1 AT+CIPMODE=0 - - [R AT1 R *] - - - ATS AT1 AT+CIPMUX=1 - - [R AT1 L OK] - - - ATS AT1 AT+CIPSERVER=0 - - [R AT1 R *] - - - ATC AT1 CIPCLOSE - - [R AT1 R *] restore post cmd set: - '' - - ATS AT1 AT+CWSTOPSMART @@ -464,50 +383,8 @@ initial condition: - - AT+SYSRAM - ['R AT1 A :(\d+)'] script path: InitCondBase.py - start: 94.0 - tag: ATAPSTA3 - test script: InitCondBase -- check cmd set: - - '' - - - ATS AT1 AT+CWMODE_CUR? - - ['R AT1 C +CWMODE_CUR:2 C OK'] - - - ATS AT2 AT+CWMODE_CUR? - - ['R AT2 C +CWMODE_CUR:3 C OK'] - - - ATS AT1 AT+CWJAP_CUR? - - [R AT1 NC OK L ERROR] - force restore cmd set: - - '' - - - ATS AT1 AT+RST - - [R AT1 C ready] - - - ATS AT1 AT+CWMODE_DEF=2 - - [R AT1 L OK] - - - ATS AT2 AT+CWMODE_DEF=3 - - [R AT2 L OK] - initial condition detail: Target 1 in SoftAP mode, Target 2 in StationSoftAP mode, - use dhcp - restore cmd set: - - '' - - - ATSO AT1 +++ - - [''] - - - ATS AT1 AT - - [R AT1 R *] - - - ATS AT1 AT+SAVETRANSLINK=0 - - [R AT1 R *] - - - ATS AT1 AT+CWMODE_DEF=2 - - [R AT1 L OK] - - - ATS AT2 AT+CWMODE_DEF=3 - - [R AT2 L OK] - restore post cmd set: - - '' - - - ATS AT1 AT+CWSTOPSMART - - [R AT1 R *] - - - ATS AT1 AT+SAVETRANSLINK=0 - - [R AT1 R *] - - - AT+SYSRAM - - ['R AT1 A :(\d+)'] - script path: InitCondBase.py - start: 80.0 - tag: ATT2_2 + start: 24.0 + tag: ATAP1 test script: InitCondBase - check cmd set: - '' @@ -586,82 +463,6 @@ initial condition: start: 31.0 tag: ATAP3 test script: InitCondBase -- check cmd set: - - '' - - - SSC SSC1 op -Q - - ['R SSC1 C +CURMODE:1'] - - - SSC SSC1 sta -D - - ['R SSC1 C +QAP:'] - - - SSC SSC1 dhcp -Q -o 1 - - ['R SSC1 C +DHCP:STA,STARTED'] - - - SSC SSC1 mac -Q -o 1 - - [R SSC1 P ] - force restore cmd set: - - '' - - - SSC SSC1 reboot - - [R SSC1 C !!!ready!!!] - - - SSC SSC1 op -S -o 1 - - ['R SSC1 C +MODE:OK'] - - - SSC SSC1 sta -D - - ['R SSC1 C +QAP:'] - - - SSC SSC1 dhcp -S -o 1 - - [R SSC1 C +DHCP] - - - SSC SSC1 mac -S -o 1 -m - - ['R SSC1 C +MAC:STA,OK'] - initial condition detail: sta mode, quit AP, will NOT autogen a TC with initial - condition STAAP1 - restore cmd set: - - '' - - - SSC SSC1 op -S -o 1 - - ['R SSC1 C +MODE:OK'] - - - SSC SSC1 sta -D - - ['R SSC1 C +QAP:'] - - - SSC SSC1 dhcp -S -o 1 - - [R SSC1 C +DHCP] - - - SSC SSC1 mac -S -o 1 -m - - ['R SSC1 C +MAC:STA,OK'] - restore post cmd set: - - '' - - - SSC SSC1 soc -T - - [R SSC1 C +CLOSEALL] - - - SSC SSC1 ram - - ['R SSC1 A :(\d+)'] - script path: InitCondBase.py - start: 17.0 - tag: STAO1 - test script: InitCondBase -- check cmd set: - - '' - - - ATS AT1 AT - - [R AT1 L OK] - - - ATS AT1 AT - - [R AT1 R *] - force restore cmd set: - - '' - - - ATS AT1 AT+RST - - [R AT1 C ready] - - - ATS AT1 AT+RST - - [R AT1 L OK] - initial condition detail: StationSoftAP mode, both PC join Target AP, single link, - use dhcp - restore cmd set: - - '' - - - ATSO AT1 +++ - - [''] - - - ATS AT1 AT+SAVETRANSLINK=0 - - [R AT1 R *] - restore post cmd set: - - '' - - - ATS AT1 AT+CWSTOPSMART - - [R AT1 R *] - - - ATS AT1 AT+SAVETRANSLINK=0 - - [R AT1 R *] - - - AT+SYSRAM - - ['R AT1 A :(\d+)'] - script path: InitCondBase.py - start: 3.0 - tag: ATAP5 - test script: InitCondBase - check cmd set: - '' - - ATS AT1 AT+CWMODE_CUR? @@ -739,6 +540,38 @@ initial condition: start: 45.0 tag: ATAP4 test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT + - [R AT1 L OK] + - - ATS AT1 AT + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+RST + - [R AT1 L OK] + initial condition detail: StationSoftAP mode, both PC join Target AP, single link, + use dhcp + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 3.0 + tag: ATAP5 + test script: InitCondBase - check cmd set: - '' - - ATS AT1 AT @@ -773,138 +606,190 @@ initial condition: test script: InitCondBase - check cmd set: - '' - - - SSC SSC1 upgrade -Q -t 1 - - ['R SSC1 C BIN_ID,0'] - - - SSC SSC1 upgrade -Q -t 2 -b 0 - - ['R SSC1 C BIN_INFO,0'] - - - SSC SSC1 op -S -o 2 - - ['R SSC1 C +MODE:OK'] + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:2'] + - - ATS AT1 AT+CWDHCP_DEF=0,1 + - [R AT1 R *] force restore cmd set: - '' - - - SSC SSC1 upgrade -R -r 1 -s - - [R SSC1 NC ERROR C !!!ready!!!] - - - SSC SSC1 op -S -o 1 - - ['R SSC1 C +MODE:OK'] - - - SSC SSC1 dhcp -S -o 1 - - [R SSC1 C +DHCP] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] - - - SOC SOC1 ULISTEN - - [R SOC_COM L OK] - - - SOC SOC1 SETOPT REPLY BIN - - [R SOC_COM C OK] - - - SSC SSC1 upgrade -I -b 0 -f 0 - - ['P SSC1 C +UPGRADE:OK'] - - - SSC SSC1 upgrade -U -i -p -u - - ['P SSC1 C +UPGRADE:SUCCEED'] - - - SSC SSC1 upgrade -R -b 0 - - [R SSC1 C !!!ready!!!] - - - SSC SSC1 op -S -o 2 - - ['R SSC1 C +MODE:OK'] - initial condition detail: AP only mode, running BIN0 (located on flash id 0) + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=2 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=0,1 + - [R AT1 R *] + initial condition detail: SoftAP mode, use dhcp restore cmd set: - '' - - - SSC SSC1 upgrade -Q -t 2 -b 0 - - ['R SSC1 C BIN_INFO,0'] - - - SSC SSC1 upgrade -R -b 0 - - [R SSC1 C !!!ready!!!] - - - SSC SSC1 op -S -o 2 - - ['R SSC1 C +MODE:OK'] + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=2 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=0,1 + - [R AT1 R *] restore post cmd set: - '' - - - SSC SSC1 upgrade -D - - ['R SSC1 C +UPGRADE:OK'] - - - SSC SSC1 ram - - ['R SSC1 A :(\d+)'] + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] script path: InitCondBase.py - start: 31.0 - tag: APOBIN0 + start: 59.0 + tag: ATAPO1 test script: InitCondBase - check cmd set: - '' - - - SSC SSC1 op -Q - - ['R SSC1 C +CURMODE:1'] - - - SSC SSC1 sta -D - - ['R SSC1 C +QAP:'] - - - SSC SSC1 dhcp -Q -o 1 - - ['R SSC1 C +DHCP:STA,STARTED'] - - - SSC SSC1 mac -Q -o 1 - - [R SSC1 P ] + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 C +CWMODE_CUR:2 L OK'] + - - ATS AT1 AT+CWLIF + - [R AT1 P ] + - - ATS AT1 AT+CIPMUX? + - ['R AT1 L +CIPMUX:1'] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CWDHCP_DEF=0,1 + - [R AT1 R *] force restore cmd set: - '' - - - SSC SSC1 reboot - - [R SSC1 C !!!ready!!!] - - - SSC SSC1 op -S -o 1 - - ['R SSC1 C +MODE:OK'] - - - SSC SSC1 sta -D - - ['R SSC1 C +QAP:'] - - - SSC SSC1 dhcp -S -o 1 - - [R SSC1 C +DHCP] - - - SSC SSC1 mac -S -o 1 -m - - ['R SSC1 C +MAC:STA,OK'] - initial condition detail: sta mode, quit AP, DHCP on + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=2 + - [R AT1 L OK] + - - ATC AT1 CWSAP_DEF + - [R AT1 L OK] + - - WIFI CONN + + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - ATS AT1 AT+CWLIF + - [R AT1 P ] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=1 + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CWDHCP_DEF=0,1 + - [R AT1 R *] + initial condition detail: SoftAP mode, PC join Target AP, multi link, use dhcp restore cmd set: - '' - - - SSC SSC1 op -S -o 1 - - ['R SSC1 C +MODE:OK'] - - - SSC SSC1 sta -D - - ['R SSC1 C +QAP:'] - - - SSC SSC1 dhcp -S -o 1 - - [R SSC1 C +DHCP] - - - SSC SSC1 mac -S -o 1 -m - - ['R SSC1 C +MAC:STA,OK'] + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=2 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=1 + - [R AT1 R *] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CWLIF + - [R AT1 P ] + - - ATS AT1 AT+CWDHCP_DEF=0,1 + - [R AT1 R *] restore post cmd set: - '' - - - SSC SSC1 soc -T - - [R SSC1 C +CLOSEALL] - - - SSC SSC1 ram - - ['R SSC1 A :(\d+)'] + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] script path: InitCondBase.py - start: 17.0 - tag: STAM1 + start: 66.0 + tag: ATAPO3 test script: InitCondBase - check cmd set: - '' - - - SSC SSC1 op -Q - - ['R SSC1 C +CURMODE:1'] - - - SSC SSC1 sta -Q - - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] - - - SSC SSC1 dhcp -Q -o 1 - - ['R SSC1 C +DHCP:STA,STARTED'] - - - SSC SSC1 mac -Q -o 1 - - [R SSC1 P ] + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 C +CWMODE_CUR:2 L OK'] + - - ATS AT1 AT+CWLIF + - [R AT1 P ] + - - ATS AT1 AT+CIPMUX? + - ['R AT1 L +CIPMUX:0'] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATS AT1 AT+CWDHCP_DEF=0,1 + - [R AT1 R *] force restore cmd set: - '' - - - SSC SSC1 reboot - - [R SSC1 C !!!ready!!!] - - - SSC SSC1 op -S -o 1 - - ['R SSC1 C +MODE:OK'] - - - SSC SSC1 dhcp -S -o 1 - - [R SSC1 C +DHCP] - - - SSC SSC1 mac -S -o 1 -m - - ['R SSC1 C +MAC:STA,OK'] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] - initial condition detail: sta mode, join AP, DHCP on + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=2 + - [R AT1 L OK] + - - ATC AT1 CWSAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=0,1 + - [R AT1 R *] + - - WIFI CONN + + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - ATS AT1 AT+CWLIF + - [R AT1 P ] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=0 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + initial condition detail: SoftAP mode, PC join Target AP, single link, use dhcp restore cmd set: - '' - - - SSC SSC1 op -S -o 1 - - ['R SSC1 C +MODE:OK'] - - - SSC SSC1 dhcp -S -o 1 - - [R SSC1 C +DHCP] - - - SSC SSC1 mac -S -o 1 -m - - ['R SSC1 C +MAC:STA,OK'] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=2 + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=0 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATS AT1 AT+CWLIF + - [R AT1 P ] + - - ATS AT1 AT+CWDHCP_DEF=0,1 + - [R AT1 R *] restore post cmd set: - '' - - - SSC SSC1 soc -T - - [R SSC1 C +CLOSEALL] - - - SSC SSC1 ram - - ['R SSC1 A :(\d+)'] + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] script path: InitCondBase.py - start: 24.0 - tag: STAM2 + start: 73.0 + tag: ATAPO4 test script: InitCondBase - check cmd set: - '' @@ -918,7 +803,8 @@ initial condition: - [R AT1 C ready] - - ATS AT1 AT+RST - [R AT1 L OK] - initial condition detail: none + initial condition detail: SoftAP mode, both PC join Target AP, single link, use + dhcp restore cmd set: - '' - - ATSO AT1 +++ @@ -935,7 +821,193 @@ initial condition: - ['R AT1 A :(\d+)'] script path: InitCondBase.py start: 3.0 - tag: ATNone + tag: ATAPO5 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT + - [R AT1 L OK] + - - ATS AT1 AT + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+RST + - [R AT1 L OK] + initial condition detail: SoftAP mode, both PC join Target AP, multi link, use dhcp + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 3.0 + tag: ATAPO6 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:3'] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + initial condition detail: StationSoftAP mode + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 87.0 + tag: ATAPSTA1 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:3'] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + initial condition detail: StationSoftAP mode, DHCP client on + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 87.0 + tag: ATAPSTA2 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:3'] + - - ATS AT1 AT+CWJAP_CUR? + - ['R AT1 C +CWJAP_CUR:', R AT1 P ] + - - ATS AT1 AT+CIPMUX? + - ['R AT1 L +CIPMUX:1'] + - - ATS AT1 AT+CWDHCP_CUR? + - ['R AT1 C DHCP:3'] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=1 + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + initial condition detail: StationSoftAP mode, connected to AP, multi link, use dhcp + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=1 + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 94.0 + tag: ATAPSTA3 test script: InitCondBase - check cmd set: - '' @@ -1009,6 +1081,278 @@ initial condition: start: 101.0 tag: ATAPSTA4 test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:3'] + - - ATS AT1 AT+CWJAP_CUR? + - ['R AT1 C +CWJAP_CUR:', R AT1 P ] + - - ATS AT1 AT+CIPMUX? + - ['R AT1 L +CIPMUX:1'] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATC AT1 CIPSTA_DEF + - [R AT1 L OK] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=1 + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATC AT1 CIPSTA_DEF + - [R AT1 L OK] + initial condition detail: StationSoftAP mode, connected to AP, multi link, use static + ip + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=1 + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATC AT1 CIPSTA_DEF + - [R AT1 L OK] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 129.0 + tag: ATAPSTA5 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:3'] + - - ATS AT1 AT+CWJAP_CUR? + - ['R AT1 C +CWJAP_CUR:', R AT1 P ] + - - ATS AT1 AT+CIPMUX? + - ['R AT1 L +CIPMUX:0'] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATC AT1 CIPSTA_DEF + - [R AT1 L OK] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=0 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATC AT1 CIPSTA_DEF + - [R AT1 L OK] + initial condition detail: StationSoftAP mode, connected to AP, single link, use + static ip + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=0 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATC AT1 CIPSTA_DEF + - [R AT1 L OK] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 136.0 + tag: ATAPSTA6 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT + - [R AT1 L OK] + - - ATS AT1 AT+RESTORE + - [R AT1 L OK, R AT1 C ready] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT + - [R AT1 L OK] + - - ATS AT1 AT+RESTORE + - [R AT1 L OK, R AT1 C ready] + initial condition detail: 'first time usage. Use restore function. ' + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+RESTORE + - [R AT1 L OK, R AT1 C ready] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 143.0 + tag: ATFTU + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT + - [R AT1 L OK] + - - ATS AT1 AT + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+RST + - [R AT1 L OK] + initial condition detail: none + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 3.0 + tag: ATNone + test script: InitCondBase +- check cmd set: + - '' + - - DELAY 0.1 + - [dummy] + force restore cmd set: + - '' + - - DELAY 0.1 + - [dummy] + initial condition detail: none 2 + restore cmd set: + - '' + - - DELAY 0.1 + - [dummy] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 108.0 + tag: ATNone2 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:1'] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 L OK] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 L OK] + initial condition detail: same as STA1, but will not autogen STA+AP STA test case + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 L OK] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 10.0 + tag: ATOSTA1 + test script: InitCondBase - check cmd set: - '' - - ATS AT1 AT+CWMODE_CUR? @@ -1078,6 +1422,51 @@ initial condition: start: 17.0 tag: ATOSTA4 test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 C +CWMODE_CUR:3 C OK'] + - - ATS AT2 AT+CWMODE_CUR? + - ['R AT2 C +CWMODE_CUR:1 C OK'] + - - ATS AT1 AT+CWJAP_CUR? + - [R AT1 NC OK L ERROR] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATS AT2 AT+CWMODE_DEF=1 + - [R AT2 L OK] + - - ATS AT1 AT+CWQAP + - [R AT1 L OK] + initial condition detail: same as OT2_1, but will not autogen STA+AP STA test case + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATS AT2 AT+CWMODE_DEF=1 + - [R AT2 L OK] + - - ATS AT1 AT+CWQAP + - [R AT1 L OK] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 52.0 + tag: ATOT2_1 + test script: InitCondBase - check cmd set: - '' - - ATS AT1 AT+CWMODE_CUR? @@ -1092,7 +1481,7 @@ initial condition: - [R AT1 L OK] - - ATS AT1 AT+CWDHCP_DEF=1,1 - [R AT1 L OK] - initial condition detail: same as STA1, but will not autogen STA+AP STA test case + initial condition detail: station mode, use dhcp restore cmd set: - '' - - ATSO AT1 +++ @@ -1115,34 +1504,23 @@ initial condition: - ['R AT1 A :(\d+)'] script path: InitCondBase.py start: 10.0 - tag: ATOSTA1 + tag: ATSTA1 test script: InitCondBase - check cmd set: - '' - - ATS AT1 AT+CWMODE_CUR? - - ['R AT1 L +CWMODE_CUR:3'] - - - ATS AT1 AT+CWLIF - - [R AT1 P ] - - - ATS AT1 AT+CWDHCP_DEF=2,1 - - [R AT1 R *] + - ['R AT1 L +CWMODE_CUR:1'] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 L OK] force restore cmd set: - '' - - ATS AT1 AT+RST - [R AT1 C ready] - - - ATS AT1 AT+CWMODE_DEF=3 + - - ATS AT1 AT+CWMODE_DEF=1 - [R AT1 L OK] - - - DELAY 5 - - [''] - - - ATC AT1 CWSAP_DEF + - - ATS AT1 AT+CWDHCP_DEF=1,1 - [R AT1 L OK] - - - ATS AT1 AT+CWDHCP_DEF=2,1 - - [R AT1 R *] - - - WIFI CONN - - - ['R PC_COM NC ERROR C +WIFICONN:OK'] - - - ATS AT1 AT+CWLIF - - [R AT1 P ] - initial condition detail: StationSoftAP mode + initial condition detail: station mode, DHCP client on, use dhcp restore cmd set: - '' - - ATSO AT1 +++ @@ -1151,12 +1529,10 @@ initial condition: - [R AT1 R *] - - ATS AT1 AT+SAVETRANSLINK=0 - [R AT1 R *] - - - ATS AT1 AT+CWMODE_DEF=3 + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=1,1 - [R AT1 L OK] - - - ATS AT1 AT+CWLIF - - [R AT1 P ] - - - ATS AT1 AT+CWDHCP_DEF=2,1 - - [R AT1 R *] restore post cmd set: - '' - - ATS AT1 AT+CWSTOPSMART @@ -1166,45 +1542,42 @@ initial condition: - - AT+SYSRAM - ['R AT1 A :(\d+)'] script path: InitCondBase.py - start: 24.0 - tag: ATAP1 - test script: InitCondBase -- check cmd set: - - '' - - - DELAY 0.1 - - [dummy] - force restore cmd set: - - '' - - - SSC SSC1 reboot - - [R SSC1 C !!!ready!!!] - initial condition detail: none - restore cmd set: - - '' - - - DELAY 0.1 - - [dummy] - restore post cmd set: - - '' - - - SSC SSC1 ram - - ['R SSC1 A :(\d+)'] - script path: InitCondBase.py start: 10.0 - tag: None + tag: ATSTA2 test script: InitCondBase - check cmd set: - '' - - - ATS AT1 AT - - [R AT1 L OK] - - - ATS AT1 AT+RESTORE - - [R AT1 L OK, R AT1 C ready] + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:1'] + - - ATS AT1 AT+CWJAP_CUR? + - ['R AT1 C +CWJAP_CUR:', R AT1 P ] + - - ATS AT1 AT+CIPMUX? + - ['R AT1 L +CIPMUX:1'] + - - ATS AT1 AT+CWDHCP_CUR? + - ['R AT1 C DHCP:3'] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] force restore cmd set: - '' - - ATS AT1 AT+RST - [R AT1 C ready] - - - ATS AT1 AT + - - ATS AT1 AT+CWMODE_DEF=1 - [R AT1 L OK] - - - ATS AT1 AT+RESTORE - - [R AT1 L OK, R AT1 C ready] - initial condition detail: 'first time usage. Use restore function. ' + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 R *] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=1 + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + initial condition detail: station mode, connected to AP, multi link, use dhcp restore cmd set: - '' - - ATSO AT1 +++ @@ -1213,39 +1586,21 @@ initial condition: - [R AT1 R *] - - ATS AT1 AT+SAVETRANSLINK=0 - [R AT1 R *] - - - ATS AT1 AT+RESTORE - - [R AT1 L OK, R AT1 C ready] - restore post cmd set: - - '' - - - ATS AT1 AT+CWSTOPSMART - - [R AT1 R *] - - - ATS AT1 AT+SAVETRANSLINK=0 - - [R AT1 R *] - - - AT+SYSRAM - - ['R AT1 A :(\d+)'] - script path: InitCondBase.py - start: 143.0 - tag: ATFTU - test script: InitCondBase -- check cmd set: - - '' - - - ATS AT1 AT + - - ATS AT1 AT+CWMODE_DEF=1 - [R AT1 L OK] - - - ATS AT1 AT + - - ATS AT1 AT+CWDHCP_DEF=1,1 - [R AT1 R *] - force restore cmd set: - - '' - - - ATS AT1 AT+RST - - [R AT1 C ready] - - - ATS AT1 AT+RST + - - ATC AT1 CWJAP_DEF - [R AT1 L OK] - initial condition detail: SoftAP mode, both PC join Target AP, single link, use - dhcp - restore cmd set: - - '' - - - ATSO AT1 +++ - - [''] - - - ATS AT1 AT+SAVETRANSLINK=0 + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=1 + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE - [R AT1 R *] restore post cmd set: - '' @@ -1256,83 +1611,217 @@ initial condition: - - AT+SYSRAM - ['R AT1 A :(\d+)'] script path: InitCondBase.py - start: 3.0 - tag: ATAPO5 + start: 38.0 + tag: ATSTA3 test script: InitCondBase - check cmd set: - '' - - - SSC SSC1 op -Q - - ['R SSC1 C +CURMODE:1'] - - - SSC SSC1 sta -Q - - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] - - - SSC SSC1 dhcp -Q -o 1 - - ['R SSC1 C +DHCP:STA,STARTED'] - - - SSC SSC1 mac -Q -o 1 - - [R SSC1 P ] + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:1'] + - - ATS AT1 AT+CWJAP_CUR? + - ['R AT1 C +CWJAP_CUR:', R AT1 P ] + - - ATS AT1 AT+CIPMUX? + - ['R AT1 L +CIPMUX:0'] + - - ATS AT1 AT+CWDHCP_CUR? + - ['R AT1 C DHCP:3'] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] force restore cmd set: - '' - - - SSC SSC1 reboot - - [R SSC1 C !!!ready!!!] - - - SSC SSC1 op -S -o 1 - - ['R SSC1 C +MODE:OK'] - - - SSC SSC1 dhcp -S -o 1 - - [R SSC1 C +DHCP] - - - SSC SSC1 mac -S -o 1 -m - - ['R SSC1 C +MAC:STA,OK'] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] - initial condition detail: sta mode, join AP, DHCP on, will NOT autogen a TC with - initial condition STAAP2 + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 R *] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=0 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + initial condition detail: station mode, connected to AP, single link, use dhcp restore cmd set: - '' - - - SSC SSC1 op -S -o 1 - - ['R SSC1 C +MODE:OK'] - - - SSC SSC1 dhcp -S -o 1 - - [R SSC1 C +DHCP] - - - SSC SSC1 mac -S -o 1 -m - - ['R SSC1 C +MAC:STA,OK'] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 R *] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=0 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] restore post cmd set: - '' - - - SSC SSC1 soc -T - - [R SSC1 C +CLOSEALL] - - - SSC SSC1 ram - - ['R SSC1 A :(\d+)'] + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] script path: InitCondBase.py - start: 24.0 - tag: STAO2 + start: 17.0 + tag: ATSTA4 test script: InitCondBase - check cmd set: - '' - - - ASSERT - - [dummy] + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:1'] + - - ATS AT1 AT+CWJAP_CUR? + - ['R AT1 C +CWJAP_CUR:', R AT1 P ] + - - ATS AT1 AT+CIPMUX? + - ['R AT1 L +CIPMUX:1'] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATC AT1 CIPSTA_DEF + - [R AT1 L OK] force restore cmd set: - '' - - - SSC SSC[1-] reboot - - ['P SSC[1-] C !!!ready!!!'] - - - SSC SSC[1-] mesh -E -o 0 - - ['P SSC[1-] C +MESH:DISABLED'] - - - SSC SSC[1-] op -S -o 1 - - ['P SSC[1-] C +MODE:OK'] - - - SSC SSC[1-] sta -D - - ['P SSC[1-] C +QAP:OK'] - initial condition detail: all mesh node disabled + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=1 + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATC AT1 CIPSTA_DEF + - [R AT1 L OK] + initial condition detail: station mode, connected to AP, multi link, use static + ip restore cmd set: - '' - - - SSC SSC[1-] mesh -E -o 0 - - ['P SSC[1-] C +MESH:DISABLED'] - - - SSC SSC[1-] op -S -o 1 - - ['P SSC[1-] C +MODE:OK'] - - - SSC SSC[1-] sta -D - - ['P SSC[1-] C +QAP:OK'] + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=1 + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATC AT1 CIPSTA_DEF + - [R AT1 L OK] restore post cmd set: - '' - - - SSC SSC1 ram - - ['R SSC1 A :(\d+)'] + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] script path: InitCondBase.py - start: 31.0 - tag: DISABLED + start: 115.0 + tag: ATSTA5 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:1'] + - - ATS AT1 AT+CWJAP_CUR? + - ['R AT1 C +CWJAP_CUR:', R AT1 P ] + - - ATS AT1 AT+CIPMUX? + - ['R AT1 L +CIPMUX:0'] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATC AT1 CIPSTA_DEF + - [R AT1 L OK] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=0 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATC AT1 CIPSTA_DEF + - [R AT1 L OK] + initial condition detail: station mode, connected to AP, single link, use static + ip + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=0 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATC AT1 CIPSTA_DEF + - [R AT1 L OK] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 122.0 + tag: ATSTA6 test script: InitCondBase - check cmd set: - '' @@ -1380,138 +1869,24 @@ initial condition: start: 52.0 tag: ATT2_1 test script: InitCondBase -- check cmd set: - - '' - - - SSC SSC1 op -Q - - ['R SSC1 C +CURMODE:2'] - - - SSC SSC1 ap -Q - - ['R SSC1 RE "\+APCONFIG:%%s,%%s,\d+,\d+,\d+,4,"%%(,)'] - - - SSC SSC1 ap -L - - ['R SSC1 RE "\+LSTA:.+,%%s"%%()'] - - - SSC SSC1 dhcp -Q -o 2 - - ['R SSC1 C +DHCP:AP,STARTED'] - - - SSC SSC1 mac -Q -o 2 - - [R SSC1 P ] - force restore cmd set: - - '' - - - SSC SSC1 reboot - - [R SSC1 C !!!ready!!!] - - - SSC SSC1 op -S -o 2 - - ['R SSC1 C +MODE:OK'] - - - SSC SSC1 ap -S -s -p -t 3 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC1 dhcp -S -o 2 - - [R SSC1 C +DHCP] - - - SSC SSC1 mac -S -o 2 -m - - ['R SSC1 C +MAC:AP,OK'] - - - WIFI CONN - - ['R PC_COM NC ERROR C +WIFICONN:OK'] - initial condition detail: AP mode, will NOT autogen a TC with initial condition - APSTA2 - restore cmd set: - - '' - - - SSC SSC1 op -S -o 2 - - ['R SSC1 C +MODE:OK'] - - - SSC SSC1 ap -S -s -p -t 3 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC1 dhcp -S -o 2 - - [R SSC1 C +DHCP] - - - SSC SSC1 mac -S -o 2 -m - - ['R SSC1 C +MAC:AP,OK'] - - - WIFI CONN - - ['R PC_COM NC ERROR C +WIFICONN:OK'] - restore post cmd set: - - '' - - - SSC SSC1 soc -T - - [R SSC1 C +CLOSEALL] - - - SSC SSC1 ram - - ['R SSC1 A :(\d+)'] - script path: InitCondBase.py - start: 38.0 - tag: APO2 - test script: InitCondBase -- check cmd set: - - '' - - - SSC SSC1 op -Q - - ['R SSC1 C +CURMODE:2'] - - - SSC SSC1 ap -Q - - ['R SSC1 RE "\+APCONFIG:%%s,%%s,\d+,\d+,\d+,4,"%%(,)'] - - - SSC SSC1 dhcp -Q -o 2 - - ['R SSC1 C +DHCP:AP,STARTED'] - - - SSC SSC1 mac -Q -o 2 - - [R SSC1 P ] - force restore cmd set: - - '' - - - SSC SSC1 reboot - - [R SSC1 C !!!ready!!!] - - - SSC SSC1 op -S -o 2 - - ['R SSC1 C +MODE:OK'] - - - SSC SSC1 dhcp -S -o 2 - - [R SSC1 C +DHCP] - - - SSC SSC1 mac -S -o 2 -m - - ['R SSC1 C +MAC:AP,OK'] - - - SSC SSC1 ap -S -s -p -t 3 - - ['R SSC1 C +SAP:OK'] - initial condition detail: AP mode, will NOT autogen a TC with initial condition - APSTA1 - restore cmd set: - - '' - - - SSC SSC1 op -S -o 2 - - ['R SSC1 C +MODE:OK'] - - - SSC SSC1 dhcp -S -o 2 - - [R SSC1 C +DHCP] - - - SSC SSC1 mac -S -o 2 -m - - ['R SSC1 C +MAC:AP,OK'] - - - SSC SSC1 ap -S -s -p -t 3 - - ['R SSC1 C +SAP:OK'] - restore post cmd set: - - '' - - - SSC SSC1 soc -T - - [R SSC1 C +CLOSEALL] - - - SSC SSC1 ram - - ['R SSC1 A :(\d+)'] - script path: InitCondBase.py - start: 31.0 - tag: APO1 - test script: InitCondBase - check cmd set: - '' - - ATS AT1 AT+CWMODE_CUR? - - ['R AT1 C +CWMODE_CUR:2 L OK'] - - - ATS AT1 AT+CWLIF - - [R AT1 P ] - - - ATS AT1 AT+CIPMUX? - - ['R AT1 L +CIPMUX:1'] - - - ATS AT1 AT+CIPSERVER=0 - - [R AT1 R *] - - - ATC AT1 CIPCLOSE - - [R AT1 R *] - - - ATS AT1 AT+CWDHCP_DEF=0,1 - - [R AT1 R *] + - ['R AT1 C +CWMODE_CUR:2 C OK'] + - - ATS AT2 AT+CWMODE_CUR? + - ['R AT2 C +CWMODE_CUR:3 C OK'] + - - ATS AT1 AT+CWJAP_CUR? + - [R AT1 NC OK L ERROR] force restore cmd set: - '' - - ATS AT1 AT+RST - [R AT1 C ready] - - ATS AT1 AT+CWMODE_DEF=2 - [R AT1 L OK] - - - ATC AT1 CWSAP_DEF - - [R AT1 L OK] - - - WIFI CONN - - - ['R PC_COM NC ERROR C +WIFICONN:OK'] - - - ATS AT1 AT+CWLIF - - [R AT1 P ] - - - ATS AT1 AT+CIPCLOSE - - [R AT1 R *] - - - ATS AT1 AT+CIPMUX=1 - - [R AT1 L OK] - - - ATS AT1 AT+CIPSERVER=0 - - [R AT1 R *] - - - ATC AT1 CIPCLOSE - - [R AT1 R *] - - - ATS AT1 AT+CWDHCP_DEF=0,1 - - [R AT1 R *] - initial condition detail: SoftAP mode, PC join Target AP, multi link, use dhcp + - - ATS AT2 AT+CWMODE_DEF=3 + - [R AT2 L OK] + initial condition detail: Target 1 in SoftAP mode, Target 2 in StationSoftAP mode, + use dhcp restore cmd set: - '' - - ATSO AT1 +++ @@ -1522,20 +1897,8 @@ initial condition: - [R AT1 R *] - - ATS AT1 AT+CWMODE_DEF=2 - [R AT1 L OK] - - - ATS AT1 AT+CIPCLOSE - - [R AT1 R *] - - - ATS AT1 AT+CIPMODE=0 - - [R AT1 R *] - - - ATS AT1 AT+CIPMUX=1 - - [R AT1 R *] - - - ATS AT1 AT+CIPSERVER=0 - - [R AT1 R *] - - - ATC AT1 CIPCLOSE - - [R AT1 R *] - - - ATS AT1 AT+CWLIF - - [R AT1 P ] - - - ATS AT1 AT+CWDHCP_DEF=0,1 - - [R AT1 R *] + - - ATS AT2 AT+CWMODE_DEF=3 + - [R AT2 L OK] restore post cmd set: - '' - - ATS AT1 AT+CWSTOPSMART @@ -1545,8 +1908,171 @@ initial condition: - - AT+SYSRAM - ['R AT1 A :(\d+)'] script path: InitCondBase.py - start: 66.0 - tag: ATAPO3 + start: 80.0 + tag: ATT2_2 + test script: InitCondBase +- check cmd set: + - '' + - - ASSERT + - [dummy] + force restore cmd set: + - '' + - - SSC SSC[1-] reboot + - ['P SSC[1-] C !!!ready!!!'] + - - SSC SSC[1-] mesh -E -o 0 + - ['P SSC[1-] C +MESH:DISABLED'] + - - SSC SSC[1-] op -S -o 1 + - ['P SSC[1-] C +MODE:OK'] + - - SSC SSC[1-] sta -D + - ['P SSC[1-] C +QAP:OK'] + initial condition detail: all mesh node disabled + restore cmd set: + - '' + - - SSC SSC[1-] mesh -E -o 0 + - ['P SSC[1-] C +MESH:DISABLED'] + - - SSC SSC[1-] op -S -o 1 + - ['P SSC[1-] C +MODE:OK'] + - - SSC SSC[1-] sta -D + - ['P SSC[1-] C +QAP:OK'] + restore post cmd set: + - '' + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 31.0 + tag: DISABLED + test script: InitCondBase +- check cmd set: + - '' + - - ASSERT + - [dummy] + - - SSC SSC[1-] mesh -Q -t 4 + - ['R SSC[1-] T '] + - - MESHTREE + - ['R PC_COM RE "MESHTREE:%%s%20nodes"%%()'] + force restore cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC[1-] mesh -E -o 0 + - ['P SSC[1-] C +MESH:DISABLED'] + - - SSC SSC[1-] mesh -I -g -a 4 -k -i + -p -h 5 + - ['P SSC[1-] C ENCRYPTION,OK C GROUP,OK C SERVER,OK C HOP,OK'] + - - SSC SSC[1-] mesh -A -s -k + - ['P SSC[1-] C +MESHINIT:AP,OK'] + - - SSC SSC1 mesh -E -o 1 -t 2 + - ['P SSC1 C +MESH:ENABLED'] + - - SOC SOC1 MACCEPT GSOC1 + - [R SOC_COM L OK] + - - SSC SSC[2-] mesh -E -o 1 -t 2 + - ['P SSC[2-] C +MESH:ENABLED'] + - - DELAY 60 + - [''] + - - SSC SSC[1-] mesh -C + - ['P SSC[1-] C +MESH:CONNECTED'] + - - SSC SSC[1-] mesh -Q -t 4 + - ['R SSC[1-] T '] + - - MESHTREE + - ['R PC_COM RE "MESHTREE:%%s%20nodes"%%()'] + - - SSC SSC[1-] mesh -O -t 1 -o 1 + - ['P SSC[1-] C +MESH:OK'] + initial condition detail: all mesh node enabled as ONLINE, mesh network established + restore cmd set: + - '' + - - SSC SSC[1-] reboot + - ['P SSC[1-] C !!!ready!!!'] + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC[1-] mesh -E -o 0 + - ['P SSC[1-] C +MESH:DISABLED'] + - - SSC SSC[1-] mesh -I -g -a 4 -k -i + -p -h 5 + - ['P SSC[1-] C ENCRYPTION,OK C GROUP,OK C SERVER,OK C HOP,OK'] + - - SSC SSC[1-] mesh -A -s -k + - ['P SSC[1-] C +MESHINIT:AP,OK'] + - - SSC SSC1 mesh -E -o 1 -t 2 + - ['P SSC1 C +MESH:ENABLED'] + - - SOC SOC1 MACCEPT GSOC1 + - [R SOC_COM L OK] + - - SSC SSC[2-] mesh -E -o 1 -t 2 + - ['P SSC[2-] C +MESH:ENABLED'] + - - DELAY 60 + - [''] + - - SSC SSC[1-] mesh -C + - ['P SSC[1-] C +MESH:CONNECTED'] + - - SSC SSC[1-] mesh -Q -t 4 + - ['R SSC[1-] T '] + - - MESHTREE + - ['R PC_COM RE "MESHTREE:%%s%20nodes"%%()'] + - - SSC SSC[1-] mesh -O -t 1 -o 1 + - ['P SSC[1-] C +MESH:OK'] + restore post cmd set: + - '' + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 17.0 + tag: ENABLED_1 + test script: InitCondBase +- check cmd set: + - '' + - - ASSERT + - [dummy] + - - SSC SSC[1-] mesh -Q -t 4 + - ['R SSC[1-] T '] + - - MESHTREE + - ['R PC_COM RE "MESHTREE:%%s%20nodes"%%()'] + force restore cmd set: + - '' + - - SSC SSC[1-] reboot + - ['P SSC[1-] C !!!ready!!!'] + - - SSC SSC[1-] mesh -I -g -a 4 -k -i + -p -h 5 + - ['P SSC[1-] C ENCRYPTION,OK C GROUP,OK C SERVER,OK C HOP,OK'] + - - SSC SSC1 mesh -A -s -k + - ['P SSC1 C +MESHINIT:AP,OK'] + - - SSC SSC1 mesh -E -o 1 -t 1 + - ['P SSC1 C +MESH:ENABLED'] + - - SSC SSC[2-] mesh -E -o 1 -t 2 + - [''] + - - DELAY 60 + - ['P SSC[2-] C +MESH:ENABLED'] + - - SSC SSC[1-] mesh -C + - ['P SSC[1-] C +MESH:CONNECTED'] + - - SSC SSC[1-] mesh -Q -t 4 + - ['R SSC[1-] T '] + - - MESHTREE + - ['R PC_COM RE "MESHTREE:%%s%20nodes"%%()'] + initial condition detail: root as LOCAL, rest node as ONLINE, mesh network established + restore cmd set: + - '' + - - SSC SSC[1-] mesh -E -o 0 + - ['P SSC[1-] C +MESH:DISABLED'] + - - SSC SSC[1-] mesh -I -g -a 4 -k -i + -p -h 5 + - ['P SSC[1-] C ENCRYPTION,OK C GROUP,OK C SERVER,OK C HOP,OK'] + - - SSC SSC1 mesh -A -s -k + - ['P SSC1 C +MESHINIT:AP,OK'] + - - SSC SSC1 mesh -E -o 1 -t 1 + - ['P SSC1 C +MESH:ENABLED'] + - - SSC SSC[2-] mesh -E -o 1 -t 2 + - [''] + - - DELAY 60 + - ['P SSC[2-] C +MESH:ENABLED'] + - - SSC SSC[1-] mesh -C + - ['P SSC[1-] C +MESH:CONNECTED'] + - - SSC SSC[1-] mesh -Q -t 4 + - ['R SSC[1-] T '] + - - MESHTREE + - ['R PC_COM RE "MESHTREE:%%s%20nodes"%%()'] + restore post cmd set: + - '' + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 24.0 + tag: ENABLED_2 test script: InitCondBase - check cmd set: - '' @@ -1641,77 +2167,24 @@ initial condition: test script: InitCondBase - check cmd set: - '' - - - ATS AT1 AT+CWMODE_CUR? - - ['R AT1 C +CWMODE_CUR:2 L OK'] - - - ATS AT1 AT+CWLIF - - [R AT1 P ] - - - ATS AT1 AT+CIPMUX? - - ['R AT1 L +CIPMUX:0'] - - - ATS AT1 AT+CIPCLOSE - - [R AT1 R *] - - - ATS AT1 AT+CIPMODE=0 - - [R AT1 R *] - - - ATS AT1 AT+CWDHCP_DEF=0,1 - - [R AT1 R *] + - - DELAY 0.1 + - [dummy] force restore cmd set: - '' - - - ATS AT1 AT+RST - - [R AT1 C ready] - - - ATS AT1 AT+CWMODE_DEF=2 - - [R AT1 L OK] - - - ATC AT1 CWSAP_DEF - - [R AT1 L OK] - - - ATS AT1 AT+CWDHCP_DEF=0,1 - - [R AT1 R *] - - - WIFI CONN - - - ['R PC_COM NC ERROR C +WIFICONN:OK'] - - - ATS AT1 AT+CWLIF - - [R AT1 P ] - - - ATS AT1 AT+CIPSERVER=0 - - [R AT1 R *] - - - ATC AT1 CIPCLOSE - - [R AT1 R *] - - - ATS AT1 AT+CIPMUX=0 - - [R AT1 L OK] - - - ATS AT1 AT+CIPCLOSE - - [R AT1 R *] - initial condition detail: SoftAP mode, PC join Target AP, single link, use dhcp + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + initial condition detail: none restore cmd set: - '' - - - ATSO AT1 +++ - - [''] - - - ATS AT1 AT - - [R AT1 R *] - - - ATS AT1 AT+SAVETRANSLINK=0 - - [R AT1 R *] - - - ATS AT1 AT+CWMODE_DEF=2 - - [R AT1 L OK] - - - ATS AT1 AT+CIPSERVER=0 - - [R AT1 R *] - - - ATC AT1 CIPCLOSE - - [R AT1 R *] - - - ATS AT1 AT+CIPMUX=0 - - [R AT1 L OK] - - - ATS AT1 AT+CIPCLOSE - - [R AT1 R *] - - - ATS AT1 AT+CIPMODE=0 - - [R AT1 R *] - - - ATS AT1 AT+CWLIF - - [R AT1 P ] - - - ATS AT1 AT+CWDHCP_DEF=0,1 - - [R AT1 R *] + - - DELAY 0.1 + - [dummy] restore post cmd set: - '' - - - ATS AT1 AT+CWSTOPSMART - - [R AT1 R *] - - - ATS AT1 AT+SAVETRANSLINK=0 - - [R AT1 R *] - - - AT+SYSRAM - - ['R AT1 A :(\d+)'] + - - DELAY 0.1 + - [dummy] script path: InitCondBase.py - start: 73.0 - tag: ATAPO4 + start: 10.0 + tag: None test script: InitCondBase - check cmd set: - '' @@ -1734,83 +2207,6 @@ initial condition: start: 31.0 tag: PAIR1 test script: InitCondBase -- check cmd set: - - '' - - - ATS AT1 AT - - [R AT1 L OK] - - - ATS AT1 AT - - [R AT1 R *] - force restore cmd set: - - '' - - - ATS AT1 AT+RST - - [R AT1 C ready] - - - ATS AT1 AT+RST - - [R AT1 L OK] - initial condition detail: SoftAP mode, both PC join Target AP, multi link, use dhcp - restore cmd set: - - '' - - - ATSO AT1 +++ - - [''] - - - ATS AT1 AT+SAVETRANSLINK=0 - - [R AT1 R *] - restore post cmd set: - - '' - - - ATS AT1 AT+CWSTOPSMART - - [R AT1 R *] - - - ATS AT1 AT+SAVETRANSLINK=0 - - [R AT1 R *] - - - AT+SYSRAM - - ['R AT1 A :(\d+)'] - script path: InitCondBase.py - start: 3.0 - tag: ATAPO6 - test script: InitCondBase -- check cmd set: - - '' - - - SSC SSC[1,2] op -Q - - ['R SSC[1,2] C +MODE:[3,3]'] - - - SSC SSC[1,2] mac -Q -o 3 - - ['R SSC[1,2] P P '] - - - SSC SSC[1,2] sp -D - - ['R SSC[1,2] C +SP:OK'] - - - SSC SSC[1,2] sp -I - - ['R SSC[1,2] C +SP:OK'] - force restore cmd set: - - '' - - - SSC SSC[1,2] reboot - - ['R SSC[1,2] C !!!ready!!!'] - - - SSC SSC[1,2] op -S -o [3,3] - - ['R SSC[1,2] C +MODE:OK'] - - - SSC SSC[1,2] mac -S -m -o 2 - - ['R SSC[1,2] C +MAC:AP,OK'] - - - SSC SSC[1,2] mac -S -m -o 1 - - ['R SSC[1,2] C +MAC:STA,OK'] - - - SSC SSC[1,2] sp -D - - ['R SSC[1,2] C +SP:OK'] - - - SSC SSC[1,2] sp -I - - ['R SSC[1,2] C +SP:OK'] - initial condition detail: target1 and target2 in STA+AP mode, two targets de-init - and init simple pair - restore cmd set: - - '' - - - SSC SSC[1,2] op -S -o [3,3] - - ['R SSC[1,2] C +MODE:OK'] - - - SSC SSC[1,2] mac -S -m -o 2 - - ['R SSC[1,2] C +MAC:AP,OK'] - - - SSC SSC[1,2] mac -S -m -o 1 - - ['R SSC[1,2] C +MAC:STA,OK'] - - - SSC SSC[1,2] sp -D - - ['R SSC[1,2] C +SP:OK'] - - - SSC SSC[1,2] sp -I - - ['R SSC[1,2] C +SP:OK'] - restore post cmd set: - - '' - - - SSC SSC1 ram - - ['R SSC1 A :(\d+)'] - script path: InitCondBase.py - start: 45.0 - tag: PAIR3 - test script: InitCondBase - check cmd set: - '' - - SSC SSC[1,2] op -Q @@ -1861,6 +2257,435 @@ initial condition: start: 38.0 tag: PAIR2 test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC[1,2] op -Q + - ['R SSC[1,2] C +MODE:[3,3]'] + - - SSC SSC[1,2] mac -Q -o 3 + - ['R SSC[1,2] P P '] + - - SSC SSC[1,2] sp -D + - ['R SSC[1,2] C +SP:OK'] + - - SSC SSC[1,2] sp -I + - ['R SSC[1,2] C +SP:OK'] + force restore cmd set: + - '' + - - SSC SSC[1,2] reboot + - ['R SSC[1,2] C !!!ready!!!'] + - - SSC SSC[1,2] op -S -o [3,3] + - ['R SSC[1,2] C +MODE:OK'] + - - SSC SSC[1,2] mac -S -m -o 2 + - ['R SSC[1,2] C +MAC:AP,OK'] + - - SSC SSC[1,2] mac -S -m -o 1 + - ['R SSC[1,2] C +MAC:STA,OK'] + - - SSC SSC[1,2] sp -D + - ['R SSC[1,2] C +SP:OK'] + - - SSC SSC[1,2] sp -I + - ['R SSC[1,2] C +SP:OK'] + initial condition detail: target1 and target2 in STA+AP mode, two targets de-init + and init simple pair + restore cmd set: + - '' + - - SSC SSC[1,2] op -S -o [3,3] + - ['R SSC[1,2] C +MODE:OK'] + - - SSC SSC[1,2] mac -S -m -o 2 + - ['R SSC[1,2] C +MAC:AP,OK'] + - - SSC SSC[1,2] mac -S -m -o 1 + - ['R SSC[1,2] C +MAC:STA,OK'] + - - SSC SSC[1,2] sp -D + - ['R SSC[1,2] C +SP:OK'] + - - SSC SSC[1,2] sp -I + - ['R SSC[1,2] C +SP:OK'] + restore post cmd set: + - '' + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 45.0 + tag: PAIR3 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:3'] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:'] + - - SSC SSC1 dhcp -Q -o 1 + - ['R SSC1 C +DHCP:STA,STARTED'] + - - SSC SSC1 mac -Q -o 1 + - [R SSC1 P ] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + initial condition detail: testing sta on sta + ap mode, quit AP (autogen by STAM1) + restore cmd set: + - '' + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 ram + - ['R SSC1 C +FREEHEAP:'] + script path: InitCondBase.py + start: 45.0 + tag: STAAP1 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:3'] + - - SSC SSC1 sta -Q + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC1 dhcp -Q -o 1 + - ['R SSC1 C +DHCP:STA,STARTED'] + - - SSC SSC1 mac -Q -o 1 + - [R SSC1 P ] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + initial condition detail: testing sta on sta + ap mode, join AP, DHCP on (autogen + by STAM2) + restore cmd set: + - '' + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 ram + - ['R SSC1 C +FREEHEAP:'] + script path: InitCondBase.py + start: 52.0 + tag: STAAP2 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 upgrade -Q -t 1 + - ['R SSC1 C BIN_ID,0'] + - - SSC SSC1 upgrade -Q -t 2 -b 0 + - ['R SSC1 C BIN_INFO,0'] + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + force restore cmd set: + - '' + - - SSC SSC1 upgrade -R -r 1 -s + - [R SSC1 NC ERROR C !!!ready!!!] + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SOC SOC1 ULISTEN + - [R SOC_COM L OK] + - - SOC SOC1 SETOPT REPLY BIN + - [R SOC_COM C OK] + - - SSC SSC1 upgrade -I -b 0 -f 0 + - ['P SSC1 C +UPGRADE:OK'] + - - SSC SSC1 upgrade -U -i -p -u + - ['P SSC1 C +UPGRADE:SUCCEED'] + - - SSC SSC1 upgrade -R -b 0 + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + initial condition detail: APSTA mode, connected to AP, running BIN0 (located on + flash id 0) + restore cmd set: + - '' + - - SSC SSC1 upgrade -Q -t 2 -b 0 + - ['R SSC1 C BIN_INFO,0'] + - - SSC SSC1 upgrade -R -b 0 + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + restore post cmd set: + - '' + - - SSC SSC1 upgrade -D + - ['R SSC1 C +UPGRADE:OK'] + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 24.0 + tag: STAAPBIN0 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:1'] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:'] + - - SSC SSC1 dhcp -Q -o 1 + - ['R SSC1 C +DHCP:STA,STARTED'] + - - SSC SSC1 mac -Q -o 1 + - [R SSC1 P ] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + initial condition detail: sta mode, quit AP, DHCP on, will autogen a TC with initial + condition STAAP1 + restore cmd set: + - '' + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 ram + - ['R SSC1 C +FREEHEAP:'] + script path: InitCondBase.py + start: 17.0 + tag: STAM1 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:1'] + - - SSC SSC1 sta -Q + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC1 dhcp -Q -o 1 + - ['R SSC1 C +DHCP:STA,STARTED'] + - - SSC SSC1 mac -Q -o 1 + - [R SSC1 P ] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + initial condition detail: sta mode, join AP, DHCP on, will autogen a TC with initial + condition STAAP2 + restore cmd set: + - '' + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 ram + - ['R SSC1 C +FREEHEAP:'] + script path: InitCondBase.py + start: 24.0 + tag: STAM2 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 upgrade -Q -t 1 + - ['R SSC1 C BIN_ID,0'] + - - SSC SSC1 upgrade -Q -t 2 -b 0 + - ['R SSC1 C BIN_INFO,0'] + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + force restore cmd set: + - '' + - - SSC SSC1 upgrade -R -r 1 -s + - [R SSC1 NC ERROR C !!!ready!!!] + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SOC SOC1 ULISTEN + - [R SOC_COM L OK] + - - SOC SOC1 SETOPT REPLY BIN + - [R SOC_COM C OK] + - - SSC SSC1 upgrade -I -b 0 -f 0 + - ['P SSC1 C +UPGRADE:OK'] + - - SSC SSC1 upgrade -U -i -p -u + - ['P SSC1 C +UPGRADE:SUCCEED'] + - - SSC SSC1 upgrade -R -b 0 + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + initial condition detail: STA mode, connected to AP, running BIN0 (located on flash + id 0) + restore cmd set: + - '' + - - SSC SSC1 upgrade -Q -t 2 -b 0 + - ['R SSC1 C BIN_INFO,0'] + - - SSC SSC1 upgrade -R -b 0 + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + restore post cmd set: + - '' + - - SSC SSC1 upgrade -D + - ['R SSC1 C +UPGRADE:OK'] + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 17.0 + tag: STAMBIN0 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:1'] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:'] + - - SSC SSC1 dhcp -Q -o 1 + - ['R SSC1 C +DHCP:STA,STARTED'] + - - SSC SSC1 mac -Q -o 1 + - [R SSC1 P ] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + initial condition detail: sta mode, quit AP, will NOT autogen a TC with initial + condition STAAP1 + restore cmd set: + - '' + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 ram + - ['R SSC1 C +FREEHEAP:'] + script path: InitCondBase.py + start: 17.0 + tag: STAO1 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:1'] + - - SSC SSC1 sta -Q + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC1 dhcp -Q -o 1 + - ['R SSC1 C +DHCP:STA,STARTED'] + - - SSC SSC1 mac -Q -o 1 + - [R SSC1 P ] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + initial condition detail: sta mode, join AP, DHCP on, will NOT autogen a TC with + initial condition STAAP2 + restore cmd set: + - '' + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 ram + - ['R SSC1 C +FREEHEAP:'] + script path: InitCondBase.py + start: 24.0 + tag: STAO2 + test script: InitCondBase - check cmd set: - '' - - SSC SSC1 op -Q @@ -1926,93 +2751,11 @@ initial condition: - - SSC SSC1 soc -T - [R SSC1 C +CLOSEALL] - - SSC SSC1 ram - - ['R SSC1 A :(\d+)'] + - ['R SSC1 C +FREEHEAP:'] script path: InitCondBase.py start: 73.0 tag: T2O_1 test script: InitCondBase -- check cmd set: - - '' - - - ATS AT1 AT+CWMODE_CUR? - - ['R AT1 L +CWMODE_CUR:2'] - - - ATS AT1 AT+CWDHCP_DEF=0,1 - - [R AT1 R *] - force restore cmd set: - - '' - - - ATS AT1 AT+RST - - [R AT1 C ready] - - - ATS AT1 AT+CWMODE_DEF=2 - - [R AT1 L OK] - - - ATS AT1 AT+CWDHCP_DEF=0,1 - - [R AT1 R *] - initial condition detail: SoftAP mode, use dhcp - restore cmd set: - - '' - - - ATSO AT1 +++ - - [''] - - - ATS AT1 AT - - [R AT1 R *] - - - ATS AT1 AT+SAVETRANSLINK=0 - - [R AT1 R *] - - - ATS AT1 AT+CWMODE_DEF=2 - - [R AT1 L OK] - - - ATS AT1 AT+CWDHCP_DEF=0,1 - - [R AT1 R *] - restore post cmd set: - - '' - - - ATS AT1 AT+CWSTOPSMART - - [R AT1 R *] - - - ATS AT1 AT+SAVETRANSLINK=0 - - [R AT1 R *] - - - AT+SYSRAM - - ['R AT1 A :(\d+)'] - script path: InitCondBase.py - start: 59.0 - tag: ATAPO1 - test script: InitCondBase -- check cmd set: - - '' - - - SSC SSC1 op -Q - - ['R SSC1 C +CURMODE:2'] - - - SSC SSC1 ap -Q - - ['R SSC1 RE "\+APCONFIG:%%s,%%s,\d+,\d+,\d+,4,"%%(,)'] - - - SSC SSC1 dhcp -Q -o 2 - - ['R SSC1 C +DHCP:AP,STARTED'] - - - SSC SSC1 mac -Q -o 2 - - [R SSC1 P ] - force restore cmd set: - - '' - - - SSC SSC1 reboot - - [R SSC1 C !!!ready!!!] - - - SSC SSC1 op -S -o 2 - - ['R SSC1 C +MODE:OK'] - - - SSC SSC1 dhcp -S -o 2 - - [R SSC1 C +DHCP] - - - SSC SSC1 mac -S -o 2 -m - - ['R SSC1 C +MAC:AP,OK'] - - - SSC SSC1 ap -S -s -p -t 3 - - ['R SSC1 C +SAP:OK'] - initial condition detail: AP mode, DHCP on - restore cmd set: - - '' - - - SSC SSC1 op -S -o 2 - - ['R SSC1 C +MODE:OK'] - - - SSC SSC1 dhcp -S -o 2 - - [R SSC1 C +DHCP] - - - SSC SSC1 mac -S -o 2 -m - - ['R SSC1 C +MAC:AP,OK'] - - - SSC SSC1 ap -S -s -p -t 3 - - ['R SSC1 C +SAP:OK'] - restore post cmd set: - - '' - - - SSC SSC1 soc -T - - [R SSC1 C +CLOSEALL] - - - SSC SSC1 ram - - ['R SSC1 A :(\d+)'] - script path: InitCondBase.py - start: 31.0 - tag: APM1 - test script: InitCondBase - check cmd set: - '' - - SSC SSC1 op -Q @@ -2053,7 +2796,8 @@ initial condition: - ['R SSC1 C +MAC:AP,OK'] - - SSC SSC2 mac -S -o 1 -m - ['R SSC2 C +MAC:STA,OK'] - initial condition detail: target 1 as SoftAP, target 2 as STA + initial condition detail: target 1 as SoftAP, target 2 as STA, will autogen a TC + with initial condition T2_2 restore cmd set: - '' - - SSC SSC1 op -S -o 2 @@ -2077,304 +2821,11 @@ initial condition: - - SSC SSC1 soc -T - [R SSC1 C +CLOSEALL] - - SSC SSC1 ram - - ['R SSC1 A :(\d+)'] + - ['R SSC1 C +FREEHEAP:'] script path: InitCondBase.py start: 73.0 tag: T2_1 test script: InitCondBase -- check cmd set: - - '' - - - ATS AT1 AT+CWMODE_CUR? - - ['R AT1 C +CWMODE_CUR:3 C OK'] - - - ATS AT2 AT+CWMODE_CUR? - - ['R AT2 C +CWMODE_CUR:1 C OK'] - - - ATS AT1 AT+CWJAP_CUR? - - [R AT1 NC OK L ERROR] - force restore cmd set: - - '' - - - ATS AT1 AT+RST - - [R AT1 C ready] - - - ATS AT1 AT+CWMODE_DEF=3 - - [R AT1 L OK] - - - ATS AT2 AT+CWMODE_DEF=1 - - [R AT2 L OK] - - - ATS AT1 AT+CWQAP - - [R AT1 L OK] - initial condition detail: same as OT2_1, but will not autogen STA+AP STA test case - restore cmd set: - - '' - - - ATSO AT1 +++ - - [''] - - - ATS AT1 AT - - [R AT1 R *] - - - ATS AT1 AT+SAVETRANSLINK=0 - - [R AT1 R *] - - - ATS AT1 AT+CWMODE_DEF=3 - - [R AT1 L OK] - - - ATS AT2 AT+CWMODE_DEF=1 - - [R AT2 L OK] - - - ATS AT1 AT+CWQAP - - [R AT1 L OK] - restore post cmd set: - - '' - - - ATS AT1 AT+CWSTOPSMART - - [R AT1 R *] - - - ATS AT1 AT+SAVETRANSLINK=0 - - [R AT1 R *] - - - AT+SYSRAM - - ['R AT1 A :(\d+)'] - script path: InitCondBase.py - start: 52.0 - tag: ATOT2_1 - test script: InitCondBase -- check cmd set: - - '' - - - ATS AT1 AT+CWMODE_CUR? - - ['R AT1 L +CWMODE_CUR:3'] - - - ATS AT1 AT+CWJAP_CUR? - - ['R AT1 C +CWJAP_CUR:', R AT1 P ] - - - ATS AT1 AT+CIPMUX? - - ['R AT1 L +CIPMUX:1'] - - - ATS AT1 AT+CIPSERVER=0 - - [R AT1 R *] - - - ATC AT1 CIPCLOSE - - [R AT1 R *] - - - ATC AT1 CIPSTA_DEF - - [R AT1 L OK] - force restore cmd set: - - '' - - - ATS AT1 AT+RST - - [R AT1 C ready] - - - ATS AT1 AT+CWMODE_DEF=3 - - [R AT1 L OK] - - - ATC AT1 CWJAP_DEF - - [R AT1 L OK] - - - ATS AT1 AT+CIPCLOSE - - [R AT1 R *] - - - ATS AT1 AT+CIPMUX=1 - - [R AT1 L OK] - - - ATS AT1 AT+CIPSERVER=0 - - [R AT1 R *] - - - ATC AT1 CIPCLOSE - - [R AT1 R *] - - - ATC AT1 CIPSTA_DEF - - [R AT1 L OK] - initial condition detail: StationSoftAP mode, connected to AP, multi link, use static - ip - restore cmd set: - - '' - - - ATSO AT1 +++ - - [''] - - - ATS AT1 AT - - [R AT1 R *] - - - ATS AT1 AT+SAVETRANSLINK=0 - - [R AT1 R *] - - - ATS AT1 AT+CWMODE_DEF=3 - - [R AT1 L OK] - - - ATC AT1 CWJAP_DEF - - [R AT1 L OK] - - - ATS AT1 AT+CIPCLOSE - - [R AT1 R *] - - - ATS AT1 AT+CIPMODE=0 - - [R AT1 R *] - - - ATS AT1 AT+CIPMUX=1 - - [R AT1 L OK] - - - ATS AT1 AT+CIPSERVER=0 - - [R AT1 R *] - - - ATC AT1 CIPCLOSE - - [R AT1 R *] - - - ATC AT1 CIPSTA_DEF - - [R AT1 L OK] - restore post cmd set: - - '' - - - ATS AT1 AT+CWSTOPSMART - - [R AT1 R *] - - - ATS AT1 AT+SAVETRANSLINK=0 - - [R AT1 R *] - - - AT+SYSRAM - - ['R AT1 A :(\d+)'] - script path: InitCondBase.py - start: 129.0 - tag: ATAPSTA5 - test script: InitCondBase -- check cmd set: - - '' - - - SSC SSC1 upgrade -Q -t 1 - - ['R SSC1 C BIN_ID,0'] - - - SSC SSC1 upgrade -Q -t 2 -b 0 - - ['R SSC1 C BIN_INFO,0'] - - - SSC SSC1 op -S -o 1 - - ['R SSC1 C +MODE:OK'] - - - SSC SSC1 dhcp -S -o 1 - - [R SSC1 C +DHCP] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] - force restore cmd set: - - '' - - - SSC SSC1 upgrade -R -r 1 -s - - [R SSC1 NC ERROR C !!!ready!!!] - - - SSC SSC1 op -S -o 1 - - ['R SSC1 C +MODE:OK'] - - - SSC SSC1 dhcp -S -o 1 - - [R SSC1 C +DHCP] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] - - - SOC SOC1 ULISTEN - - [R SOC_COM L OK] - - - SOC SOC1 SETOPT REPLY BIN - - [R SOC_COM C OK] - - - SSC SSC1 upgrade -I -b 0 -f 0 - - ['P SSC1 C +UPGRADE:OK'] - - - SSC SSC1 upgrade -U -i -p -u - - ['P SSC1 C +UPGRADE:SUCCEED'] - - - SSC SSC1 upgrade -R -b 0 - - [R SSC1 C !!!ready!!!] - - - SSC SSC1 dhcp -S -o 1 - - [R SSC1 C +DHCP] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] - initial condition detail: STA mode, connected to AP, running BIN0 (located on flash - id 0) - restore cmd set: - - '' - - - SSC SSC1 upgrade -Q -t 2 -b 0 - - ['R SSC1 C BIN_INFO,0'] - - - SSC SSC1 upgrade -R -b 0 - - [R SSC1 C !!!ready!!!] - - - SSC SSC1 op -S -o 1 - - ['R SSC1 C +MODE:OK'] - - - SSC SSC1 dhcp -S -o 1 - - [R SSC1 C +DHCP] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] - restore post cmd set: - - '' - - - SSC SSC1 upgrade -D - - ['R SSC1 C +UPGRADE:OK'] - - - SSC SSC1 ram - - ['R SSC1 A :(\d+)'] - script path: InitCondBase.py - start: 17.0 - tag: STAMBIN0 - test script: InitCondBase -- check cmd set: - - '' - - - ATS AT1 AT+CWMODE_CUR? - - ['R AT1 L +CWMODE_CUR:1'] - - - ATS AT1 AT+CWDHCP_DEF=1,1 - - [R AT1 L OK] - force restore cmd set: - - '' - - - ATS AT1 AT+RST - - [R AT1 C ready] - - - ATS AT1 AT+CWMODE_DEF=1 - - [R AT1 L OK] - - - ATS AT1 AT+CWDHCP_DEF=1,1 - - [R AT1 L OK] - initial condition detail: station mode, DHCP client on, use dhcp - restore cmd set: - - '' - - - ATSO AT1 +++ - - [''] - - - ATS AT1 AT - - [R AT1 R *] - - - ATS AT1 AT+SAVETRANSLINK=0 - - [R AT1 R *] - - - ATS AT1 AT+CWMODE_DEF=1 - - [R AT1 L OK] - - - ATS AT1 AT+CWDHCP_DEF=1,1 - - [R AT1 L OK] - restore post cmd set: - - '' - - - ATS AT1 AT+CWSTOPSMART - - [R AT1 R *] - - - ATS AT1 AT+SAVETRANSLINK=0 - - [R AT1 R *] - - - AT+SYSRAM - - ['R AT1 A :(\d+)'] - script path: InitCondBase.py - start: 10.0 - tag: ATSTA2 - test script: InitCondBase -- check cmd set: - - '' - - - SSC SSC[1-3] op -Q - - ['R SSC[1-3] C +CURMODE:3'] - - - SSC SSC[1-3] phy -Q -o 3 - - ['R SSC[1-3] C STA,n,40 C AP,n,40'] - force restore cmd set: - - '' - - - SSC SSC[1-3] reboot - - ['R SSC[1-3] C !!!ready!!!'] - - - SSC SSC[1-3] op -S -o 3 - - ['R SSC[1-3] C +MODE:OK'] - - - SSC SSC[1-3] phy -S -o 3 -m n -b 40 - - ['R SSC[1-3] C +PHY:OK'] - initial condition detail: '1. target 1 and target 2 set to AP+STA mode, target 3 - set to STA mode - - 2. all interface of target 2,3 set to 11n ht40 - - 3. config softAP of target 1 and target 2' - restore cmd set: - - '' - - - SSC SSC[1-3] op -S -o 3 - - ['R SSC[1-3] C +MODE:OK'] - - - SSC SSC[1-3] phy -S -o 3 -m n -b 40 - - ['R SSC[1-3] C +PHY:OK'] - restore post cmd set: - - '' - - - SSC SSC1 soc -T - - [R SSC1 C +CLOSEALL] - - - SSC SSC1 sta -R -r 1 - - [R SSC1 C OK] - - - SSC SSC1 ram - - ['R SSC1 A :(\d+)'] - script path: InitCondBase.py - start: 87.0 - tag: T3_PHY1 - test script: InitCondBase -- check cmd set: - - '' - - - ATS AT1 AT+CWMODE_CUR? - - ['R AT1 L +CWMODE_CUR:3'] - - - ATS AT1 AT+CWDHCP_DEF=2,1 - - [R AT1 R *] - - - ATS AT1 AT+CWDHCP_DEF=2,1 - - [R AT1 R *] - force restore cmd set: - - '' - - - ATS AT1 AT+RST - - [R AT1 C ready] - - - ATS AT1 AT+CWMODE_DEF=3 - - [R AT1 L OK] - - - ATS AT1 AT+CWDHCP_DEF=2,1 - - [R AT1 R *] - initial condition detail: StationSoftAP mode, DHCP client on - restore cmd set: - - '' - - - ATSO AT1 +++ - - [''] - - - ATS AT1 AT - - [R AT1 R *] - - - ATS AT1 AT+SAVETRANSLINK=0 - - [R AT1 R *] - - - ATS AT1 AT+CWMODE_DEF=3 - - [R AT1 L OK] - - - ATS AT1 AT+CWDHCP_DEF=2,1 - - [R AT1 R *] - restore post cmd set: - - '' - - - ATS AT1 AT+CWSTOPSMART - - [R AT1 R *] - - - ATS AT1 AT+SAVETRANSLINK=0 - - [R AT1 R *] - - - AT+SYSRAM - - ['R AT1 A :(\d+)'] - script path: InitCondBase.py - start: 87.0 - tag: ATAPSTA2 - test script: InitCondBase - check cmd set: - '' - - SSC SSC1 op -Q @@ -2439,485 +2890,46 @@ initial condition: - - SSC SSC1 soc -T - [R SSC1 C +CLOSEALL] - - SSC SSC1 ram - - ['R SSC1 A :(\d+)'] + - ['R SSC1 C +FREEHEAP:'] script path: InitCondBase.py start: 80.0 tag: T2_2 test script: InitCondBase - check cmd set: - '' - - - ATS AT1 AT+CWMODE_CUR? - - ['R AT1 L +CWMODE_CUR:3'] - - - ATS AT1 AT+CWJAP_CUR? - - ['R AT1 C +CWJAP_CUR:', R AT1 P ] - - - ATS AT1 AT+CIPMUX? - - ['R AT1 L +CIPMUX:0'] - - - ATS AT1 AT+CIPCLOSE - - [R AT1 R *] - - - ATS AT1 AT+CIPMODE=0 - - [R AT1 R *] - - - ATC AT1 CIPSTA_DEF - - [R AT1 L OK] + - - SSC SSC[1-3] op -Q + - ['R SSC[1-3] C +CURMODE:3'] + - - SSC SSC[1-3] phy -Q -o 3 + - ['R SSC[1-3] C STA,n,40 C AP,n,40'] force restore cmd set: - '' - - - ATS AT1 AT+RST - - [R AT1 C ready] - - - ATS AT1 AT+CWMODE_DEF=3 - - [R AT1 L OK] - - - ATC AT1 CWJAP_DEF - - [R AT1 L OK] - - - ATS AT1 AT+CIPSERVER=0 - - [R AT1 R *] - - - ATC AT1 CIPCLOSE - - [R AT1 R *] - - - ATS AT1 AT+CIPMUX=0 - - [R AT1 L OK] - - - ATS AT1 AT+CIPCLOSE - - [R AT1 R *] - - - ATC AT1 CIPSTA_DEF - - [R AT1 L OK] - initial condition detail: StationSoftAP mode, connected to AP, single link, use - static ip + - - SSC SSC[1-3] reboot + - ['R SSC[1-3] C !!!ready!!!'] + - - SSC SSC[1-3] op -S -o 3 + - ['R SSC[1-3] C +MODE:OK'] + - - SSC SSC[1-3] phy -S -o 3 -m n -b 40 + - ['R SSC[1-3] C +PHY:OK'] + initial condition detail: '1. target 1 and target 2 set to AP+STA mode, target 3 + set to STA mode + + 2. all interface of target 2,3 set to 11n ht40 + + 3. config softAP of target 1 and target 2' restore cmd set: - '' - - - ATSO AT1 +++ - - [''] - - - ATS AT1 AT - - [R AT1 R *] - - - ATS AT1 AT+SAVETRANSLINK=0 - - [R AT1 R *] - - - ATS AT1 AT+CWMODE_DEF=3 - - [R AT1 L OK] - - - ATC AT1 CWJAP_DEF - - [R AT1 L OK] - - - ATS AT1 AT+CIPSERVER=0 - - [R AT1 R *] - - - ATC AT1 CIPCLOSE - - [R AT1 R *] - - - ATS AT1 AT+CIPMUX=0 - - [R AT1 L OK] - - - ATS AT1 AT+CIPCLOSE - - [R AT1 R *] - - - ATS AT1 AT+CIPMODE=0 - - [R AT1 R *] - - - ATC AT1 CIPSTA_DEF - - [R AT1 L OK] - restore post cmd set: - - '' - - - ATS AT1 AT+CWSTOPSMART - - [R AT1 R *] - - - ATS AT1 AT+SAVETRANSLINK=0 - - [R AT1 R *] - - - AT+SYSRAM - - ['R AT1 A :(\d+)'] - script path: InitCondBase.py - start: 136.0 - tag: ATAPSTA6 - test script: InitCondBase -- check cmd set: - - '' - - - ATS AT1 AT+CWMODE_CUR? - - ['R AT1 L +CWMODE_CUR:1'] - - - ATS AT1 AT+CWJAP_CUR? - - ['R AT1 C +CWJAP_CUR:', R AT1 P ] - - - ATS AT1 AT+CIPMUX? - - ['R AT1 L +CIPMUX:0'] - - - ATS AT1 AT+CIPCLOSE - - [R AT1 R *] - - - ATS AT1 AT+CIPMODE=0 - - [R AT1 R *] - - - ATC AT1 CIPSTA_DEF - - [R AT1 L OK] - force restore cmd set: - - '' - - - ATS AT1 AT+RST - - [R AT1 C ready] - - - ATS AT1 AT+CWMODE_DEF=1 - - [R AT1 L OK] - - - ATC AT1 CWJAP_DEF - - [R AT1 L OK] - - - ATS AT1 AT+CIPSERVER=0 - - [R AT1 R *] - - - ATC AT1 CIPCLOSE - - [R AT1 R *] - - - ATS AT1 AT+CIPMUX=0 - - [R AT1 L OK] - - - ATS AT1 AT+CIPCLOSE - - [R AT1 R *] - - - ATC AT1 CIPSTA_DEF - - [R AT1 L OK] - initial condition detail: station mode, connected to AP, single link, use static - ip - restore cmd set: - - '' - - - ATSO AT1 +++ - - [''] - - - ATS AT1 AT - - [R AT1 R *] - - - ATS AT1 AT+SAVETRANSLINK=0 - - [R AT1 R *] - - - ATS AT1 AT+CWMODE_DEF=1 - - [R AT1 L OK] - - - ATC AT1 CWJAP_DEF - - [R AT1 L OK] - - - ATS AT1 AT+CIPSERVER=0 - - [R AT1 R *] - - - ATC AT1 CIPCLOSE - - [R AT1 R *] - - - ATS AT1 AT+CIPMUX=0 - - [R AT1 L OK] - - - ATS AT1 AT+CIPCLOSE - - [R AT1 R *] - - - ATS AT1 AT+CIPMODE=0 - - [R AT1 R *] - - - ATC AT1 CIPSTA_DEF - - [R AT1 L OK] - restore post cmd set: - - '' - - - ATS AT1 AT+CWSTOPSMART - - [R AT1 R *] - - - ATS AT1 AT+SAVETRANSLINK=0 - - [R AT1 R *] - - - AT+SYSRAM - - ['R AT1 A :(\d+)'] - script path: InitCondBase.py - start: 122.0 - tag: ATSTA6 - test script: InitCondBase -- check cmd set: - - '' - - - ATS AT1 AT+CWMODE_CUR? - - ['R AT1 L +CWMODE_CUR:1'] - - - ATS AT1 AT+CWJAP_CUR? - - ['R AT1 C +CWJAP_CUR:', R AT1 P ] - - - ATS AT1 AT+CIPMUX? - - ['R AT1 L +CIPMUX:1'] - - - ATS AT1 AT+CIPSERVER=0 - - [R AT1 R *] - - - ATC AT1 CIPCLOSE - - [R AT1 R *] - - - ATC AT1 CIPSTA_DEF - - [R AT1 L OK] - force restore cmd set: - - '' - - - ATS AT1 AT+RST - - [R AT1 C ready] - - - ATS AT1 AT+CWMODE_DEF=1 - - [R AT1 L OK] - - - ATC AT1 CWJAP_DEF - - [R AT1 L OK] - - - ATS AT1 AT+CIPCLOSE - - [R AT1 R *] - - - ATS AT1 AT+CIPMUX=1 - - [R AT1 L OK] - - - ATS AT1 AT+CIPSERVER=0 - - [R AT1 R *] - - - ATC AT1 CIPCLOSE - - [R AT1 R *] - - - ATC AT1 CIPSTA_DEF - - [R AT1 L OK] - initial condition detail: station mode, connected to AP, multi link, use static - ip - restore cmd set: - - '' - - - ATSO AT1 +++ - - [''] - - - ATS AT1 AT - - [R AT1 R *] - - - ATS AT1 AT+SAVETRANSLINK=0 - - [R AT1 R *] - - - ATS AT1 AT+CWMODE_DEF=1 - - [R AT1 L OK] - - - ATC AT1 CWJAP_DEF - - [R AT1 L OK] - - - ATS AT1 AT+CIPCLOSE - - [R AT1 R *] - - - ATS AT1 AT+CIPMODE=0 - - [R AT1 R *] - - - ATS AT1 AT+CIPMUX=1 - - [R AT1 L OK] - - - ATS AT1 AT+CIPSERVER=0 - - [R AT1 R *] - - - ATC AT1 CIPCLOSE - - [R AT1 R *] - - - ATC AT1 CIPSTA_DEF - - [R AT1 L OK] - restore post cmd set: - - '' - - - ATS AT1 AT+CWSTOPSMART - - [R AT1 R *] - - - ATS AT1 AT+SAVETRANSLINK=0 - - [R AT1 R *] - - - AT+SYSRAM - - ['R AT1 A :(\d+)'] - script path: InitCondBase.py - start: 115.0 - tag: ATSTA5 - test script: InitCondBase -- check cmd set: - - '' - - - ATS AT1 AT+CWMODE_CUR? - - ['R AT1 L +CWMODE_CUR:1'] - - - ATS AT1 AT+CWJAP_CUR? - - ['R AT1 C +CWJAP_CUR:', R AT1 P ] - - - ATS AT1 AT+CIPMUX? - - ['R AT1 L +CIPMUX:0'] - - - ATS AT1 AT+CWDHCP_CUR? - - ['R AT1 C DHCP:3'] - - - ATS AT1 AT+CIPCLOSE - - [R AT1 R *] - - - ATS AT1 AT+CIPMODE=0 - - [R AT1 R *] - force restore cmd set: - - '' - - - ATS AT1 AT+RST - - [R AT1 C ready] - - - ATS AT1 AT+CWMODE_DEF=1 - - [R AT1 L OK] - - - ATS AT1 AT+CWDHCP_DEF=1,1 - - [R AT1 R *] - - - ATC AT1 CWJAP_DEF - - [R AT1 L OK] - - - ATS AT1 AT+CIPSERVER=0 - - [R AT1 R *] - - - ATC AT1 CIPCLOSE - - [R AT1 R *] - - - ATS AT1 AT+CIPMUX=0 - - [R AT1 L OK] - - - ATS AT1 AT+CIPCLOSE - - [R AT1 R *] - initial condition detail: station mode, connected to AP, single link, use dhcp - restore cmd set: - - '' - - - ATSO AT1 +++ - - [''] - - - ATS AT1 AT - - [R AT1 R *] - - - ATS AT1 AT+SAVETRANSLINK=0 - - [R AT1 R *] - - - ATS AT1 AT+CWMODE_DEF=1 - - [R AT1 L OK] - - - ATS AT1 AT+CWDHCP_DEF=1,1 - - [R AT1 R *] - - - ATC AT1 CWJAP_DEF - - [R AT1 L OK] - - - ATS AT1 AT+CIPSERVER=0 - - [R AT1 R *] - - - ATC AT1 CIPCLOSE - - [R AT1 R *] - - - ATS AT1 AT+CIPMUX=0 - - [R AT1 L OK] - - - ATS AT1 AT+CIPCLOSE - - [R AT1 R *] - - - ATS AT1 AT+CIPMODE=0 - - [R AT1 R *] - restore post cmd set: - - '' - - - ATS AT1 AT+CWSTOPSMART - - [R AT1 R *] - - - ATS AT1 AT+SAVETRANSLINK=0 - - [R AT1 R *] - - - AT+SYSRAM - - ['R AT1 A :(\d+)'] - script path: InitCondBase.py - start: 17.0 - tag: ATSTA4 - test script: InitCondBase -- check cmd set: - - '' - - - ATS AT1 AT+CWMODE_CUR? - - ['R AT1 L +CWMODE_CUR:1'] - - - ATS AT1 AT+CWJAP_CUR? - - ['R AT1 C +CWJAP_CUR:', R AT1 P ] - - - ATS AT1 AT+CIPMUX? - - ['R AT1 L +CIPMUX:1'] - - - ATS AT1 AT+CWDHCP_CUR? - - ['R AT1 C DHCP:3'] - - - ATS AT1 AT+CIPSERVER=0 - - [R AT1 R *] - - - ATC AT1 CIPCLOSE - - [R AT1 R *] - force restore cmd set: - - '' - - - ATS AT1 AT+RST - - [R AT1 C ready] - - - ATS AT1 AT+CWMODE_DEF=1 - - [R AT1 L OK] - - - ATS AT1 AT+CWDHCP_DEF=1,1 - - [R AT1 R *] - - - ATC AT1 CWJAP_DEF - - [R AT1 L OK] - - - ATS AT1 AT+CIPCLOSE - - [R AT1 R *] - - - ATS AT1 AT+CIPMUX=1 - - [R AT1 L OK] - - - ATS AT1 AT+CIPSERVER=0 - - [R AT1 R *] - - - ATC AT1 CIPCLOSE - - [R AT1 R *] - initial condition detail: station mode, connected to AP, multi link, use dhcp - restore cmd set: - - '' - - - ATSO AT1 +++ - - [''] - - - ATS AT1 AT - - [R AT1 R *] - - - ATS AT1 AT+SAVETRANSLINK=0 - - [R AT1 R *] - - - ATS AT1 AT+CWMODE_DEF=1 - - [R AT1 L OK] - - - ATS AT1 AT+CWDHCP_DEF=1,1 - - [R AT1 R *] - - - ATC AT1 CWJAP_DEF - - [R AT1 L OK] - - - ATS AT1 AT+CIPCLOSE - - [R AT1 R *] - - - ATS AT1 AT+CIPMODE=0 - - [R AT1 R *] - - - ATS AT1 AT+CIPMUX=1 - - [R AT1 L OK] - - - ATS AT1 AT+CIPSERVER=0 - - [R AT1 R *] - - - ATC AT1 CIPCLOSE - - [R AT1 R *] - restore post cmd set: - - '' - - - ATS AT1 AT+CWSTOPSMART - - [R AT1 R *] - - - ATS AT1 AT+SAVETRANSLINK=0 - - [R AT1 R *] - - - AT+SYSRAM - - ['R AT1 A :(\d+)'] - script path: InitCondBase.py - start: 38.0 - tag: ATSTA3 - test script: InitCondBase -- check cmd set: - - '' - - - SSC SSC1 op -Q - - ['R SSC1 C +CURMODE:2'] - - - SSC SSC1 ap -Q - - ['R SSC1 RE "\+APCONFIG:%%s,%%s,\d+,\d+,\d+,4,"%%(,)'] - - - SSC SSC1 ap -L - - ['R SSC1 RE "\+LSTA:.+,%%s"%%()'] - - - SSC SSC1 dhcp -Q -o 2 - - ['R SSC1 C +DHCP:AP,STARTED'] - - - SSC SSC1 mac -Q -o 2 - - [R SSC1 P ] - force restore cmd set: - - '' - - - SSC SSC1 reboot - - [R SSC1 C !!!ready!!!] - - - SSC SSC1 op -S -o 2 - - ['R SSC1 C +MODE:OK'] - - - SSC SSC1 ap -S -s -p -t 3 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC1 dhcp -S -o 2 - - [R SSC1 C +DHCP] - - - SSC SSC1 mac -S -o 2 -m - - ['R SSC1 C +MAC:AP,OK'] - - - WIFI CONN - - ['R PC_COM NC ERROR C +WIFICONN:OK'] - initial condition detail: AP mode, PC join AP, DHCP on - restore cmd set: - - '' - - - SSC SSC1 op -S -o 2 - - ['R SSC1 C +MODE:OK'] - - - SSC SSC1 ap -S -s -p -t 3 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC1 dhcp -S -o 2 - - [R SSC1 C +DHCP] - - - SSC SSC1 mac -S -o 2 -m - - ['R SSC1 C +MAC:AP,OK'] - - - WIFI CONN - - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - SSC SSC[1-3] op -S -o 3 + - ['R SSC[1-3] C +MODE:OK'] + - - SSC SSC[1-3] phy -S -o 3 -m n -b 40 + - ['R SSC[1-3] C +PHY:OK'] restore post cmd set: - '' - - SSC SSC1 soc -T - [R SSC1 C +CLOSEALL] + - - SSC SSC1 sta -R -r 1 + - [R SSC1 C OK] - - SSC SSC1 ram - ['R SSC1 A :(\d+)'] script path: InitCondBase.py - start: 38.0 - tag: APM2 - test script: InitCondBase -- check cmd set: - - '' - - - ATS AT1 AT+CWMODE_CUR? - - ['R AT1 L +CWMODE_CUR:1'] - - - ATS AT1 AT+CWDHCP_DEF=1,1 - - [R AT1 L OK] - force restore cmd set: - - '' - - - ATS AT1 AT+RST - - [R AT1 C ready] - - - ATS AT1 AT+CWMODE_DEF=1 - - [R AT1 L OK] - - - ATS AT1 AT+CWDHCP_DEF=1,1 - - [R AT1 L OK] - initial condition detail: station mode, use dhcp - restore cmd set: - - '' - - - ATSO AT1 +++ - - [''] - - - ATS AT1 AT - - [R AT1 R *] - - - ATS AT1 AT+SAVETRANSLINK=0 - - [R AT1 R *] - - - ATS AT1 AT+CWMODE_DEF=1 - - [R AT1 L OK] - - - ATS AT1 AT+CWDHCP_DEF=1,1 - - [R AT1 L OK] - restore post cmd set: - - '' - - - ATS AT1 AT+CWSTOPSMART - - [R AT1 R *] - - - ATS AT1 AT+SAVETRANSLINK=0 - - [R AT1 R *] - - - AT+SYSRAM - - ['R AT1 A :(\d+)'] - script path: InitCondBase.py - start: 10.0 - tag: ATSTA1 - test script: InitCondBase -- check cmd set: - - '' - - - ATS AT1 AT+CWMODE_CUR? - - ['R AT1 L +CWMODE_CUR:3'] - - - ATS AT1 AT+CWDHCP_DEF=2,1 - - [R AT1 R *] - - - ATS AT1 AT+CWDHCP_DEF=2,1 - - [R AT1 R *] - force restore cmd set: - - '' - - - ATS AT1 AT+RST - - [R AT1 C ready] - - - ATS AT1 AT+CWMODE_DEF=3 - - [R AT1 L OK] - - - ATS AT1 AT+CWDHCP_DEF=2,1 - - [R AT1 R *] - initial condition detail: StationSoftAP mode - restore cmd set: - - '' - - - ATSO AT1 +++ - - [''] - - - ATS AT1 AT - - [R AT1 R *] - - - ATS AT1 AT+SAVETRANSLINK=0 - - [R AT1 R *] - - - ATS AT1 AT+CWMODE_DEF=3 - - [R AT1 L OK] - - - ATS AT1 AT+CWDHCP_DEF=2,1 - - [R AT1 R *] - restore post cmd set: - - '' - - - ATS AT1 AT+CWSTOPSMART - - [R AT1 R *] - - - ATS AT1 AT+SAVETRANSLINK=0 - - [R AT1 R *] - - - AT+SYSRAM - - ['R AT1 A :(\d+)'] - script path: InitCondBase.py start: 87.0 - tag: ATAPSTA1 + tag: T3_PHY1 test script: InitCondBase diff --git a/components/test/KnownIssues b/components/idf_test/integration_test/KnownIssues similarity index 100% rename from components/test/KnownIssues rename to components/idf_test/integration_test/KnownIssues diff --git a/components/test/TestCaseAll.yml b/components/idf_test/integration_test/TestCaseAll.yml similarity index 98% rename from components/test/TestCaseAll.yml rename to components/idf_test/integration_test/TestCaseAll.yml index 7112c87936..0835c146bd 100644 --- a/components/test/TestCaseAll.yml +++ b/components/idf_test/integration_test/TestCaseAll.yml @@ -1,96 +1,4 @@ test cases: -- CI ready: 'Yes' - ID: ^WIFI_CONN_0601 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -p -t - - ['R SSC1 C +SAP:OK'] - - - WIFI CONN - - - ['R PC_COM C +WIFICONN:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC1 ap -L - - ['R SSC1 C +LSTA:', 'R SSC1 C +LSTA:', R SSC1 C +LSTADONE] - comment: '' - execution time: 0.0 - expected result: '1.target1 set AP - - 2.PC WIFI CONNECTED - - 3.target2 jap target 1 - - 4.查询到两个sta 连接到target1 上' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. target1下设置ssid 和pwd 加密方式 - - 2.PC WIFI CONNECTED target1 - - 3.target2 jap target 1 - - 4.查询到两个sta 连接到target1 上' - sub module: WIFI Connect - summary: list stations connected to soft ap test - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: list SoftAP connected station - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_ICMP_0101 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: 1/5 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ping -i - - ['R SSC1 C +PING:OK'] - - - SSC SSC1 ping -i -c 2 - - ['R SSC1 C +PING:OK'] - comment: '' - execution time: 0.0 - expected result: '1.ok - - 2.ok' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: '1.ping -i - - 2.ping -i -c 2' - sub module: ICMP - summary: ping function test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: ping function test - version: v1 (2016-8-15) - CI ready: 'Yes' ID: SYS_MISC_0101 SDK: '8266_NonOS @@ -111,6 +19,7 @@ test cases: expected result: 重启成功 initial condition: None initial condition description (auto): none + level: Integration module: System steps: 系统重启 sub module: Misc @@ -125,7 +34,7 @@ test cases: test point 2: sw reboot version: v1 (2016-8-15) - CI ready: 'Yes' - ID: ^TCPIP_DHCP_0302 + ID: SYS_MISC_0201 SDK: '8266_NonOS 8266_RTOS @@ -137,62 +46,929 @@ test cases: category: Function cmd set: - '' - - - SSC SSC1 dhcp -S -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC1 ip -S -i 192.168.123.123 -o 2 - - ['R SSC1 C +IP:ERROR'] - - - SSC SSC1 dhcp -L -s 192.168.2.2 -e 192.168.2.10 - - ['R SSC1 C +DHCP:LEASE,ERROR'] - - - SSC SSC1 ap -S -s -p -t - - [''] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED'] - - - SSC SSC1 dhcp -E -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC1 ip -S -i 192.168.4.1 -o 2 - - ['R SSC1 C +IP:OK'] - - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.10 - - ['R SSC1 C +DHCP:LEASE,OK'] - - - SSC SSC2 sta -C -s -p - - [''] - - - DELAY 10 - - [P PC_COM C +DELAYDONE, 'P SSC2 NC +JAP:CONNECTED'] + - - SSC SSC1 ram -H + - ['R SSC1 RE FREEHEAP:\d+\r\n'] comment: '' execution time: 0.0 - expected result: '1.target 1 OK + expected result: ' - 2.target1 ERROR + 可以查询到一个数值 - 3.target1 ERROR + ' + initial condition: None + initial condition description (auto): none + level: Integration + module: System + steps: 查询空闲ram + sub module: Misc + summary: get heap size test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. - 4.target2 jap target1 OK + PC has 1 WiFi NIC. - 5.target1 OK + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: 'get heap size ' + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_DHCP_0101 + SDK: '8266_NonOS - 6.target1 OK + 8266_RTOS - 7.target1 OK - - 8.target2 jap target1 OK' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 dhcp -E -o 1 + - ['R SSC1 C +DHCP:STA,OK'] + - - SSC SSC1 ip -S -i 0.0.0.0 + - ['R SSC1 C +IP:OK'] + - - SSC SSC1 sta -C -s -p + - [''] + - - DELAY 20 + - [P PC_COM C +DELAYDONE, 'P SSC1 NC +JAP:CONNECTED'] + - - SSC SSC1 dhcp -S -o 1 + - ['R SSC1 C +DHCP:STA,OK'] + - - SSC SSC1 ip -Q + - ['R SSC1 C +STAIP:0.0.0.0'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC1 ip -Q + - ['R SSC1 RE "\+STAIP:%%s"%%()'] + comment: '' + execution time: 0.0 + expected result: "1.target1 关闭DHCP OK\n2.target1 设置ip add OK\n3.target1 连接AP fail\n\ + 4.target1 打开DHCP OK\n5.查询到sta ip \n6.target1 连接AP ok\n7.查询到sta ip 为target_ip" + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + level: Integration module: TCPIP - steps: "1.target1 打开DHCP 2\n2.target1 设置softAP ip 192.168.123.123\n3.target1 设置地址池\n\ - 4.target1下设置ssid 和pwd 加密方式\n5.target2 连接target1 \n6.target1 关闭DHCP 2\n7.target1\ - \ 设置softAP ip \n8.target1 设置正确的地址池\n9.target2 连接target1" + steps: "1.target1 关闭DHCP OK\n2.target1 设置ip add OK\n3.target1 连接AP fail\n4.target1\ + \ 打开DHCP OK\n5.查询到sta ip \n6.target1 连接AP ok\n7.查询到sta ip 为target_ip" sub module: DHCP - summary: ap dhcp static ip interaction + summary: dhcp client function test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP client function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_DHCP_0102 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC2 sta -C -s -p + - [''] + - - DELAY 20 + - [P PC_COM C +DELAYDONE, 'P SSC2 NC +JAP:CONNECTED'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: "1.target1 set AP OK \n2.target1 关闭DHCP OK\n3.target2 jap target\ + \ 1,FAIL \n4.target1 打开DHCP OK\n5.target2 jap target 1,ok" + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + level: Integration + module: TCPIP + steps: "1.target1 set AP OK \n2.target1 关闭DHCP OK\n3.target2 jap target 1,FAIL \n\ + 4.target1 打开DHCP OK\n5.target2 jap target 1,ok" + sub module: DHCP + summary: dhcp server function test test environment: SSC_T2_1 test environment description (auto): 'PC has 1 wired NIC connected to AP. PC has 1 WiFi NIC. 2 SSC target connect with PC by UART.' - test point 1: interaction - test point 2: static IP and DHCP interaction test + test point 1: basic function + test point 2: DHCP client function test version: v1 (2016-8-15) - CI ready: 'Yes' - ID: ^TCPIP_DHCP_0301 + ID: TCPIP_DHCP_0103 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 3 + - ['R SSC1 C +DHCP:AP,OK C +DHCP:STA,OK'] + - - SSC SSC1 dhcp -Q -o 3 + - ['R SSC1 C +DHCP:STA,STARTED C +DHCP:AP,STARTED'] + - - SSC SSC1 dhcp -Q -o 1 + - ['R SSC1 C +DHCP:STA,STARTED NC +DHCP:AP,STARTED'] + - - SSC SSC1 dhcp -Q -o 2 + - ['R SSC1 NC +DHCP:STA,STARTED C +DHCP:AP,STARTED'] + - - SSC SSC1 dhcp -E -o 3 + - ['R SSC1 C +DHCP:AP,OK C +DHCP:STA,OK'] + - - SSC SSC1 dhcp -Q -o 3 + - ['R SSC1 C +DHCP:STA,STOPPED C +DHCP:AP,STOPPED'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.STA&AP STARTED + + 4.STA STARTED + + 5.AP STARTED + + 6.OK + + 7.STA&AP STOPPED' + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + level: Integration + module: TCPIP + steps: '1.target1 设置mode 为sta+softAP mode + + 2.target1 打开DHCP 3 + + 3.target1 查询DHCP 状态 + + 4.target1 查询sta DHCP 状态 + + 5.target1 查询softAP DHCP 状态 + + 6.target1 关闭 DHCP 3 + + 7.target1 查询 DHCP 状态' + sub module: DHCP + summary: dhcp status query + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP client function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_DHCP_0201 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 ip -S -o 2 -i + - ['R SSC1 C +IP:OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.1 -e 192.168.4.10 + - ['R SSC1 C +DHCP:LEASE,ERROR'] + - - SSC SSC1 dhcp -L -s 192.168.4.5 -e 192.168.4.2 + - ['R SSC1 C +DHCP:LEASE,ERROR'] + - - SSC SSC1 dhcp -L -s 192.168.2.2 -e 192.168.2.5 + - ['R SSC1 C +DHCP:LEASE,ERROR'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + comment: '' + execution time: 0.0 + expected result: '1.target1 关闭DHCP 2 OK + + 2.target1 设置ip 成功 + + 3.设置dhcp 地址池 OK + + 4.ERROR + + 5.ERROR + + 6.ERROR + + 7.target1 打开DHCP ok' + initial condition: APM1 + initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial + condition APSTA1 + level: Integration + module: TCPIP + steps: "1.target1 关闭DHCP 2 \n2.target1 设置ip \n3.设置dhcp 地址池\n4.设置dhcp错误的参数\n5.设置dhcp错误的参数\n\ + 6.设置dhcp错误的参数\n7.target1 打开DHCP ok" + sub module: DHCP + summary: server dhcp lease test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_DHCP_0202 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - LOOP 3 4 "['01','02','03']" "[2,3,4]" + - [''] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:OK'] + - - SSC SSC2 mac -S -o 1 -m 10:22:33:44:55:{%s} + - ['R SSC2 C +MAC:STA,OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC2 ip -Q -o 1 + - ['R SSC2 C +STAIP:192.168.4.{%s}'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3,4: get IP from dhcp pool with correct sequence' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + level: Integration + module: TCPIP + steps: '1. config softap to a random ssid + + 2. config DHCP Server on Target1 + + 3. target change mac, connect to Target1 + + 4. Loop step3' + sub module: DHCP + summary: dhcp server ip pool + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_DHCP_0203 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.3 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - LOOP 2 4 "['01','02']" "[2,3]" + - [''] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:OK'] + - - SSC SSC2 mac -S -o 1 -m 10:22:33:44:55:{%s} + - ['R SSC2 C +MAC:STA,OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC2 ip -Q -o 1 + - ['R SSC2 C +STAIP:192.168.4.{%s}'] + - - SSC SSC2 mac -S -o 1 -m 10:22:33:44:55:66 + - ['R SSC2 C +MAC:STA,OK'] + - - DELAY 20 + - [''] + - - SSC SSC2 ip -Q -o 1 + - ['R SSC2 C +STAIP:0.0.0.0'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. succeed + + 4.1 succeed + + 4.2 failed' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + level: Integration + module: TCPIP + steps: '1. config softap to a random ssid + + 2. config DHCP Server on Target1(.4.2 - .4.3) + + 3. target change mac, connect to Target1 + + 4. Loop step3 twice' + sub module: DHCP + summary: dhcp server ip pool empty + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_DHCP_0204 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.3 -t 1 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC2 ip -Q -o 1 + - ['R SSC2 C +STAIP:192.168.4.2'] + - - DELAY 90 + - [''] + - - SSC SSC2 ip -Q -o 1 + - ['R SSC2 C +STAIP:192.168.4.2'] + - - SSC SSC2 sta -D + - ['R SSC2 C +JAP:DISCONNECTED'] + - - DELAY 60 + - [''] + - - SSC SSC2 mac -S -o 1 -m 10:22:33:44:55:66 + - ['R SSC2 C +MAC:STA,OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC2 ip -Q -o 1 + - ['R SSC2 C +STAIP:192.168.4.2'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. get IP 192.168.4.2 + + 5. succeed + + 6. succeed + + 8. get IP 192.168.4.2' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + level: Integration + module: TCPIP + steps: '1. config softap to a random ssid + + 2. config DHCP timeout as 1 minute + + 3. target2 connect to target1 + + 4. wait 90 seconds + + 5. check if target2 IP is same + + 6. target2 disconnect + + 7. wait 60s + + 8. target2 change mac and connect to target1' + sub module: DHCP + summary: dhcp server timeout test + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_DHCP_0205 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.3 -t 1 + - ['P SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['P SSC1 C +DHCP:AP,OK', 'P SSC2 C +JAP:DISCONNECTED'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. target2 wifi disconnected' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + level: Integration + module: TCPIP + steps: '1. config softap to a random ssid + + 2. target2 connect to target1 + + 3. disable DHCP server, do config and enable' + sub module: DHCP + summary: disconnect STA if config dhcp server + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_DHCP_0206 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - LOOP 4 4 "['01','02','03','01']" "[2,3,4,2]" + - [''] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:OK'] + - - SSC SSC2 mac -S -o 1 -m 10:22:33:44:55:{%s} + - ['R SSC2 C +MAC:STA,OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC2 ip -Q -o 1 + - ['R SSC2 C +STAIP:192.168.4.{%s}'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 4. get IP 192.168.4.2 - 192.168.4.4 + + 5. get IP 192.168.4.2' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + level: Integration + module: TCPIP + steps: '1. config softap to a random ssid + + 2. disable DHCP server, do config and enable + + 3. target2 change mac, connect to softap, disconnect + + 4. Loop step3 twice + + 5. change to first mac, connect to softap' + sub module: DHCP + summary: dhcp server assign same IP to same MAC when it's not released + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_DHCP_0207 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - WIFI CONN 192.168.4.2 + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - WIFI DISCONN2 + - ['R PC_COM NC ERROR C +WIFIDISCONN:OK'] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:OK'] + - - SSC SSC2 mac -S -o 1 -m 10:22:33:44:55:66 + - ['R SSC2 C +MAC:STA,OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC2 ip -Q -o 1 + - ['R SSC2 C +STAIP:192.168.4.2'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. get IP 192.168.4.2 + + 4. succeed + + 5. succeed + + 6. get IP 192.168.4.2' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + level: Integration + module: TCPIP + steps: '1. config softap to a random ssid + + 2. disable DHCP server, do config and enable + + 3. PC WIFI NIC connect to target1 softap + + 4. target2 connect to target1 softap and disnnect + + 5. PC release IP and disconnected + + 6. target2 change mac and connect to target1' + sub module: DHCP + summary: dhcp server prefer assign released IP to new client + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_DHCP_0208 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['P SSC1 C +DHCP:AP,OK', 'P SSC2 C +JAP:DISCONNECTED'] + - - SSC SSC2 sta -D + - ['R SSC2 C +JAP:DISCONNECTED'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - WIFI CONN 192.168.4.2 + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - SSC SSC1 ap -L + - [R SSC1 C 192.168.4.2 P ] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. succeed + + 4. get IP 192.168.4.2 + + 5. can only find target2 with IP 192.168.4.2' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + level: Integration + module: TCPIP + steps: '1. config softap to a random ssid + + 2. PC NIC connect to target1 softap + + 3. disable DHCP server, do config and enable + + 4. target2 connect to target1 softap + + 5. softap list connected station' + sub module: DHCP + summary: dhcp server reconfig and new client able to get first IP in pool + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_DHCP_0209 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - WIFI CONN 192.168.4.2 + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - DELAY 20 + - [''] + - - SSC SSC1 ap -L + - [R SSC1 C 192.168.4.2 C 192.168.4.3 P P ] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. succeed + + 4. succeed + + 5. find target2 and PC' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + level: Integration + module: TCPIP + steps: '1. config softap to a random ssid + + 2. target2 connect to target1 softap + + 3. disable DHCP server, do config and enable + + 4. PC NIC connect to target1 softap + + 5. softap list connected station' + sub module: DHCP + summary: dhcp server reconfig, old client and new client able to get IP + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_DHCP_0210 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - WIFI CONN2 192.168.4.2 + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - SSC SSC1 ap -L + - [R SSC1 C 192.168.4.2 C 192.168.4.3 P P ] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. succeed + + 4. succeed + + 5. find target2 and PC' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + level: Integration + module: TCPIP + steps: '1. config softap to a random ssid + + 2. target2 connect to target1 softap + + 3. disable DHCP server, do config and enable + + 4. PC NIC connect to target1 softap try to renew IP 192.168.4.2 + + 5. softap list connected station' + sub module: DHCP + summary: dhcp server reconfig, old client able to get IP (discover with requested + IP) + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_DHCP_0211 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - WIFI CONN 192.168.4.2 + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - DELAY 10 + - [''] + - - SSC SSC1 ap -L + - [R SSC1 C 192.168.4.2 C 192.168.4.3 P P ] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. succeed + + 4. succeed + + 5. find target2 and PC' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + level: Integration + module: TCPIP + steps: '1. config softap to a random ssid + + 2. target2 connect to target1 softap + + 3. disable DHCP server, do config and enable + + 4. PC NIC connect to target1 softap try to renew IP 192.168.4.2 + + 5. softap list connected station' + sub module: DHCP + summary: dhcp server reconfig, old client able to renew IP (direct send request) + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_DHCP_0301 SDK: '8266_NonOS 8266_RTOS @@ -227,9 +1003,10 @@ test cases: 4.OK 5.等待10s,JAP fail' - initial condition: STAAP1 - initial condition description (auto): testing sta on sta + ap mode, quit AP (autogen - by STAM1) + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + level: Integration module: TCPIP steps: '1.target1 关闭DHCP 1 @@ -251,64 +1028,6 @@ test cases: test point 1: interaction test point 2: static IP and DHCP interaction test version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_UDP_0113 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 RE BIND:(\d+),OK'] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 RE BIND:(\d+),OK'] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 RE BIND:(\d+),OK'] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 RE BIND:(\d+),OK'] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 RE BIND:(\d+),OK'] - comment: '' - execution time: 0.0 - expected result: '1.ok - - 2.ok - - 3.ok - - 4.ok - - 5.ok' - initial condition: APSTA2 - initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen - by APM2) - module: TCPIP - steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - - 2.target1上UDP传输,Bind socket2,本地ip target_udp_port2 - - 3.target1上UDP传输,Bind socket3,本地ip target_udp_port3 - - 4.target1上UDP传输,Bind socket4,本地ip target_udp_port4 - - 5.target1上UDP传输,Bind socket5,本地ip target_udp_port5' - sub module: UDP - summary: AP mode, create max udp socket test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use UDP SAP (socket/espconn API) with different parameter - version: v1 (2016-8-15) - CI ready: 'Yes' ID: TCPIP_DHCP_0302 SDK: '8266_NonOS @@ -362,6 +1081,7 @@ test cases: initial condition: T2_1 initial condition description (auto): target 1 as SoftAP, target 2 as STA, will autogen a TC with initial condition T2_2 + level: Integration module: TCPIP steps: "1.target1 打开DHCP 2\n2.target1 设置softAP ip 192.168.123.123\n3.target1 设置地址池\n\ 4.target1下设置ssid 和pwd 加密方式\n5.target2 连接target1 \n6.target1 关闭DHCP 2\n7.target1\ @@ -378,1627 +1098,37 @@ test cases: test point 2: static IP and DHCP interaction test version: v1 (2016-8-15) - CI ready: 'Yes' - ID: TCPIP_DHCP_0301 + ID: TCPIP_DNS_0101 SDK: '8266_NonOS 8266_RTOS ESP32_IDF' Test App: SSC - allow fail: '' + allow fail: 3/5 auto test: 'Yes' category: Function cmd set: - '' - - - SSC SSC1 dhcp -E -o 1 - - ['R SSC1 C +DHCP:STA,OK'] - - - SSC SSC1 ip -S -i 192.168.123.123 -o 1 - - ['R SSC1 C +IP:OK'] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:CONNECTED'] - - - SSC SSC1 ip -S -i 0.0.0.0 -o 1 - - ['R SSC1 C +IP:OK'] - - - SSC SSC1 sta -C -s -p - - [''] - - - DELAY 10 - - [P PC_COM C +DELAYDONE, 'P SSC1 NC +JAP:CONNECTED'] + - - SSC SSC1 soc -H -d iot.espressif.cn + - ['R SSC1 C +HOSTIP:OK,115.29.202.58'] comment: '' execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.JAP CONNETED - - 4.OK - - 5.等待10s,JAP fail' - initial condition: STAM1 - initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a - TC with initial condition STAAP1 - module: TCPIP - steps: '1.target1 关闭DHCP 1 - - 2.target1 设置sta ip 192.168.123.123 - - 4.target1 jap AP - - 5.target1 设置sta ip 0.0.0.0 - - 6.target1 jap AP' - sub module: DHCP - summary: sta dhcp static ip interaction - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: interaction - test point 2: static IP and DHCP interaction test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: SYS_MISC_0201 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ram -H - - ['R SSC1 RE FREEHEAP:\d+\r\n'] - comment: '' - execution time: 0.0 - expected result: ' - - 可以查询到一个数值 - - ' - initial condition: None - initial condition description (auto): none - module: System - steps: 查询空闲ram - sub module: Misc - summary: get heap size test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: 'get heap size ' - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_TCP_0412 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SOC SOC1 ACCEPT SOC2 - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -T -s - - ['R SSC1 RE CLOSE:\d+,OK'] - - - SSC SSC1 soc -T -s - - ['R SSC1 RE CLOSE:\d+,OK'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK; PC TCP server accept 成功 - - 4.OK - - 5.OK - - 6.OK - - 7.OK' + expected result: 1.OK initial condition: STAM2 initial condition description (auto): sta mode, join AP, DHCP on, will autogen a TC with initial condition STAAP2 + level: Integration module: TCPIP - steps: '1.PC上建立TCP 监听 test_tcp_port1 - - 2.target1上创建TCP socket1 - - 3.target1上使用步骤2创建的socket1,去连接 PC的ip,test_tcp_port1 - - 4.PC与target1创建好TCP 连接,有ACCEPT - - 5.target1上创建TCP socket2 - - 6.关闭socket1 连接 - - 7.关闭socket2连接' - sub module: TCP - summary: close TCP send after socket changed - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: TCP handling abnormal event - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_TCP_0403 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SOC SOC1 ACCEPT SOC2 - - [R SOC_COM L OK] - - - SSC SSC1 op -S -o 2 - - ['P SSC1 C +MODE:OK', 'P SSC1 RE CLOSED:\d+,0'] - - - SSC SSC1 soc -S -s -l 5 - - ['P SSC1 RE SEND:\d+,ERROR'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK; PC TCP server accept 成功 - - 4.OK - - 5.OK - - 6.ERROR' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1上使用步骤2创建的socket1,去连接\ - \ PC的ip,test_tcp_port1\n4.PC与target1创建好TCP 连接,有ACCEPT\n5.修改8266的Mode为softAP mode\ - \ \n6.8266往PC上发送5字节数据" - sub module: TCP - summary: do TCP send after mode changed - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: TCP handling abnormal event - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_TCP_0402 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SOC SOC1 ACCEPT SOC2 - - [R SOC_COM L OK] - - - SSC SSC1 sta -D - - ['P SSC1 C +QAP:OK', 'P SSC1 RE CLOSED:\d+,0'] - - - SSC SSC1 soc -T -s - - ['R SSC1 RE CLOSE:\d+,OK'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK; PC TCP server accept 成功 - - 4.OK - - 5.OK - - 6.OK' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: '1.PC上建立TCP 监听 test_tcp_port1 - - 2.target1上创建TCP socket1 - - 3.target1上使用步骤2创建的socket1,去连接 PC的ip,test_tcp_port1 - - 4.PC与target1创建好TCP 连接,有ACCEPT - - 5.断开与AP 连接 - - 6.关闭建立的socket1连接' - sub module: TCP - summary: "close TCP socket after WIFI \ndisconnected" - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: TCP handling abnormal event - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_TCP_0401 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SOC SOC1 ACCEPT SOC2 - - [R SOC_COM L OK] - - - SSC SSC1 sta -D - - ['P SSC1 C +QAP:OK', 'P SSC1 RE CLOSED:\d+,0'] - - - SSC SSC1 soc -S -s -l 5 - - ['P SSC1 RE SEND:\d+,ERROR'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK; PC TCP server accept 成功 - - 4.OK - - 5.OK - - 6.ERROR' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: '1.PC上建立TCP 监听 test_tcp_port1 - - 2.target1上创建TCP socket1 - - 3.target1上使用步骤2创建的socket1,去连接 PC的ip,test_tcp_port1 - - 4.PC与target1创建好TCP 连接,有ACCEPT - - 5.断开与AP 连接 - - 6.8266往PC上发送5字节数据' - sub module: TCP - summary: do TCP send after WIFI disconnected - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: TCP handling abnormal event - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^WIFI_ADDR_0101 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 op -S -o 3 - - ['R SSC1 C +MODE:OK'] - - - SSC SSC1 mac -S -o 1 -m 44:55:66:77:88:99 - - ['R SSC1 C +MAC:STA,OK'] - - - SSC SSC1 mac -S -o 2 -m 22:33:44:55:66:77 - - ['R SSC1 C +MAC:AP,OK'] - - - SSC SSC1 mac -Q -o 3 - - ['R SSC1 C +STAMAC:44:55:66:77:88:99 C +APMAC:22:33:44:55:66:77'] - - - SSC SSC1 mac -S -o 1 -m - - ['R SSC1 C +MAC:STA,OK'] - - - SSC SSC1 mac -S -o 2 -m - - ['R SSC1 C +MAC:AP,OK'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.ok - - 3.ok - - 4.ok - - 5.ok - - 6.ok' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: "1.target1 设置mode 为sta+softAP mode\n2.target1 设置sta mode 下的mac \n3.target1\ - \ 设置softAP mode 下的mac\n4.target1 查询softAP+sta 下的mac\n5.target1 设置sta mode 下的mac\ - \ 为target1_mac\n6.target1 设置softAP mode 下的mac 为target1_ap_mac" - sub module: MAC Address - summary: set mac, query mac - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: mac address function test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_TCP_0407 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SOC SOC1 ACCEPT SOC2 - - [R SOC_COM L OK] - - - SSC SSC1 dhcp -E -o 1 - - ['R SSC1 C +DHCP:STA,OK'] - - - SSC SSC1 ip -S -o 1 -i 192.168.111.210 - - ['P SSC1 C +IP:OK', 'P SSC1 RE CLOSED:\d+,0'] - - - SSC SSC1 ip -Q -o 1 - - ['R SSC1 C +STAIP:192.168.111.210'] - - - SSC SSC1 soc -S -s -l 5 - - ['P SSC1 RE SEND:\d+,ERROR'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK; PC TCP server accept 成功 - - 4.OK - - 5.OK - - 6.OK - - 7.OK - - 8.ERROR' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1上使用步骤2创建的socket1,去连接\ - \ PC的ip,test_tcp_port1\n4.PC与target1创建好TCP 连接,有ACCEPT\n5.关闭8266的DHCP 1\n6.设置sta\ - \ ip \n7.查询sta ip 地址是否生效\n8.8266往PC上发送5字节数据" - sub module: TCP - summary: do TCP send after IP changed - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: TCP handling abnormal event - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_TCP_0406 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SOC SOC1 ACCEPT SOC2 - - [R SOC_COM L OK] - - - NIC DISABLED - - [R PC_COM C OK] - - - SSC SSC1 soc -T -s - - ['R SSC1 RE CLOSE:\d+,OK'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK; PC TCP server accept 成功 - - 4.OK - - 5.OK - - 6.OK' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1上使用步骤2创建的socket1,去连接\ - \ PC的ip,test_tcp_port1\n4.PC与target1创建好TCP 连接,有ACCEPT\n5.PC上网卡禁止掉 \n6.关闭建立的socket1连接" - sub module: TCP - summary: close TCP socket after PC NIC disabled - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: TCP handling abnormal event - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_TCP_0405 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SOC SOC1 ACCEPT SOC2 - - [R SOC_COM L OK] - - - NIC DISABLED - - [R PC_COM C OK] - - - SSC SSC1 soc -S -s -l 1 - - [''] - - - DELAY 5400 - - ['P SSC1 RE CLOSED:\d+,0'] - comment: '' - execution time: 1.5 - expected result: '1.OK - - 2.OK - - 3.OK; PC TCP server accept 成功 - - 4.OK - - 5.OK - - 6.TCP连接断开' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: '1.PC上建立TCP 监听 test_tcp_port1 - - 2.target1上创建TCP socket1 - - 3.target1上使用步骤2创建的socket1,去连接 PC的ip,test_tcp_port1 - - 4.PC与target1创建好TCP 连接,有ACCEPT - - 5.PC 网卡 disable - - 6.target1上使用socket1发送数据,等待 90 分钟' - sub module: TCP - summary: do TCP send after PC NIC disabled - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: TCP handling abnormal event - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_TCP_0404 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SOC SOC1 ACCEPT SOC2 - - [R SOC_COM L OK] - - - SSC SSC1 op -S -o 2 - - ['P SSC1 C +MODE:OK', 'P SSC1 RE CLOSED:\d+,0'] - - - SSC SSC1 soc -T -s - - ['R SSC1 RE CLOSE:\d+,OK'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK; PC TCP server accept 成功 - - 4.OK - - 5.OK - - 6.OK' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1上使用步骤2创建的socket1,去连接\ - \ PC的ip,test_tcp_port1\n4.PC与target1创建好TCP 连接,有ACCEPT\n5.修改8266的Mode为softAP mode\ - \ \n6.关闭建立的socket1连接" - sub module: TCP - summary: close TCP socket after mode changed - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: TCP handling abnormal event - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^WIFI_CONN_0903 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 sta -C -s -p bacfd - - ['R SSC1 RE JAP:DISCONNECTED,\d+,2'] - comment: '' - execution time: 0.0 - expected result: 1. disconect event reason REASON_AUTH_EXPIRE - initial condition: STAAP1 - initial condition description (auto): testing sta on sta + ap mode, quit AP (autogen - by STAM1) - module: WIFI MAC - steps: 1. connect WEP ap with error password (valid wep password) - sub module: WIFI Connect - summary: test wifi disconnect reason REASON_AUTH_EXPIRE - test environment: SSC_T1_WEP - test environment description (auto): '1 SSC target connect with PC by UART. - - One WEP share key AP placed near SSC1.' - test point 1: basic function - test point 2: wifi disconnect reason test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_TCP_0408 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SOC SOC1 ACCEPT SOC2 - - [R SOC_COM L OK] - - - SSC SSC1 dhcp -E -o 1 - - ['R SSC1 C +DHCP:STA,OK'] - - - SSC SSC1 ip -S -o 1 -i 192.168.111.210 - - ['P SSC1 C +IP:OK', 'P SSC1 RE CLOSED:\d+,0'] - - - SSC SSC1 ip -Q -o 1 - - ['R SSC1 C +STAIP:192.168.111.210'] - - - SSC SSC1 soc -T -s - - ['R SSC1 RE CLOSE:\d+,OK'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK; PC TCP server accept 成功 - - 4.OK - - 5.OK - - 6.OK - - 7.OK - - 8.OK' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1上使用步骤2创建的socket1,去连接\ - \ PC的ip,test_tcp_port1\n4.PC与target1创建好TCP 连接,有ACCEPT\n5.关闭8266的DHCP 1\n6.设置sta\ - \ ip \n7.查询sta ip 地址是否生效\n8.关闭建立的socket1连接" - sub module: TCP - summary: close TCP socket after IP changed - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: TCP handling abnormal event - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_TCP_0202 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -L -s - - ['R SSC1 RE LISTEN:\d+,ERROR'] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SSC SSC1 soc -L -s - - ['R SSC1 RE LISTEN:\d+,ERROR'] - - - SSC SSC1 soc -D -s - - ['R SSC1 RE SHUTDOWN:\d+,OK'] - - - SSC SSC1 soc -L -s - - ['R SSC1 RE LISTEN:\d+,ERROR'] - - - SSC SSC1 soc -L -s 1000 - - ['R SSC1 RE LISTEN:\d+,ERROR'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.ERROR - - 4.OK - - 5.OK - - 6.ERROR - - 7.OK - - 8.ERROR - - 9.ERROR' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: '1.PC上建立TCP 监听 test_tcp_port1 - - 2.target1上创建UDP传输socket,bind到本地ip 0.0.0.0, - - 3.target1上使用步骤2创建的socket,去建立TCP 监听 - - 4.target1上创建TCP socket - - 5.target1上使用步骤4创建的socket,去连接 PC的ip, - - 6.target1上使用步骤4创建的socket,创建TCP 监听 - - 7.target1上shutdown 步骤4的socket - - 8.target1上使用步骤4创建的socket,创建TCP 监听 - - 9.target1上使用不存在socket,创建TCP 监听' - sub module: TCP - summary: STA mode, server listen test. use socket in state that can't listen - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. + steps: 1. get host name "espressif.cn" + sub module: DNS + summary: get host by name test + test environment: SSC_T1_2 + test environment description (auto): 'Able to access WAN after connect to AP. 1 SSC target connect with PC by UART.' test point 1: basic function - test point 2: use TCP SAP (socket/espconn API) in different state - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_TCP_0110 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [SOCR SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP -i 0.0.0.0 -p 0 - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['P SSC1 RE CONNECT:\d+,OK', P SOC1 C +ACCEPT] - - - SSC SSC1 soc -B -t TCP -i 0.0.0.0 -p 0 - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i 123.456.678.789 -p - - ['P SSC1 RE CONNECT:\d+,ERROR'] - - - SSC SSC1 soc -C -s -i -p - - ['P SSC1 RE CONNECT:\d+,ERROR'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK; PC TCP server accept 成功 - - 4.OK - - 5.ERROR - - 6.ERROR' - initial condition: APM2 - initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen - a TC with initial condition APSTA2 - module: TCPIP - steps: '1.PC上建立TCP 监听 test_tcp_port1 - - 2.target1上创建TCP socket,bind到本地ip 0.0.0.0,本地端口 0 - - 3.target1上使用步骤2创建的socket,去连接 PC的ip,test_tcp_port1 - - 4.target1上创建TCP socket,bind到本地ip 0.0.0.0,本地端口 0 - - 5.target1上使用步骤4创建的socket,去连接不存在的ip,test_tcp_port1 - - 6.target1上使用步骤2创建的socket,去连接 PC的ip,远端端口不存在。' - sub module: TCP - summary: AP mode, connect test. use different ip, port - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use TCP SAP (socket/espconn API) with different parameter - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_TCP_0203 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -S -s - - ['R SSC1 RE SEND:\d+,ERROR'] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -S -s - - ['R SSC1 RE SEND:\d+,ERROR'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SSC SSC1 soc -D -s - - ['R SSC1 RE SHUTDOWN:\d+,OK'] - - - SSC SSC1 soc -S -s - - ['R SSC1 RE SEND:\d+,ERROR'] - - - SSC SSC1 soc -S -s 1000 - - ['R SSC1 RE SEND:\d+,ERROR'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.ERROR - - 4.OK - - 5.ERROR - - 6.OK - - 7.OK - - 8.ERROR - - 9.ERROR' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: '1.PC上建立TCP 监听 test_tcp_port1 - - 2.target1上创建UDP传输socket1, - - 3.target1上使用步骤2创建的socket1,去发送数据 - - 4.target1上创建TCP socket2 - - 5.target1上使用步骤4创建的socket2,去发送数据 - - 6.target1上使用步骤4创建的socket2,创建TCP连接,连接成功 - - 7.target1上shutdown 步骤4的socket2 - - 8.target1往socket2发送错误命令发送数据 - - 9.target1上不指定socket往上发送数据' - sub module: TCP - summary: send test. use socket in state that can't send - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use TCP SAP (socket/espconn API) in different state - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_DHCP_0101 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 dhcp -E -o 1 - - ['R SSC1 C +DHCP:STA,OK'] - - - SSC SSC1 ip -S -i 0.0.0.0 - - ['R SSC1 C +IP:OK'] - - - SSC SSC1 sta -C -s -p - - [''] - - - DELAY 20 - - [P PC_COM C +DELAYDONE, 'P SSC1 NC +JAP:CONNECTED'] - - - SSC SSC1 dhcp -S -o 1 - - ['R SSC1 C +DHCP:STA,OK'] - - - SSC SSC1 ip -Q - - ['R SSC1 C +STAIP:0.0.0.0'] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:CONNECTED'] - - - SSC SSC1 ip -Q - - ['R SSC1 RE "\+STAIP:%%s"%%()'] - comment: '' - execution time: 0.0 - expected result: "1.target1 关闭DHCP OK\n2.target1 设置ip add OK\n3.target1 连接AP fail\n\ - 4.target1 打开DHCP OK\n5.查询到sta ip \n6.target1 连接AP ok\n7.查询到sta ip 为target_ip" - initial condition: STAM1 - initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a - TC with initial condition STAAP1 - module: TCPIP - steps: "1.target1 关闭DHCP OK\n2.target1 设置ip add OK\n3.target1 连接AP fail\n4.target1\ - \ 打开DHCP OK\n5.查询到sta ip \n6.target1 连接AP ok\n7.查询到sta ip 为target_ip" - sub module: DHCP - summary: dhcp client function test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: DHCP client function test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_DHCP_0103 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 op -S -o 3 - - ['R SSC1 C +MODE:OK'] - - - SSC SSC1 dhcp -S -o 3 - - ['R SSC1 C +DHCP:AP,OK C +DHCP:STA,OK'] - - - SSC SSC1 dhcp -Q -o 3 - - ['R SSC1 C +DHCP:STA,STARTED C +DHCP:AP,STARTED'] - - - SSC SSC1 dhcp -Q -o 1 - - ['R SSC1 C +DHCP:STA,STARTED NC +DHCP:AP,STARTED'] - - - SSC SSC1 dhcp -Q -o 2 - - ['R SSC1 NC +DHCP:STA,STARTED C +DHCP:AP,STARTED'] - - - SSC SSC1 dhcp -E -o 3 - - ['R SSC1 C +DHCP:AP,OK C +DHCP:STA,OK'] - - - SSC SSC1 dhcp -Q -o 3 - - ['R SSC1 C +DHCP:STA,STOPPED C +DHCP:AP,STOPPED'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.STA&AP STARTED - - 4.STA STARTED - - 5.AP STARTED - - 6.OK - - 7.STA&AP STOPPED' - initial condition: STAM1 - initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a - TC with initial condition STAAP1 - module: TCPIP - steps: '1.target1 设置mode 为sta+softAP mode - - 2.target1 打开DHCP 3 - - 3.target1 查询DHCP 状态 - - 4.target1 查询sta DHCP 状态 - - 5.target1 查询softAP DHCP 状态 - - 6.target1 关闭 DHCP 3 - - 7.target1 查询 DHCP 状态' - sub module: DHCP - summary: dhcp status query - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: DHCP client function test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_DHCP_0102 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -p -t - - ['R SSC1 C +SAP:OK'] - - - SSC SSC1 dhcp -E -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC2 sta -C -s -p - - [''] - - - DELAY 20 - - [P PC_COM C +DELAYDONE, 'P SSC2 NC +JAP:CONNECTED'] - - - SSC SSC1 dhcp -S -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - comment: '' - execution time: 0.0 - expected result: "1.target1 set AP OK \n2.target1 关闭DHCP OK\n3.target2 jap target\ - \ 1,FAIL \n4.target1 打开DHCP OK\n5.target2 jap target 1,ok" - initial condition: T2_1 - initial condition description (auto): target 1 as SoftAP, target 2 as STA, will - autogen a TC with initial condition T2_2 - module: TCPIP - steps: "1.target1 set AP OK \n2.target1 关闭DHCP OK\n3.target2 jap target 1,FAIL \n\ - 4.target1 打开DHCP OK\n5.target2 jap target 1,ok" - sub module: DHCP - summary: dhcp server function test - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: DHCP client function test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_UDP_0303 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: 1/5 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 BIND - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -S -s -i -p -l 5 - - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] - - - SSC SSC1 op -S -o 2 - - ['P SSC1 C +MODE:OK'] - - - SSC SSC1 soc -S -s -i -p -l 5 - - ['P SSC1 RE SEND:(\d+),OK'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK - - 4.OK - - 5.ERROR' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: "1.PC上SOC1 UDP传输,bing \n2.target1上UDP传输,Bind socket1,本地ip\ - \ target_udp_port1\n3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据\n\ - 4.修改8266的Mode为softAP mode \n5.8266往PC上发送5字节数据" - sub module: UDP - summary: do UDP send after mode changed - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: UDP handling abnormal event - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_SCAN_0103 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 sta -D - - ['R SSC1 C +QAP:'] - - - SSC SSC1 ap -S -s -p 123456789 -t 3 -n 6 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC2 sta -S -n 5 - - [R SSC2 NP C +SCANDONE] - - - SSC SSC2 sta -S -n 6 - - ['R SSC2 C +SCAN:', R SSC2 P ] - comment: '' - execution time: 0.0 - expected result: '1.target1 QAP - - 2. target1 set AP,set channel 6 - - 3.target2 上scan不到 channel 5 - - 4.target2 上查询channel 6的' - initial condition: T2_1 - initial condition description (auto): target 1 as SoftAP, target 2 as STA, will - autogen a TC with initial condition T2_2 - module: WIFI MAC - steps: '1.target1 断开连接AP - - 2.target1下设置ssid 和pwd 加密方式,set channel 6 - - 3.target2 上scan channel 5 - - 4.target2 上查询channel 6的' - sub module: WIFI Scan - summary: scan with scan config channel - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: scan with different config - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_SCAN_0102 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC2 sta -S -b ff:ff:ff:ff:ff:11 - - ['R SSC2 NC +SCAN: C +SCANDONE'] - - - SSC SSC2 sta -S -b - - ['R SSC2 RE "\+SCAN:.+,%%s"%%()', 'R SSC2 NC +SCAN: C +SCANDONE'] - comment: '' - execution time: 0.0 - expected result: '1.target2 上不能查询到此mac - - 2.target2上查询到' - initial condition: T2_1 - initial condition description (auto): target 1 as SoftAP, target 2 as STA, will - autogen a TC with initial condition T2_2 - module: WIFI MAC - steps: '1.target2 上查询此macff:ff:ff:ff:ff:11 - - 2.target2上查询' - sub module: WIFI Scan - summary: scan with scan config bssid - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: scan with different config - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_SCAN_0101 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC2 sta -S -s .,juhg123 - - ['R SSC2 NC +SCAN: C +SCANDONE'] - - - SSC SSC1 ap -S -s -p 123456789 -t 3 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC2 sta -S -s - - ['R SSC2 C +SCAN:', R SSC2 P , 'R SSC2 NC +SCAN: C +SCANDONE'] - comment: '' - execution time: 0.0 - expected result: '1.target 2上不能scan .,juhg123 - - 2.target1 set AP - - 3.target2上查询到' - initial condition: T2_1 - initial condition description (auto): target 1 as SoftAP, target 2 as STA, will - autogen a TC with initial condition T2_2 - module: WIFI MAC - steps: '1.target 2 scan .,juhg123 - - 2.target1下设置ssid 和pwd 加密方式 - - 3.target2 scan ' - sub module: WIFI Scan - summary: scan with scan config ssid - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: scan with different config - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_SCAN_0105 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 sta -D - - ['R SSC1 C +QAP:'] - - - SSC SSC1 ap -S -s -p 123456789 -t 3 -h 0 -n 11 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC2 sta -S -s -b -n 11 - - [R SSC2 P C +SCANDONE] - - - SSC SSC2 sta -S -s -b -n 11 - - [R SSC2 NP C +SCANDONE] - - - SSC SSC2 sta -S -s -b ff:ff:ff:ff:ff:11 -n 11 - - [R SSC2 P , R SSC2 NP C +SCANDONE] - - - SSC SSC2 sta -S -s -b -n 10 - - [R SSC2 P , R SSC2 NP C +SCANDONE] - comment: '' - execution time: 0.0 - expected result: '1.target1 QAP - - 2. target1 set AP,set ssid broad cast,set channel 11 - - 3.target2 上查询到 - - 4.target2 上查询不到 - - 5.target2 上查询不到 - - 6.target2 上查询不到' - initial condition: T2_1 - initial condition description (auto): target 1 as SoftAP, target 2 as STA, will - autogen a TC with initial condition T2_2 - module: WIFI MAC - steps: '1.target1 QAP - - 2. target1 set AP,set ssid broad cast,set channel 11 - - 3.target2 上查询到 - - 4.target2 上查询不到 - - 5.target2 上查询不到 - - 6.target2 上查询不到' - sub module: WIFI Scan - summary: scan with several configs - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: scan with different config - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_SCAN_0104 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -p 123456789 -t 3 -h 0 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC2 sta -S -h 0 - - [R SSC2 P C +SCANDONE] - - - SSC SSC2 sta -S -h 1 - - [R SSC2 P C +SCANDONE] - - - SSC SSC1 ap -S -s -p 123456789 -h 1 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC2 sta -S -h 0 - - [R SSC2 NP C +SCANDONE] - - - SSC SSC2 sta -S -h 1 - - [R SSC2 P C +SCANDONE] - comment: '' - execution time: 0.0 - expected result: '1.target1 set AP,set ssid broad cast - - 2.target 2上scan - - 3.target 2上scan - - 4.target1 set AP,set ssid hidden, - - 5.target 2上不能查询到 - - 6.target 2上查询到' - initial condition: T2_1 - initial condition description (auto): target 1 as SoftAP, target 2 as STA, will - autogen a TC with initial condition T2_2 - module: WIFI MAC - steps: '1.target1下设置ssid 和pwd 加密方式,set ssid broad cast - - 2.target 2上scan - - 3.target 2上scan - - 4.target1下设置ssid 和pwd 加密方式,set ssid hidden, - - 5.target 2上查询 - - 6.target 2上查询' - sub module: WIFI Scan - summary: scan with scan config show hidden - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: scan with different config - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_UDP_0302 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: 1/5 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 BIND - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -S -s -i -p -l 5 - - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] - - - SSC SSC1 sta -D - - ['P SSC1 C +QAP:OK'] - - - SSC SSC1 soc -T -s - - ['R SSC1 RE CLOSE:\d+,OK'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK - - 4.OK - - 5.OK' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: '1.PC上SOC1 UDP传输,bing - - 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - - 3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据 - - 4.断开与AP 连接 - - 5.关闭建立的socket1连接' - sub module: UDP - summary: "close UDP socket after WIFI \ndisconnected" - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: UDP handling abnormal event - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_UDP_0301 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: 1/5 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 BIND - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t UDP -i -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -S -s -i -p -l 5 - - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] - - - SSC SSC1 sta -D - - ['P SSC1 C +QAP:OK'] - - - SSC SSC1 soc -S -s -i -p -l 5 - - ['P SSC1 RE SEND:\d+,ERROR'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK - - 4.OK - - 5.ERROR' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: '1.PC上SOC1 UDP传输,bing - - 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - - 3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据 - - 4.断开与AP 连接 - - 5.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据' - sub module: UDP - summary: do UDP send after WIFI disconnected - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: UDP handling abnormal event - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_CONN_0201 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 sta -C -s -p - - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] - - - SSC SSC1 sta -Q - - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] - - - SSC SSC1 sta -D - - ['R SSC1 C +QAP:OK'] - - - SSC SSC1 sta -Q - - ['R SSC1 C +JAP:DISCONNECTED'] - comment: '' - execution time: 0.0 - expected result: '1.target1 jion AP 成功 - - 2.查询JAP的状态 - - 3.target1 断开AP - - 4.查询target1 JAP 是DISCONN' - initial condition: STAM1 - initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a - TC with initial condition STAAP1 - module: WIFI MAC - steps: '1.target1 jion AP 成功 - - 2.查询JAP的状态 - - 3.target1 断开AP - - 4.查询target1 JAP 是DISCONN' - sub module: WIFI Connect - summary: JAP query test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: query JAP status + test point 2: DNS function test version: v1 (2016-8-15) - CI ready: 'Yes' ID: TCPIP_DNS_0102 @@ -2033,6 +1163,7 @@ test cases: initial condition: STAM2 initial condition description (auto): sta mode, join AP, DHCP on, will autogen a TC with initial condition STAAP2 + level: Integration module: TCPIP steps: '1. get host name "espressif.cn" @@ -2049,7 +1180,7 @@ test cases: test point 2: DNS function test version: v1 (2016-8-15) - CI ready: 'Yes' - ID: TCPIP_DNS_0101 + ID: TCPIP_DNS_0103 SDK: '8266_NonOS 8266_RTOS @@ -2062,17 +1193,30 @@ test cases: cmd set: - '' - - SSC SSC1 soc -H -d iot.espressif.cn - - ['R SSC1 C +HOSTIP:OK,115.29.202.58'] + - ['R SSC1 A :\+HOSTIP:OK,(.+)\r\n'] + - - SSC SSC1 soc -B -t UDP + - ['R SSC1 A :\+BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p 9003 -l 10 + - ['P SSC1 RE \+SEND:\d+,OK', P SSC1 SL +10] comment: '' execution time: 0.0 - expected result: 1.OK + expected result: '1.OK + + 2.OK + + 3.OK' initial condition: STAM2 initial condition description (auto): sta mode, join AP, DHCP on, will autogen a TC with initial condition STAAP2 + level: Integration module: TCPIP - steps: 1. get host name "espressif.cn" + steps: '1. get host name "espressif.cn" + + 2. sendto, recvfrom1. get host name "espressif.cn" + + 2. sendto, recvfrom' sub module: DNS - summary: get host by name test + summary: UDP send to iot.expressif.com test environment: SSC_T1_2 test environment description (auto): 'Able to access WAN after connect to AP. @@ -2081,53 +1225,48 @@ test cases: test point 2: DNS function test version: v1 (2016-8-15) - CI ready: 'Yes' - ID: WIFI_PHY_0403 - SDK: ESP32_IDF + ID: TCPIP_ICMP_0101 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' Test App: SSC - allow fail: '' + allow fail: 1/5 auto test: 'Yes' category: Function cmd set: - '' - - - SSC SSC1 phy -S -o 1 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m n -b 20 - - ['R SSC2 C +PHY:OK'] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:CONNECTED'] - - - SSC SSC2 sta -C -s -p - - [''] - - - DELAY 10 - - ['P SSC1 NC +JAP:DISCONNECTED', 'P SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 ping -i + - ['R SSC1 C +PING:OK'] + - - SSC SSC1 ping -i -c 2 + - ['R SSC1 C +PING:OK'] comment: '' execution time: 0.0 - expected result: 3. SoftAP and STA in channel2, SoftAP 20M, STA 40M, STA not disconnected - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. SoftAP 11n ht20, in channel1, ext AP 11n ht40, in channel2 + expected result: '1.ok - 2. STA connect to ext AP + 2.ok' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration + module: TCPIP + steps: '1.ping -i - 3. AP get connected' - sub module: Phy Mode - summary: SoftAP ext AP in defferent channel, SoftAP 20M, ext AP 40M, STA connect - to AP then Softap get connected - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. + 2.ping -i -c 2' + sub module: ICMP + summary: ping function test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. - PC has one WiFi NIC support capture wlan packet using libpcap. + PC has 1 WiFi NIC. - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' + 1 SSC target connect with PC by UART.' test point 1: basic function - test point 2: STA+SoftAP initial channel test - version: v1 (2015-8-15) + test point 2: ping function test + version: v1 (2016-8-15) - CI ready: 'Yes' - ID: WIFI_CONN_0904 + ID: TCPIP_IGMP_0101 SDK: '8266_NonOS 8266_RTOS @@ -2139,55 +1278,326 @@ test cases: category: Function cmd set: - '' - - - SSC SSC1 ap -S -s -p -t 3 -m 1 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC2 sta -C -s -p 1234567890 - - ['R SSC2 RE JAP:DISCONNECTED,\d+,204'] - - - SSC SSC2 sta -D - - ['R SSC2 C +QAP:OK'] - - - WIFI CONN - - ['R PC_COM NC ERROR C +WIFICONN:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 RE JAP:DISCONNECTED,\d+,5'] - - - WIFI DISCONN - - [P PC_COM C OK, 'R SSC2 C +JAP:CONNECTED'] - - - SSC SSC1 ap -S -s -p -t 3 -m 1 - - ['P SSC1 C +SAP:OK', 'P SSC2 RE JAP:DISCONNECTED,\d+,4'] + - - SSC SSC1 igmp -J -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 igmp -L -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 igmp -J -h -m 223.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -J -h -m 240.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -J -h 192.168.237.77 -m 224.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -J -h 192.168.237.77 -m 240.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + comment: '' + execution time: 0.0 + expected result: '1. success + + 2. failed + + 3. failed + + 4. failed' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration + module: TCPIP + steps: '1. join group with correct host addr and multicast addr + + 2. join group with correct host addr and wrong multicast addr + + 3. join group with wrong host addr and correct multicast addr + + 4. join group with wrong host addr and wrong multicast addr' + sub module: IGMP + summary: station IGMP join group address check + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: IGMP API parameter check + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_IGMP_0102 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 igmp -J -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 igmp -L -h -m 224.1.1.2 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -L -h 192.168.237.77 -m 224.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -L -h 192.168.237.77 -m 240.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -L -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + comment: '' + execution time: 0.0 + expected result: '1. success + + 2. failed + + 3. failed + + 4. failed + + 5. succeed' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration + module: TCPIP + steps: '1. join group with correct host addr and multicast addr + + 2. leave group with correct host addr and wrong multicast addr + + 3. leave group with wrong host addr and correct multicast addr + + 4. leave group with wrong host addr and wrong multicast addr + + 5. leave group with correct host addr and correct multicast addr' + sub module: IGMP + summary: station IGMP leave group address check + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: IGMP API parameter check + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_IGMP_0103 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 igmp -J -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 igmp -L -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 igmp -J -h -m 223.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -J -h -m 240.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -J -h 192.168.237.77 -m 224.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -J -h 192.168.237.77 -m 240.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + comment: '' + execution time: 0.0 + expected result: '1. success + + 2. failed + + 3. failed + + 4. failed' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + level: Integration + module: TCPIP + steps: '1. join group with correct host addr and multicast addr + + 2. join group with correct host addr and wrong multicast addr + + 3. join group with wrong host addr and correct multicast addr + + 4. join group with wrong host addr and wrong multicast addr' + sub module: IGMP + summary: softAP IGMP join group address check + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: IGMP API parameter check + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_IGMP_0104 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 igmp -J -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 igmp -L -h -m 224.1.1.2 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -L -h 192.168.237.77 -m 224.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -L -h 192.168.237.77 -m 240.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -L -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + comment: '' + execution time: 0.0 + expected result: '1. success + + 2. failed + + 3. failed + + 4. failed + + 5. succeed' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + level: Integration + module: TCPIP + steps: '1. join group with correct host addr and multicast addr + + 2. leave group with correct host addr and wrong multicast addr + + 3. leave group with wrong host addr and correct multicast addr + + 4. leave group with wrong host addr and wrong multicast addr + + 5. leave group with correct host addr and correct multicast addr' + sub module: IGMP + summary: softAP IGMP leave group address check + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: IGMP API parameter check + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_IGMP_0201 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 igmp -J -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 soc -B -t UDP -i 224.1.1.1 -p + - ['R SSC1 A :\+BIND:(\d+),OK'] + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SOC SOC1 SENDTO 1 224.1.1.1 + - [R SSC1 SL +1] + - - SSC SSC1 igmp -L -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] comment: '' execution time: 0.0 expected result: '1. succeed - 2. disconnect event REASON_HANDSHAKE_TIMEOUT + 2. succeed + + 3. able to recv packet' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration + module: TCPIP + steps: '1. join group + + 2. create UDP socket using multicast addr + + 3. PC send UDP packet to multicast addr' + sub module: IGMP + summary: station IGMP recv packets + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: IGMP send/recv test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_IGMP_0202 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC2 op -S -o 1 + - ['R SSC2 C +MODE:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 igmp -J -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 soc -B -t UDP -i 224.1.1.1 -p + - ['R SSC1 A :\+BIND:(\d+),OK'] + - - SSC SSC2 soc -B -t UDP -p + - ['R SSC2 A :\+BIND:(\d+),OK'] + - - SSC SSC2 soc -S -s -i 224.1.1.1 -p -l 10 + - [R SSC1 SL +1] + - - SSC SSC1 igmp -L -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed 3. succeed - 4. succeed + 4. target1 recv multicast packet' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration + module: TCPIP + steps: '1. target2 set to sta mode and join AP - 5. disconnect event REASON_ASSOC_TOOMANY + 2. target1 join group and create UDP socket using multicast addr - 6. succeed, target2 connect succeed + 3. target2 create UDP socket - 7. disconnect event REASON_ASSOC_EXPIRE' - initial condition: T2_1 - initial condition description (auto): target 1 as SoftAP, target 2 as STA, will - autogen a TC with initial condition T2_2 - module: WIFI MAC - steps: '1. config target1 softap max sta allowed 1 - - 2. target2 connect to target1 with wrong password - - 3. target2 disconnect - - 4. PC WIFI NIC connect to target1 - - 5. target2 connect to target1 with correct password - - 6. PC WIFI NIC disconnect - - 7. reconfig softap' - sub module: WIFI Connect - summary: test wifi disconnect reason REASON_ASSOC_TOOMANY, REASON_HANDSHAKE_TIMEOUT, - REASON_ASSOC_EXPIRE + 4. target2 send to multicast addr' + sub module: IGMP + summary: station send multicast packets test environment: SSC_T2_1 test environment description (auto): 'PC has 1 wired NIC connected to AP. @@ -2195,7 +1605,115 @@ test cases: 2 SSC target connect with PC by UART.' test point 1: basic function - test point 2: wifi disconnect reason test + test point 2: IGMP send/recv test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_IGMP_0203 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 igmp -J -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 soc -B -t UDP -i 224.1.1.1 -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SOC SOC1 SENDTO 1 224.1.1.1 + - [R SSC1 SL +1] + - - SSC SSC1 igmp -L -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. able to recv packet' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + level: Integration + module: TCPIP + steps: '1. join group + + 2. create UDP socket using multicast addr + + 3. PC send UDP packet to multicast addr' + sub module: IGMP + summary: softAP IGMP recv packets + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: IGMP send/recv test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_IGMP_0204 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 igmp -J -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 soc -B -t UDP -i 224.1.1.1 -p + - ['R SSC1 A :\+BIND:(\d+),OK'] + - - SSC SSC2 soc -B -t UDP -p + - ['R SSC2 A :\+BIND:(\d+),OK'] + - - SSC SSC2 soc -S -s -i 224.1.1.1 -p -l 10 + - [R SSC1 SL +1] + - - SSC SSC1 igmp -L -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. succeed + + 4. target1 recv multicast packet' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + level: Integration + module: TCPIP + steps: '1. target2 join SoftAP + + 2. target1 join group and create UDP socket using multicast addr + + 3. target2 create UDP socket + + 4. target2 send to multicast addr' + sub module: IGMP + summary: softAP send multicast packets + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: IGMP send/recv test version: v1 (2016-8-15) - CI ready: 'Yes' ID: TCPIP_IP_0101 @@ -2234,6 +1752,7 @@ test cases: initial condition: STAM1 initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a TC with initial condition STAAP1 + level: Integration module: TCPIP steps: '1.target1 打开DHCP 1 @@ -2296,6 +1815,7 @@ test cases: initial condition: APM1 initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial condition APSTA1 + level: Integration module: TCPIP steps: "1.target1 打开DHCP 2\n2.target1 设置softAP ip 192.168.123.123\n4.target1 关闭DHCP\ \ 2\n5.target1 设置softAP ip 192.168.123.123\n6.target1 查询 当前sta ip \n7.target1\ @@ -2312,2559 +1832,7 @@ test cases: test point 2: set and query static IP version: v1 (2016-8-15) - CI ready: 'Yes' - ID: ^WIFI_CONN_0201 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 sta -C -s -p - - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] - - - SSC SSC1 sta -Q - - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] - - - SSC SSC1 sta -D - - ['R SSC1 C +QAP:OK'] - - - SSC SSC1 sta -Q - - ['R SSC1 C +JAP:DISCONNECTED'] - comment: '' - execution time: 0.0 - expected result: '1.target1 jion AP 成功 - - 2.查询JAP的状态 - - 3.target1 断开AP - - 4.查询target1 JAP 是DISCONN' - initial condition: STAAP1 - initial condition description (auto): testing sta on sta + ap mode, quit AP (autogen - by STAM1) - module: WIFI MAC - steps: '1.target1 jion AP 成功 - - 2.查询JAP的状态 - - 3.target1 断开AP - - 4.查询target1 JAP 是DISCONN' - sub module: WIFI Connect - summary: JAP query test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: query JAP status - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_IGMP_0102 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 igmp -J -h -m 224.1.1.1 - - ['R SSC1 C +IGMP:OK'] - - - SSC SSC1 igmp -L -h -m 224.1.1.2 - - ['R SSC1 C +IGMP:ERROR'] - - - SSC SSC1 igmp -L -h 192.168.237.77 -m 224.1.1.1 - - ['R SSC1 C +IGMP:ERROR'] - - - SSC SSC1 igmp -L -h 192.168.237.77 -m 240.1.1.1 - - ['R SSC1 C +IGMP:ERROR'] - - - SSC SSC1 igmp -L -h -m 224.1.1.1 - - ['R SSC1 C +IGMP:OK'] - comment: '' - execution time: 0.0 - expected result: '1. success - - 2. failed - - 3. failed - - 4. failed - - 5. succeed' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: '1. join group with correct host addr and multicast addr - - 2. leave group with correct host addr and wrong multicast addr - - 3. leave group with wrong host addr and correct multicast addr - - 4. leave group with wrong host addr and wrong multicast addr - - 5. leave group with correct host addr and correct multicast addr' - sub module: IGMP - summary: station IGMP leave group address check - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: IGMP API parameter check - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_IGMP_0101 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 igmp -J -h -m 224.1.1.1 - - ['R SSC1 C +IGMP:OK'] - - - SSC SSC1 igmp -L -h -m 224.1.1.1 - - ['R SSC1 C +IGMP:OK'] - - - SSC SSC1 igmp -J -h -m 223.1.1.1 - - ['R SSC1 C +IGMP:ERROR'] - - - SSC SSC1 igmp -J -h -m 240.1.1.1 - - ['R SSC1 C +IGMP:ERROR'] - - - SSC SSC1 igmp -J -h 192.168.237.77 -m 224.1.1.1 - - ['R SSC1 C +IGMP:ERROR'] - - - SSC SSC1 igmp -J -h 192.168.237.77 -m 240.1.1.1 - - ['R SSC1 C +IGMP:ERROR'] - comment: '' - execution time: 0.0 - expected result: '1. success - - 2. failed - - 3. failed - - 4. failed' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: '1. join group with correct host addr and multicast addr - - 2. join group with correct host addr and wrong multicast addr - - 3. join group with wrong host addr and correct multicast addr - - 4. join group with wrong host addr and wrong multicast addr' - sub module: IGMP - summary: station IGMP join group address check - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: IGMP API parameter check - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_IGMP_0104 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 igmp -J -h -m 224.1.1.1 - - ['R SSC1 C +IGMP:OK'] - - - SSC SSC1 igmp -L -h -m 224.1.1.2 - - ['R SSC1 C +IGMP:ERROR'] - - - SSC SSC1 igmp -L -h 192.168.237.77 -m 224.1.1.1 - - ['R SSC1 C +IGMP:ERROR'] - - - SSC SSC1 igmp -L -h 192.168.237.77 -m 240.1.1.1 - - ['R SSC1 C +IGMP:ERROR'] - - - SSC SSC1 igmp -L -h -m 224.1.1.1 - - ['R SSC1 C +IGMP:OK'] - comment: '' - execution time: 0.0 - expected result: '1. success - - 2. failed - - 3. failed - - 4. failed - - 5. succeed' - initial condition: APSTA2 - initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen - by APM2) - module: TCPIP - steps: '1. join group with correct host addr and multicast addr - - 2. leave group with correct host addr and wrong multicast addr - - 3. leave group with wrong host addr and correct multicast addr - - 4. leave group with wrong host addr and wrong multicast addr - - 5. leave group with correct host addr and correct multicast addr' - sub module: IGMP - summary: softAP IGMP leave group address check - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: IGMP API parameter check - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_UDP_0110 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: 1/5 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 BIND - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -S -s -i -p -l 1 - - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 1] - - - SSC SSC1 soc -S -s -i -p -l 1472 - - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 1472] - - - SSC SSC1 soc -S -s -i -p -l 1473 - - ['P SSC1 RE SEND:(\d+),OK', P SOC_COM NC SOC_RECVFROM] - - - SSC SSC1 soc -S -s -i -p -l 1472 -n 10 - -j 20 - - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 14720] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK - - 4.OK - - 5.OK,没收到UDP包 - - 6.OK' - initial condition: APSTA2 - initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen - by APM2) - module: TCPIP - steps: '1.PC上SOC1 UDP传输,bing - - 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - - 3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1字节数据 - - 4.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1472字节数据 - - 5.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1473字节数据 - - 6.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1472*10字节数据' - sub module: UDP - summary: AP mode, sendto test with different length - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use UDP SAP (socket/espconn API) with different parameter - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^WIFI_SCAN_0102 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC2 sta -S -b ff:ff:ff:ff:ff:11 - - ['R SSC2 NC +SCAN: C +SCANDONE'] - - - SSC SSC2 sta -S -b - - ['R SSC2 RE "\+SCAN:.+,%%s"%%()', 'R SSC2 NC +SCAN: C +SCANDONE'] - comment: '' - execution time: 0.0 - expected result: '1.target2 上不能查询到此mac - - 2.target2上查询到' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1.target2 上查询此macff:ff:ff:ff:ff:11 - - 2.target2上查询' - sub module: WIFI Scan - summary: scan with scan config bssid - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: scan with different config - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^WIFI_SCAN_0103 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 sta -D - - ['R SSC1 C +QAP:'] - - - SSC SSC1 ap -S -s -p 123456789 -t 3 -n 6 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC2 sta -S -n 5 - - [R SSC2 NP C +SCANDONE] - - - SSC SSC2 sta -S -n 6 - - ['R SSC2 C +SCAN:', R SSC2 P ] - comment: '' - execution time: 0.0 - expected result: '1.target1 QAP - - 2. target1 set AP,set channel 6 - - 3.target2 上scan不到 channel 5 - - 4.target2 上查询channel 6的' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1.target1 断开连接AP - - 2.target1下设置ssid 和pwd 加密方式,set channel 6 - - 3.target2 上scan channel 5 - - 4.target2 上查询channel 6的' - sub module: WIFI Scan - summary: scan with scan config channel - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: scan with different config - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^WIFI_SCAN_0104 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -p 123456789 -t 3 -h 0 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC2 sta -S -h 0 - - [R SSC2 P C +SCANDONE] - - - SSC SSC2 sta -S -h 1 - - [R SSC2 P C +SCANDONE] - - - SSC SSC1 ap -S -s -p 123456789 -h 1 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC2 sta -S -h 0 - - [R SSC2 NP C +SCANDONE] - - - SSC SSC2 sta -S -h 1 - - [R SSC2 P C +SCANDONE] - comment: '' - execution time: 0.0 - expected result: '1.target1 set AP,set ssid broad cast - - 2.target 2上scan - - 3.target 2上scan - - 4.target1 set AP,set ssid hidden, - - 5.target 2上不能查询到 - - 6.target 2上查询到' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1.target1下设置ssid 和pwd 加密方式,set ssid broad cast - - 2.target 2上scan - - 3.target 2上scan - - 4.target1下设置ssid 和pwd 加密方式,set ssid hidden, - - 5.target 2上查询 - - 6.target 2上查询' - sub module: WIFI Scan - summary: scan with scan config show hidden - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: scan with different config - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^WIFI_SCAN_0105 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 sta -D - - ['R SSC1 C +QAP:'] - - - SSC SSC1 ap -S -s -p 123456789 -t 3 -h 0 -n 11 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC2 sta -S -s -b -n 11 - - [R SSC2 P C +SCANDONE] - - - SSC SSC2 sta -S -s -b -n 11 - - [R SSC2 NP C +SCANDONE] - - - SSC SSC2 sta -S -s -b ff:ff:ff:ff:ff:11 -n 11 - - [R SSC2 P , R SSC2 NP C +SCANDONE] - - - SSC SSC2 sta -S -s -b -n 10 - - [R SSC2 P , R SSC2 NP C +SCANDONE] - comment: '' - execution time: 0.0 - expected result: '1.target1 QAP - - 2. target1 set AP,set ssid broad cast,set channel 11 - - 3.target2 上查询到 - - 4.target2 上查询不到 - - 5.target2 上查询不到 - - 6.target2 上查询不到' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1.target1 QAP - - 2. target1 set AP,set ssid broad cast,set channel 11 - - 3.target2 上查询到 - - 4.target2 上查询不到 - - 5.target2 上查询不到 - - 6.target2 上查询不到' - sub module: WIFI Scan - summary: scan with several configs - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: scan with different config - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_IGMP_0104 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 igmp -J -h -m 224.1.1.1 - - ['R SSC1 C +IGMP:OK'] - - - SSC SSC1 igmp -L -h -m 224.1.1.2 - - ['R SSC1 C +IGMP:ERROR'] - - - SSC SSC1 igmp -L -h 192.168.237.77 -m 224.1.1.1 - - ['R SSC1 C +IGMP:ERROR'] - - - SSC SSC1 igmp -L -h 192.168.237.77 -m 240.1.1.1 - - ['R SSC1 C +IGMP:ERROR'] - - - SSC SSC1 igmp -L -h -m 224.1.1.1 - - ['R SSC1 C +IGMP:OK'] - comment: '' - execution time: 0.0 - expected result: '1. success - - 2. failed - - 3. failed - - 4. failed - - 5. succeed' - initial condition: APM2 - initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen - a TC with initial condition APSTA2 - module: TCPIP - steps: '1. join group with correct host addr and multicast addr - - 2. leave group with correct host addr and wrong multicast addr - - 3. leave group with wrong host addr and correct multicast addr - - 4. leave group with wrong host addr and wrong multicast addr - - 5. leave group with correct host addr and correct multicast addr' - sub module: IGMP - summary: softAP IGMP leave group address check - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: IGMP API parameter check - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_IGMP_0103 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 igmp -J -h -m 224.1.1.1 - - ['R SSC1 C +IGMP:OK'] - - - SSC SSC1 igmp -L -h -m 224.1.1.1 - - ['R SSC1 C +IGMP:OK'] - - - SSC SSC1 igmp -J -h -m 223.1.1.1 - - ['R SSC1 C +IGMP:ERROR'] - - - SSC SSC1 igmp -J -h -m 240.1.1.1 - - ['R SSC1 C +IGMP:ERROR'] - - - SSC SSC1 igmp -J -h 192.168.237.77 -m 224.1.1.1 - - ['R SSC1 C +IGMP:ERROR'] - - - SSC SSC1 igmp -J -h 192.168.237.77 -m 240.1.1.1 - - ['R SSC1 C +IGMP:ERROR'] - comment: '' - execution time: 0.0 - expected result: '1. success - - 2. failed - - 3. failed - - 4. failed' - initial condition: APM2 - initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen - a TC with initial condition APSTA2 - module: TCPIP - steps: '1. join group with correct host addr and multicast addr - - 2. join group with correct host addr and wrong multicast addr - - 3. join group with wrong host addr and correct multicast addr - - 4. join group with wrong host addr and wrong multicast addr' - sub module: IGMP - summary: softAP IGMP join group address check - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: IGMP API parameter check - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_IGMP_0102 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 igmp -J -h -m 224.1.1.1 - - ['R SSC1 C +IGMP:OK'] - - - SSC SSC1 igmp -L -h -m 224.1.1.2 - - ['R SSC1 C +IGMP:ERROR'] - - - SSC SSC1 igmp -L -h 192.168.237.77 -m 224.1.1.1 - - ['R SSC1 C +IGMP:ERROR'] - - - SSC SSC1 igmp -L -h 192.168.237.77 -m 240.1.1.1 - - ['R SSC1 C +IGMP:ERROR'] - - - SSC SSC1 igmp -L -h -m 224.1.1.1 - - ['R SSC1 C +IGMP:OK'] - comment: '' - execution time: 0.0 - expected result: '1. success - - 2. failed - - 3. failed - - 4. failed - - 5. succeed' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: '1. join group with correct host addr and multicast addr - - 2. leave group with correct host addr and wrong multicast addr - - 3. leave group with wrong host addr and correct multicast addr - - 4. leave group with wrong host addr and wrong multicast addr - - 5. leave group with correct host addr and correct multicast addr' - sub module: IGMP - summary: station IGMP leave group address check - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: IGMP API parameter check - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_IGMP_0101 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 igmp -J -h -m 224.1.1.1 - - ['R SSC1 C +IGMP:OK'] - - - SSC SSC1 igmp -L -h -m 224.1.1.1 - - ['R SSC1 C +IGMP:OK'] - - - SSC SSC1 igmp -J -h -m 223.1.1.1 - - ['R SSC1 C +IGMP:ERROR'] - - - SSC SSC1 igmp -J -h -m 240.1.1.1 - - ['R SSC1 C +IGMP:ERROR'] - - - SSC SSC1 igmp -J -h 192.168.237.77 -m 224.1.1.1 - - ['R SSC1 C +IGMP:ERROR'] - - - SSC SSC1 igmp -J -h 192.168.237.77 -m 240.1.1.1 - - ['R SSC1 C +IGMP:ERROR'] - comment: '' - execution time: 0.0 - expected result: '1. success - - 2. failed - - 3. failed - - 4. failed' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: '1. join group with correct host addr and multicast addr - - 2. join group with correct host addr and wrong multicast addr - - 3. join group with wrong host addr and correct multicast addr - - 4. join group with wrong host addr and wrong multicast addr' - sub module: IGMP - summary: station IGMP join group address check - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: IGMP API parameter check - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_UDP_0201 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 BIND - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -W -s -o 0 - - ['R SSC1 RE WORKTHREAD:\d+,OK'] - - - SOC SOC1 SENDTO 1472 - - [''] - - - SOC SOC1 SENDTO 1472 - - [''] - - - SOC SOC1 SENDTO 1472 - - [''] - - - SOC SOC1 SENDTO 1472 - - [''] - - - SOC SOC1 SENDTO 1472 - - [''] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK - - 4.PC OK - - 5.PC OK - - 6.PC OK - - 7.PC OK - - 8.PC OK SOC_CLOSE=SOC1' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: '1.PC上SOC1 UDP传输,bing - - 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - - 3.target1上关闭工作线程 - - 4.PC往8266上发送1472字节数据 - - 5.PC往8266上发送1472字节数据 - - 6.PC往8266上发送1472字节数据 - - 7.PC往8266上发送1472字节数据 - - 8.PC往8266上发送1472字节数据' - sub module: UDP - summary: STA mode, recv buffer test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: use UDP SAP (socket/espconn API) in different state - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_ICMP_0101 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: 1/5 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ping -i - - ['R SSC1 C +PING:OK'] - - - SSC SSC1 ping -i -c 2 - - ['R SSC1 C +PING:OK'] - comment: '' - execution time: 0.0 - expected result: '1.ok - - 2.ok' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: '1.ping -i - - 2.ping -i -c 2' - sub module: ICMP - summary: ping function test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: ping function test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^WIFI_ADDR_0102 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 mac -S -o 2 -m 44:55:66:77:88:99 - - ['R SSC1 C +MAC:AP,OK'] - - - SSC SSC1 ap -S -s -p -t - - [''] - - - SSC SSC2 sta -S -b 44:55:66:77:88:99 - - ['R SSC2 RE \+SCAN:.+,44:55:66:77:88:99,'] - - - SSC SSC1 mac -S -o 2 -m - - ['R SSC1 C +MAC:AP,OK'] - - - SSC SSC2 mac -Q -o 1 - - ['R SSC2 A :\+STAMAC:(.+)\r\n'] - - - SSC SSC2 mac -S -o 1 -m 22:33:44:55:66:77 - - ['R SSC2 C +MAC:STA,OK'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED'] - - - SSC SSC1 ap -L - - ['R SSC1 C +LSTA:22:33:44:55:66:77'] - - - SSC SSC2 mac -S -o 1 -m - - ['R SSC2 C +MAC:STA,OK'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.ok - - 3.ok - - 4.ok - - 5.ok - - 6.ok - - 7.ok - - 8.ok - - 9.ok' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: "1.target1 设置sta mode下的mac 44:55:66:77:88:99\n2.target1下设置ssid 和pwd 加密方式\n\ - 3.target2 查询mac为44:55:66:77:88:99的ssid\n4.target1 设置sta mode下的mac target_ap_mac\n\ - 5.target2 查询sta mode 下的mac 为target2_mac_tmp\n6.target2 设置sta mode 下的mac 为22:33:44:55:66:77\n\ - 7.target2 jap target1\n8.target1 查询连接到的sta \n9.target2 设置sta mode 下的mac 为 target2_mac" - sub module: MAC Address - summary: set mac and do scan/JAP/SAP - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: mac address function test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_UDP_0108 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 RE BIND:(\d+),OK'] - - - SSC SSC1 soc -B -t UDP -i 0.0.0.0 -p - - ['R SSC1 RE BIND:(\d+),OK'] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 C BIND:ERROR'] - - - SSC SSC1 soc -B -t TCP -p - - ['R SSC1 RE BIND:(\d+),OK'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.ERROR - - 4.OK' - initial condition: APM2 - initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen - a TC with initial condition APSTA2 - module: TCPIP - steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - - 2.target1上UDP传输,Bind socket2,本地ip 0.0.0.0 target_udp_port2 - - 3.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - - 4.target1上创建TCP socket3, target_udp_port1' - sub module: UDP - summary: AP mode, udp bind test. use different ip, port - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use UDP SAP (socket/espconn API) with different parameter - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_UDP_0109 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: 1/5 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -p -t - - ['R SSC1 C +SAP:OK'] - - - WIFI CONN - - - ['R PC_COM NC ERROR C +WIFICONN:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] - - - SOC SOC1 BIND - - [R SOC_COM L OK] - - - SSC SSC2 ip - - ['R SSC2 A :STAIP:(.+)\r\n'] - - - SSC SSC2 soc -B -t UDP -p - - ['R SSC2 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -S -s -i -p -l 5 - - [R SOC1 UL 5] - - - SSC SSC1 soc -S -s -i -p -l 5 - - ['R SSC2 RE "RECVFROM:%%s,5,%%s,%%u"%%(,,)'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK - - 4.OK - - 5.OK' - initial condition: T2O_1 - initial condition description (auto): same as T2_1 but will NOT autogen a TC with - initial condition T2_2 - module: TCPIP - steps: '1.PC上SOC1 UDP传输,bing - - 2.PC上SOC2 UDP传输,bing - - 3.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - - 4.target1上使用步骤3创建的socket1,往pc_ip,test_tcp_port1上发送10字节数据 - - 5.target1上使用步骤3创建的socket1,往pc_ip2,test_tcp_port2上发送10字节数据' - sub module: UDP - summary: AP mode, sendto test. use different ip, port - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use UDP SAP (socket/espconn API) with different parameter - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_UDP_0106 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 RE BIND:(\d+),OK'] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 RE BIND:(\d+),OK'] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 RE BIND:(\d+),OK'] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 RE BIND:(\d+),OK'] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 RE BIND:(\d+),OK'] - comment: '' - execution time: 0.0 - expected result: '1.ok - - 2.ok - - 3.ok - - 4.ok - - 5.ok' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - - 2.target1上UDP传输,Bind socket2,本地ip target_udp_port2 - - 3.target1上UDP传输,Bind socket3,本地ip target_udp_port3 - - 4.target1上UDP传输,Bind socket4,本地ip target_udp_port4 - - 5.target1上UDP传输,Bind socket5,本地ip target_udp_port5' - sub module: UDP - summary: STA mode, create max udp socket test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use UDP SAP (socket/espconn API) with different parameter - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_UDP_0107 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -I - - ['P SSC1 RE "SOCINFO:%%s,1,.+,%%d"%%(,)'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - - 2.target1上查询创建socket信息' - sub module: UDP - summary: STA mode, get active socket info test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use UDP SAP (socket/espconn API) with different parameter - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_UDP_0104 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: 1/5 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 BIND - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SOC SOC1 SENDTO 1 - - [R SSC1 SL +1] - - - SOC SOC1 SENDTO 1472 - - ['R SSC1 RE "RECVFROM:%%s,1472,%%s,%%u"%%(,,)'] - - - SOC SOC1 SENDTO 1473 - - [P SSC1 NC +RECVFROM, P SOC_COM C OK] - - - SOC SOC2 BIND - - [R SOC_COM L OK] - - - SOC SOC2 SENDTO 1472 - - ['R SSC1 RE "RECVFROM:%%s,1472,%%s,%%u"%%(,,)'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK - - 4.OK - - 5.OK,没收到UDP包 - - 6.OK - - 7.OK' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: '1.PC上SOC1 UDP传输,bing - - 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - - 3.PC往8266上发送1字节数据 - - 4.PC往8266上发送1472字节数据 - - 5.PC往8266上发送1473字节数据 - - 6.PC上SOC2 UDP传输,bing - - 7.PC往8266上发送1472字节数据' - sub module: UDP - summary: STA mode, recvfrom basic test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use UDP SAP (socket/espconn API) with different parameter - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_UDP_0105 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -T -s - - ['R SSC1 RE CLOSE:\d+'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - - 2.关闭socket1' - sub module: UDP - summary: STA mode, close UDP sockets test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use UDP SAP (socket/espconn API) with different parameter - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_UDP_0102 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: 1/5 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 BIND - - [R SOC_COM L OK] - - - SOC SOC2 BIND - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -S -s -i -p -l 10 - - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 10] - - - SSC SSC1 soc -S -s -i -p -l 10 - - ['P SSC1 RE SEND:(\d+),OK', P SOC2 UL 10] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK - - 4.OK - - 5.OK' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: '1.PC上SOC1 UDP传输,bing - - 2.PC上SOC2 UDP传输,bing - - 3.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - - 4.target1上使用步骤3创建的socket1,往pc_ip,test_tcp_port1上发送10字节数据 - - 5.target1上使用步骤3创建的socket1,往pc_ip2,test_tcp_port2上发送10字节数据' - sub module: UDP - summary: STA mode, sendto test. use different ip, port - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use UDP SAP (socket/espconn API) with different parameter - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_UDP_0103 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: 1/5 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 BIND - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -S -s -i -p -l 1 - - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 1] - - - SSC SSC1 soc -S -s -i -p -l 1472 - - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 1472] - - - SSC SSC1 soc -S -s -i -p -l 1473 - - ['P SSC1 RE SEND:(\d+),OK', P SOC_COM NC SOC_RECVFROM] - - - SSC SSC1 soc -S -s -i -p -l 1472 -n 10 -j 20 - - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 14720] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK - - 4.OK - - 5.OK,没有到UDP包 - - 6.OK' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: '1.PC上SOC1 UDP传输,bing - - 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - - 3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1字节数据 - - 4.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1472字节数据 - - 5.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1473字节数据 - - 6.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1472*10字节数据' - sub module: UDP - summary: STA mode, sendto test with different length - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use UDP SAP (socket/espconn API) with different parameter - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_UDP_0101 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 RE BIND:(\d+),OK'] - - - SSC SSC1 soc -B -t UDP -i 0.0.0.0 -p - - ['R SSC1 RE BIND:(\d+),OK'] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 C BIND:ERROR'] - - - SSC SSC1 soc -B -t TCP -p - - ['R SSC1 RE BIND:(\d+),OK'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.ERROR - - 4.OK' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - - 2.target1上UDP传输,Bind socket2,本地ip 0.0.0.0 target_udp_port2 - - 3.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - - 4.target1上创建TCP socket3, target_udp_port1' - sub module: UDP - summary: STA mode, udp bind test. use different ip, port - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use UDP SAP (socket/espconn API) with different parameter - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_IGMP_0204 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC1 igmp -J -h -m 224.1.1.1 - - ['R SSC1 C +IGMP:OK'] - - - SSC SSC1 soc -B -t UDP -i 224.1.1.1 -p - - ['R SSC1 A :\+BIND:(\d+),OK'] - - - SSC SSC2 soc -B -t UDP -p - - ['R SSC2 A :\+BIND:(\d+),OK'] - - - SSC SSC2 soc -S -s -i 224.1.1.1 -p -l 10 - - [R SSC1 SL +1] - - - SSC SSC1 igmp -L -h -m 224.1.1.1 - - ['R SSC1 C +IGMP:OK'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 3. succeed - - 4. target1 recv multicast packet' - initial condition: T2_1 - initial condition description (auto): target 1 as SoftAP, target 2 as STA, will - autogen a TC with initial condition T2_2 - module: TCPIP - steps: '1. target2 join SoftAP - - 2. target1 join group and create UDP socket using multicast addr - - 3. target2 create UDP socket - - 4. target2 send to multicast addr' - sub module: IGMP - summary: softAP send multicast packets - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: IGMP send/recv test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_IGMP_0201 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 igmp -J -h -m 224.1.1.1 - - ['R SSC1 C +IGMP:OK'] - - - SSC SSC1 soc -B -t UDP -i 224.1.1.1 -p - - ['R SSC1 A :\+BIND:(\d+),OK'] - - - SOC SOC1 BIND - - [R SOC_COM L OK] - - - SOC SOC1 SENDTO 1 224.1.1.1 - - [R SSC1 SL +1] - - - SSC SSC1 igmp -L -h -m 224.1.1.1 - - ['R SSC1 C +IGMP:OK'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 3. able to recv packet' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: '1. join group - - 2. create UDP socket using multicast addr - - 3. PC send UDP packet to multicast addr' - sub module: IGMP - summary: station IGMP recv packets - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: IGMP send/recv test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_IGMP_0202 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC2 op -S -o 1 - - ['R SSC2 C +MODE:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC1 igmp -J -h -m 224.1.1.1 - - ['R SSC1 C +IGMP:OK'] - - - SSC SSC1 soc -B -t UDP -i 224.1.1.1 -p - - ['R SSC1 A :\+BIND:(\d+),OK'] - - - SSC SSC2 soc -B -t UDP -p - - ['R SSC2 A :\+BIND:(\d+),OK'] - - - SSC SSC2 soc -S -s -i 224.1.1.1 -p -l 10 - - [R SSC1 SL +1] - - - SSC SSC1 igmp -L -h -m 224.1.1.1 - - ['R SSC1 C +IGMP:OK'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 3. succeed - - 4. target1 recv multicast packet' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: '1. target2 set to sta mode and join AP - - 2. target1 join group and create UDP socket using multicast addr - - 3. target2 create UDP socket - - 4. target2 send to multicast addr' - sub module: IGMP - summary: station send multicast packets - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: IGMP send/recv test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_IGMP_0203 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 igmp -J -h -m 224.1.1.1 - - ['R SSC1 C +IGMP:OK'] - - - SSC SSC1 soc -B -t UDP -i 224.1.1.1 -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SOC SOC1 BIND - - [R SOC_COM L OK] - - - SOC SOC1 SENDTO 1 224.1.1.1 - - [R SSC1 SL +1] - - - SSC SSC1 igmp -L -h -m 224.1.1.1 - - ['R SSC1 C +IGMP:OK'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 3. able to recv packet' - initial condition: APM2 - initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen - a TC with initial condition APSTA2 - module: TCPIP - steps: '1. join group - - 2. create UDP socket using multicast addr - - 3. PC send UDP packet to multicast addr' - sub module: IGMP - summary: softAP IGMP recv packets - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: IGMP send/recv test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_CONN_0401 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 sta -R -a 0 - - ['R SSC1 C +AUTORECONN:OK'] - - - SSC SSC1 sta -R -a 2 - - ['R SSC1 C +AUTORECONN:0'] - - - SSC SSC1 reboot - - [''] - - - DELAY 15 - - [''] - - - SSC SSC1 sta -Q - - ['R SSC1 C JAP:DISCONNECTED'] - - - SSC SSC1 sta -R -a 1 - - ['R SSC1 C +AUTORECONN:OK'] - - - SSC SSC1 sta -R -a 2 - - ['R SSC1 C +AUTORECONN:1'] - - - SSC SSC1 reboot - - ['R SSC1 C +JAP:CONNECTED'] - comment: '' - execution time: 0.0 - expected result: '1.设置autoreconn,关闭 - - 2.查询当前autoreconn状态是否关闭 - - 3.重启系统,等待15s - - 4.查询target1 未自动重连AP - - 5.设置autoreconn,开启 - - 6.查询当前autoreconn状态是否开启 - - 7.系统重启后target1 自动重连AP' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: WIFI MAC - steps: '1.设置autoreconn,关闭 - - 2.查询当前autoreconn状态是否关闭 - - 3.重启系统,等待15s - - 4.查询target1 未自动重连AP - - 5.设置autoreconn,开启 - - 6.查询当前autoreconn状态是否开启 - - 7.系统重启后target1 自动重连AP' - sub module: WIFI Connect - summary: auto reconnect test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: power on auto reconnect test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_TCP_0404 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SOC SOC1 ACCEPT SOC2 - - [R SOC_COM L OK] - - - SSC SSC1 op -S -o 2 - - ['P SSC1 C +MODE:OK', 'P SSC1 RE CLOSED:\d+,0'] - - - SSC SSC1 soc -T -s - - ['R SSC1 RE CLOSE:\d+,OK'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK; PC TCP server accept 成功 - - 4.OK - - 5.OK - - 6.OK' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1上使用步骤2创建的socket1,去连接\ - \ PC的ip,test_tcp_port1\n4.PC与target1创建好TCP 连接,有ACCEPT\n5.修改8266的Mode为softAP mode\ - \ \n6.关闭建立的socket1连接" - sub module: TCP - summary: close TCP socket after mode changed - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: TCP handling abnormal event - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_TCP_0405 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SOC SOC1 ACCEPT SOC2 - - [R SOC_COM L OK] - - - NIC DISABLED - - [R PC_COM C OK] - - - SSC SSC1 soc -S -s -l 1 - - [''] - - - DELAY 5400 - - ['P SSC1 RE CLOSED:\d+,0'] - comment: '' - execution time: 1.5 - expected result: '1.OK - - 2.OK - - 3.OK; PC TCP server accept 成功 - - 4.OK - - 5.OK - - 6.TCP连接断开' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: '1.PC上建立TCP 监听 test_tcp_port1 - - 2.target1上创建TCP socket1 - - 3.target1上使用步骤2创建的socket1,去连接 PC的ip,test_tcp_port1 - - 4.PC与target1创建好TCP 连接,有ACCEPT - - 5.PC 网卡 disable - - 6.target1上使用socket1发送数据,等待 90 分钟' - sub module: TCP - summary: do TCP send after PC NIC disabled - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: TCP handling abnormal event - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_TCP_0406 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SOC SOC1 ACCEPT SOC2 - - [R SOC_COM L OK] - - - NIC DISABLED - - [R PC_COM C OK] - - - SSC SSC1 soc -T -s - - ['R SSC1 RE CLOSE:\d+,OK'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK; PC TCP server accept 成功 - - 4.OK - - 5.OK - - 6.OK' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1上使用步骤2创建的socket1,去连接\ - \ PC的ip,test_tcp_port1\n4.PC与target1创建好TCP 连接,有ACCEPT\n5.PC上网卡禁止掉 \n6.关闭建立的socket1连接" - sub module: TCP - summary: close TCP socket after PC NIC disabled - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: TCP handling abnormal event - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_TCP_0407 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SOC SOC1 ACCEPT SOC2 - - [R SOC_COM L OK] - - - SSC SSC1 dhcp -E -o 1 - - ['R SSC1 C +DHCP:STA,OK'] - - - SSC SSC1 ip -S -o 1 -i 192.168.111.210 - - ['P SSC1 C +IP:OK', 'P SSC1 RE CLOSED:\d+,0'] - - - SSC SSC1 ip -Q -o 1 - - ['R SSC1 C +STAIP:192.168.111.210'] - - - SSC SSC1 soc -S -s -l 5 - - ['P SSC1 RE SEND:\d+,ERROR'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK; PC TCP server accept 成功 - - 4.OK - - 5.OK - - 6.OK - - 7.OK - - 8.ERROR' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1上使用步骤2创建的socket1,去连接\ - \ PC的ip,test_tcp_port1\n4.PC与target1创建好TCP 连接,有ACCEPT\n5.关闭8266的DHCP 1\n6.设置sta\ - \ ip \n7.查询sta ip 地址是否生效\n8.8266往PC上发送5字节数据" - sub module: TCP - summary: do TCP send after IP changed - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: TCP handling abnormal event - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_TCP_0401 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SOC SOC1 ACCEPT SOC2 - - [R SOC_COM L OK] - - - SSC SSC1 sta -D - - ['P SSC1 C +QAP:OK', 'P SSC1 RE CLOSED:\d+,0'] - - - SSC SSC1 soc -S -s -l 5 - - ['P SSC1 RE SEND:\d+,ERROR'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK; PC TCP server accept 成功 - - 4.OK - - 5.OK - - 6.ERROR' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: '1.PC上建立TCP 监听 test_tcp_port1 - - 2.target1上创建TCP socket1 - - 3.target1上使用步骤2创建的socket1,去连接 PC的ip,test_tcp_port1 - - 4.PC与target1创建好TCP 连接,有ACCEPT - - 5.断开与AP 连接 - - 6.8266往PC上发送5字节数据' - sub module: TCP - summary: do TCP send after WIFI disconnected - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: TCP handling abnormal event - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_TCP_0402 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SOC SOC1 ACCEPT SOC2 - - [R SOC_COM L OK] - - - SSC SSC1 sta -D - - ['P SSC1 C +QAP:OK', 'P SSC1 RE CLOSED:\d+,0'] - - - SSC SSC1 soc -T -s - - ['R SSC1 RE CLOSE:\d+,OK'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK; PC TCP server accept 成功 - - 4.OK - - 5.OK - - 6.OK' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: '1.PC上建立TCP 监听 test_tcp_port1 - - 2.target1上创建TCP socket1 - - 3.target1上使用步骤2创建的socket1,去连接 PC的ip,test_tcp_port1 - - 4.PC与target1创建好TCP 连接,有ACCEPT - - 5.断开与AP 连接 - - 6.关闭建立的socket1连接' - sub module: TCP - summary: "close TCP socket after WIFI \ndisconnected" - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: TCP handling abnormal event - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_TCP_0403 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SOC SOC1 ACCEPT SOC2 - - [R SOC_COM L OK] - - - SSC SSC1 op -S -o 2 - - ['P SSC1 C +MODE:OK', 'P SSC1 RE CLOSED:\d+,0'] - - - SSC SSC1 soc -S -s -l 5 - - ['P SSC1 RE SEND:\d+,ERROR'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK; PC TCP server accept 成功 - - 4.OK - - 5.OK - - 6.ERROR' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1上使用步骤2创建的socket1,去连接\ - \ PC的ip,test_tcp_port1\n4.PC与target1创建好TCP 连接,有ACCEPT\n5.修改8266的Mode为softAP mode\ - \ \n6.8266往PC上发送5字节数据" - sub module: TCP - summary: do TCP send after mode changed - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: TCP handling abnormal event - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_TCP_0408 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SOC SOC1 ACCEPT SOC2 - - [R SOC_COM L OK] - - - SSC SSC1 dhcp -E -o 1 - - ['R SSC1 C +DHCP:STA,OK'] - - - SSC SSC1 ip -S -o 1 -i 192.168.111.210 - - ['P SSC1 C +IP:OK', 'P SSC1 RE CLOSED:\d+,0'] - - - SSC SSC1 ip -Q -o 1 - - ['R SSC1 C +STAIP:192.168.111.210'] - - - SSC SSC1 soc -T -s - - ['R SSC1 RE CLOSE:\d+,OK'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK; PC TCP server accept 成功 - - 4.OK - - 5.OK - - 6.OK - - 7.OK - - 8.OK' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1上使用步骤2创建的socket1,去连接\ - \ PC的ip,test_tcp_port1\n4.PC与target1创建好TCP 连接,有ACCEPT\n5.关闭8266的DHCP 1\n6.设置sta\ - \ ip \n7.查询sta ip 地址是否生效\n8.关闭建立的socket1连接" - sub module: TCP - summary: close TCP socket after IP changed - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: TCP handling abnormal event - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_UDP_0201 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 BIND - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -W -s -o 0 - - ['R SSC1 RE WORKTHREAD:\d+,OK'] - - - SOC SOC1 SENDTO 1472 - - [''] - - - SOC SOC1 SENDTO 1472 - - [''] - - - SOC SOC1 SENDTO 1472 - - [''] - - - SOC SOC1 SENDTO 1472 - - [''] - - - SOC SOC1 SENDTO 1472 - - [''] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK - - 4.PC OK - - 5.PC OK - - 6.PC OK - - 7.PC OK - - 8.PC OK SOC_CLOSE=SOC1' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: '1.PC上SOC1 UDP传输,bing - - 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - - 3.target1上关闭工作线程 - - 4.PC往8266上发送1472字节数据 - - 5.PC往8266上发送1472字节数据 - - 6.PC往8266上发送1472字节数据 - - 7.PC往8266上发送1472字节数据 - - 8.PC往8266上发送1472字节数据' - sub module: UDP - summary: STA mode, recv buffer test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: use UDP SAP (socket/espconn API) in different state - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_UDP_0307 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: 1/5 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 BIND - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -S -s -i -p -l 5 - - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] - - - SSC SSC1 dhcp -E -o 1 - - ['R SSC1 C +DHCP:STA,OK'] - - - SSC SSC1 ip -S -o 1 -i 192.168.111.210 - - ['P SSC1 C +IP:OK'] - - - SSC SSC1 ip -Q -o 1 - - ['R SSC1 C +STAIP:192.168.111.210'] - - - SSC SSC1 soc -T -s - - ['R SSC1 RE CLOSE:\d+,OK'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK; PC TCP server accept 成功 - - 4.OK - - 5.OK - - 6.OK - - 7.OK' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: "1.PC上SOC1 UDP传输,bing \n2.target1上UDP传输,Bind socket1,本地ip\ - \ target_udp_port1\n3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据\n\ - 4.关闭8266的DHCP 1\n5.设置sta ip \n6.查询sta ip 地址是否生效\n7.关闭建立的socket1连接" - sub module: UDP - summary: close UDP socket after IP changed - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: UDP handling abnormal event - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_UDP_0306 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: 1/5 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 BIND - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -S -s -i -p -l 5 - - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] - - - SSC SSC1 dhcp -E -o 1 - - ['R SSC1 C +DHCP:STA,OK'] - - - SSC SSC1 ip -S -o 1 -i 192.168.111.210 - - ['P SSC1 C +IP:OK'] - - - SSC SSC1 ip -Q -o 1 - - ['R SSC1 C +STAIP:192.168.111.210'] - - - SSC SSC1 soc -S -s -i -p -l 1 - - ['P SSC1 RE SEND:\d+,OK'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK; PC TCP server accept 成功 - - 4.OK - - 5.OK - - 6.OK - - 7.OK' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: "1.PC上SOC1 UDP传输,bing \n2.target1上UDP传输,Bind socket1,本地ip\ - \ target_udp_port1\n3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据\n\ - 4.关闭8266的DHCP 1\n5.设置sta ip \n6.查询sta ip 地址是否生效\n7.8266往PC上发送5字节数据" - sub module: UDP - summary: do UDP send after IP changed - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: UDP handling abnormal event - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_UDP_0305 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: 1/5 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 BIND - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -S -s -i -p -l 5 - - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] - - - NIC DISABLED - - [R PC_COM C OK] - - - SSC SSC1 soc -T -s - - ['R SSC1 RE CLOSE:\d+,OK'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK - - 4.OK - - 5.OK' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: "1.PC上SOC1 UDP传输,bing \n2.target1上UDP传输,Bind socket1,本地ip\ - \ target_udp_port1\n3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据\n\ - 4.PC上网卡禁止掉 \n5.关闭建立的socket1连接" - sub module: UDP - summary: close UDP socket after PC NIC disabled - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: UDP handling abnormal event - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_UDP_0304 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: 1/5 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 BIND - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -S -s -i -p -l 5 - - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] - - - SSC SSC1 op -S -o 2 - - ['P SSC1 C +MODE:OK'] - - - SSC SSC1 soc -T -s - - ['R SSC1 RE CLOSE:\d+,OK'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK - - 4.OK - - 5.OK' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: "1.PC上SOC1 UDP传输,bing \n2.target1上UDP传输,Bind socket1,本地ip\ - \ target_udp_port1\n3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据\n\ - 4.修改8266的Mode为softAP mode \n5.关闭建立的socket1连接" - sub module: UDP - summary: close UDP socket after mode changed - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: UDP handling abnormal event - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^WIFI_CONN_0103 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -p -t -h - 0 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC2 sta -S -h 0 - - [R SSC2 P , R SSC2 C +SCANDONE] - - - SSC SSC1 ap -S -s -p -t -h - 1 - - ['R SSC1 C +SAP:OK'] - - - DELAY 3 - - [''] - - - SSC SSC2 sta -S -h 0 - - [R SSC2 C +SCANDONE] - - - DELAY 3 - - [''] - - - SSC SSC2 sta -S -h 0 - - [R SSC2 NP C +SCANDONE] - comment: '' - execution time: 0.0 - expected result: '1.target1 set AP,set ssid broad cast - - 2.target 2上scan target_ap_mac - - 3.target1 set AP,set ssid hidden, - - 4.target 2上不能scan target_ap_mac' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. target1下设置ssid 和pwd 加密方式,set ssid broad cast - - 2.target 2上scan target_ap_mac - - 3. target1下设置ssid 和pwd 加密方式,set ssid hidden, - - 4.target 2上scan target_ap_mac' - sub module: WIFI Connect - summary: station SAP+JAP test, ssid hidden - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: SAP/JAP with different config - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_TCP_0101 + ID: TCPIP_TCP_0101 SDK: '8266_NonOS 8266_RTOS @@ -4901,9 +1869,10 @@ test cases: 5.ERROR 6.ERROR' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration module: TCPIP steps: '1.PC上建立TCP 监听 test_tcp_port1 @@ -4928,7 +1897,60 @@ test cases: test point 2: use TCP SAP (socket/espconn API) with different parameter version: v1 (2016-8-15) - CI ready: 'Yes' - ID: ^TCPIP_TCP_0103 + ID: TCPIP_TCP_0102 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -B -t TCP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,OK'] + - - SOC SOC1 CONNECT + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+', P SOC_COM C OK] + - - SOC SOC1 CONNECT + - [P SOC_COM C ERROR, P SSC1 NC ACCEPT] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.PC TCP client accept + + 4.error' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration + module: TCPIP + steps: '1.target1上创建TCP socket,bind到本地端口 + + 2.target1上使用步骤1创建的socket,创建TCP 监听 + + 3.PC TCP 连接到target1 , + + 4.PC tcp 连接到不存在的port ,' + sub module: TCP + summary: STA mode, server listen test. use different kinds of port + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0103 SDK: '8266_NonOS 8266_RTOS @@ -4973,9 +1995,10 @@ test cases: 7.target收到 146000 byte 8.OK,PC 回SOC_RECV=SOC2,RECV_LEN=字节数' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration module: TCPIP steps: '1. PC上建立TCP 监听 test_tcp_port1 @@ -4991,7 +2014,7 @@ test cases: 7. PC send 100 * 1460 data to 8266, - 8.8266 send 100 * 1460 to PC.' + 8.8266 send 100 * 1460 to PC. ' sub module: TCP summary: STA mode, send/recv basic test test environment: SSC_T1_1 @@ -5003,4051 +2026,6 @@ test cases: test point 1: basic function test point 2: use TCP SAP (socket/espconn API) with different parameter version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_TCP_0102 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 soc -B -t TCP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -L -s - - ['R SSC1 RE LISTEN:\d+,OK'] - - - SOC SOC1 CONNECT - - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+', P SOC_COM C OK] - - - SOC SOC1 CONNECT - - [P SOC_COM C ERROR, P SSC1 NC ACCEPT] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.PC TCP client accept - - 4.error' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: '1.target1上创建TCP socket,bind到本地端口 - - 2.target1上使用步骤1创建的socket,创建TCP 监听 - - 3.PC TCP 连接到target1 , - - 4.PC tcp 连接到不存在的port ,' - sub module: TCP - summary: STA mode, server listen test. use different kinds of port - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use TCP SAP (socket/espconn API) with different parameter - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_TCP_0105 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -T -s - - ['R SSC1 RE CLOSE:\d+,OK'] - - - SSC SSC1 soc -B -t TCP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -L -s - - ['R SSC1 RE LISTEN:\d+,OK'] - - - SOC SOC2 CONNECT - - ['R SSC1 A :ACCEPT:(\d+),\d+,.+,\d+'] - - - SSC SSC1 soc -T -s - - ['R SSC1 RE CLOSE:\d+,OK'] - - - SSC SSC1 soc -T -s - - ['R SSC1 RE CLOSE:\d+,OK'] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SSC SSC1 soc -T -s - - ['R SSC1 RE CLOSE:\d+,OK'] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SSC SSC1 soc -D -s - - ['R SSC1 RE SHUTDOWN:\d+,OK'] - - - SSC SSC1 soc -T -s - - ['R SSC1 RE CLOSE:\d+,OK'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK - - 4.OK - - 5.OK - - 6.OK - - 7.target1关闭socket1 - - 8.target1关闭socket2 - - 9.OK - - 10.OK,pc tcp server accept成功 - - 11.target1关闭socket1 - - 12.OK - - 13.OK,pc tcp server accept成功 - - 14.OK - - 15.target1关闭socket1' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1关闭socket1\n\ - 4.target1上创建TCP socket 端口随机\n5.target1上使用步骤4创建的socket1,去监听\n6.PC CONNECT,\ - \ ,tcp 连接创建成功,创建socket2 \n7.target1关闭socket1\n8.target1关闭socket2\n\ - 9.target1上创建TCP socket1\n10.target1上使用步骤10创建的socket1,去连接 PC的ip,test_tcp_port1,PC有ACCEPT\n\ - 11.target1关闭socket1\n12.target1上创建TCP socket1\n13.target1上使用步骤13创建的socket1,去连接\ - \ PC的ip,test_tcp_port1,PC有ACCEPT\n14.target1shutdown socket1\n15.target1关闭socket1" - sub module: TCP - summary: STA mode, close for different types of TCP sockets test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use TCP SAP (socket/espconn API) with different parameter - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_TCP_0104 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SSC SSC1 soc -D -s -h B - - ['R SSC1 RE SHUTDOWN:\d+,OK'] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SSC SSC1 soc -D -s -h W - - ['R SSC1 RE SHUTDOWN:\d+,OK'] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SSC SSC1 soc -D -s -h R - - ['R SSC1 RE SHUTDOWN:\d+,OK'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK,pc tcp server accept OK - - 4.OK - - 5.OK - - 6.OK,pc tcp server accept OK - - 7.OK - - 8.OK - - 9.OK,pc tcp server accept OK - - 10.OK' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: '1. PC上建立TCP 监听 test_tcp_port1 - - 2.target1上创建TCP socket - - 3.target1上使用步骤2创建的socket,去连接 PC的ip,test_tcp_port1,PC有ACCEPT - - 4.target1 shutdown socket1 B - - 5.target1上创建TCP socket - - 6.target1上使用步骤5创建的socket,去连接 PC的ip,test_tcp_port1,PC有ACCEPT - - 7.target1 shutdown socket2 W - - 8.target1上创建TCP socket - - 9.target1上使用步骤8创建的socket,去连接 PC的ip,test_tcp_port1,PC有ACCEPT - - 10.target1 shutdown socket3 R' - sub module: TCP - summary: STA mode, shutdown basic test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use TCP SAP (socket/espconn API) with different parameter - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_TCP_0107 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 soc -B -t TCP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -L -s - - ['R SSC1 RE LISTEN:\d+,OK'] - - - SOC SOC2 CONNECT - - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] - - - SOC SOC3 CONNECT - - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] - - - SOC SOC4 CONNECT - - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] - - - SOC SOC5 CONNECT - - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] - - - SOC SOC6 CONNECT - - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] - comment: '' - execution time: 0.0 - expected result: '1.+BIND:0,OK,0.0.0.0 - - 2.OK - - 3.OK,pc tcp server accept成功 - - 4.OK,pc tcp server accept成功 - - 5.OK,pc tcp server accept成功 - - 6.OK,pc tcp server accept成功 - - 7.OK,pc tcp server accept成功' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: "1.target1上创建TCP socket 端口随机\n2.target1上使用步骤4创建的socket1,去监听\n3.PC CONNECT,\ - \ ,tcp 连接创建成功,创建socket2 \n4.PC CONNECT, ,tcp 连接创建成功,创建socket3\ - \ \n5.PC CONNECT, ,tcp 连接创建成功,创建socket4 \n6.PC CONNECT,\ - \ ,tcp 连接创建成功,创建socket5 \n7.PC CONNECT, ,tcp 连接创建成功,创建socket6" - sub module: TCP - summary: STA mode, accept max TCP client by server test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use TCP SAP (socket/espconn API) with different parameter - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_TCP_0106 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK,pc tcp server accept成功 - - 4 OK - - 5.OK,pc tcp server accept成功 - - 6.OK - - 7.OK,pc tcp server accept成功 - - 8 OK - - 9.OK,pc tcp server accept成功 - - 10.OK - - 11.OK,pc tcp server accept成功' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: '1.PC上建立TCP 监听 test_tcp_port1 - - 2.target1上创建TCP socket1 - - 3.target1上使用步骤2创建的socket1,去连接 PC的ip,test_tcp_port1,PC有ACCEPT - - 4.target1上创建TCP socket2 - - 5.target1上使用步骤4创建的socket2,去连接 PC的ip,test_tcp_port1,PC有ACCEPT - - 6.target1上创建TCP socket3 - - 7.target1上使用步骤6创建的socket3,去连接 PC的ip,test_tcp_port1,PC有ACCEPT - - 8.target1上创建TCP socket4 - - 9.target1上使用步骤8创建的socket4,去连接 PC的ip,test_tcp_port1,PC有ACCEPT - - 10.target1上创建TCP socket5 - - 11.target1上使用步骤10创建的socket5,去连接 PC的ip,test_tcp_port1,PC有ACCEPT' - sub module: TCP - summary: STA mode, create max TCP sockets test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use TCP SAP (socket/espconn API) with different parameter - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_DHCP_0210 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -p -t 4 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC1 dhcp -E -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 - - ['R SSC1 C +DHCP:LEASE,OK'] - - - SSC SSC1 dhcp -S -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - WIFI CONN2 192.168.4.2 - - ['R PC_COM NC ERROR C +WIFICONN:OK'] - - - SSC SSC1 ap -L - - [R SSC1 C 192.168.4.2 C 192.168.4.3 P P ] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 3. succeed - - 4. succeed - - 5. find target2 and PC' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: TCPIP - steps: '1. config softap to a random ssid - - 2. target2 connect to target1 softap - - 3. disable DHCP server, do config and enable - - 4. PC NIC connect to target1 softap try to renew IP 192.168.4.2 - - 5. softap list connected station' - sub module: DHCP - summary: dhcp server reconfig, old client able to get IP (discover with requested - IP) - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: DHCP server function test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_DHCP_0211 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -p -t 4 - - ['R SSC1 C +SAP:OK'] - - - WIFI CONN 192.168.4.2 - - ['R PC_COM NC ERROR C +WIFICONN:OK'] - - - SSC SSC1 dhcp -E -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 - - ['R SSC1 C +DHCP:LEASE,OK'] - - - SSC SSC1 dhcp -S -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - DELAY 10 - - [''] - - - SSC SSC1 ap -L - - [R SSC1 C 192.168.4.2 C 192.168.4.3 P P ] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 3. succeed - - 4. succeed - - 5. find target2 and PC' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: TCPIP - steps: '1. config softap to a random ssid - - 2. target2 connect to target1 softap - - 3. disable DHCP server, do config and enable - - 4. PC NIC connect to target1 softap try to renew IP 192.168.4.2 - - 5. softap list connected station' - sub module: DHCP - summary: dhcp server reconfig, old client able to renew IP (direct send request) - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: DHCP server function test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_TCP_0212 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP -i - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SSC SSC1 soc -B -t TCP -i - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SSC SSC1 soc -D -s - - ['R SSC1 RE SHUTDOWN:\d+,OK'] - - - SSC SSC1 soc -B -t TCP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -L -s - - ['R SSC1 RE LISTEN:\d+,OK'] - - - SOC SOC2 CONNECT 0 - - ['R SSC1 A :ACCEPT:(\d+),\d+,.+,\d+'] - - - SSC SSC1 soc -I - - ['P SSC1 RE "SOCINFO:%%s,2,%%s,\d+,%%s,%%d"%%(,,,)', - 'P SSC1 RE "SOCINFO:%%s,2,.+,\d+,.+,\d+"%%()', 'P SSC1 RE "SOCINFO:%%s,82,.+,%%d,.+,\d+"%%(,)', - 'P SSC1 RE "SOCINFO:%%s,2,%%s,%%d,%%s,\d+"%%(,,,)'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK,pc tcp server accept成功 - - 4.OK - - 5.OK - - 6.OK - - 7.OK - - 8.OK - - 9.PC OK, target1 +ACCEPT:3,2,,port - - 10.+SOCINFO:,,, - - +SOCINFO:,,, - - +SOCINFO:, - - +SOCINFO:,,, - - +SOCINF0ALL' - initial condition: APM2 - initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen - a TC with initial condition APSTA2 - module: TCPIP - steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1,本地ip target_ip\n3.target1上使用步骤2创建的socket1,去连接\ - \ PC的ip,test_tcp_port1,PC有ACCEPT\n4.target1上创建TCP socket2,本地ip target_ip\n5.target1上使用步骤4创建的socket2,去连接\ - \ PC的ip,test_tcp_port1,PC有ACCEPT\n6.target1 shutdown socket2 \n7.target1上创建TCP\ - \ socket3,本地端口random_port\n8.target1上使用步骤7创建的socket3,去监听\n9.PC CONNECT,\ - \ ,tcp 连接创建成功,创建socket4 \n10.target1 查询the socket information" - sub module: TCP - summary: AP mode, get active socket info test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use TCP SAP (socket/espconn API) in different state - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_TCP_0210 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SOC SOC1 ACCEPT SOC2 - - [R SOC_COM L OK] - - - SSC SSC1 soc -W -s -o 0 - - ['R SSC1 RE WORKTHREAD:\d+,OK'] - - - SOC SOC2 SEND 146000 - - [P SOC_COM R *] - - - SSC SSC1 soc -W -s -o 1 - - ['P SSC1 RE WORKTHREAD:\d+,OK', P SSC1 SL +2920] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK,pc tcp server accept成功 - - 4.OK - - 6.OK - - 7.收到 146000 数据 - - ' - initial condition: APM2 - initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen - a TC with initial condition APSTA2 - module: TCPIP - steps: '1. PC上建立TCP 监听 test_tcp_port1 - - 2.target1上创建TCP socket - - 3.target1上使用步骤2创建的socket,去连接 PC的ip,test_tcp_port1 - - 4.PC与target1 创建好TCP 连接,有ACCEPT - - 5.target停止调用recv - - 6.PC send 100 * 1460 data to 8266, - - 7.target重新调用recv' - sub module: TCP - summary: AP mode, recv buffer test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use TCP SAP (socket/espconn API) in different state - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_TCP_0210 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SOC SOC1 ACCEPT SOC2 - - [R SOC_COM L OK] - - - SSC SSC1 soc -W -s -o 0 - - ['R SSC1 RE WORKTHREAD:\d+,OK'] - - - SOC SOC2 SEND 146000 - - [P SOC_COM R *] - - - SSC SSC1 soc -W -s -o 1 - - ['P SSC1 RE WORKTHREAD:\d+,OK', P SSC1 SL +2920] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK,pc tcp server accept成功 - - 4.OK - - 6.OK - - 7.收到 146000 数据' - initial condition: APSTA2 - initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen - by APM2) - module: TCPIP - steps: '1. PC上建立TCP 监听 test_tcp_port1 - - 2.target1上创建TCP socket - - 3.target1上使用步骤2创建的socket,去连接 PC的ip,test_tcp_port1 - - 4.PC与target1 创建好TCP 连接,有ACCEPT - - 5.target停止调用recv - - 6.PC send 100 * 1460 data to 8266, - - 7.target重新调用recv' - sub module: TCP - summary: AP mode, recv buffer test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use TCP SAP (socket/espconn API) in different state - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_TCP_0212 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP -i - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SSC SSC1 soc -B -t TCP -i - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SSC SSC1 soc -D -s - - ['R SSC1 RE SHUTDOWN:\d+,OK'] - - - SSC SSC1 soc -B -t TCP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -L -s - - ['R SSC1 RE LISTEN:\d+,OK'] - - - SOC SOC2 CONNECT 0 - - ['R SSC1 A :ACCEPT:(\d+),\d+,.+,\d+'] - - - SSC SSC1 soc -I - - ['P SSC1 RE "SOCINFO:%%s,2,%%s,\d+,%%s,%%d"%%(,,,)', - 'P SSC1 RE "SOCINFO:%%s,2,.+,\d+,.+,\d+"%%()', 'P SSC1 RE "SOCINFO:%%s,82,.+,%%d,.+,\d+"%%(,)', - 'P SSC1 RE "SOCINFO:%%s,2,%%s,%%d,%%s,\d+"%%(,,,)'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK,pc tcp server accept成功 - - 4.OK - - 5.OK - - 6.OK - - 7.OK - - 8.OK - - 9.PC OK, target1 +ACCEPT:3,2,,port - - 10.+SOCINFO:,,, - - +SOCINFO:,,, - - +SOCINFO:, - - +SOCINFO:,,, - - +SOCINF0ALL' - initial condition: APSTA2 - initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen - by APM2) - module: TCPIP - steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1,本地ip target_ip\n3.target1上使用步骤2创建的socket1,去连接\ - \ PC的ip,test_tcp_port1,PC有ACCEPT\n4.target1上创建TCP socket2,本地ip target_ip\n5.target1上使用步骤4创建的socket2,去连接\ - \ PC的ip,test_tcp_port1,PC有ACCEPT\n6.target1 shutdown socket2 \n7.target1上创建TCP\ - \ socket3,本地端口random_port\n8.target1上使用步骤7创建的socket3,去监听\n9.PC CONNECT,\ - \ ,tcp 连接创建成功,创建socket4 \n10.target1 查询the socket information" - sub module: TCP - summary: AP mode, get active socket info test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use TCP SAP (socket/espconn API) in different state - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_DHCP_0211 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -p -t 4 - - ['R SSC1 C +SAP:OK'] - - - WIFI CONN 192.168.4.2 - - ['R PC_COM NC ERROR C +WIFICONN:OK'] - - - SSC SSC1 dhcp -E -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 - - ['R SSC1 C +DHCP:LEASE,OK'] - - - SSC SSC1 dhcp -S -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - DELAY 10 - - [''] - - - SSC SSC1 ap -L - - [R SSC1 C 192.168.4.2 C 192.168.4.3 P P ] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 3. succeed - - 4. succeed - - 5. find target2 and PC' - initial condition: T2_1 - initial condition description (auto): target 1 as SoftAP, target 2 as STA, will - autogen a TC with initial condition T2_2 - module: TCPIP - steps: '1. config softap to a random ssid - - 2. target2 connect to target1 softap - - 3. disable DHCP server, do config and enable - - 4. PC NIC connect to target1 softap try to renew IP 192.168.4.2 - - 5. softap list connected station' - sub module: DHCP - summary: dhcp server reconfig, old client able to renew IP (direct send request) - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: DHCP server function test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_DHCP_0210 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -p -t 4 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC1 dhcp -E -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 - - ['R SSC1 C +DHCP:LEASE,OK'] - - - SSC SSC1 dhcp -S -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - WIFI CONN2 192.168.4.2 - - ['R PC_COM NC ERROR C +WIFICONN:OK'] - - - SSC SSC1 ap -L - - [R SSC1 C 192.168.4.2 C 192.168.4.3 P P ] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 3. succeed - - 4. succeed - - 5. find target2 and PC' - initial condition: T2_1 - initial condition description (auto): target 1 as SoftAP, target 2 as STA, will - autogen a TC with initial condition T2_2 - module: TCPIP - steps: '1. config softap to a random ssid - - 2. target2 connect to target1 softap - - 3. disable DHCP server, do config and enable - - 4. PC NIC connect to target1 softap try to renew IP 192.168.4.2 - - 5. softap list connected station' - sub module: DHCP - summary: dhcp server reconfig, old client able to get IP (discover with requested - IP) - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: DHCP server function test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_ADDR_0101 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 op -S -o 3 - - ['R SSC1 C +MODE:OK'] - - - SSC SSC1 mac -S -o 1 -m 44:55:66:77:88:99 - - ['R SSC1 C +MAC:STA,OK'] - - - SSC SSC1 mac -S -o 2 -m 22:33:44:55:66:77 - - ['R SSC1 C +MAC:AP,OK'] - - - SSC SSC1 mac -Q -o 3 - - ['R SSC1 C +STAMAC:44:55:66:77:88:99 C +APMAC:22:33:44:55:66:77'] - - - SSC SSC1 mac -S -o 1 -m - - ['R SSC1 C +MAC:STA,OK'] - - - SSC SSC1 mac -S -o 2 -m - - ['R SSC1 C +MAC:AP,OK'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.ok - - 3.ok - - 4.ok - - 5.ok - - 6.ok' - initial condition: T2_1 - initial condition description (auto): target 1 as SoftAP, target 2 as STA, will - autogen a TC with initial condition T2_2 - module: WIFI MAC - steps: "1.target1 设置mode 为sta+softAP mode\n2.target1 设置sta mode 下的mac \n3.target1\ - \ 设置softAP mode 下的mac\n4.target1 查询softAP+sta 下的mac\n5.target1 设置sta mode 下的mac\ - \ 为target1_mac\n6.target1 设置softAP mode 下的mac 为target1_ap_mac\n" - sub module: MAC Address - summary: set mac, query mac - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: mac address function test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_ADDR_0102 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 mac -S -o 2 -m 44:55:66:77:88:99 - - ['R SSC1 C +MAC:AP,OK'] - - - SSC SSC1 ap -S -s -p -t - - [''] - - - SSC SSC2 sta -S -b 44:55:66:77:88:99 - - ['R SSC2 RE \+SCAN:.+,44:55:66:77:88:99,'] - - - SSC SSC1 mac -S -o 2 -m - - ['R SSC1 C +MAC:AP,OK'] - - - SSC SSC2 mac -Q -o 1 - - ['R SSC2 A :\+STAMAC:(.+)\r\n'] - - - SSC SSC2 mac -S -o 1 -m 22:33:44:55:66:77 - - ['R SSC2 C +MAC:STA,OK'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED'] - - - SSC SSC1 ap -L - - ['R SSC1 C +LSTA:22:33:44:55:66:77'] - - - SSC SSC2 mac -S -o 1 -m - - ['R SSC2 C +MAC:STA,OK'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.ok - - 3.ok - - 4.ok - - 5.ok - - 6.ok - - 7.ok - - 8.ok - - 9.ok' - initial condition: T2_1 - initial condition description (auto): target 1 as SoftAP, target 2 as STA, will - autogen a TC with initial condition T2_2 - module: WIFI MAC - steps: "1.target1 设置sta mode下的mac 44:55:66:77:88:99\n2.target1下设置ssid 和pwd 加密方式\n\ - 3.target2 查询mac为44:55:66:77:88:99的ssid\n4.target1 设置sta mode下的mac target_ap_mac\n\ - 5.target2 查询sta mode 下的mac 为target2_mac_tmp\n6.target2 设置sta mode 下的mac 为22:33:44:55:66:77\n\ - 7.target2 jap target1\n8.target1 查询连接到的sta \n9.target2 设置sta mode 下的mac 为 target2_mac\n" - sub module: MAC Address - summary: set mac and do scan/JAP/SAP - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: mac address function test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_UDP_0202 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 BIND - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -W -s -o 0 - - ['R SSC1 RE WORKTHREAD:\d+,OK'] - - - SOC SOC1 SENDTO 1472 - - [''] - - - SOC SOC1 SENDTO 1472 - - [''] - - - SOC SOC1 SENDTO 1472 - - [''] - - - SOC SOC1 SENDTO 1472 - - [''] - - - SOC SOC1 SENDTO 1472 - - [''] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK - - 4.PC OK - - 5.PC OK - - 6.PC OK - - 7.PC OK - - 8.PC OK SOC_CLOSE=SOC1' - initial condition: APM2 - initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen - a TC with initial condition APSTA2 - module: TCPIP - steps: '1.PC上SOC1 UDP传输,bing - - 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - - 3.target1上关闭工作线程 - - 4.PC往8266上发送1472字节数据 - - 5.PC往8266上发送1472字节数据 - - 6.PC往8266上发送1472字节数据 - - 7.PC往8266上发送1472字节数据 - - 8.PC往8266上发送1472字节数据' - sub module: UDP - summary: AP mode, recv buffer test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: use UDP SAP (socket/espconn API) in different state - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_TCP_0411 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SOC SOC1 ACCEPT SOC2 - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -S -s -l 5 - - ['P SSC1 RE SEND:\d+,ERROR'] - - - SSC SSC1 soc -S -s -l 5 - - ['P SSC1 RE SEND:\d+,OK'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK; PC TCP server accept 成功 - - 4.OK - - 5.OK - - 6.ERROR - - 7.OK' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: '1.PC上建立TCP 监听 test_tcp_port1 - - 2.target1上创建TCP socket1 - - 3.target1上使用步骤2创建的socket1,去连接 PC的ip,test_tcp_port1 - - 4.PC与target1创建好TCP 连接,有ACCEPT - - 5.target1上创建TCP socket2 - - 6.8266往PC socket2上发送5字节数据 - - 7.8266往PC socket1上发送5字节数据' - sub module: TCP - summary: do TCP send after socket changed - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: TCP handling abnormal event - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0502 - SDK: ESP32_IDF - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:CONNECTED'] - - - SSC SSC3 sta -C -s -p - - ['R SSC3 C +JAP:CONNECTED'] - - - SSC SSC2 sta -C -s -p - - [''] - - - DELAY 10 - - ['P SSC2 C +JAP:CONNECTED', 'P SSC[1,3] NC +JAP:DISCONNECTED'] - comment: '' - execution time: 0.0 - expected result: 4. all STA not get disconnected; target 1 SoftAP and STA both in - channel2; SoftAP in 20M, STA in 40M - initial condition: T3_PHY1 - initial condition description (auto): '1. target 1 and target 2 set to AP+STA mode, - target 3 set to STA mode - - 2. all interface of target 2,3 set to 11n ht40 - - 3. config softAP of target 1 and target 2' - module: WIFI MAC - steps: '1. target 1 STA set to 40M, SoftAP set to 20M - - 2. target 2 STA connect to ap_channel1_20 - - 3. target 1/3 STA connect to target 2/1 SoftAP - - 4. target 2 STA connect to ap_channel2_40' - sub module: Phy Mode - summary: SoftAP STA in channel1 20M, STA changed to channel2 40M - test environment: SSC_T3_PhyMode - test environment description (auto): '3 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with (HT20, channel1), (HT20, channel2), (HT40, channel1), (HT40, channel2). - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA+SoftAP dynamic channel switch test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0503 - SDK: ESP32_IDF - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:CONNECTED'] - - - SSC SSC3 sta -C -s -p - - ['R SSC3 C +JAP:CONNECTED'] - - - SSC SSC2 sta -C -s -p - - [''] - - - DELAY 10 - - ['P SSC2 C +JAP:CONNECTED', 'P SSC[1,3] NC +JAP:DISCONNECTED'] - comment: '' - execution time: 0.0 - expected result: 4. all STA not get disconnected; target 1 SoftAP and STA both in - channel2 20M - initial condition: T3_PHY1 - initial condition description (auto): '1. target 1 and target 2 set to AP+STA mode, - target 3 set to STA mode - - 2. all interface of target 2,3 set to 11n ht40 - - 3. config softAP of target 1 and target 2' - module: WIFI MAC - steps: '1. target 1 STA set to 40M, SoftAP set to 20M - - 2. target 2 STA connect to ap_channel1_40 - - 3. target 1/3 STA connect to target 2/1 SoftAP - - 4. target 2 STA connect to ap_channel2_20' - sub module: Phy Mode - summary: SoftAP STA in channel1, SoftAP 20M, STA 40M, STA changed to channel2 20M - test environment: SSC_T3_PhyMode - test environment description (auto): '3 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with (HT20, channel1), (HT20, channel2), (HT40, channel1), (HT40, channel2). - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA+SoftAP dynamic channel switch test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0501 - SDK: ESP32_IDF - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:CONNECTED'] - - - SSC SSC3 sta -C -s -p - - ['R SSC3 C +JAP:CONNECTED'] - - - SSC SSC2 sta -C -s -p - - [''] - - - DELAY 10 - - ['P SSC2 C +JAP:CONNECTED', 'P SSC[1,3] NC +JAP:DISCONNECTED'] - comment: '' - execution time: 0.0 - expected result: 4. all STA not get disconnected; target 1 SoftAP and STA both in - channel2 20M - initial condition: T3_PHY1 - initial condition description (auto): '1. target 1 and target 2 set to AP+STA mode, - target 3 set to STA mode - - 2. all interface of target 2,3 set to 11n ht40 - - 3. config softAP of target 1 and target 2' - module: WIFI MAC - steps: '1. target 1 STA and SoftAP set to 20M - - 2. target 2 STA connect to ap_channel1_20 - - 3. target 1/3 STA connect to target 2/1 SoftAP - - 4. target 2 STA connect to ap_channel2_20' - sub module: Phy Mode - summary: SoftAP STA in channel1 20M, STA changed to channel2 20M - test environment: SSC_T3_PhyMode - test environment description (auto): '3 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with (HT20, channel1), (HT20, channel2), (HT40, channel1), (HT40, channel2). - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA+SoftAP dynamic channel switch test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0506 - SDK: ESP32_IDF - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:CONNECTED'] - - - SSC SSC3 sta -C -s -p - - ['R SSC3 C +JAP:CONNECTED'] - - - SSC SSC2 sta -C -s -p - - [''] - - - DELAY 10 - - ['P SSC2 C +JAP:CONNECTED', 'P SSC[1,3] NC +JAP:DISCONNECTED'] - comment: '' - execution time: 0.0 - expected result: 4. all STA not get disconnected; target 1 SoftAP and STA both in - channel2 40M - initial condition: T3_PHY1 - initial condition description (auto): '1. target 1 and target 2 set to AP+STA mode, - target 3 set to STA mode - - 2. all interface of target 2,3 set to 11n ht40 - - 3. config softAP of target 1 and target 2' - module: WIFI MAC - steps: '1. target 1 STA and SoftAP set to 40M - - 2. target 2 STA connect to ap_channel1_40 - - 3. target 1/3 STA connect to target 2/1 SoftAP - - 4. target 2 STA connect to ap_channel2_40' - sub module: Phy Mode - summary: SoftAP STA in channel1, SoftAP 40M, STA 40M, STA changed to channel2 40M - test environment: SSC_T3_PhyMode - test environment description (auto): '3 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with (HT20, channel1), (HT20, channel2), (HT40, channel1), (HT40, channel2). - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA+SoftAP dynamic channel switch test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0505 - SDK: ESP32_IDF - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:CONNECTED'] - - - SSC SSC3 sta -C -s -p - - ['R SSC3 C +JAP:CONNECTED'] - - - SSC SSC2 sta -C -s -p - - [''] - - - DELAY 10 - - ['P SSC2 C +JAP:CONNECTED', 'P SSC[1,3] NC +JAP:DISCONNECTED'] - comment: '' - execution time: 0.0 - expected result: 4. all STA not get disconnected; target 1 SoftAP and STA both in - channel2; SoftAP in 20M, STA in 40M - initial condition: T3_PHY1 - initial condition description (auto): '1. target 1 and target 2 set to AP+STA mode, - target 3 set to STA mode - - 2. all interface of target 2,3 set to 11n ht40 - - 3. config softAP of target 1 and target 2' - module: WIFI MAC - steps: '1. target 1 STA set to 40M ,SoftAP set to 20M - - 2. target 2 STA connect to ap_channel1_40 - - 3. target 1/3 STA connect to target 2/1 SoftAP - - 4. target 2 STA connect to ap_channel2_20' - sub module: Phy Mode - summary: SoftAP STA in channel1, SoftAP 40M, STA 40M, STA changed to channel2 20M - test environment: SSC_T3_PhyMode - test environment description (auto): '3 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with (HT20, channel1), (HT20, channel2), (HT40, channel1), (HT40, channel2). - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA+SoftAP dynamic channel switch test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_CONN_0301 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -p -t -h - 0 -m 8 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC1 ap -Q - - ['R SSC1 RE "\+APCONFIG:%%s,%%s,\d+,3,0,8,\d+"%%(,)'] - comment: '' - execution time: 0.0 - expected result: '1. target1 set AP - - 2.target 1上查询到跟设置AP时一致 - - ' - initial condition: APM1 - initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial - condition APSTA1 - module: WIFI MAC - steps: '1. target1 set AP - - 2.target 1上查询到跟设置AP时一致 - - ' - sub module: WIFI Connect - summary: AP config query test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: query AP config - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_IP_0102 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 dhcp -S -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC1 ip -S -o 2 -i 192.168.123.123 - - ['R SSC1 C +IP:ERROR'] - - - SSC SSC1 dhcp -E -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC1 ip -S -o 2 -i 192.168.123.123 - - ['R SSC1 C +IP:OK'] - - - SSC SSC1 ip -Q -o 2 - - ['R SSC1 C +APIP:192.168.123.123'] - - - SSC SSC1 ip -S -o 2 -i - - ['R SSC1 C +IP:OK'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.ERROR - - 3.OK - - 4.OK - - 5.APIP:192.168.123.123 - - 6.OK' - initial condition: APSTA1 - initial condition description (auto): testing ap on sta + ap mode (autogen by APM1) - module: TCPIP - steps: "1.target1 打开DHCP 2\n2.target1 设置softAP ip 192.168.123.123\n4.target1 关闭DHCP\ - \ 2\n5.target1 设置softAP ip 192.168.123.123\n6.target1 查询 当前sta ip \n7.target1\ - \ 设置softAP ip 为target_ap_ip" - sub module: IP - summary: ap set and query static ip test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: set and query static IP - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_UDP_0105 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -T -s - - ['R SSC1 RE CLOSE:\d+'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - - 2.关闭socket1' - sub module: UDP - summary: STA mode, close UDP sockets test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use UDP SAP (socket/espconn API) with different parameter - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_UDP_0104 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: 1/5 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 BIND - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SOC SOC1 SENDTO 1 - - [R SSC1 SL +1] - - - SOC SOC1 SENDTO 1472 - - ['R SSC1 RE "RECVFROM:%%s,1472,%%s,%%u"%%(,,)'] - - - SOC SOC1 SENDTO 1473 - - [P SSC1 NC +RECVFROM, P SOC_COM C OK] - - - SOC SOC2 BIND - - [R SOC_COM L OK] - - - SOC SOC2 SENDTO 1472 - - ['R SSC1 RE "RECVFROM:%%s,1472,%%s,%%u"%%(,,)'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK - - 4.OK - - 5.OK,没收到UDP包 - - 6.OK - - 7.OK' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: '1.PC上SOC1 UDP传输,bing - - 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - - 3.PC往8266上发送1字节数据 - - 4.PC往8266上发送1472字节数据 - - 5.PC往8266上发送1473字节数据 - - 6.PC上SOC2 UDP传输,bing - - 7.PC往8266上发送1472字节数据' - sub module: UDP - summary: STA mode, recvfrom basic test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use UDP SAP (socket/espconn API) with different parameter - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_UDP_0107 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -I - - ['P SSC1 RE "SOCINFO:%%s,1,.+,%%d"%%(,)'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - - 2.target1上查询创建socket信息' - sub module: UDP - summary: STA mode, get active socket info test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use UDP SAP (socket/espconn API) with different parameter - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_UDP_0106 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 RE BIND:(\d+),OK'] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 RE BIND:(\d+),OK'] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 RE BIND:(\d+),OK'] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 RE BIND:(\d+),OK'] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 RE BIND:(\d+),OK'] - comment: '' - execution time: 0.0 - expected result: '1.ok - - 2.ok - - 3.ok - - 4.ok - - 5.ok' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - - 2.target1上UDP传输,Bind socket2,本地ip target_udp_port2 - - 3.target1上UDP传输,Bind socket3,本地ip target_udp_port3 - - 4.target1上UDP传输,Bind socket4,本地ip target_udp_port4 - - 5.target1上UDP传输,Bind socket5,本地ip target_udp_port5' - sub module: UDP - summary: STA mode, create max udp socket test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use UDP SAP (socket/espconn API) with different parameter - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_UDP_0101 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 RE BIND:(\d+),OK'] - - - SSC SSC1 soc -B -t UDP -i 0.0.0.0 -p - - ['R SSC1 RE BIND:(\d+),OK'] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 C BIND:ERROR'] - - - SSC SSC1 soc -B -t TCP -p - - ['R SSC1 RE BIND:(\d+),OK'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.ERROR - - 4.OK' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - - 2.target1上UDP传输,Bind socket2,本地ip 0.0.0.0 target_udp_port2 - - 3.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - - 4.target1上创建TCP socket3, target_udp_port1' - sub module: UDP - summary: STA mode, udp bind test. use different ip, port - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use UDP SAP (socket/espconn API) with different parameter - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_UDP_0103 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: 1/5 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 BIND - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -S -s -i -p -l 1 - - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 1] - - - SSC SSC1 soc -S -s -i -p -l 1472 - - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 1472] - - - SSC SSC1 soc -S -s -i -p -l 1473 - - ['P SSC1 RE SEND:(\d+),OK', P SOC_COM NC SOC_RECVFROM] - - - SSC SSC1 soc -S -s -i -p -l 1472 -n 10 -j 20 - - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 14720] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK - - 4.OK - - 5.OK,没有到UDP包 - - 6.OK' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: '1.PC上SOC1 UDP传输,bing - - 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - - 3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1字节数据 - - 4.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1472字节数据 - - 5.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1473字节数据 - - 6.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1472*10字节数据' - sub module: UDP - summary: STA mode, sendto test with different length - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use UDP SAP (socket/espconn API) with different parameter - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_UDP_0102 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: 1/5 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 BIND - - [R SOC_COM L OK] - - - SOC SOC2 BIND - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -S -s -i -p -l 10 - - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 10] - - - SSC SSC1 soc -S -s -i -p -l 10 - - ['P SSC1 RE SEND:(\d+),OK', P SOC2 UL 10] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK - - 4.OK - - 5.OK' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: '1.PC上SOC1 UDP传输,bing - - 2.PC上SOC2 UDP传输,bing - - 3.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - - 4.target1上使用步骤3创建的socket1,往pc_ip,test_tcp_port1上发送10字节数据 - - 5.target1上使用步骤3创建的socket1,往pc_ip2,test_tcp_port2上发送10字节数据' - sub module: UDP - summary: STA mode, sendto test. use different ip, port - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use UDP SAP (socket/espconn API) with different parameter - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_DHCP_0102 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -p -t - - ['R SSC1 C +SAP:OK'] - - - SSC SSC1 dhcp -E -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC2 sta -C -s -p - - [''] - - - DELAY 20 - - [P PC_COM C +DELAYDONE, 'P SSC2 NC +JAP:CONNECTED'] - - - SSC SSC1 dhcp -S -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - comment: '' - execution time: 0.0 - expected result: "1.target1 set AP OK \n2.target1 关闭DHCP OK\n3.target2 jap target\ - \ 1,FAIL \n4.target1 打开DHCP OK\n5.target2 jap target 1,ok" - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: TCPIP - steps: "1.target1 set AP OK \n2.target1 关闭DHCP OK\n3.target2 jap target 1,FAIL \n\ - 4.target1 打开DHCP OK\n5.target2 jap target 1,ok" - sub module: DHCP - summary: dhcp server function test - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: DHCP client function test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_DHCP_0103 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 op -S -o 3 - - ['R SSC1 C +MODE:OK'] - - - SSC SSC1 dhcp -S -o 3 - - ['R SSC1 C +DHCP:AP,OK C +DHCP:STA,OK'] - - - SSC SSC1 dhcp -Q -o 3 - - ['R SSC1 C +DHCP:STA,STARTED C +DHCP:AP,STARTED'] - - - SSC SSC1 dhcp -Q -o 1 - - ['R SSC1 C +DHCP:STA,STARTED NC +DHCP:AP,STARTED'] - - - SSC SSC1 dhcp -Q -o 2 - - ['R SSC1 NC +DHCP:STA,STARTED C +DHCP:AP,STARTED'] - - - SSC SSC1 dhcp -E -o 3 - - ['R SSC1 C +DHCP:AP,OK C +DHCP:STA,OK'] - - - SSC SSC1 dhcp -Q -o 3 - - ['R SSC1 C +DHCP:STA,STOPPED C +DHCP:AP,STOPPED'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.STA&AP STARTED - - 4.STA STARTED - - 5.AP STARTED - - 6.OK - - 7.STA&AP STOPPED' - initial condition: STAAP1 - initial condition description (auto): testing sta on sta + ap mode, quit AP (autogen - by STAM1) - module: TCPIP - steps: '1.target1 设置mode 为sta+softAP mode - - 2.target1 打开DHCP 3 - - 3.target1 查询DHCP 状态 - - 4.target1 查询sta DHCP 状态 - - 5.target1 查询softAP DHCP 状态 - - 6.target1 关闭 DHCP 3 - - 7.target1 查询 DHCP 状态' - sub module: DHCP - summary: dhcp status query - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: DHCP client function test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_SCAN_0301 - SDK: ESP32_IDF - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 sta -S - - [''] - - - SSC SSC1 sta -S - - [P SSC1 C +SCANFAIL, 'P SSC1 P +SCAN:', R SSC1 C +SCANDONE] - comment: '' - execution time: 0.0 - expected result: '1. second scan failed - - 2. first scan succeed' - initial condition: STAM1 - initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a - TC with initial condition STAAP1 - module: WIFI MAC - steps: '1. do all channel scan - - 2. do scan before scan finished' - sub module: WIFI Scan - summary: reject scan request before scan finished - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: interaction - test point 2: Scan interact with other WiFi operation - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_SCAN_0303 - SDK: ESP32_IDF - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:OK'] - - - SSC SSC1 sta -S - - [P SSC1 C +SCANDONE, 'P SSC1 C +JAP:CONNECTED'] - - - SSC SSC1 sta -D - - ['R SSC1 C +QAP:OK'] - - - SSC SSC1 sta -S - - [''] - - - SSC SSC1 sta -C -s -p - - [P SSC1 C +SCANDONE, 'P SSC1 C +JAP:CONNECTED'] - comment: '' - execution time: 0.0 - expected result: '2. scan succeed, JAP succeed - - 5. JAP succeed, scan succeed' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. target 1 STA join AP - - 2. target 1 STA scan before JAP succeed - - 3. target 1 quite AP - - 4. target 1 scan - - 5. target 1 JAP before scan succeed' - sub module: WIFI Scan - summary: scan during JAP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: interaction - test point 2: Scan interact with other WiFi operation - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: ^WIFI_CONN_0801 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -p -t 0 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC1 ap -S -s -p -t 2 - - ['P SSC1 C +SAP:OK', 'P SSC2 C +JAP:AUTHCHANGED,2,0'] - - - SSC SSC1 ap -S -s -p -t 3 - - ['P SSC1 C +SAP:OK', 'P SSC2 C +JAP:AUTHCHANGED,3,2'] - - - SSC SSC1 ap -S -s -p -t 4 - - ['P SSC1 C +SAP:OK', 'P SSC2 C +JAP:AUTHCHANGED,4,3'] - - - SSC SSC1 ap -S -s -p -t 0 - - ['P SSC1 C +SAP:OK', 'P SSC2 C +JAP:AUTHCHANGED,0,4'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 3. auth change event old mode 0 new mode 2 - - 4. auth change event old mode 2 new mode 3 - - 5. auth change event old mode 3 new mode 4 - - 6. auth change event old mode 4 new mode 0' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. set target1 softap auth mode 0 - - 2. target2 connect to target1 - - 3. set target1 softap auth mode 2, wait sta connected - - 4. set target1 softap auth mode 3, wait sta connected - - 5. set target1 softap auth mode 4, wait sta connected - - 6. set target1 softap auth mode 0, wait sta connected' - sub module: WIFI Connect - summary: test auth change event - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: wifi auth changed event test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_SCAN_0304 - SDK: ESP32_IDF - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:OK'] - - - SSC SSC1 sta -S - - [P SSC1 C +SCANDONE, 'P SSC2 C +JAP:CONNECTED'] - - - SSC SSC2 sta -D - - ['R SSC2 C +QAP:OK'] - - - SSC SSC1 sta -S - - [''] - - - SSC SSC2 sta -C -s -p - - [P SSC1 C +SCANDONE, 'P SSC2 C +JAP:CONNECTED'] - comment: '' - execution time: 0.0 - expected result: '2. scan succeed, JAP succeed - - 5. JAP succeed, scan succeed' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. target 2 STA join target 1 SoftAP - - 2. target 1 STA scan before target 2 JAP succeed - - 3. target 2 STA QAP - - 4. target 1 STA scan - - 5. target 2 STA JAP before target 1 STA scan succeed' - sub module: WIFI Scan - summary: scan during ext STA join SoftAP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: interaction - test point 2: Scan interact with other WiFi operation - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_UDP_0108 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 RE BIND:(\d+),OK'] - - - SSC SSC1 soc -B -t UDP -i 0.0.0.0 -p - - ['R SSC1 RE BIND:(\d+),OK'] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 C BIND:ERROR'] - - - SSC SSC1 soc -B -t TCP -p - - ['R SSC1 RE BIND:(\d+),OK'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.ERROR - - 4.OK' - initial condition: APSTA2 - initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen - by APM2) - module: TCPIP - steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - - 2.target1上UDP传输,Bind socket2,本地ip 0.0.0.0 target_udp_port2 - - 3.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - - 4.target1上创建TCP socket3, target_udp_port1' - sub module: UDP - summary: AP mode, udp bind test. use different ip, port - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use UDP SAP (socket/espconn API) with different parameter - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_CONN_0104 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -p -t -m - 1 - - ['R SSC1 C +SAP:OK'] - - - WIFI DISCONN - - ['R PC_COM C +WIFIDISCONN:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] - - - WIFI CONN - - - ['R PC_COM C +WIFICONN:ERROR'] - comment: '' - execution time: 0.0 - expected result: '1. target1 set AP,set max allowed sta as 1 - - 2. use PC disconnect, - - 3.target 2 jap succeed - - 4.PC WIFI can not CONN' - initial condition: T2_1 - initial condition description (auto): target 1 as SoftAP, target 2 as STA, will - autogen a TC with initial condition T2_2 - module: WIFI MAC - steps: '1.target1下设置ssid 和pwd 加密方式,set max allowed sta as 1 - - 2.use PC disconnect target1 - - 3.target 2 jap target1 - - 4.PC WIFI CONNECT target1' - sub module: WIFI Connect - summary: station SAP test, max allowed sta - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: SAP/JAP with different config - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_IGMP_0201 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 igmp -J -h -m 224.1.1.1 - - ['R SSC1 C +IGMP:OK'] - - - SSC SSC1 soc -B -t UDP -i 224.1.1.1 -p - - ['R SSC1 A :\+BIND:(\d+),OK'] - - - SOC SOC1 BIND - - [R SOC_COM L OK] - - - SOC SOC1 SENDTO 1 224.1.1.1 - - [R SSC1 SL +1] - - - SSC SSC1 igmp -L -h -m 224.1.1.1 - - ['R SSC1 C +IGMP:OK'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 3. able to recv packet' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: '1. join group - - 2. create UDP socket using multicast addr - - 3. PC send UDP packet to multicast addr' - sub module: IGMP - summary: station IGMP recv packets - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: IGMP send/recv test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_IGMP_0203 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 igmp -J -h -m 224.1.1.1 - - ['R SSC1 C +IGMP:OK'] - - - SSC SSC1 soc -B -t UDP -i 224.1.1.1 -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SOC SOC1 BIND - - [R SOC_COM L OK] - - - SOC SOC1 SENDTO 1 224.1.1.1 - - [R SSC1 SL +1] - - - SSC SSC1 igmp -L -h -m 224.1.1.1 - - ['R SSC1 C +IGMP:OK'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 3. able to recv packet' - initial condition: APSTA2 - initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen - by APM2) - module: TCPIP - steps: '1. join group - - 2. create UDP socket using multicast addr - - 3. PC send UDP packet to multicast addr' - sub module: IGMP - summary: softAP IGMP recv packets - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: IGMP send/recv test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_IGMP_0202 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC2 op -S -o 1 - - ['R SSC2 C +MODE:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC1 igmp -J -h -m 224.1.1.1 - - ['R SSC1 C +IGMP:OK'] - - - SSC SSC1 soc -B -t UDP -i 224.1.1.1 -p - - ['R SSC1 A :\+BIND:(\d+),OK'] - - - SSC SSC2 soc -B -t UDP -p - - ['R SSC2 A :\+BIND:(\d+),OK'] - - - SSC SSC2 soc -S -s -i 224.1.1.1 -p -l 10 - - [R SSC1 SL +1] - - - SSC SSC1 igmp -L -h -m 224.1.1.1 - - ['R SSC1 C +IGMP:OK'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 3. succeed - - 4. target1 recv multicast packet' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: '1. target2 set to sta mode and join AP - - 2. target1 join group and create UDP socket using multicast addr - - 3. target2 create UDP socket - - 4. target2 send to multicast addr' - sub module: IGMP - summary: station send multicast packets - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: IGMP send/recv test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_IGMP_0204 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC1 igmp -J -h -m 224.1.1.1 - - ['R SSC1 C +IGMP:OK'] - - - SSC SSC1 soc -B -t UDP -i 224.1.1.1 -p - - ['R SSC1 A :\+BIND:(\d+),OK'] - - - SSC SSC2 soc -B -t UDP -p - - ['R SSC2 A :\+BIND:(\d+),OK'] - - - SSC SSC2 soc -S -s -i 224.1.1.1 -p -l 10 - - [R SSC1 SL +1] - - - SSC SSC1 igmp -L -h -m 224.1.1.1 - - ['R SSC1 C +IGMP:OK'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 3. succeed - - 4. target1 recv multicast packet' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: TCPIP - steps: '1. target2 join SoftAP - - 2. target1 join group and create UDP socket using multicast addr - - 3. target2 create UDP socket - - 4. target2 send to multicast addr' - sub module: IGMP - summary: softAP send multicast packets - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: IGMP send/recv test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^WIFI_CONN_0301 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -p -t -h - 0 -m 8 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC1 ap -Q - - ['R SSC1 RE "\+APCONFIG:%%s,%%s,\d+,3,0,8,\d+"%%(,)'] - comment: '' - execution time: 0.0 - expected result: '1. target1 set AP - - 2.target 1上查询到跟设置AP时一致' - initial condition: APSTA1 - initial condition description (auto): testing ap on sta + ap mode (autogen by APM1) - module: WIFI MAC - steps: '1. target1 set AP - - 2.target 1上查询到跟设置AP时一致' - sub module: WIFI Connect - summary: AP config query test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: query AP config - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_UDP_0114 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -I - - ['P SSC1 RE "SOCINFO:%%s,1,.+,%%d"%%(,)'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK' - initial condition: APM2 - initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen - a TC with initial condition APSTA2 - module: TCPIP - steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - - 2.target1上查询创建socket信息' - sub module: UDP - summary: AP mode, get active socket info test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use UDP SAP (socket/espconn API) with different parameter - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_UDP_0111 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: 1/5 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -p -t - - ['R SSC1 C +SAP:OK'] - - - WIFI CONN - - - ['R PC_COM NC ERROR C +WIFICONN:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] - - - SOC SOC1 BIND - - [R SOC_COM L OK] - - - SSC SSC2 ip - - ['R SSC2 A :STAIP:(.+)\r\n'] - - - SSC SSC2 soc -B -t UDP -p - - ['R SSC2 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SOC SOC1 SENDTO 5 - - ['R SSC1 RE "RECVFROM:%%s,5,%%s,%%u"%%(,,)'] - - - SSC SSC2 soc -S -s -i -p -l 5 - - ['R SSC1 RE "RECVFROM:%%s,5,%%s,%%u"%%(,,)'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK - - 4.OK - - 5.OK,没收到UDP包 - - 6.OK - - 7.OK' - initial condition: T2O_1 - initial condition description (auto): same as T2_1 but will NOT autogen a TC with - initial condition T2_2 - module: TCPIP - steps: '1.PC上SOC1 UDP传输,bing - - 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - - 3.PC往8266上发送1字节数据 - - 4.PC往8266上发送1472字节数据 - - 5.PC往8266上发送1473字节数据 - - 6.PC上SOC2 UDP传输,bing - - 7.PC往8266上发送1472字节数据' - sub module: UDP - summary: AP mode, recvfrom basic test - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use UDP SAP (socket/espconn API) with different parameter - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_UDP_0110 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: 1/5 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 BIND - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -S -s -i -p -l 1 - - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 1] - - - SSC SSC1 soc -S -s -i -p -l 1472 - - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 1472] - - - SSC SSC1 soc -S -s -i -p -l 1473 - - ['P SSC1 RE SEND:(\d+),OK', P SOC_COM NC SOC_RECVFROM] - - - SSC SSC1 soc -S -s -i -p -l 1472 -n 10 - -j 20 - - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 14720] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK - - 4.OK - - 5.OK,没收到UDP包 - - 6.OK' - initial condition: APM2 - initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen - a TC with initial condition APSTA2 - module: TCPIP - steps: '1.PC上SOC1 UDP传输,bing - - 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - - 3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1字节数据 - - 4.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1472字节数据 - - 5.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1473字节数据 - - 6.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1472*10字节数据' - sub module: UDP - summary: AP mode, sendto test with different length - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use UDP SAP (socket/espconn API) with different parameter - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_UDP_0113 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 RE BIND:(\d+),OK'] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 RE BIND:(\d+),OK'] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 RE BIND:(\d+),OK'] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 RE BIND:(\d+),OK'] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 RE BIND:(\d+),OK'] - comment: '' - execution time: 0.0 - expected result: '1.ok - - 2.ok - - 3.ok - - 4.ok - - 5.ok' - initial condition: APM2 - initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen - a TC with initial condition APSTA2 - module: TCPIP - steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - - 2.target1上UDP传输,Bind socket2,本地ip target_udp_port2 - - 3.target1上UDP传输,Bind socket3,本地ip target_udp_port3 - - 4.target1上UDP传输,Bind socket4,本地ip target_udp_port4 - - 5.target1上UDP传输,Bind socket5,本地ip target_udp_port5' - sub module: UDP - summary: AP mode, create max udp socket test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use UDP SAP (socket/espconn API) with different parameter - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_UDP_0112 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -T -s - - ['R SSC1 RE CLOSE:\d+'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK' - initial condition: APM2 - initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen - a TC with initial condition APSTA2 - module: TCPIP - steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - - 2.关闭socket1' - sub module: UDP - summary: AP mode, close UDP sockets test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use UDP SAP (socket/espconn API) with different parameter - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_CONN_0501 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC2 sta -R -r 1 - - ['R SSC2 C +RECONN:OK'] - - - SSC SSC1 ap -S -s -p -t - - ['R SSC1 C +SAP:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] - - - SSC SSC1 op -S -o 1 - - ['R SSC1 C +MODE:OK'] - - - DELAY 10 - - [''] - - - SSC SSC1 op -S -o 2 - - ['R SSC1 C +MODE:OK'] - - - DELAY 15 - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC2 sta -R -r 0 - - ['R SSC2 C +RECONN:OK'] - - - SSC SSC2 sta -R -r 2 - - ['R SSC2 C +RECONN:0'] - - - SSC SSC1 op -S -o 1 - - ['R SSC1 C +MODE:OK'] - - - DELAY 10 - - [''] - - - SSC SSC1 op -S -o 2 - - ['R SSC1 C +MODE:OK'] - - - DELAY 15 - - [P PC_COM C +DELAYDONE, 'P SSC2 NC +JAP:CONNECTED'] - - - SSC SSC2 sta -R -r 1 - - ['R SSC2 C +RECONN:OK'] - comment: '' - execution time: 0.0 - expected result: '1.设置reconn,开启(此功能不需要重启系统) - - 2.target1 set AP - - 3.target2 JAP target1 成功 - - 4.target2 断开target1 连接 - - 5.等待10s,target2 自动重连target1 - - 6.成功 - - 7.查询reconn状态,关闭 - - 8.修改mode 成功 - - 9.等待15s,target2 不会自动重连target1' - initial condition: T2_1 - initial condition description (auto): target 1 as SoftAP, target 2 as STA, will - autogen a TC with initial condition T2_2 - module: WIFI MAC - steps: "1.设置reconn,开启(此功能不需要重启系统)\n2.target1下设置ssid 和pwd 加密方式\n3.target2 JAP target1\ - \ \n4.target1 修改mode 为sta mode\n5.等待10s,target1 修改mode 为softAP mode\n6.设置reconn,关闭\n\ - 7.查询reconn状态,关闭\n8.target1 修改mode 为sta mode\n9.等待15s,target1 修改mode 为softAP mode" - sub module: WIFI Connect - summary: reconnect policy test - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: reconnect policy test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_CONN_0502 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -p -t - - ['R SSC1 C +SAP:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC2 sta -R -r 1 - - ['R SSC2 C +RECONN:OK'] - - - SSC SSC1 op -S -o 1 - - ['R SSC1 C +MODE:OK'] - - - DELAY 5 - - ['R SSC2 C +JAP:DISCONNECTED'] - - - SSC SSC1 op -S -o 2 - - ['R SSC1 C +MODE:OK'] - - - DELAY 10 - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC2 sta -D - - ['R SSC2 C +QAP:OK'] - - - DELAY 10 - - [P PC_COM C +DELAYDONE, 'P SSC2 NC +JAP:CONNECTED'] - comment: '' - execution time: 0.0 - expected result: '1.target1 set AP - - 2.target2 jap target 1 - - 3.设置reconn,开启(此功能不需要重启系统) - - 4.target2 断开target1 连接 - - 5.等待10s,target2 自动重连target1 - - 6.target2 断开target1 连接' - initial condition: T2_1 - initial condition description (auto): target 1 as SoftAP, target 2 as STA, will - autogen a TC with initial condition T2_2 - module: WIFI MAC - steps: '1.target1下设置ssid 和pwd 加密方式 - - 2.target2 jap target 1 - - 3.设置reconn,开启(此功能不需要重启系统) - - 4.target2 断开target1 连接 - - 5.等待10s,target2 自动重连target1 - - 6.target2 断开target1 连接' - sub module: WIFI Connect - summary: will not do reconnect after manually disconnected - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: reconnect policy test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^WIFI_CONN_0401 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 sta -R -a 0 - - ['R SSC1 C +AUTORECONN:OK'] - - - SSC SSC1 sta -R -a 2 - - ['R SSC1 C +AUTORECONN:0'] - - - SSC SSC1 reboot - - [''] - - - DELAY 15 - - [''] - - - SSC SSC1 sta -Q - - ['R SSC1 C JAP:DISCONNECTED'] - - - SSC SSC1 sta -R -a 1 - - ['R SSC1 C +AUTORECONN:OK'] - - - SSC SSC1 sta -R -a 2 - - ['R SSC1 C +AUTORECONN:1'] - - - SSC SSC1 reboot - - ['R SSC1 C +JAP:CONNECTED'] - comment: '' - execution time: 0.0 - expected result: '1.设置autoreconn,关闭 - - 2.查询当前autoreconn状态是否关闭 - - 3.重启系统,等待15s - - 4.查询target1 未自动重连AP - - 5.设置autoreconn,开启 - - 6.查询当前autoreconn状态是否开启 - - 7.系统重启后target1 自动重连AP' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: WIFI MAC - steps: '1.设置autoreconn,关闭 - - 2.查询当前autoreconn状态是否关闭 - - 3.重启系统,等待15s - - 4.查询target1 未自动重连AP - - 5.设置autoreconn,开启 - - 6.查询当前autoreconn状态是否开启 - - 7.系统重启后target1 自动重连AP' - sub module: WIFI Connect - summary: auto reconnect test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: power on auto reconnect test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_MODE_0101 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -p -t - - ['R SSC1 C +SAP:OK'] - - - SSC SSC1 op -S -o 1 - - ['R SSC1 C +MODE:OK'] - - - SSC SSC1 dhcp -S -o 1 - - ['R SSC1 C +DHCP:STA,OK'] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] - - - SSC SSC2 sta -S - - [R SSC2 NP C +SCANDONE] - - - SSC SSC1 sta -D - - ['R SSC1 C +QAP:OK'] - comment: '' - execution time: 0.0 - expected result: '1.target1下设置ssid 和pwd 、加密方式成功 - - 2.修改target 1的mode 为sta mode - - 3.target1的dhcp打开 - - 4.target1成功连接上AP - - 5.target2上不能查询到target_ssid - - 6.target1断开AP' - initial condition: T2O_1 - initial condition description (auto): same as T2_1 but will NOT autogen a TC with - initial condition T2_2 - module: WIFI MAC - steps: '1.target1下设置ssid 和pwd 加密方式 - - 2.修改target1的mode 为sta mode - - 3.target1的dhcp打开 - - 4.target1连接AP - - 5.target2查询target_ssid - - 6.target1断开AP' - sub module: WIFI Mode - summary: mode switch test (sta mode) - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: wifi mode fucntion - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_MODE_0103 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 op -S -o 3 - - ['R SSC1 C +MODE:OK'] - - - SSC SSC1 ap -S -s -p -t - - ['R SSC1 C +SAP:OK'] - - - SSC SSC1 dhcp -S -o 1 - - ['R SSC1 C +DHCP:STA,OK'] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] - - - SSC SSC2 sta -S - - [R SSC2 P , R SSC2 C +SCANDONE] - comment: '' - execution time: 0.0 - expected result: '1.target1 change to AP mode - - 2.target1 set AP - - 3.target 1 的dhcp 打开 - - 4.target 1 成功连接上AP - - 5.target 2 上查询到target_ssid' - initial condition: T2O_1 - initial condition description (auto): same as T2_1 but will NOT autogen a TC with - initial condition T2_2 - module: WIFI MAC - steps: '1.target1 change to AP mode - - 2.target1下设置ssid 和pwd 加密方式 - - 3.target1 的dhcp 打开 - - 4.target1 连接AP - - 5.target2 上查询target_ssid' - sub module: WIFI Mode - summary: mode switch test (STA+AP mode) - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: wifi mode fucntion - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_MODE_0102 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -p -t - - ['R SSC1 C +SAP:OK'] - - - SSC SSC2 sta -S - - [R SSC2 P , R SSC2 C +SCANDONE] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:ERROR'] - - - SSC SSC1 sta -D - - ['R SSC1 C +QAP:ERROR'] - comment: '' - execution time: 0.0 - expected result: '1. target1 set AP - - 2.target 2 上查询到target_ssid - - 3. target1 can''t join AP - - 4. target1 can''t QAP' - initial condition: T2O_1 - initial condition description (auto): same as T2_1 but will NOT autogen a TC with - initial condition T2_2 - module: WIFI MAC - steps: '1.target1下设置ssid 和pwd 加密方式 - - 2.target 2 上查询target_ssid - - 3.target1 join AP - - 4.target1 DISCONN AP' - sub module: WIFI Mode - summary: mode switch test (AP mode) - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: wifi mode fucntion - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^WIFI_CONN_0904 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -p -t 3 -m 1 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC2 sta -C -s -p 1234567890 - - ['R SSC2 RE JAP:DISCONNECTED,\d+,204'] - - - SSC SSC2 sta -D - - ['R SSC2 C +QAP:OK'] - - - WIFI CONN - - ['R PC_COM NC ERROR C +WIFICONN:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 RE JAP:DISCONNECTED,\d+,5'] - - - WIFI DISCONN - - [P PC_COM C OK, 'R SSC2 C +JAP:CONNECTED'] - - - SSC SSC1 ap -S -s -p -t 3 -m 1 - - ['P SSC1 C +SAP:OK', 'P SSC2 RE JAP:DISCONNECTED,\d+,4'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. disconnect event REASON_HANDSHAKE_TIMEOUT - - 3. succeed - - 4. succeed - - 5. disconnect event REASON_ASSOC_TOOMANY - - 6. succeed, target2 connect succeed - - 7. disconnect event REASON_ASSOC_EXPIRE' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. config target1 softap max sta allowed 1 - - 2. target2 connect to target1 with wrong password - - 3. target2 disconnect - - 4. PC WIFI NIC connect to target1 - - 5. target2 connect to target1 with correct password - - 6. PC WIFI NIC disconnect - - 7. reconfig softap' - sub module: WIFI Connect - summary: test wifi disconnect reason REASON_ASSOC_TOOMANY, REASON_HANDSHAKE_TIMEOUT, - REASON_ASSOC_EXPIRE - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: wifi disconnect reason test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^WIFI_CONN_0902 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:CONNECTED'] - - - APC OFF - - [P PC_COM L OK, 'R SSC1 RE JAP:DISCONNECTED,\d+,200'] - - - APC ON - - [P PC_COM L OK] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. disconnect event REASON_BEACON_TIMEOUT' - initial condition: STAAP1 - initial condition description (auto): testing sta on sta + ap mode, quit AP (autogen - by STAM1) - module: WIFI MAC - steps: '1. connect to AP - - 2. AP power off' - sub module: WIFI Connect - summary: test wifi disconnect reason REASON_BEACON_TIMEOUT - test environment: SSC_T1_APC - test environment description (auto): "PC has 1 wired NIC connected to AP.\nPC has\ - \ 1 wired NIC connected to APC (static IP within the same subnet with APC). \n\ - APC control AP power supply. \nPC has 1 WiFi NIC. \n1 SSC target connect with\ - \ PC by UART." - test point 1: basic function - test point 2: wifi disconnect reason test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^WIFI_CONN_0901 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: basic function - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:CONNECTED'] - - - SSC SSC1 sta -D - - ['R SSC1 RE JAP:DISCONNECTED,\d+,8'] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 RE JAP:DISCONNECTED,\d+,15'] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 RE JAP:DISCONNECTED,\d+,201'] - comment: '' - execution time: 0.0 - expected result: '1. disconnect event reason REASON_ASSOC_LEAVE - - 2. disconnect event reason REASON_4WAY_HANDSHAKE_TIMEOUT - - 3. disconnect event reason REASON_NO_AP_FOUND' - initial condition: STAAP1 - initial condition description (auto): testing sta on sta + ap mode, quit AP (autogen - by STAM1) - module: WIFI MAC - steps: '1. sta connect to AP, and disconnect - - 2. connect to AP with wrong password - - 3. connect to AP not exist' - sub module: WIFI Connect - summary: test wifi disconnect reason REASON_ASSOC_LEAVE, REASON_4WAY_HANDSHAKE_TIMEOUT, - REASON_NO_AP_FOUND - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: wifi disconnect reason test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_TCP_0201 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [SOCR SOC_COM L OK] - - - SSC SSC1 soc -B -t UDP -i 0.0.0.0 -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['P SSC1 RE CONNECT:\d+,ERROR'] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -L -s - - ['R SSC1 RE LISTEN:\d+,OK'] - - - SSC SSC1 soc -C -s -i -p - - ['P SSC1 RE CONNECT:\d+,ERROR'] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['P SSC1 RE CONNECT:\d+,OK'] - - - SSC SSC1 soc -D -s -h B - - ['P SSC1 RE SHUTDOWN:\d+,OK'] - - - SSC SSC1 soc -C -s -i -p - - ['P SSC1 RE CONNECT:\d+,ERROR'] - - - SSC SSC1 soc -T - - [R SSC1 C +CLOSEALL] - - - SSC SSC1 soc -C -s -i -p - - ['P SSC1 RE CONNECT:\d+,ERROR'] - comment: '' - execution time: 0.0 - expected result: '1.ok - - 2.OK - - 3.ERROR - - 4.OK - - 5.OK - - 6.ERROR - - 7.OK - - 8.OK - - 9.OK - - 10.OK - - 11.OK - - 12.ERROR' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: '1.PC上建立TCP 监听 test_tcp_port1 - - 2.target1上创建UDP传输socket,bind到本地ip 0.0.0.0, - - 3.target1上使用步骤2创建的socket,去连接 PC的ip, - - 4.target1上创建TCP socket - - 5.target1上使用步骤4创建的socket,创建TCP 监听 - - 6.target1上使用步骤4创建的socket,去连接 PC的ip, - - 7.target1上创建TCP socket - - 8.target1上使用步骤7创建的socket,去连接 PC的ip, - - 9.target1上关闭步骤7创建的socket - - 10.target1上使用步骤7创建的socket,去连接 PC的ip, - - 11.target1上关闭所有创建的socket - - 12.target1上使用步骤2创建的socket,去连接 PC的ip,' - sub module: TCP - summary: STA mode, connect test. use socket in state that can't connect - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use TCP SAP (socket/espconn API) in different state - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_TCP_0206 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP -i - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SSC SSC1 soc -B -t TCP -i - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SSC SSC1 soc -D -s - - ['R SSC1 RE SHUTDOWN:\d+,OK'] - - - SSC SSC1 soc -B -t TCP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -L -s - - ['R SSC1 RE LISTEN:\d+,OK'] - - - SOC SOC2 CONNECT - - ['R SSC1 A :ACCEPT:(\d+),\d+,.+,\d+'] - - - SSC SSC1 soc -I - - ['P SSC1 RE "SOCINFO:%%s,2,%%s,\d+,%%s,%%d"%%(,,,)', - 'P SSC1 RE "SOCINFO:%%s,2,.+,\d+,.+,\d+"%%()', 'P SSC1 RE "SOCINFO:%%s,82,.+,%%d,.+,\d+"%%(,)', - 'P SSC1 RE "SOCINFO:%%s,2,%%s,%%d,%%s,\d+"%%(,,,)'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK,pc tcp server accept成功 - - 4.OK - - 5.OK - - 6.OK - - 7.OK - - 8.OK - - 9.PC OK, target1 +ACCEPT:3,2,,port - - 10.+SOCINFO:,,, - - +SOCINFO:,,, - - +SOCINFO:, - - +SOCINFO:,,, - - +SOCINF0ALL' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1,本地ip target_ip\n3.target1上使用步骤2创建的socket1,去连接\ - \ PC的ip,test_tcp_port1,PC有ACCEPT\n4.target1上创建TCP socket2,本地ip target_ip\n5.target1上使用步骤4创建的socket2,去连接\ - \ PC的ip,test_tcp_port1,PC有ACCEPT\n6.target1 shutdown socket2 \n7.target1上创建TCP\ - \ socket3,本地端口random_port\n8.target1上使用步骤7创建的socket3,去监听\n9.PC CONNECT,\ - \ ,tcp 连接创建成功,创建socket4 \n10.target1 查询the socket information" - sub module: TCP - summary: STA mode, get active socket info test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use TCP SAP (socket/espconn API) in different state - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_TCP_0207 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [SOCR SOC_COM L OK] - - - SSC SSC1 soc -B -t UDP -i 0.0.0.0 -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['P SSC1 RE CONNECT:\d+,ERROR'] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -L -s - - ['R SSC1 RE LISTEN:\d+,OK'] - - - SSC SSC1 soc -C -s -i -p - - ['P SSC1 RE CONNECT:\d+,ERROR'] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['P SSC1 RE CONNECT:\d+,OK'] - - - SSC SSC1 soc -D -s -h B - - ['P SSC1 RE SHUTDOWN:\d+,OK'] - - - SSC SSC1 soc -C -s -i -p - - ['P SSC1 RE CONNECT:\d+,ERROR'] - - - SSC SSC1 soc -T - - [R SSC1 C +CLOSEALL] - - - SSC SSC1 soc -C -s -i -p - - ['P SSC1 RE CONNECT:\d+,ERROR'] - comment: '' - execution time: 0.0 - expected result: '1.ok - - 2 OK - - 3.ERROR - - 4.OK - - 5.OK - - 6.ERROR - - 7.OK - - 8.OK - - 9.OK - - 10.OK - - 11.OK - - 12.ERROR' - initial condition: APSTA2 - initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen - by APM2) - module: TCPIP - steps: '1.PC上建立TCP 监听 test_tcp_port1 - - 2.target1上创建UDP传输socket,bind到本地ip 0.0.0.0, - - 3.target1上使用步骤2创建的socket,去连接 PC的ip, - - 4.target1上创建TCP socket - - 5.target1上使用步骤4创建的socket,创建TCP 监听 - - 6.target1上使用步骤4创建的socket,去连接 PC的ip, - - 7.target1上创建TCP socket - - 8.target1上使用步骤7创建的socket,去连接 PC的ip, - - 9.target1上关闭步骤7创建的socket - - 10.target1上使用步骤7创建的socket,去连接 PC的ip, - - 11.target1上关闭所有创建的socket - - 12.target1上使用步骤2创建的socket,去连接 PC的ip,' - sub module: TCP - summary: AP mode, connect test. use socket in state that can't connect - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use TCP SAP (socket/espconn API) in different state - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_DNS_0101 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: 3/5 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 soc -H -d iot.espressif.cn - - ['R SSC1 C +HOSTIP:OK,115.29.202.58'] - comment: '' - execution time: 0.0 - expected result: 1.OK - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: 1. get host name "espressif.cn" - sub module: DNS - summary: get host by name test - test environment: SSC_T1_2 - test environment description (auto): 'Able to access WAN after connect to AP. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: DNS function test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_DNS_0103 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: 3/5 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 soc -H -d iot.espressif.cn - - ['R SSC1 A :\+HOSTIP:OK,(.+)\r\n'] - - - SSC SSC1 soc -B -t UDP - - ['R SSC1 A :\+BIND:(\d+),OK'] - - - SSC SSC1 soc -S -s -i -p 9003 -l 10 - - ['P SSC1 RE \+SEND:\d+,OK', P SSC1 SL +10] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: '1. get host name "espressif.cn" - - 2. sendto, recvfrom1. get host name "espressif.cn" - - 2. sendto, recvfrom' - sub module: DNS - summary: UDP send to iot.expressif.com - test environment: SSC_T1_2 - test environment description (auto): 'Able to access WAN after connect to AP. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: DNS function test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_DNS_0102 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: 3/5 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 soc -H -d iot.espressif.cn - - ['R SSC1 A :\+HOSTIP:OK,(.+)\r\n'] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :\+BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p 9001 - - ['R SSC1 RE \+CONNECT:\d+,OK'] - - - SSC SSC1 soc -S -s -l 10 - - ['P SSC1 RE \+SEND:\d+,OK', P SSC1 SL +10] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK - - 4.OK' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: '1. get host name "espressif.cn" - - 2. connect, send, recv1. get host name "espressif.cn" - - 2. connect, send, recv' - sub module: DNS - summary: TCP connect to iot.espressif.com - test environment: SSC_T1_2 - test environment description (auto): 'Able to access WAN after connect to AP. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: DNS function test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_TCP_0106 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK,pc tcp server accept成功 - - 4 OK - - 5.OK,pc tcp server accept成功 - - 6.OK - - 7.OK,pc tcp server accept成功 - - 8 OK - - 9.OK,pc tcp server accept成功 - - 10.OK - - 11.OK,pc tcp server accept成功' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: '1.PC上建立TCP 监听 test_tcp_port1 - - 2.target1上创建TCP socket1 - - 3.target1上使用步骤2创建的socket1,去连接 PC的ip,test_tcp_port1,PC有ACCEPT - - 4.target1上创建TCP socket2 - - 5.target1上使用步骤4创建的socket2,去连接 PC的ip,test_tcp_port1,PC有ACCEPT - - 6.target1上创建TCP socket3 - - 7.target1上使用步骤6创建的socket3,去连接 PC的ip,test_tcp_port1,PC有ACCEPT - - 8.target1上创建TCP socket4 - - 9.target1上使用步骤8创建的socket4,去连接 PC的ip,test_tcp_port1,PC有ACCEPT - - 10.target1上创建TCP socket5 - - 11.target1上使用步骤10创建的socket5,去连接 PC的ip,test_tcp_port1,PC有ACCEPT' - sub module: TCP - summary: STA mode, create max TCP sockets test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use TCP SAP (socket/espconn API) with different parameter - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_TCP_0107 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 soc -B -t TCP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -L -s - - ['R SSC1 RE LISTEN:\d+,OK'] - - - SOC SOC2 CONNECT - - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] - - - SOC SOC3 CONNECT - - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] - - - SOC SOC4 CONNECT - - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] - - - SOC SOC5 CONNECT - - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] - - - SOC SOC6 CONNECT - - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] - comment: '' - execution time: 0.0 - expected result: '1.+BIND:0,OK,0.0.0.0 - - 2.OK - - 3.OK,pc tcp server accept成功 - - 4.OK,pc tcp server accept成功 - - 5.OK,pc tcp server accept成功 - - 6.OK,pc tcp server accept成功 - - 7.OK,pc tcp server accept成功' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: "1.target1上创建TCP socket 端口随机\n2.target1上使用步骤4创建的socket1,去监听\n3.PC CONNECT,\ - \ ,tcp 连接创建成功,创建socket2 \n4.PC CONNECT, ,tcp 连接创建成功,创建socket3\ - \ \n5.PC CONNECT, ,tcp 连接创建成功,创建socket4 \n6.PC CONNECT,\ - \ ,tcp 连接创建成功,创建socket5 \n7.PC CONNECT, ,tcp 连接创建成功,创建socket6\ - \ " - sub module: TCP - summary: STA mode, accept max TCP client by server test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use TCP SAP (socket/espconn API) with different parameter - version: v1 (2016-8-15) - CI ready: 'Yes' ID: TCPIP_TCP_0104 SDK: '8266_NonOS @@ -9105,6 +2083,7 @@ test cases: initial condition: STAM2 initial condition description (auto): sta mode, join AP, DHCP on, will autogen a TC with initial condition STAAP2 + level: Integration module: TCPIP steps: '1. PC上建立TCP 监听 test_tcp_port1 @@ -9213,6 +2192,7 @@ test cases: initial condition: STAM2 initial condition description (auto): sta mode, join AP, DHCP on, will autogen a TC with initial condition STAAP2 + level: Integration module: TCPIP steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1关闭socket1\n\ 4.target1上创建TCP socket 端口随机\n5.target1上使用步骤4创建的socket1,去监听\n6.PC CONNECT,\ @@ -9232,7 +2212,7704 @@ test cases: test point 2: use TCP SAP (socket/espconn API) with different parameter version: v1 (2016-8-15) - CI ready: 'Yes' - ID: TCPIP_TCP_0102 + ID: TCPIP_TCP_0106 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK,pc tcp server accept成功 + + 4 OK + + 5.OK,pc tcp server accept成功 + + 6.OK + + 7.OK,pc tcp server accept成功 + + 8 OK + + 9.OK,pc tcp server accept成功 + + 10.OK + + 11.OK,pc tcp server accept成功' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket1 + + 3.target1上使用步骤2创建的socket1,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 4.target1上创建TCP socket2 + + 5.target1上使用步骤4创建的socket2,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 6.target1上创建TCP socket3 + + 7.target1上使用步骤6创建的socket3,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 8.target1上创建TCP socket4 + + 9.target1上使用步骤8创建的socket4,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 10.target1上创建TCP socket5 + + 11.target1上使用步骤10创建的socket5,去连接 PC的ip,test_tcp_port1,PC有ACCEPT' + sub module: TCP + summary: STA mode, create max TCP sockets test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0107 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -B -t TCP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,OK'] + - - SOC SOC2 CONNECT + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] + - - SOC SOC3 CONNECT + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] + - - SOC SOC4 CONNECT + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] + - - SOC SOC5 CONNECT + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] + - - SOC SOC6 CONNECT + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] + comment: '' + execution time: 0.0 + expected result: '1.+BIND:0,OK,0.0.0.0 + + 2.OK + + 3.OK,pc tcp server accept成功 + + 4.OK,pc tcp server accept成功 + + 5.OK,pc tcp server accept成功 + + 6.OK,pc tcp server accept成功 + + 7.OK,pc tcp server accept成功' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration + module: TCPIP + steps: "1.target1上创建TCP socket 端口随机\n2.target1上使用步骤4创建的socket1,去监听\n3.PC CONNECT,\ + \ ,tcp 连接创建成功,创建socket2 \n4.PC CONNECT, ,tcp 连接创建成功,创建socket3\ + \ \n5.PC CONNECT, ,tcp 连接创建成功,创建socket4 \n6.PC CONNECT,\ + \ ,tcp 连接创建成功,创建socket5 \n7.PC CONNECT, ,tcp 连接创建成功,创建socket6\ + \ " + sub module: TCP + summary: STA mode, accept max TCP client by server test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0110 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [SOCR SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP -i 0.0.0.0 -p 0 + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,OK', P SOC1 C +ACCEPT] + - - SSC SSC1 soc -B -t TCP -i 0.0.0.0 -p 0 + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i 123.456.678.789 -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.ERROR + + 6.ERROR' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + level: Integration + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket,bind到本地ip 0.0.0.0,本地端口 0 + + 3.target1上使用步骤2创建的socket,去连接 PC的ip,test_tcp_port1 + + 4.target1上创建TCP socket,bind到本地ip 0.0.0.0,本地端口 0 + + 5.target1上使用步骤4创建的socket,去连接不存在的ip,test_tcp_port1 + + 6.target1上使用步骤2创建的socket,去连接 PC的ip,远端端口不存在。' + sub module: TCP + summary: AP mode, connect test. use different ip, port + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0111 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -B -t TCP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,OK'] + - - SOC SOC1 CONNECT 0 + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+', P SOC_COM C OK] + - - SOC SOC1 CONNECT 0 + - [P SOC_COM C ERROR, P SSC1 NC ACCEPT] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.PC TCP client accept + + 4.error' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + level: Integration + module: TCPIP + steps: '1.target1上创建TCP socket,bind到本地端口 + + 2.target1上使用步骤1创建的socket,创建TCP 监听 + + 3.PC TCP 连接到target1 , + + 4.PC tcp 连接到不存在的port ,' + sub module: TCP + summary: AP mode, server listen test. use different kinds of port + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0112 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SOC SOC2 SEND 5 + - [R SSC1 SL +5] + - - SSC SSC1 soc -S -s -l 5 + - ['P SSC1 RE SEND:\d+,OK', P SOC2 RL 5] + - - SOC SOC2 SEND 146000 + - [R SSC1 SL +146000] + - - SSC SSC1 soc -S -s -l 1460 -n 100 + - ['P SSC1 RE SEND:\d+,OK', P SOC2 RL 146000] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK,pc tcp server accept成功 + + 4.OK + + 5.target收到5byte数据 + + 6.PC收到5byte数据 + + 7.target收到146000 byte数据 + + 8.OK,PC 收到146000 byte数据' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + level: Integration + module: TCPIP + steps: '1. PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket + + 3.target1上使用步骤2创建的socket,去连接 PC的ip,test_tcp_port1 + + 4.PC与target1 创建好TCP 连接,有ACCEPT + + 5.PC send 5 bytes to 8266 + + 6.8266 send 5 bytes to PC + + 7. PC send 100 * 1460 data to 8266, + + 8.8266 send 100 * 1460 to PC. ' + sub module: TCP + summary: AP mode, send/recv basic test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0113 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s -h B + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s -h W + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s -h R + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK,pc tcp server accept成功 + + 4.OK + + 5.OK + + 6.OK,pc tcp server accept成功 + + 7.OK + + 8.OK + + 9.OK,pc tcp server accept成功 + + 10.OK' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + level: Integration + module: TCPIP + steps: '1. PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket + + 3.target1上使用步骤2创建的socket,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 4.target1 shutdown socket1 B + + 5.target1上创建TCP socket + + 6.target1上使用步骤5创建的socket,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 7.target1 shutdown socket2 W + + 8.target1上创建TCP socket + + 9.target1上使用步骤8创建的socket,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 10.target1 shutdown socket3 R' + sub module: TCP + summary: AP mode, shutdown basic test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0114 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + - - SSC SSC1 soc -B -t TCP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,OK'] + - - SOC SOC2 CONNECT 0 + - ['R SSC1 A :ACCEPT:(\d+),\d+,.+,\d+'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.OK + + 6.OK,target1上accept 成功 + + 7.target1关闭socket1 + + 8.target1关闭socket2 + + 9.OK + + 10.OK,pc tcp server accept成功 + + 11.target1关闭socket1 + + 12.OK + + 13.OK,pc tcp server accept成功 + + 14.OK + + 15.target1关闭socket1' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + level: Integration + module: TCPIP + steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1关闭socket1\n\ + 4.target1上创建TCP socket 端口随机\n5.target1上使用步骤4创建的socket1,去监听\n6.PC CONNECT,\ + \ ,tcp 连接创建成功,创建socket2 \n7.target1关闭socket1\n8.target1关闭socket2\n\ + 9.target1上创建TCP socket1\n10.target1上使用步骤10创建的socket1,去连接 PC的ip,test_tcp_port1,PC有ACCEPT\n\ + 11.target1关闭socket1\n12.target1上创建TCP socket1\n13.target1上使用步骤13创建的socket1,去连接\ + \ PC的ip,test_tcp_port1,PC有ACCEPT\n14.target1shutdown socket1\n15.target1关闭socket1" + sub module: TCP + summary: AP mode, close for different types of TCP sockets test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0115 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK,pc tcp server accept成功 + + 4 OK + + 5.OK,pc tcp server accept成功 + + 6.OK + + 7.OK,pc tcp server accept成功 + + 8 OK + + 9.OK,pc tcp server accept成功 + + 10.OK + + 11.OK,pc tcp server accept成功' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + level: Integration + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket1 + + 3.target1上使用步骤2创建的socket1,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 4.target1上创建TCP socket2 + + 5.target1上使用步骤4创建的socket2,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 6.target1上创建TCP socket3 + + 7.target1上使用步骤6创建的socket3,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 8.target1上创建TCP socket4 + + 9.target1上使用步骤8创建的socket4,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 10.target1上创建TCP socket5 + + 11.target1上使用步骤10创建的socket5,去连接 PC的ip,test_tcp_port1,PC有ACCEPT' + sub module: TCP + summary: AP mode, create max TCP sockets test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0116 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -B -t TCP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,OK'] + - - SOC SOC2 CONNECT 0 + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] + - - SOC SOC3 CONNECT 0 + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] + - - SOC SOC4 CONNECT 0 + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] + - - SOC SOC5 CONNECT 0 + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] + - - SOC SOC6 CONNECT 0 + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] + comment: '' + execution time: 0.0 + expected result: '1.+BIND:0,OK,0.0.0.0 + + 2.OK + + 3.OK,pc tcp server accept成功 + + 4.OK,pc tcp server accept成功 + + 5.OK,pc tcp server accept成功 + + 6.OK,pc tcp server accept成功 + + 7.OK,pc tcp server accept成功' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + level: Integration + module: TCPIP + steps: "1.target1上创建TCP socket 端口随机\n2.target1上使用步骤4创建的socket1,去监听\n3.PC CONNECT,\ + \ ,tcp 连接创建成功,创建socket2 \n4.PC CONNECT, ,tcp 连接创建成功,创建socket3\ + \ \n5.PC CONNECT, ,tcp 连接创建成功,创建socket4 \n6.PC CONNECT,\ + \ ,tcp 连接创建成功,创建socket5 \n7.PC CONNECT, ,tcp 连接创建成功,创建socket6\ + \ " + sub module: TCP + summary: AP mode, accept max TCP client by server test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0201 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [SOCR SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -i 0.0.0.0 -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,OK'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s -h B + - ['P SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: '1.ok + + 2.OK + + 3.ERROR + + 4.OK + + 5.OK + + 6.ERROR + + 7.OK + + 8.OK + + 9.OK + + 10.OK + + 11.OK + + 12.ERROR' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建UDP传输socket,bind到本地ip 0.0.0.0, + + 3.target1上使用步骤2创建的socket,去连接 PC的ip, + + 4.target1上创建TCP socket + + 5.target1上使用步骤4创建的socket,创建TCP 监听 + + 6.target1上使用步骤4创建的socket,去连接 PC的ip, + + 7.target1上创建TCP socket + + 8.target1上使用步骤7创建的socket,去连接 PC的ip, + + 9.target1上关闭步骤7创建的socket + + 10.target1上使用步骤7创建的socket,去连接 PC的ip, + + 11.target1上关闭所有创建的socket + + 12.target1上使用步骤2创建的socket,去连接 PC的ip,' + sub module: TCP + summary: STA mode, connect test. use socket in state that can't connect + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) in different state + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0202 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,ERROR'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,ERROR'] + - - SSC SSC1 soc -D -s + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,ERROR'] + - - SSC SSC1 soc -L -s 1000 + - ['R SSC1 RE LISTEN:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.ERROR + + 4.OK + + 5.OK + + 6.ERROR + + 7.OK + + 8.ERROR + + 9.ERROR' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建UDP传输socket,bind到本地ip 0.0.0.0, + + 3.target1上使用步骤2创建的socket,去建立TCP 监听 + + 4.target1上创建TCP socket + + 5.target1上使用步骤4创建的socket,去连接 PC的ip, + + 6.target1上使用步骤4创建的socket,创建TCP 监听 + + 7.target1上shutdown 步骤4的socket + + 8.target1上使用步骤4创建的socket,创建TCP 监听 + + 9.target1上使用不存在socket,创建TCP 监听' + sub module: TCP + summary: STA mode, server listen test. use socket in state that can't listen + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) in different state + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0203 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s + - ['R SSC1 RE SEND:\d+,ERROR'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s + - ['R SSC1 RE SEND:\d+,ERROR'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -S -s + - ['R SSC1 RE SEND:\d+,ERROR'] + - - SSC SSC1 soc -S -s 1000 + - ['R SSC1 RE SEND:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.ERROR + + 4.OK + + 5.ERROR + + 6.OK + + 7.OK + + 8.ERROR + + 9.ERROR' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建UDP传输socket1, + + 3.target1上使用步骤2创建的socket1,去发送数据 + + 4.target1上创建TCP socket2 + + 5.target1上使用步骤4创建的socket2,去发送数据 + + 6.target1上使用步骤4创建的socket2,创建TCP连接,连接成功 + + 7.target1上shutdown 步骤4的socket2 + + 8.target1往socket2发送错误命令发送数据 + + 9.target1上不指定socket往上发送数据' + sub module: TCP + summary: send test. use socket in state that can't send + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) in different state + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0204 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SSC SSC1 soc -W -s -o 0 + - ['R SSC1 RE WORKTHREAD:\d+,OK'] + - - SOC SOC2 SEND 146000 + - [P SOC_COM R *] + - - SSC SSC1 soc -W -s -o 1 + - ['P SSC1 RE WORKTHREAD:\d+,OK', P SSC1 SL +2920] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK,pc server accept OK + + 4.OK + + 5.OK + + 6.OK + + 7.target收到146000 byte + + ' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration + module: TCPIP + steps: '1. PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket + + 3.target1上使用步骤2创建的socket,去连接 PC的ip,test_tcp_port1 + + 4.PC与target1 创建好TCP 连接,有ACCEPT + + 5.target上不进行recv + + 6.PC send 100 * 1460 data to target, + + 7.在target上开始recv' + sub module: TCP + summary: STA mode, recv buffer test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) in different state + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0206 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP -i + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -B -t TCP -i + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -B -t TCP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,OK'] + - - SOC SOC2 CONNECT + - ['R SSC1 A :ACCEPT:(\d+),\d+,.+,\d+'] + - - SSC SSC1 soc -I + - ['P SSC1 RE "SOCINFO:%%s,2,%%s,\d+,%%s,%%d"%%(,,,)', + 'P SSC1 RE "SOCINFO:%%s,2,.+,\d+,.+,\d+"%%()', 'P SSC1 RE "SOCINFO:%%s,82,.+,%%d,.+,\d+"%%(,)', + 'P SSC1 RE "SOCINFO:%%s,2,%%s,%%d,%%s,\d+"%%(,,,)'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK,pc tcp server accept成功 + + 4.OK + + 5.OK + + 6.OK + + 7.OK + + 8.OK + + 9.PC OK, target1 +ACCEPT:3,2,,port + + 10.+SOCINFO:,,, + + +SOCINFO:,,, + + +SOCINFO:, + + +SOCINFO:,,, + + +SOCINF0ALL' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration + module: TCPIP + steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1,本地ip target_ip\n3.target1上使用步骤2创建的socket1,去连接\ + \ PC的ip,test_tcp_port1,PC有ACCEPT\n4.target1上创建TCP socket2,本地ip target_ip\n5.target1上使用步骤4创建的socket2,去连接\ + \ PC的ip,test_tcp_port1,PC有ACCEPT\n6.target1 shutdown socket2 \n7.target1上创建TCP\ + \ socket3,本地端口random_port\n8.target1上使用步骤7创建的socket3,去监听\n9.PC CONNECT,\ + \ ,tcp 连接创建成功,创建socket4 \n10.target1 查询the socket information" + sub module: TCP + summary: STA mode, get active socket info test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) in different state + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0207 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [SOCR SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -i 0.0.0.0 -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,OK'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s -h B + - ['P SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: '1.ok + + 2 OK + + 3.ERROR + + 4.OK + + 5.OK + + 6.ERROR + + 7.OK + + 8.OK + + 9.OK + + 10.OK + + 11.OK + + 12.ERROR' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + level: Integration + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建UDP传输socket,bind到本地ip 0.0.0.0, + + 3.target1上使用步骤2创建的socket,去连接 PC的ip, + + 4.target1上创建TCP socket + + 5.target1上使用步骤4创建的socket,创建TCP 监听 + + 6.target1上使用步骤4创建的socket,去连接 PC的ip, + + 7.target1上创建TCP socket + + 8.target1上使用步骤7创建的socket,去连接 PC的ip, + + 9.target1上关闭步骤7创建的socket + + 10.target1上使用步骤7创建的socket,去连接 PC的ip, + + 11.target1上关闭所有创建的socket + + 12.target1上使用步骤2创建的socket,去连接 PC的ip,' + sub module: TCP + summary: AP mode, connect test. use socket in state that can't connect + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) in different state + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0208 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,ERROR'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,ERROR'] + - - SSC SSC1 soc -D -s + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,ERROR'] + - - SSC SSC1 soc -L -s 1000 + - ['R SSC1 RE LISTEN:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.ERROR + + 4 OK + + 5.OK + + 6.ERROR + + 7.OK + + 8.ERROR + + 9.ERROR' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + level: Integration + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建UDP传输socket,bind到本地ip 0.0.0.0, + + 3.target1上使用步骤2创建的socket,去建立TCP 监听 + + 4.target1上创建TCP socket + + 5.target1上使用步骤4创建的socket,去连接 PC的ip, + + 6.target1上使用步骤4创建的socket,创建TCP 监听 + + 7.target1上shutdown 步骤4的socket + + 8.target1上使用步骤4创建的socket,创建TCP 监听 + + 9.target1上使用不存在socket,创建TCP 监听' + sub module: TCP + summary: AP mode, server listen test. use socket in state that can't listen + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) in different state + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0210 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SSC SSC1 soc -W -s -o 0 + - ['R SSC1 RE WORKTHREAD:\d+,OK'] + - - SOC SOC2 SEND 146000 + - [P SOC_COM R *] + - - SSC SSC1 soc -W -s -o 1 + - ['P SSC1 RE WORKTHREAD:\d+,OK', P SSC1 SL +2920] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK,pc tcp server accept成功 + + 4.OK + + 6.OK + + 7.收到 146000 数据 + + ' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + level: Integration + module: TCPIP + steps: '1. PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket + + 3.target1上使用步骤2创建的socket,去连接 PC的ip,test_tcp_port1 + + 4.PC与target1 创建好TCP 连接,有ACCEPT + + 5.target停止调用recv + + 6.PC send 100 * 1460 data to 8266, + + 7.target重新调用recv' + sub module: TCP + summary: AP mode, recv buffer test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) in different state + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0212 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP -i + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -B -t TCP -i + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -B -t TCP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,OK'] + - - SOC SOC2 CONNECT 0 + - ['R SSC1 A :ACCEPT:(\d+),\d+,.+,\d+'] + - - SSC SSC1 soc -I + - ['P SSC1 RE "SOCINFO:%%s,2,%%s,\d+,%%s,%%d"%%(,,,)', + 'P SSC1 RE "SOCINFO:%%s,2,.+,\d+,.+,\d+"%%()', 'P SSC1 RE "SOCINFO:%%s,82,.+,%%d,.+,\d+"%%(,)', + 'P SSC1 RE "SOCINFO:%%s,2,%%s,%%d,%%s,\d+"%%(,,,)'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK,pc tcp server accept成功 + + 4.OK + + 5.OK + + 6.OK + + 7.OK + + 8.OK + + 9.PC OK, target1 +ACCEPT:3,2,,port + + 10.+SOCINFO:,,, + + +SOCINFO:,,, + + +SOCINFO:, + + +SOCINFO:,,, + + +SOCINF0ALL' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + level: Integration + module: TCPIP + steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1,本地ip target_ip\n3.target1上使用步骤2创建的socket1,去连接\ + \ PC的ip,test_tcp_port1,PC有ACCEPT\n4.target1上创建TCP socket2,本地ip target_ip\n5.target1上使用步骤4创建的socket2,去连接\ + \ PC的ip,test_tcp_port1,PC有ACCEPT\n6.target1 shutdown socket2 \n7.target1上创建TCP\ + \ socket3,本地端口random_port\n8.target1上使用步骤7创建的socket3,去监听\n9.PC CONNECT,\ + \ ,tcp 连接创建成功,创建socket4 \n10.target1 查询the socket information" + sub module: TCP + summary: AP mode, get active socket info test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) in different state + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0401 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SSC SSC1 sta -D + - ['P SSC1 C +QAP:OK', 'P SSC1 RE CLOSED:\d+,0'] + - - SSC SSC1 soc -S -s -l 5 + - ['P SSC1 RE SEND:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.ERROR' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket1 + + 3.target1上使用步骤2创建的socket1,去连接 PC的ip,test_tcp_port1 + + 4.PC与target1创建好TCP 连接,有ACCEPT + + 5.断开与AP 连接 + + 6.8266往PC上发送5字节数据' + sub module: TCP + summary: do TCP send after WIFI disconnected + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: TCP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0402 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SSC SSC1 sta -D + - ['P SSC1 C +QAP:OK', 'P SSC1 RE CLOSED:\d+,0'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.OK' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket1 + + 3.target1上使用步骤2创建的socket1,去连接 PC的ip,test_tcp_port1 + + 4.PC与target1创建好TCP 连接,有ACCEPT + + 5.断开与AP 连接 + + 6.关闭建立的socket1连接' + sub module: TCP + summary: "close TCP socket after WIFI \ndisconnected" + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: TCP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0403 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SSC SSC1 op -S -o 2 + - ['P SSC1 C +MODE:OK', 'P SSC1 RE CLOSED:\d+,0'] + - - SSC SSC1 soc -S -s -l 5 + - ['P SSC1 RE SEND:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.ERROR' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration + module: TCPIP + steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1上使用步骤2创建的socket1,去连接\ + \ PC的ip,test_tcp_port1\n4.PC与target1创建好TCP 连接,有ACCEPT\n5.修改8266的Mode为softAP mode\ + \ \n6.8266往PC上发送5字节数据" + sub module: TCP + summary: do TCP send after mode changed + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: TCP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0404 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SSC SSC1 op -S -o 2 + - ['P SSC1 C +MODE:OK', 'P SSC1 RE CLOSED:\d+,0'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.OK' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration + module: TCPIP + steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1上使用步骤2创建的socket1,去连接\ + \ PC的ip,test_tcp_port1\n4.PC与target1创建好TCP 连接,有ACCEPT\n5.修改8266的Mode为softAP mode\ + \ \n6.关闭建立的socket1连接" + sub module: TCP + summary: close TCP socket after mode changed + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: TCP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0405 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - NIC DISABLED + - [R PC_COM C OK] + - - SSC SSC1 soc -S -s -l 1 + - [''] + - - DELAY 5400 + - ['P SSC1 RE CLOSED:\d+,0'] + comment: '' + execution time: 1.5 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.TCP连接断开' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket1 + + 3.target1上使用步骤2创建的socket1,去连接 PC的ip,test_tcp_port1 + + 4.PC与target1创建好TCP 连接,有ACCEPT + + 5.PC 网卡 disable + + 6.target1上使用socket1发送数据,等待 90 分钟' + sub module: TCP + summary: do TCP send after PC NIC disabled + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: TCP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0406 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - NIC DISABLED + - [R PC_COM C OK] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.OK' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration + module: TCPIP + steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1上使用步骤2创建的socket1,去连接\ + \ PC的ip,test_tcp_port1\n4.PC与target1创建好TCP 连接,有ACCEPT\n5.PC上网卡禁止掉 \n6.关闭建立的socket1连接" + sub module: TCP + summary: close TCP socket after PC NIC disabled + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: TCP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0407 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SSC SSC1 dhcp -E -o 1 + - ['R SSC1 C +DHCP:STA,OK'] + - - SSC SSC1 ip -S -o 1 -i 192.168.111.210 + - ['P SSC1 C +IP:OK', 'P SSC1 RE CLOSED:\d+,0'] + - - SSC SSC1 ip -Q -o 1 + - ['R SSC1 C +STAIP:192.168.111.210'] + - - SSC SSC1 soc -S -s -l 5 + - ['P SSC1 RE SEND:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.OK + + 7.OK + + 8.ERROR' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration + module: TCPIP + steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1上使用步骤2创建的socket1,去连接\ + \ PC的ip,test_tcp_port1\n4.PC与target1创建好TCP 连接,有ACCEPT\n5.关闭8266的DHCP 1\n6.设置sta\ + \ ip \n7.查询sta ip 地址是否生效\n8.8266往PC上发送5字节数据" + sub module: TCP + summary: do TCP send after IP changed + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: TCP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0408 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SSC SSC1 dhcp -E -o 1 + - ['R SSC1 C +DHCP:STA,OK'] + - - SSC SSC1 ip -S -o 1 -i 192.168.111.210 + - ['P SSC1 C +IP:OK', 'P SSC1 RE CLOSED:\d+,0'] + - - SSC SSC1 ip -Q -o 1 + - ['R SSC1 C +STAIP:192.168.111.210'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.OK + + 7.OK + + 8.OK' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration + module: TCPIP + steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1上使用步骤2创建的socket1,去连接\ + \ PC的ip,test_tcp_port1\n4.PC与target1创建好TCP 连接,有ACCEPT\n5.关闭8266的DHCP 1\n6.设置sta\ + \ ip \n7.查询sta ip 地址是否生效\n8.关闭建立的socket1连接" + sub module: TCP + summary: close TCP socket after IP changed + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: TCP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0411 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -l 5 + - ['P SSC1 RE SEND:\d+,ERROR'] + - - SSC SSC1 soc -S -s -l 5 + - ['P SSC1 RE SEND:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.ERROR + + 7.OK' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket1 + + 3.target1上使用步骤2创建的socket1,去连接 PC的ip,test_tcp_port1 + + 4.PC与target1创建好TCP 连接,有ACCEPT + + 5.target1上创建TCP socket2 + + 6.8266往PC socket2上发送5字节数据 + + 7.8266往PC socket1上发送5字节数据' + sub module: TCP + summary: do TCP send after socket changed + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: TCP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_0412 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.OK + + 7.OK' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket1 + + 3.target1上使用步骤2创建的socket1,去连接 PC的ip,test_tcp_port1 + + 4.PC与target1创建好TCP 连接,有ACCEPT + + 5.target1上创建TCP socket2 + + 6.关闭socket1 连接 + + 7.关闭socket2连接' + sub module: TCP + summary: close TCP send after socket changed + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: TCP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0101 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -i 0.0.0.0 -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 C BIND:ERROR'] + - - SSC SSC1 soc -B -t TCP -p + - ['R SSC1 RE BIND:(\d+),OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.ERROR + + 4.OK' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration + module: TCPIP + steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 2.target1上UDP传输,Bind socket2,本地ip 0.0.0.0 target_udp_port2 + + 3.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 4.target1上创建TCP socket3, target_udp_port1' + sub module: UDP + summary: STA mode, udp bind test. use different ip, port + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0102 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: 1/5 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SOC SOC2 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 10 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 10] + - - SSC SSC1 soc -S -s -i -p -l 10 + - ['P SSC1 RE SEND:(\d+),OK', P SOC2 UL 10] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.OK' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration + module: TCPIP + steps: '1.PC上SOC1 UDP传输,bing + + 2.PC上SOC2 UDP传输,bing + + 3.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 4.target1上使用步骤3创建的socket1,往pc_ip,test_tcp_port1上发送10字节数据 + + 5.target1上使用步骤3创建的socket1,往pc_ip2,test_tcp_port2上发送10字节数据' + sub module: UDP + summary: STA mode, sendto test. use different ip, port + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0103 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: 1/5 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 1 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 1] + - - SSC SSC1 soc -S -s -i -p -l 1472 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 1472] + - - SSC SSC1 soc -S -s -i -p -l 1473 + - ['P SSC1 RE SEND:(\d+),OK', P SOC_COM NC SOC_RECVFROM] + - - SSC SSC1 soc -S -s -i -p -l 1472 -n 10 -j 20 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 14720] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.OK,没有到UDP包 + + 6.OK' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration + module: TCPIP + steps: '1.PC上SOC1 UDP传输,bing + + 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1字节数据 + + 4.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1472字节数据 + + 5.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1473字节数据 + + 6.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1472*10字节数据' + sub module: UDP + summary: STA mode, sendto test with different length + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0104 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: 1/5 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SOC SOC1 SENDTO 1 + - [R SSC1 SL +1] + - - SOC SOC1 SENDTO 1472 + - ['R SSC1 RE "RECVFROM:%%s,1472,%%s,%%u"%%(,,)'] + - - SOC SOC1 SENDTO 1473 + - [P SSC1 NC +RECVFROM, P SOC_COM C OK] + - - SOC SOC2 BIND + - [R SOC_COM L OK] + - - SOC SOC2 SENDTO 1472 + - ['R SSC1 RE "RECVFROM:%%s,1472,%%s,%%u"%%(,,)'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.OK,没收到UDP包 + + 6.OK + + 7.OK' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration + module: TCPIP + steps: '1.PC上SOC1 UDP传输,bing + + 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 3.PC往8266上发送1字节数据 + + 4.PC往8266上发送1472字节数据 + + 5.PC往8266上发送1473字节数据 + + 6.PC上SOC2 UDP传输,bing + + 7.PC往8266上发送1472字节数据' + sub module: UDP + summary: STA mode, recvfrom basic test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0105 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration + module: TCPIP + steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 2.关闭socket1' + sub module: UDP + summary: STA mode, close UDP sockets test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0106 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + comment: '' + execution time: 0.0 + expected result: '1.ok + + 2.ok + + 3.ok + + 4.ok + + 5.ok' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration + module: TCPIP + steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 2.target1上UDP传输,Bind socket2,本地ip target_udp_port2 + + 3.target1上UDP传输,Bind socket3,本地ip target_udp_port3 + + 4.target1上UDP传输,Bind socket4,本地ip target_udp_port4 + + 5.target1上UDP传输,Bind socket5,本地ip target_udp_port5' + sub module: UDP + summary: STA mode, create max udp socket test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0107 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -I + - ['P SSC1 RE "SOCINFO:%%s,1,.+,%%d"%%(,)'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration + module: TCPIP + steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 2.target1上查询创建socket信息' + sub module: UDP + summary: STA mode, get active socket info test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0108 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -i 0.0.0.0 -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 C BIND:ERROR'] + - - SSC SSC1 soc -B -t TCP -p + - ['R SSC1 RE BIND:(\d+),OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.ERROR + + 4.OK' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + level: Integration + module: TCPIP + steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 2.target1上UDP传输,Bind socket2,本地ip 0.0.0.0 target_udp_port2 + + 3.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 4.target1上创建TCP socket3, target_udp_port1' + sub module: UDP + summary: AP mode, udp bind test. use different ip, port + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0109 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: 1/5 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - WIFI CONN + + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC2 ip + - ['R SSC2 A :STAIP:(.+)\r\n'] + - - SSC SSC2 soc -B -t UDP -p + - ['R SSC2 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 5 + - [R SOC1 UL 5] + - - SSC SSC1 soc -S -s -i -p -l 5 + - ['R SSC2 RE "RECVFROM:%%s,5,%%s,%%u"%%(,,)'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.OK' + initial condition: T2O_1 + initial condition description (auto): same as T2_1 but will NOT autogen a TC with + initial condition T2_2 + level: Integration + module: TCPIP + steps: '1.PC上SOC1 UDP传输,bing + + 2.PC上SOC2 UDP传输,bing + + 3.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 4.target1上使用步骤3创建的socket1,往pc_ip,test_tcp_port1上发送10字节数据 + + 5.target1上使用步骤3创建的socket1,往pc_ip2,test_tcp_port2上发送10字节数据' + sub module: UDP + summary: AP mode, sendto test. use different ip, port + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0110 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: 1/5 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 1 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 1] + - - SSC SSC1 soc -S -s -i -p -l 1472 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 1472] + - - SSC SSC1 soc -S -s -i -p -l 1473 + - ['P SSC1 RE SEND:(\d+),OK', P SOC_COM NC SOC_RECVFROM] + - - SSC SSC1 soc -S -s -i -p -l 1472 -n 10 + -j 20 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 14720] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.OK,没收到UDP包 + + 6.OK' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + level: Integration + module: TCPIP + steps: '1.PC上SOC1 UDP传输,bing + + 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1字节数据 + + 4.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1472字节数据 + + 5.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1473字节数据 + + 6.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1472*10字节数据' + sub module: UDP + summary: AP mode, sendto test with different length + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0111 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: 1/5 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - WIFI CONN + + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC2 ip + - ['R SSC2 A :STAIP:(.+)\r\n'] + - - SSC SSC2 soc -B -t UDP -p + - ['R SSC2 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SOC SOC1 SENDTO 5 + - ['R SSC1 RE "RECVFROM:%%s,5,%%s,%%u"%%(,,)'] + - - SSC SSC2 soc -S -s -i -p -l 5 + - ['R SSC1 RE "RECVFROM:%%s,5,%%s,%%u"%%(,,)'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.OK,没收到UDP包 + + 6.OK + + 7.OK' + initial condition: T2O_1 + initial condition description (auto): same as T2_1 but will NOT autogen a TC with + initial condition T2_2 + level: Integration + module: TCPIP + steps: '1.PC上SOC1 UDP传输,bing + + 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 3.PC往8266上发送1字节数据 + + 4.PC往8266上发送1472字节数据 + + 5.PC往8266上发送1473字节数据 + + 6.PC上SOC2 UDP传输,bing + + 7.PC往8266上发送1472字节数据' + sub module: UDP + summary: AP mode, recvfrom basic test + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0112 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + level: Integration + module: TCPIP + steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 2.关闭socket1' + sub module: UDP + summary: AP mode, close UDP sockets test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0113 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + comment: '' + execution time: 0.0 + expected result: '1.ok + + 2.ok + + 3.ok + + 4.ok + + 5.ok' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + level: Integration + module: TCPIP + steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 2.target1上UDP传输,Bind socket2,本地ip target_udp_port2 + + 3.target1上UDP传输,Bind socket3,本地ip target_udp_port3 + + 4.target1上UDP传输,Bind socket4,本地ip target_udp_port4 + + 5.target1上UDP传输,Bind socket5,本地ip target_udp_port5' + sub module: UDP + summary: AP mode, create max udp socket test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0114 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -I + - ['P SSC1 RE "SOCINFO:%%s,1,.+,%%d"%%(,)'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + level: Integration + module: TCPIP + steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 2.target1上查询创建socket信息' + sub module: UDP + summary: AP mode, get active socket info test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0201 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -W -s -o 0 + - ['R SSC1 RE WORKTHREAD:\d+,OK'] + - - SOC SOC1 SENDTO 1472 + - [''] + - - SOC SOC1 SENDTO 1472 + - [''] + - - SOC SOC1 SENDTO 1472 + - [''] + - - SOC SOC1 SENDTO 1472 + - [''] + - - SOC SOC1 SENDTO 1472 + - [''] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.PC OK + + 5.PC OK + + 6.PC OK + + 7.PC OK + + 8.PC OK SOC_CLOSE=SOC1' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration + module: TCPIP + steps: '1.PC上SOC1 UDP传输,bing + + 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 3.target1上关闭工作线程 + + 4.PC往8266上发送1472字节数据 + + 5.PC往8266上发送1472字节数据 + + 6.PC往8266上发送1472字节数据 + + 7.PC往8266上发送1472字节数据 + + 8.PC往8266上发送1472字节数据' + sub module: UDP + summary: STA mode, recv buffer test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: use UDP SAP (socket/espconn API) in different state + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0202 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -W -s -o 0 + - ['R SSC1 RE WORKTHREAD:\d+,OK'] + - - SOC SOC1 SENDTO 1472 + - [''] + - - SOC SOC1 SENDTO 1472 + - [''] + - - SOC SOC1 SENDTO 1472 + - [''] + - - SOC SOC1 SENDTO 1472 + - [''] + - - SOC SOC1 SENDTO 1472 + - [''] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.PC OK + + 5.PC OK + + 6.PC OK + + 7.PC OK + + 8.PC OK SOC_CLOSE=SOC1' + initial condition: APM2 + initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen + a TC with initial condition APSTA2 + level: Integration + module: TCPIP + steps: '1.PC上SOC1 UDP传输,bing + + 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 3.target1上关闭工作线程 + + 4.PC往8266上发送1472字节数据 + + 5.PC往8266上发送1472字节数据 + + 6.PC往8266上发送1472字节数据 + + 7.PC往8266上发送1472字节数据 + + 8.PC往8266上发送1472字节数据' + sub module: UDP + summary: AP mode, recv buffer test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: use UDP SAP (socket/espconn API) in different state + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0301 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: 1/5 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -i -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 5 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] + - - SSC SSC1 sta -D + - ['P SSC1 C +QAP:OK'] + - - SSC SSC1 soc -S -s -i -p -l 5 + - ['P SSC1 RE SEND:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.ERROR' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration + module: TCPIP + steps: '1.PC上SOC1 UDP传输,bing + + 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据 + + 4.断开与AP 连接 + + 5.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据' + sub module: UDP + summary: do UDP send after WIFI disconnected + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: UDP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0302 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: 1/5 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 5 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] + - - SSC SSC1 sta -D + - ['P SSC1 C +QAP:OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.OK + + ' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration + module: TCPIP + steps: '1.PC上SOC1 UDP传输,bing + + 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据 + + 4.断开与AP 连接 + + 5.关闭建立的socket1连接' + sub module: UDP + summary: "close UDP socket after WIFI \ndisconnected" + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: UDP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0303 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: 1/5 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 5 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] + - - SSC SSC1 op -S -o 2 + - ['P SSC1 C +MODE:OK'] + - - SSC SSC1 soc -S -s -i -p -l 5 + - ['P SSC1 RE SEND:(\d+),OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.ERROR' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration + module: TCPIP + steps: "1.PC上SOC1 UDP传输,bing \n2.target1上UDP传输,Bind socket1,本地ip\ + \ target_udp_port1\n3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据\n\ + 4.修改8266的Mode为softAP mode \n5.8266往PC上发送5字节数据" + sub module: UDP + summary: do UDP send after mode changed + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: UDP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0304 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: 1/5 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 5 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] + - - SSC SSC1 op -S -o 2 + - ['P SSC1 C +MODE:OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.OK' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration + module: TCPIP + steps: "1.PC上SOC1 UDP传输,bing \n2.target1上UDP传输,Bind socket1,本地ip\ + \ target_udp_port1\n3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据\n\ + 4.修改8266的Mode为softAP mode \n5.关闭建立的socket1连接" + sub module: UDP + summary: close UDP socket after mode changed + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: UDP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0305 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: 1/5 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 5 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] + - - NIC DISABLED + - [R PC_COM C OK] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.OK' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration + module: TCPIP + steps: "1.PC上SOC1 UDP传输,bing \n2.target1上UDP传输,Bind socket1,本地ip\ + \ target_udp_port1\n3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据\n\ + 4.PC上网卡禁止掉 \n5.关闭建立的socket1连接" + sub module: UDP + summary: close UDP socket after PC NIC disabled + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: UDP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0306 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: 1/5 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 5 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] + - - SSC SSC1 dhcp -E -o 1 + - ['R SSC1 C +DHCP:STA,OK'] + - - SSC SSC1 ip -S -o 1 -i 192.168.111.210 + - ['P SSC1 C +IP:OK'] + - - SSC SSC1 ip -Q -o 1 + - ['R SSC1 C +STAIP:192.168.111.210'] + - - SSC SSC1 soc -S -s -i -p -l 1 + - ['P SSC1 RE SEND:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.OK + + 7.OK' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration + module: TCPIP + steps: "1.PC上SOC1 UDP传输,bing \n2.target1上UDP传输,Bind socket1,本地ip\ + \ target_udp_port1\n3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据\n\ + 4.关闭8266的DHCP 1\n5.设置sta ip \n6.查询sta ip 地址是否生效\n7.8266往PC上发送5字节数据" + sub module: UDP + summary: do UDP send after IP changed + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: UDP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_0307 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: 1/5 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 5 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] + - - SSC SSC1 dhcp -E -o 1 + - ['R SSC1 C +DHCP:STA,OK'] + - - SSC SSC1 ip -S -o 1 -i 192.168.111.210 + - ['P SSC1 C +IP:OK'] + - - SSC SSC1 ip -Q -o 1 + - ['R SSC1 C +STAIP:192.168.111.210'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.OK + + 7.OK' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration + module: TCPIP + steps: "1.PC上SOC1 UDP传输,bing \n2.target1上UDP传输,Bind socket1,本地ip\ + \ target_udp_port1\n3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据\n\ + 4.关闭8266的DHCP 1\n5.设置sta ip \n6.查询sta ip 地址是否生效\n7.关闭建立的socket1连接" + sub module: UDP + summary: close UDP socket after IP changed + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: UDP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_ADDR_0101 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 mac -S -o 1 -m 44:55:66:77:88:99 + - ['R SSC1 C +MAC:STA,OK'] + - - SSC SSC1 mac -S -o 2 -m 22:33:44:55:66:77 + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC1 mac -Q -o 3 + - ['R SSC1 C +STAMAC:44:55:66:77:88:99 C +APMAC:22:33:44:55:66:77'] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.ok + + 3.ok + + 4.ok + + 5.ok + + 6.ok' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + level: Integration + module: WIFI MAC + steps: "1.target1 设置mode 为sta+softAP mode\n2.target1 设置sta mode 下的mac \n3.target1\ + \ 设置softAP mode 下的mac\n4.target1 查询softAP+sta 下的mac\n5.target1 设置sta mode 下的mac\ + \ 为target1_mac\n6.target1 设置softAP mode 下的mac 为target1_ap_mac\n" + sub module: MAC Address + summary: set mac, query mac + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: mac address function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_ADDR_0102 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 mac -S -o 2 -m 44:55:66:77:88:99 + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC1 ap -S -s -p -t + - [''] + - - SSC SSC2 sta -S -b 44:55:66:77:88:99 + - ['R SSC2 RE \+SCAN:.+,44:55:66:77:88:99,'] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC2 mac -Q -o 1 + - ['R SSC2 A :\+STAMAC:(.+)\r\n'] + - - SSC SSC2 mac -S -o 1 -m 22:33:44:55:66:77 + - ['R SSC2 C +MAC:STA,OK'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 ap -L + - ['R SSC1 C +LSTA:22:33:44:55:66:77'] + - - SSC SSC2 mac -S -o 1 -m + - ['R SSC2 C +MAC:STA,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.ok + + 3.ok + + 4.ok + + 5.ok + + 6.ok + + 7.ok + + 8.ok + + 9.ok' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + level: Integration + module: WIFI MAC + steps: "1.target1 设置sta mode下的mac 44:55:66:77:88:99\n2.target1下设置ssid 和pwd 加密方式\n\ + 3.target2 查询mac为44:55:66:77:88:99的ssid\n4.target1 设置sta mode下的mac target_ap_mac\n\ + 5.target2 查询sta mode 下的mac 为target2_mac_tmp\n6.target2 设置sta mode 下的mac 为22:33:44:55:66:77\n\ + 7.target2 jap target1\n8.target1 查询连接到的sta \n9.target2 设置sta mode 下的mac 为 target2_mac\n" + sub module: MAC Address + summary: set mac and do scan/JAP/SAP + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: mac address function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_CONN_0101 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -t 0 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC1 ap -S -s -p -t 2 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC1 ap -S -s -p -t 1 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -S + - ['R SSC2 RE "\+SCAN:%%s,.+,0,\d+"%%()'] + - - SSC SSC1 ap -S -s -p -t 5 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -S + - ['R SSC2 RE "\+SCAN:%%s,.+,0,\d+"%%()'] + comment: '' + execution time: 0.0 + expected result: "1.target1 set AP,open, \n2.target 2 jap succeed\n3.target1 set\ + \ AP,wpa_psk \n4.target 2 jap succeed\n5.target1 set AP, wpa2_psk \n6.target 2\ + \ jap succeed\n7.target1 set AP,wap_wpa2_psk\n8.target 2 jap succeed\n9.target1\ + \ set AP,加密方式为t 1\n10.target 2 上查询到target_ssid\n11.target1 set AP,加密方式为t 5\n12.target\ + \ 2 上查询到target_ssid" + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + level: Integration + module: WIFI MAC + steps: "1.target1下设置ssid 和pwd,加密方式 open\n2.target2 jap target1\n3.target1下设置ssid\ + \ 和pwd,加密方式 wpa_psk \n4.target2 jap target1\n5.target1下设置ssid 和pwd,加密方式 wpa2_psk\ + \ \n6.target 2 jap target1\n7.target1下设置ssid 和pwd,加密方式 wap_wpa2_psk\n8.target2\ + \ jap target1\n9.target1下设置ssid 和pwd,加密方式 wep \n10.target2上查询target_ssid\n11.target1下设置ssid\ + \ 和pwd,加密方式 t 5 错误的加密方式\n12.target2上查询 target_ssid" + sub module: WIFI Connect + summary: station SAP+JAP test, different encryption + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: SAP/JAP with different config + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_CONN_0102 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -t 0 -n 1 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC1 ap -S -s -t 0 -n 13 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC1 ap -S -s -n 15 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -S + - ['R SSC2 RE "\+SCAN:%%s,.+,\d+,1"%%()'] + comment: '' + execution time: 0.0 + expected result: '1. target1 set AP,set channel 1 + + 2.target 2 jap succeed + + 3.target1 set AP,set channel 10 + + 4.target 2 jap succeed + + 5.target1 set AP,set channel 15 + + 6.target 2 上查询到target_ssid' + initial condition: T2O_1 + initial condition description (auto): same as T2_1 but will NOT autogen a TC with + initial condition T2_2 + level: Integration + module: WIFI MAC + steps: '1. target1下设置ssid 和pwd 加密方式,set channel 1 + + 2.target2 jap target 1 + + 3.target1下设置ssid 和pwd 加密方式,set channel 10 + + 4.target2 jap target 1 + + 5.target1下设置ssid 和pwd 加密方式,set channel 15 + + 6.target 2 上查询target_ssid' + sub module: WIFI Connect + summary: station SAP+JAP test, different channel + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: SAP/JAP with different config + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_CONN_0103 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t -h + 0 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -S -h 0 + - [R SSC2 P , R SSC2 C +SCANDONE] + - - SSC SSC1 ap -S -s -p -t -h + 1 + - ['R SSC1 C +SAP:OK'] + - - DELAY 3 + - [''] + - - SSC SSC2 sta -S -h 0 + - [R SSC2 C +SCANDONE] + - - DELAY 3 + - [''] + - - SSC SSC2 sta -S -h 0 + - [R SSC2 NP C +SCANDONE] + comment: '' + execution time: 0.0 + expected result: '1.target1 set AP,set ssid broad cast + + 2.target 2上scan target_ap_mac + + 3.target1 set AP,set ssid hidden, + + 4.target 2上不能scan target_ap_mac' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + level: Integration + module: WIFI MAC + steps: '1. target1下设置ssid 和pwd 加密方式,set ssid broad cast + + 2.target 2上scan target_ap_mac + + 3. target1下设置ssid 和pwd 加密方式,set ssid hidden, + + 4.target 2上scan target_ap_mac' + sub module: WIFI Connect + summary: station SAP+JAP test, ssid hidden + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: SAP/JAP with different config + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_CONN_0104 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t -m + 1 + - ['R SSC1 C +SAP:OK'] + - - WIFI DISCONN + - ['R PC_COM C +WIFIDISCONN:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] + - - WIFI CONN + + - ['R PC_COM C +WIFICONN:ERROR'] + comment: '' + execution time: 0.0 + expected result: '1. target1 set AP,set max allowed sta as 1 + + 2. use PC disconnect, + + 3.target 2 jap succeed + + 4.PC WIFI can not CONN' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + level: Integration + module: WIFI MAC + steps: '1.target1下设置ssid 和pwd 加密方式,set max allowed sta as 1 + + 2.use PC disconnect target1 + + 3.target 2 jap target1 + + 4.PC WIFI CONNECT target1' + sub module: WIFI Connect + summary: station SAP test, max allowed sta + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: SAP/JAP with different config + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_CONN_0201 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC1 sta -Q + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:OK'] + - - SSC SSC1 sta -Q + - ['R SSC1 C +JAP:DISCONNECTED'] + comment: '' + execution time: 0.0 + expected result: '1.target1 jion AP 成功 + + 2.查询JAP的状态 + + 3.target1 断开AP + + 4.查询target1 JAP 是DISCONN' + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + level: Integration + module: WIFI MAC + steps: '1.target1 jion AP 成功 + + 2.查询JAP的状态 + + 3.target1 断开AP + + 4.查询target1 JAP 是DISCONN' + sub module: WIFI Connect + summary: JAP query test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: query JAP status + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_CONN_0301 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t -h + 0 -m 8 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 ap -Q + - ['R SSC1 RE "\+APCONFIG:%%s,%%s,\d+,3,0,8,\d+"%%(,)'] + comment: '' + execution time: 0.0 + expected result: '1. target1 set AP + + 2.target 1上查询到跟设置AP时一致 + + ' + initial condition: APM1 + initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial + condition APSTA1 + level: Integration + module: WIFI MAC + steps: '1. target1 set AP + + 2.target 1上查询到跟设置AP时一致 + + ' + sub module: WIFI Connect + summary: AP config query test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: query AP config + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_CONN_0401 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -R -a 0 + - ['R SSC1 C +AUTORECONN:OK'] + - - SSC SSC1 sta -R -a 2 + - ['R SSC1 C +AUTORECONN:0'] + - - SSC SSC1 reboot + - [''] + - - DELAY 15 + - [''] + - - SSC SSC1 sta -Q + - ['R SSC1 C JAP:DISCONNECTED'] + - - SSC SSC1 sta -R -a 1 + - ['R SSC1 C +AUTORECONN:OK'] + - - SSC SSC1 sta -R -a 2 + - ['R SSC1 C +AUTORECONN:1'] + - - SSC SSC1 reboot + - ['R SSC1 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: '1.设置autoreconn,关闭 + + 2.查询当前autoreconn状态是否关闭 + + 3.重启系统,等待15s + + 4.查询target1 未自动重连AP + + 5.设置autoreconn,开启 + + 6.查询当前autoreconn状态是否开启 + + 7.系统重启后target1 自动重连AP' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on, will autogen a + TC with initial condition STAAP2 + level: Integration + module: WIFI MAC + steps: '1.设置autoreconn,关闭 + + 2.查询当前autoreconn状态是否关闭 + + 3.重启系统,等待15s + + 4.查询target1 未自动重连AP + + 5.设置autoreconn,开启 + + 6.查询当前autoreconn状态是否开启 + + 7.系统重启后target1 自动重连AP' + sub module: WIFI Connect + summary: auto reconnect test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: power on auto reconnect test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_CONN_0501 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC2 sta -R -r 1 + - ['R SSC2 C +RECONN:OK'] + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - DELAY 10 + - [''] + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - DELAY 15 + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC2 sta -R -r 0 + - ['R SSC2 C +RECONN:OK'] + - - SSC SSC2 sta -R -r 2 + - ['R SSC2 C +RECONN:0'] + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - DELAY 10 + - [''] + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - DELAY 15 + - [P PC_COM C +DELAYDONE, 'P SSC2 NC +JAP:CONNECTED'] + - - SSC SSC2 sta -R -r 1 + - ['R SSC2 C +RECONN:OK'] + comment: '' + execution time: 0.0 + expected result: '1.设置reconn,开启(此功能不需要重启系统) + + 2.target1 set AP + + 3.target2 JAP target1 成功 + + 4.target2 断开target1 连接 + + 5.等待10s,target2 自动重连target1 + + 6.成功 + + 7.查询reconn状态,关闭 + + 8.修改mode 成功 + + 9.等待15s,target2 不会自动重连target1' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + level: Integration + module: WIFI MAC + steps: "1.设置reconn,开启(此功能不需要重启系统)\n2.target1下设置ssid 和pwd 加密方式\n3.target2 JAP target1\ + \ \n4.target1 修改mode 为sta mode\n5.等待10s,target1 修改mode 为softAP mode\n6.设置reconn,关闭\n\ + 7.查询reconn状态,关闭\n8.target1 修改mode 为sta mode\n9.等待15s,target1 修改mode 为softAP mode" + sub module: WIFI Connect + summary: reconnect policy test + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: reconnect policy test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_CONN_0502 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC2 sta -R -r 1 + - ['R SSC2 C +RECONN:OK'] + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - DELAY 5 + - ['R SSC2 C +JAP:DISCONNECTED'] + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - DELAY 10 + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:OK'] + - - DELAY 10 + - [P PC_COM C +DELAYDONE, 'P SSC2 NC +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: '1.target1 set AP + + 2.target2 jap target 1 + + 3.设置reconn,开启(此功能不需要重启系统) + + 4.target2 断开target1 连接 + + 5.等待10s,target2 自动重连target1 + + 6.target2 断开target1 连接' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + level: Integration + module: WIFI MAC + steps: '1.target1下设置ssid 和pwd 加密方式 + + 2.target2 jap target 1 + + 3.设置reconn,开启(此功能不需要重启系统) + + 4.target2 断开target1 连接 + + 5.等待10s,target2 自动重连target1 + + 6.target2 断开target1 连接' + sub module: WIFI Connect + summary: will not do reconnect after manually disconnected + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: reconnect policy test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_CONN_0601 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - WIFI CONN + + - ['R PC_COM C +WIFICONN:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 ap -L + - ['R SSC1 C +LSTA:', 'R SSC1 C +LSTA:', R SSC1 C +LSTADONE] + comment: '' + execution time: 0.0 + expected result: '1.target1 set AP + + 2.PC WIFI CONNECTED + + 3.target2 jap target 1 + + 4.查询到两个sta 连接到target1 上' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + level: Integration + module: WIFI MAC + steps: '1. target1下设置ssid 和pwd 加密方式 + + 2.PC WIFI CONNECTED target1 + + 3.target2 jap target 1 + + 4.查询到两个sta 连接到target1 上' + sub module: WIFI Connect + summary: list stations connected to soft ap test + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: list SoftAP connected station + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_CONN_0801 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 0 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 ap -S -s -p -t 2 + - ['P SSC1 C +SAP:OK', 'P SSC2 C +JAP:AUTHCHANGED,2,0'] + - - SSC SSC1 ap -S -s -p -t 3 + - ['P SSC1 C +SAP:OK', 'P SSC2 C +JAP:AUTHCHANGED,3,2'] + - - SSC SSC1 ap -S -s -p -t 4 + - ['P SSC1 C +SAP:OK', 'P SSC2 C +JAP:AUTHCHANGED,4,3'] + - - SSC SSC1 ap -S -s -p -t 0 + - ['P SSC1 C +SAP:OK', 'P SSC2 C +JAP:AUTHCHANGED,0,4'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. auth change event old mode 0 new mode 2 + + 4. auth change event old mode 2 new mode 3 + + 5. auth change event old mode 3 new mode 4 + + 6. auth change event old mode 4 new mode 0' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + level: Integration + module: WIFI MAC + steps: '1. set target1 softap auth mode 0 + + 2. target2 connect to target1 + + 3. set target1 softap auth mode 2, wait sta connected + + 4. set target1 softap auth mode 3, wait sta connected + + 5. set target1 softap auth mode 4, wait sta connected + + 6. set target1 softap auth mode 0, wait sta connected' + sub module: WIFI Connect + summary: test auth change event + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: wifi auth changed event test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_CONN_0901 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: basic function + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC1 sta -D + - ['R SSC1 RE JAP:DISCONNECTED,\d+,8'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE JAP:DISCONNECTED,\d+,15'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE JAP:DISCONNECTED,\d+,201'] + comment: '' + execution time: 0.0 + expected result: '1. disconnect event reason REASON_ASSOC_LEAVE + + 2. disconnect event reason REASON_4WAY_HANDSHAKE_TIMEOUT + + 3. disconnect event reason REASON_NO_AP_FOUND' + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + level: Integration + module: WIFI MAC + steps: '1. sta connect to AP, and disconnect + + 2. connect to AP with wrong password + + 3. connect to AP not exist' + sub module: WIFI Connect + summary: test wifi disconnect reason REASON_ASSOC_LEAVE, REASON_4WAY_HANDSHAKE_TIMEOUT, + REASON_NO_AP_FOUND + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: wifi disconnect reason test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_CONN_0902 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - APC OFF + - [P PC_COM L OK, 'R SSC1 RE JAP:DISCONNECTED,\d+,200'] + - - APC ON + - [P PC_COM L OK] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. disconnect event REASON_BEACON_TIMEOUT' + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + level: Integration + module: WIFI MAC + steps: '1. connect to AP + + 2. AP power off' + sub module: WIFI Connect + summary: test wifi disconnect reason REASON_BEACON_TIMEOUT + test environment: SSC_T1_APC + test environment description (auto): "PC has 1 wired NIC connected to AP.\nPC has\ + \ 1 wired NIC connected to APC (static IP within the same subnet with APC). \n\ + APC control AP power supply. \nPC has 1 WiFi NIC. \n1 SSC target connect with\ + \ PC by UART." + test point 1: basic function + test point 2: wifi disconnect reason test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_CONN_0903 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -C -s -p bacfd + - ['R SSC1 RE JAP:DISCONNECTED,\d+,2'] + comment: '' + execution time: 0.0 + expected result: 1. disconect event reason REASON_AUTH_EXPIRE + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + level: Integration + module: WIFI MAC + steps: 1. connect WEP ap with error password (valid wep password) + sub module: WIFI Connect + summary: test wifi disconnect reason REASON_AUTH_EXPIRE + test environment: SSC_T1_WEP + test environment description (auto): '1 SSC target connect with PC by UART. + + One WEP share key AP placed near SSC1.' + test point 1: basic function + test point 2: wifi disconnect reason test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_CONN_0904 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 3 -m 1 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p 1234567890 + - ['R SSC2 RE JAP:DISCONNECTED,\d+,204'] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:OK'] + - - WIFI CONN + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 RE JAP:DISCONNECTED,\d+,5'] + - - WIFI DISCONN + - [P PC_COM C OK, 'R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 ap -S -s -p -t 3 -m 1 + - ['P SSC1 C +SAP:OK', 'P SSC2 RE JAP:DISCONNECTED,\d+,4'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. disconnect event REASON_HANDSHAKE_TIMEOUT + + 3. succeed + + 4. succeed + + 5. disconnect event REASON_ASSOC_TOOMANY + + 6. succeed, target2 connect succeed + + 7. disconnect event REASON_ASSOC_EXPIRE' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + level: Integration + module: WIFI MAC + steps: '1. config target1 softap max sta allowed 1 + + 2. target2 connect to target1 with wrong password + + 3. target2 disconnect + + 4. PC WIFI NIC connect to target1 + + 5. target2 connect to target1 with correct password + + 6. PC WIFI NIC disconnect + + 7. reconfig softap' + sub module: WIFI Connect + summary: test wifi disconnect reason REASON_ASSOC_TOOMANY, REASON_HANDSHAKE_TIMEOUT, + REASON_ASSOC_EXPIRE + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: wifi disconnect reason test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_MODE_0101 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - ['R SSC1 C +DHCP:STA,OK'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC2 sta -S + - [R SSC2 NP C +SCANDONE] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:OK'] + comment: '' + execution time: 0.0 + expected result: '1.target1下设置ssid 和pwd 、加密方式成功 + + 2.修改target 1的mode 为sta mode + + 3.target1的dhcp打开 + + 4.target1成功连接上AP + + 5.target2上不能查询到target_ssid + + 6.target1断开AP' + initial condition: T2O_1 + initial condition description (auto): same as T2_1 but will NOT autogen a TC with + initial condition T2_2 + level: Integration + module: WIFI MAC + steps: '1.target1下设置ssid 和pwd 加密方式 + + 2.修改target1的mode 为sta mode + + 3.target1的dhcp打开 + + 4.target1连接AP + + 5.target2查询target_ssid + + 6.target1断开AP' + sub module: WIFI Mode + summary: mode switch test (sta mode) + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: wifi mode fucntion + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_MODE_0102 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -S + - [R SSC2 P , R SSC2 C +SCANDONE] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:ERROR'] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:ERROR'] + comment: '' + execution time: 0.0 + expected result: '1. target1 set AP + + 2.target 2 上查询到target_ssid + + 3. target1 can''t join AP + + 4. target1 can''t QAP' + initial condition: T2O_1 + initial condition description (auto): same as T2_1 but will NOT autogen a TC with + initial condition T2_2 + level: Integration + module: WIFI MAC + steps: '1.target1下设置ssid 和pwd 加密方式 + + 2.target 2 上查询target_ssid + + 3.target1 join AP + + 4.target1 DISCONN AP' + sub module: WIFI Mode + summary: mode switch test (AP mode) + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: wifi mode fucntion + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_MODE_0103 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -S -o 1 + - ['R SSC1 C +DHCP:STA,OK'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC2 sta -S + - [R SSC2 P , R SSC2 C +SCANDONE] + comment: '' + execution time: 0.0 + expected result: '1.target1 change to AP mode + + 2.target1 set AP + + 3.target 1 的dhcp 打开 + + 4.target 1 成功连接上AP + + 5.target 2 上查询到target_ssid' + initial condition: T2O_1 + initial condition description (auto): same as T2_1 but will NOT autogen a TC with + initial condition T2_2 + level: Integration + module: WIFI MAC + steps: '1.target1 change to AP mode + + 2.target1下设置ssid 和pwd 加密方式 + + 3.target1 的dhcp 打开 + + 4.target1 连接AP + + 5.target2 上查询target_ssid' + sub module: WIFI Mode + summary: mode switch test (STA+AP mode) + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: wifi mode fucntion + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0401 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 20 + - ['R SSC2 C +PHY:OK'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC2 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC1 NC +JAP:DISCONNECTED', 'P SSC2 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: 3. SoftAP and STA in channel2, both bandwidth 20M, STA not disconnected + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration + module: WIFI MAC + steps: '1. SoftAP 11n ht20, in channel1, ext AP 11n ht20, in channel2 + + 2. STA connect to ext AP + + 3. AP get connected' + sub module: Phy Mode + summary: SoftAP ext AP in defferent channel, both bandwidth 20M, STA connect to + AP then Softap get connected + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP initial channel test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0402 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 20 + - ['R SSC2 C +PHY:OK'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC2 NC +JAP:DISCONNECTED', 'P SSC1 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: 3. SoftAP and STA in channel2, both bandwidth 20M, SoftAP not get + disconnected + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration + module: WIFI MAC + steps: '1. SoftAP 11n ht20, in channel1, ext AP 11n ht20, in channel2 + + 2. AP get connected + + 3. STA connect to ext AP' + sub module: Phy Mode + summary: SoftAP ext AP in defferent channel, both bandwidth 20M, Softap get connected + than STA connect to AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP initial channel test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0403 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 20 + - ['R SSC2 C +PHY:OK'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC2 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC1 NC +JAP:DISCONNECTED', 'P SSC2 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: 3. SoftAP and STA in channel2, SoftAP 20M, STA 40M, STA not disconnected + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration + module: WIFI MAC + steps: '1. SoftAP 11n ht20, in channel1, ext AP 11n ht40, in channel2 + + 2. STA connect to ext AP + + 3. AP get connected' + sub module: Phy Mode + summary: SoftAP ext AP in defferent channel, SoftAP 20M, ext AP 40M, STA connect + to AP then Softap get connected + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP initial channel test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0404 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 20 + - ['R SSC2 C +PHY:OK'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC2 NC +JAP:DISCONNECTED', 'P SSC1 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: 3. SoftAP and STA in channel2, SoftAP 20M, STA 40M, SoftAP not + get disconnected + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration + module: WIFI MAC + steps: '1. SoftAP 11n ht20, in channel1, ext AP 11n ht40, in channel2 + + 2. AP get connected + + 3. STA connect to ext AP' + sub module: Phy Mode + summary: SoftAP ext AP in defferent channel, SoftAP 20M, ext AP 40M, Softap get + connected than STA connect to AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP initial channel test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0405 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 40 + - ['R SSC2 C +PHY:OK'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC2 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC1 NC +JAP:DISCONNECTED', 'P SSC2 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: 3. SoftAP and STA in channel2, both bandwidth 40M, STA not disconnected + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration + module: WIFI MAC + steps: '1. SoftAP 11n ht40, in channel1, ext AP 11n ht40, in channel2 + + 2. STA connect to ext AP + + 3. AP get connected' + sub module: Phy Mode + summary: SoftAP ext AP in defferent channel, both bandwidth 40M, STA connect to + AP then Softap get connected + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP initial channel test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0406 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 40 + - ['R SSC2 C +PHY:OK'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC2 NC +JAP:DISCONNECTED', 'P SSC1 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: 3. SoftAP and STA in channel2, both bandwidth 40M, SoftAP not get + disconnected + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration + module: WIFI MAC + steps: '1. SoftAP 11n ht40, in channel1, ext AP 11n ht40, in channel2 + + 2. AP get connected + + 3. STA connect to ext AP' + sub module: Phy Mode + summary: SoftAP ext AP in defferent channel, both bandwidth 40M, Softap get connected + than STA connect to AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP initial channel test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0407 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 40 + - ['R SSC2 C +PHY:OK'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC2 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC1 NC +JAP:DISCONNECTED', 'P SSC2 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: 3. SoftAP and STA in channel2, SoftAP 40M, STA 20M, STA not disconnected + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration + module: WIFI MAC + steps: '1. SoftAP 11n ht40, in channel1, ext AP 11n ht20, in channel2 + + 2. STA connect to ext AP + + 3. AP get connected' + sub module: Phy Mode + summary: SoftAP ext AP in defferent channel, SoftAP 40M, ext AP 20M, STA connect + to AP then Softap get connected + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP initial channel test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0408 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 phy -S -o 1 -m n -b 40 + - ['R SSC2 C +PHY:OK'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC2 NC +JAP:DISCONNECTED', 'P SSC1 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: 3. SoftAP and STA in channel2, SoftAP 40M, STA 20M, SoftAP not + get disconnected + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration + module: WIFI MAC + steps: '1. SoftAP 11n ht40, in channel1, ext AP 11n ht20, in channel2 + + 2. AP get connected + + 3. STA connect to ext AP' + sub module: Phy Mode + summary: SoftAP ext AP in defferent channel, SoftAP 40M, ext AP 20M, Softap get + connected than STA connect to AP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP initial channel test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0501 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC3 sta -C -s -p + - ['R SSC3 C +JAP:CONNECTED'] + - - SSC SSC2 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC2 C +JAP:CONNECTED', 'P SSC[1,3] NC +JAP:DISCONNECTED'] + comment: '' + execution time: 0.0 + expected result: 4. all STA not get disconnected; target 1 SoftAP and STA both in + channel2 20M + initial condition: T3_PHY1 + initial condition description (auto): '1. target 1 and target 2 set to AP+STA mode, + target 3 set to STA mode + + 2. all interface of target 2,3 set to 11n ht40 + + 3. config softAP of target 1 and target 2' + level: Integration + module: WIFI MAC + steps: '1. target 1 STA and SoftAP set to 20M + + 2. target 2 STA connect to ap_channel1_20 + + 3. target 1/3 STA connect to target 2/1 SoftAP + + 4. target 2 STA connect to ap_channel2_20' + sub module: Phy Mode + summary: SoftAP STA in channel1 20M, STA changed to channel2 20M + test environment: SSC_T3_PhyMode + test environment description (auto): '3 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with (HT20, channel1), (HT20, channel2), (HT40, channel1), (HT40, channel2). + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP dynamic channel switch test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0502 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC3 sta -C -s -p + - ['R SSC3 C +JAP:CONNECTED'] + - - SSC SSC2 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC2 C +JAP:CONNECTED', 'P SSC[1,3] NC +JAP:DISCONNECTED'] + comment: '' + execution time: 0.0 + expected result: 4. all STA not get disconnected; target 1 SoftAP and STA both in + channel2; SoftAP in 20M, STA in 40M + initial condition: T3_PHY1 + initial condition description (auto): '1. target 1 and target 2 set to AP+STA mode, + target 3 set to STA mode + + 2. all interface of target 2,3 set to 11n ht40 + + 3. config softAP of target 1 and target 2' + level: Integration + module: WIFI MAC + steps: '1. target 1 STA set to 40M, SoftAP set to 20M + + 2. target 2 STA connect to ap_channel1_20 + + 3. target 1/3 STA connect to target 2/1 SoftAP + + 4. target 2 STA connect to ap_channel2_40' + sub module: Phy Mode + summary: SoftAP STA in channel1 20M, STA changed to channel2 40M + test environment: SSC_T3_PhyMode + test environment description (auto): '3 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with (HT20, channel1), (HT20, channel2), (HT40, channel1), (HT40, channel2). + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP dynamic channel switch test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0503 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC3 sta -C -s -p + - ['R SSC3 C +JAP:CONNECTED'] + - - SSC SSC2 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC2 C +JAP:CONNECTED', 'P SSC[1,3] NC +JAP:DISCONNECTED'] + comment: '' + execution time: 0.0 + expected result: 4. all STA not get disconnected; target 1 SoftAP and STA both in + channel2 20M + initial condition: T3_PHY1 + initial condition description (auto): '1. target 1 and target 2 set to AP+STA mode, + target 3 set to STA mode + + 2. all interface of target 2,3 set to 11n ht40 + + 3. config softAP of target 1 and target 2' + level: Integration + module: WIFI MAC + steps: '1. target 1 STA set to 40M, SoftAP set to 20M + + 2. target 2 STA connect to ap_channel1_40 + + 3. target 1/3 STA connect to target 2/1 SoftAP + + 4. target 2 STA connect to ap_channel2_20' + sub module: Phy Mode + summary: SoftAP STA in channel1, SoftAP 20M, STA 40M, STA changed to channel2 20M + test environment: SSC_T3_PhyMode + test environment description (auto): '3 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with (HT20, channel1), (HT20, channel2), (HT40, channel1), (HT40, channel2). + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP dynamic channel switch test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0504 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC3 sta -C -s -p + - ['R SSC3 C +JAP:CONNECTED'] + - - SSC SSC2 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC2 C +JAP:CONNECTED', 'P SSC[1,3] NC +JAP:DISCONNECTED'] + comment: '' + execution time: 0.0 + expected result: 4. all STA not get disconnected; target 1 SoftAP and STA both in + channel2 20M + initial condition: T3_PHY1 + initial condition description (auto): '1. target 1 and target 2 set to AP+STA mode, + target 3 set to STA mode + + 2. all interface of target 2,3 set to 11n ht40 + + 3. config softAP of target 1 and target 2' + level: Integration + module: WIFI MAC + steps: '1. target 1 STA and SoftAP set to 40M + + 2. target 2 STA connect to ap_channel1_40 + + 3. target 1/3 STA connect to target 2/1 SoftAP + + 4. target 2 STA connect to ap_channel2_20' + sub module: Phy Mode + summary: SoftAP STA in channel1, SoftAP 20M, STA 40M, STA changed to channel2 40M + test environment: SSC_T3_PhyMode + test environment description (auto): '3 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with (HT20, channel1), (HT20, channel2), (HT40, channel1), (HT40, channel2). + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP dynamic channel switch test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0505 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC3 sta -C -s -p + - ['R SSC3 C +JAP:CONNECTED'] + - - SSC SSC2 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC2 C +JAP:CONNECTED', 'P SSC[1,3] NC +JAP:DISCONNECTED'] + comment: '' + execution time: 0.0 + expected result: 4. all STA not get disconnected; target 1 SoftAP and STA both in + channel2; SoftAP in 20M, STA in 40M + initial condition: T3_PHY1 + initial condition description (auto): '1. target 1 and target 2 set to AP+STA mode, + target 3 set to STA mode + + 2. all interface of target 2,3 set to 11n ht40 + + 3. config softAP of target 1 and target 2' + level: Integration + module: WIFI MAC + steps: '1. target 1 STA set to 40M ,SoftAP set to 20M + + 2. target 2 STA connect to ap_channel1_40 + + 3. target 1/3 STA connect to target 2/1 SoftAP + + 4. target 2 STA connect to ap_channel2_20' + sub module: Phy Mode + summary: SoftAP STA in channel1, SoftAP 40M, STA 40M, STA changed to channel2 20M + test environment: SSC_T3_PhyMode + test environment description (auto): '3 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with (HT20, channel1), (HT20, channel2), (HT40, channel1), (HT40, channel2). + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP dynamic channel switch test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_PHY_0506 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 phy -S -o 2 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC3 sta -C -s -p + - ['R SSC3 C +JAP:CONNECTED'] + - - SSC SSC2 sta -C -s -p + - [''] + - - DELAY 10 + - ['P SSC2 C +JAP:CONNECTED', 'P SSC[1,3] NC +JAP:DISCONNECTED'] + comment: '' + execution time: 0.0 + expected result: 4. all STA not get disconnected; target 1 SoftAP and STA both in + channel2 40M + initial condition: T3_PHY1 + initial condition description (auto): '1. target 1 and target 2 set to AP+STA mode, + target 3 set to STA mode + + 2. all interface of target 2,3 set to 11n ht40 + + 3. config softAP of target 1 and target 2' + level: Integration + module: WIFI MAC + steps: '1. target 1 STA and SoftAP set to 40M + + 2. target 2 STA connect to ap_channel1_40 + + 3. target 1/3 STA connect to target 2/1 SoftAP + + 4. target 2 STA connect to ap_channel2_40' + sub module: Phy Mode + summary: SoftAP STA in channel1, SoftAP 40M, STA 40M, STA changed to channel2 40M + test environment: SSC_T3_PhyMode + test environment description (auto): '3 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with (HT20, channel1), (HT20, channel2), (HT40, channel1), (HT40, channel2). + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: STA+SoftAP dynamic channel switch test + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_SCAN_0101 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC2 sta -S -s .,juhg123 + - ['R SSC2 NC +SCAN: C +SCANDONE'] + - - SSC SSC1 ap -S -s -p 123456789 -t 3 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -S -s + - ['R SSC2 C +SCAN:', R SSC2 P , 'R SSC2 NC +SCAN: C +SCANDONE'] + comment: '' + execution time: 0.0 + expected result: '1.target 2上不能scan .,juhg123 + + 2.target1 set AP + + 3.target2上查询到' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + level: Integration + module: WIFI MAC + steps: '1.target 2 scan .,juhg123 + + 2.target1下设置ssid 和pwd 加密方式 + + 3.target2 scan ' + sub module: WIFI Scan + summary: scan with scan config ssid + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: scan with different config + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_SCAN_0102 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC2 sta -S -b ff:ff:ff:ff:ff:11 + - ['R SSC2 NC +SCAN: C +SCANDONE'] + - - SSC SSC2 sta -S -b + - ['R SSC2 RE "\+SCAN:.+,%%s"%%()', 'R SSC2 NC +SCAN: C +SCANDONE'] + comment: '' + execution time: 0.0 + expected result: '1.target2 上不能查询到此mac + + 2.target2上查询到' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + level: Integration + module: WIFI MAC + steps: '1.target2 上查询此macff:ff:ff:ff:ff:11 + + 2.target2上查询' + sub module: WIFI Scan + summary: scan with scan config bssid + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: scan with different config + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_SCAN_0103 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:'] + - - SSC SSC1 ap -S -s -p 123456789 -t 3 -n 6 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -S -n 5 + - [R SSC2 NP C +SCANDONE] + - - SSC SSC2 sta -S -n 6 + - ['R SSC2 C +SCAN:', R SSC2 P ] + comment: '' + execution time: 0.0 + expected result: '1.target1 QAP + + 2. target1 set AP,set channel 6 + + 3.target2 上scan不到 channel 5 + + 4.target2 上查询channel 6的' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + level: Integration + module: WIFI MAC + steps: '1.target1 断开连接AP + + 2.target1下设置ssid 和pwd 加密方式,set channel 6 + + 3.target2 上scan channel 5 + + 4.target2 上查询channel 6的' + sub module: WIFI Scan + summary: scan with scan config channel + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: scan with different config + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_SCAN_0104 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p 123456789 -t 3 -h 0 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -S -h 0 + - [R SSC2 P C +SCANDONE] + - - SSC SSC2 sta -S -h 1 + - [R SSC2 P C +SCANDONE] + - - SSC SSC1 ap -S -s -p 123456789 -h 1 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -S -h 0 + - [R SSC2 NP C +SCANDONE] + - - SSC SSC2 sta -S -h 1 + - [R SSC2 P C +SCANDONE] + comment: '' + execution time: 0.0 + expected result: '1.target1 set AP,set ssid broad cast + + 2.target 2上scan + + 3.target 2上scan + + 4.target1 set AP,set ssid hidden, + + 5.target 2上不能查询到 + + 6.target 2上查询到' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + level: Integration + module: WIFI MAC + steps: '1.target1下设置ssid 和pwd 加密方式,set ssid broad cast + + 2.target 2上scan + + 3.target 2上scan + + 4.target1下设置ssid 和pwd 加密方式,set ssid hidden, + + 5.target 2上查询 + + 6.target 2上查询' + sub module: WIFI Scan + summary: scan with scan config show hidden + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: scan with different config + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_SCAN_0105 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:'] + - - SSC SSC1 ap -S -s -p 123456789 -t 3 -h 0 -n 11 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -S -s -b -n 11 + - [R SSC2 P C +SCANDONE] + - - SSC SSC2 sta -S -s -b -n 11 + - [R SSC2 NP C +SCANDONE] + - - SSC SSC2 sta -S -s -b ff:ff:ff:ff:ff:11 -n 11 + - [R SSC2 P , R SSC2 NP C +SCANDONE] + - - SSC SSC2 sta -S -s -b -n 10 + - [R SSC2 P , R SSC2 NP C +SCANDONE] + comment: '' + execution time: 0.0 + expected result: '1.target1 QAP + + 2. target1 set AP,set ssid broad cast,set channel 11 + + 3.target2 上查询到 + + 4.target2 上查询不到 + + 5.target2 上查询不到 + + 6.target2 上查询不到' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + level: Integration + module: WIFI MAC + steps: '1.target1 QAP + + 2. target1 set AP,set ssid broad cast,set channel 11 + + 3.target2 上查询到 + + 4.target2 上查询不到 + + 5.target2 上查询不到 + + 6.target2 上查询不到' + sub module: WIFI Scan + summary: scan with several configs + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: scan with different config + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_SCAN_0201 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 phy -S -o 1 -m b + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 sta -S + - [R SSC1 P P P P ] + - - SSC SSC1 phy -S -o 1 -m g + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 sta -S + - [R SSC1 P P P P ] + - - SSC SSC1 phy -S -o 1 -m n -b 20 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 sta -S + - [R SSC1 P P P P ] + - - SSC SSC1 phy -S -o 1 -m n -b 40 + - ['R SSC1 C +PHY:OK'] + - - SSC SSC1 sta -S + - [R SSC1 P P P P ] + comment: '' + execution time: 0.0 + expected result: '3. find all 3 ext APs + + 5. find all 3 ext APs + + 7. find all 3 ext APs + + 9. find all 3 ext APs' + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + level: Integration + module: WIFI MAC + steps: '1. 3 ext APs in 11b, 11g, 11n mode + + 2. STA in 11b mode + + 3. do all channel scan + + 4. STA in 11g mode + + 5. do all channel scan + + 6. STA in 11n ht20 mode + + 7. do all channel scan + + 8. STA in 11n ht40 mode + + 9. do all channel scan' + sub module: WIFI Scan + summary: STA in differnt PHY mode to scan AP in different PHY mode + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: basic function + test point 2: Scan in different mode and channel + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_SCAN_0301 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -S + - [''] + - - SSC SSC1 sta -S + - [P SSC1 C +SCANFAIL, 'P SSC1 P +SCAN:', R SSC1 C +SCANDONE] + comment: '' + execution time: 0.0 + expected result: '1. second scan failed + + 2. first scan succeed' + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 + level: Integration + module: WIFI MAC + steps: '1. do all channel scan + + 2. do scan before scan finished' + sub module: WIFI Scan + summary: reject scan request before scan finished + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: interaction + test point 2: Scan interact with other WiFi operation + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_SCAN_0302 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -n 1000000 -j 5 + - [''] + - - SSC SSC2 phy -S -o 1 -m b + - ['R SSC2 C +PHY:OK'] + - - SSC SSC2 sta -S -n + - [R SSC2 P ] + - - SSC SSC2 phy -S -o 1 -m g + - ['R SSC2 C +PHY:OK'] + - - SSC SSC2 sta -S -n + - [R SSC2 P ] + - - SSC SSC2 phy -S -o 1 -m n -b 20 + - ['R SSC2 C +PHY:OK'] + - - SSC SSC2 sta -S -n + - [R SSC2 P ] + - - SSC SSC2 phy -S -o 1 -m n -b 40 + - ['R SSC2 C +PHY:OK'] + - - SSC SSC2 sta -S -n + - [R SSC2 P ] + comment: '' + execution time: 0.0 + expected result: 3. target 2 able to scan AP + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration + module: WIFI MAC + steps: '1. target 1 connect to AP + + 2. target 1 start sending UDP packets + + 3. target 2 scan in AP channel in 11b.g,n,ht40 mode' + sub module: WIFI Scan + summary: scan in congest channel + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: interaction + test point 2: Scan interact with other WiFi operation + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_SCAN_0303 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:OK'] + - - SSC SSC1 sta -S + - [P SSC1 C +SCANDONE, 'P SSC1 C +JAP:CONNECTED'] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:OK'] + - - SSC SSC1 sta -S + - [''] + - - SSC SSC1 sta -C -s -p + - [P SSC1 C +SCANDONE, 'P SSC1 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: '2. scan succeed, JAP succeed + + 5. JAP succeed, scan succeed' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration + module: WIFI MAC + steps: '1. target 1 STA join AP + + 2. target 1 STA scan before JAP succeed + + 3. target 1 quite AP + + 4. target 1 scan + + 5. target 1 JAP before scan succeed' + sub module: WIFI Scan + summary: scan during JAP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: interaction + test point 2: Scan interact with other WiFi operation + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: WIFI_SCAN_0304 + SDK: ESP32_IDF + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:OK'] + - - SSC SSC1 sta -S + - [P SSC1 C +SCANDONE, 'P SSC2 C +JAP:CONNECTED'] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:OK'] + - - SSC SSC1 sta -S + - [''] + - - SSC SSC2 sta -C -s -p + - [P SSC1 C +SCANDONE, 'P SSC2 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: '2. scan succeed, JAP succeed + + 5. JAP succeed, scan succeed' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration + module: WIFI MAC + steps: '1. target 2 STA join target 1 SoftAP + + 2. target 1 STA scan before target 2 JAP succeed + + 3. target 2 STA QAP + + 4. target 1 STA scan + + 5. target 2 STA JAP before target 1 STA scan succeed' + sub module: WIFI Scan + summary: scan during ext STA join SoftAP + test environment: SSC_T2_PhyMode + test environment description (auto): '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.' + test point 1: interaction + test point 2: Scan interact with other WiFi operation + version: v1 (2015-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_DHCP_0101 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 dhcp -E -o 1 + - ['R SSC1 C +DHCP:STA,OK'] + - - SSC SSC1 ip -S -i 0.0.0.0 + - ['R SSC1 C +IP:OK'] + - - SSC SSC1 sta -C -s -p + - [''] + - - DELAY 20 + - [P PC_COM C +DELAYDONE, 'P SSC1 NC +JAP:CONNECTED'] + - - SSC SSC1 dhcp -S -o 1 + - ['R SSC1 C +DHCP:STA,OK'] + - - SSC SSC1 ip -Q + - ['R SSC1 C +STAIP:0.0.0.0'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC1 ip -Q + - ['R SSC1 RE "\+STAIP:%%s"%%()'] + comment: '' + execution time: 0.0 + expected result: "1.target1 关闭DHCP OK\n2.target1 设置ip add OK\n3.target1 连接AP fail\n\ + 4.target1 打开DHCP OK\n5.查询到sta ip \n6.target1 连接AP ok\n7.查询到sta ip 为target_ip" + initial condition: STAAP1 + initial condition description (auto): testing sta on sta + ap mode, quit AP (autogen + by STAM1) + level: Integration + module: TCPIP + steps: "1.target1 关闭DHCP OK\n2.target1 设置ip add OK\n3.target1 连接AP fail\n4.target1\ + \ 打开DHCP OK\n5.查询到sta ip \n6.target1 连接AP ok\n7.查询到sta ip 为target_ip" + sub module: DHCP + summary: dhcp client function test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP client function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_DHCP_0102 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC2 sta -C -s -p + - [''] + - - DELAY 20 + - [P PC_COM C +DELAYDONE, 'P SSC2 NC +JAP:CONNECTED'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: "1.target1 set AP OK \n2.target1 关闭DHCP OK\n3.target2 jap target\ + \ 1,FAIL \n4.target1 打开DHCP OK\n5.target2 jap target 1,ok" + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration + module: TCPIP + steps: "1.target1 set AP OK \n2.target1 关闭DHCP OK\n3.target2 jap target 1,FAIL \n\ + 4.target1 打开DHCP OK\n5.target2 jap target 1,ok" + sub module: DHCP + summary: dhcp server function test + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP client function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_DHCP_0103 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 3 + - ['R SSC1 C +DHCP:AP,OK C +DHCP:STA,OK'] + - - SSC SSC1 dhcp -Q -o 3 + - ['R SSC1 C +DHCP:STA,STARTED C +DHCP:AP,STARTED'] + - - SSC SSC1 dhcp -Q -o 1 + - ['R SSC1 C +DHCP:STA,STARTED NC +DHCP:AP,STARTED'] + - - SSC SSC1 dhcp -Q -o 2 + - ['R SSC1 NC +DHCP:STA,STARTED C +DHCP:AP,STARTED'] + - - SSC SSC1 dhcp -E -o 3 + - ['R SSC1 C +DHCP:AP,OK C +DHCP:STA,OK'] + - - SSC SSC1 dhcp -Q -o 3 + - ['R SSC1 C +DHCP:STA,STOPPED C +DHCP:AP,STOPPED'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.STA&AP STARTED + + 4.STA STARTED + + 5.AP STARTED + + 6.OK + + 7.STA&AP STOPPED' + initial condition: STAAP1 + initial condition description (auto): testing sta on sta + ap mode, quit AP (autogen + by STAM1) + level: Integration + module: TCPIP + steps: '1.target1 设置mode 为sta+softAP mode + + 2.target1 打开DHCP 3 + + 3.target1 查询DHCP 状态 + + 4.target1 查询sta DHCP 状态 + + 5.target1 查询softAP DHCP 状态 + + 6.target1 关闭 DHCP 3 + + 7.target1 查询 DHCP 状态' + sub module: DHCP + summary: dhcp status query + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP client function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_DHCP_0201 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 ip -S -o 2 -i + - ['R SSC1 C +IP:OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.1 -e 192.168.4.10 + - ['R SSC1 C +DHCP:LEASE,ERROR'] + - - SSC SSC1 dhcp -L -s 192.168.4.5 -e 192.168.4.2 + - ['R SSC1 C +DHCP:LEASE,ERROR'] + - - SSC SSC1 dhcp -L -s 192.168.2.2 -e 192.168.2.5 + - ['R SSC1 C +DHCP:LEASE,ERROR'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + comment: '' + execution time: 0.0 + expected result: '1.target1 关闭DHCP 2 OK + + 2.target1 设置ip 成功 + + 3.设置dhcp 地址池 OK + + 4.ERROR + + 5.ERROR + + 6.ERROR + + 7.target1 打开DHCP ok' + initial condition: APSTA1 + initial condition description (auto): testing ap on sta + ap mode (autogen by APM1) + level: Integration + module: TCPIP + steps: "1.target1 关闭DHCP 2 \n2.target1 设置ip \n3.设置dhcp 地址池\n4.设置dhcp错误的参数\n5.设置dhcp错误的参数\n\ + 6.设置dhcp错误的参数\n7.target1 打开DHCP ok" + sub module: DHCP + summary: server dhcp lease test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_DHCP_0202 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - LOOP 3 4 "['01','02','03']" "[2,3,4]" + - [''] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:OK'] + - - SSC SSC2 mac -S -o 1 -m 10:22:33:44:55:{%s} + - ['R SSC2 C +MAC:STA,OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC2 ip -Q -o 1 + - ['R SSC2 C +STAIP:192.168.4.{%s}'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3,4: get IP from dhcp pool with correct sequence' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration + module: TCPIP + steps: '1. config softap to a random ssid + + 2. config DHCP Server on Target1 + + 3. target change mac, connect to Target1 + + 4. Loop step3' + sub module: DHCP + summary: dhcp server ip pool + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_DHCP_0203 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.3 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - LOOP 2 4 "['01','02']" "[2,3]" + - [''] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:OK'] + - - SSC SSC2 mac -S -o 1 -m 10:22:33:44:55:{%s} + - ['R SSC2 C +MAC:STA,OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC2 ip -Q -o 1 + - ['R SSC2 C +STAIP:192.168.4.{%s}'] + - - SSC SSC2 mac -S -o 1 -m 10:22:33:44:55:66 + - ['R SSC2 C +MAC:STA,OK'] + - - DELAY 20 + - [''] + - - SSC SSC2 ip -Q -o 1 + - ['R SSC2 C +STAIP:0.0.0.0'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. succeed + + 4.1 succeed + + 4.2 failed' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration + module: TCPIP + steps: '1. config softap to a random ssid + + 2. config DHCP Server on Target1(.4.2 - .4.3) + + 3. target change mac, connect to Target1 + + 4. Loop step3 twice' + sub module: DHCP + summary: dhcp server ip pool empty + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_DHCP_0204 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.3 -t 1 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC2 ip -Q -o 1 + - ['R SSC2 C +STAIP:192.168.4.2'] + - - DELAY 90 + - [''] + - - SSC SSC2 ip -Q -o 1 + - ['R SSC2 C +STAIP:192.168.4.2'] + - - SSC SSC2 sta -D + - ['R SSC2 C +JAP:DISCONNECTED'] + - - DELAY 60 + - [''] + - - SSC SSC2 mac -S -o 1 -m 10:22:33:44:55:66 + - ['R SSC2 C +MAC:STA,OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC2 ip -Q -o 1 + - ['R SSC2 C +STAIP:192.168.4.2'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. get IP 192.168.4.2 + + 5. succeed + + 6. succeed + + 8. get IP 192.168.4.2' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration + module: TCPIP + steps: '1. config softap to a random ssid + + 2. config DHCP timeout as 1 minute + + 3. target2 connect to target1 + + 4. wait 90 seconds + + 5. check if target2 IP is same + + 6. target2 disconnect + + 7. wait 60s + + 8. target2 change mac and connect to target1' + sub module: DHCP + summary: dhcp server timeout test + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_DHCP_0205 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.3 -t 1 + - ['P SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['P SSC1 C +DHCP:AP,OK', 'P SSC2 C +JAP:DISCONNECTED'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. target2 wifi disconnected' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration + module: TCPIP + steps: '1. config softap to a random ssid + + 2. target2 connect to target1 + + 3. disable DHCP server, do config and enable' + sub module: DHCP + summary: disconnect STA if config dhcp server + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_DHCP_0206 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - LOOP 4 4 "['01','02','03','01']" "[2,3,4,2]" + - [''] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:OK'] + - - SSC SSC2 mac -S -o 1 -m 10:22:33:44:55:{%s} + - ['R SSC2 C +MAC:STA,OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC2 ip -Q -o 1 + - ['R SSC2 C +STAIP:192.168.4.{%s}'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 4. get IP 192.168.4.2 - 192.168.4.4 + + 5. get IP 192.168.4.2' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration + module: TCPIP + steps: '1. config softap to a random ssid + + 2. disable DHCP server, do config and enable + + 3. target2 change mac, connect to softap, disconnect + + 4. Loop step3 twice + + 5. change to first mac, connect to softap' + sub module: DHCP + summary: dhcp server assign same IP to same MAC when it's not released + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_DHCP_0207 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - WIFI CONN 192.168.4.2 + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - WIFI DISCONN2 + - ['R PC_COM NC ERROR C +WIFIDISCONN:OK'] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:OK'] + - - SSC SSC2 mac -S -o 1 -m 10:22:33:44:55:66 + - ['R SSC2 C +MAC:STA,OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC2 ip -Q -o 1 + - ['R SSC2 C +STAIP:192.168.4.2'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. get IP 192.168.4.2 + + 4. succeed + + 5. succeed + + 6. get IP 192.168.4.2' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration + module: TCPIP + steps: '1. config softap to a random ssid + + 2. disable DHCP server, do config and enable + + 3. PC WIFI NIC connect to target1 softap + + 4. target2 connect to target1 softap and disnnect + + 5. PC release IP and disconnected + + 6. target2 change mac and connect to target1' + sub module: DHCP + summary: dhcp server prefer assign released IP to new client + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_DHCP_0208 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['P SSC1 C +DHCP:AP,OK', 'P SSC2 C +JAP:DISCONNECTED'] + - - SSC SSC2 sta -D + - ['R SSC2 C +JAP:DISCONNECTED'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - WIFI CONN 192.168.4.2 + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - SSC SSC1 ap -L + - [R SSC1 C 192.168.4.2 P ] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. succeed + + 4. get IP 192.168.4.2 + + 5. can only find target2 with IP 192.168.4.2' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration + module: TCPIP + steps: '1. config softap to a random ssid + + 2. PC NIC connect to target1 softap + + 3. disable DHCP server, do config and enable + + 4. target2 connect to target1 softap + + 5. softap list connected station' + sub module: DHCP + summary: dhcp server reconfig and new client able to get first IP in pool + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_DHCP_0209 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - WIFI CONN 192.168.4.2 + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - DELAY 20 + - [''] + - - SSC SSC1 ap -L + - [R SSC1 C 192.168.4.2 C 192.168.4.3 P P ] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. succeed + + 4. succeed + + 5. find target2 and PC' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration + module: TCPIP + steps: '1. config softap to a random ssid + + 2. target2 connect to target1 softap + + 3. disable DHCP server, do config and enable + + 4. PC NIC connect to target1 softap + + 5. softap list connected station' + sub module: DHCP + summary: dhcp server reconfig, old client and new client able to get IP + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_DHCP_0210 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - WIFI CONN2 192.168.4.2 + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - SSC SSC1 ap -L + - [R SSC1 C 192.168.4.2 C 192.168.4.3 P P ] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. succeed + + 4. succeed + + 5. find target2 and PC' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration + module: TCPIP + steps: '1. config softap to a random ssid + + 2. target2 connect to target1 softap + + 3. disable DHCP server, do config and enable + + 4. PC NIC connect to target1 softap try to renew IP 192.168.4.2 + + 5. softap list connected station' + sub module: DHCP + summary: dhcp server reconfig, old client able to get IP (discover with requested + IP) + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_DHCP_0211 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 4 + - ['R SSC1 C +SAP:OK'] + - - WIFI CONN 192.168.4.2 + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - DELAY 10 + - [''] + - - SSC SSC1 ap -L + - [R SSC1 C 192.168.4.2 C 192.168.4.3 P P ] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. succeed + + 4. succeed + + 5. find target2 and PC' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration + module: TCPIP + steps: '1. config softap to a random ssid + + 2. target2 connect to target1 softap + + 3. disable DHCP server, do config and enable + + 4. PC NIC connect to target1 softap try to renew IP 192.168.4.2 + + 5. softap list connected station' + sub module: DHCP + summary: dhcp server reconfig, old client able to renew IP (direct send request) + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_DHCP_0301 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 dhcp -E -o 1 + - ['R SSC1 C +DHCP:STA,OK'] + - - SSC SSC1 ip -S -i 192.168.123.123 -o 1 + - ['R SSC1 C +IP:OK'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC1 ip -S -i 0.0.0.0 -o 1 + - ['R SSC1 C +IP:OK'] + - - SSC SSC1 sta -C -s -p + - [''] + - - DELAY 10 + - [P PC_COM C +DELAYDONE, 'P SSC1 NC +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.JAP CONNETED + + 4.OK + + 5.等待10s,JAP fail' + initial condition: STAAP1 + initial condition description (auto): testing sta on sta + ap mode, quit AP (autogen + by STAM1) + level: Integration + module: TCPIP + steps: '1.target1 关闭DHCP 1 + + 2.target1 设置sta ip 192.168.123.123 + + 4.target1 jap AP + + 5.target1 设置sta ip 0.0.0.0 + + 6.target1 jap AP' + sub module: DHCP + summary: sta dhcp static ip interaction + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: interaction + test point 2: static IP and DHCP interaction test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_DHCP_0302 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 ip -S -i 192.168.123.123 -o 2 + - ['R SSC1 C +IP:ERROR'] + - - SSC SSC1 dhcp -L -s 192.168.2.2 -e 192.168.2.10 + - ['R SSC1 C +DHCP:LEASE,ERROR'] + - - SSC SSC1 ap -S -s -p -t + - [''] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 ip -S -i 192.168.4.1 -o 2 + - ['R SSC1 C +IP:OK'] + - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.10 + - ['R SSC1 C +DHCP:LEASE,OK'] + - - SSC SSC2 sta -C -s -p + - [''] + - - DELAY 10 + - [P PC_COM C +DELAYDONE, 'P SSC2 NC +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: '1.target 1 OK + + 2.target1 ERROR + + 3.target1 ERROR + + 4.target2 jap target1 OK + + 5.target1 OK + + 6.target1 OK + + 7.target1 OK + + 8.target2 jap target1 OK' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration + module: TCPIP + steps: "1.target1 打开DHCP 2\n2.target1 设置softAP ip 192.168.123.123\n3.target1 设置地址池\n\ + 4.target1下设置ssid 和pwd 加密方式\n5.target2 连接target1 \n6.target1 关闭DHCP 2\n7.target1\ + \ 设置softAP ip \n8.target1 设置正确的地址池\n9.target2 连接target1" + sub module: DHCP + summary: ap dhcp static ip interaction + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: interaction + test point 2: static IP and DHCP interaction test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_DNS_0101 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: 3/5 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -H -d iot.espressif.cn + - ['R SSC1 C +HOSTIP:OK,115.29.202.58'] + comment: '' + execution time: 0.0 + expected result: 1.OK + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration + module: TCPIP + steps: 1. get host name "espressif.cn" + sub module: DNS + summary: get host by name test + test environment: SSC_T1_2 + test environment description (auto): 'Able to access WAN after connect to AP. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DNS function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_DNS_0102 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: 3/5 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -H -d iot.espressif.cn + - ['R SSC1 A :\+HOSTIP:OK,(.+)\r\n'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :\+BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p 9001 + - ['R SSC1 RE \+CONNECT:\d+,OK'] + - - SSC SSC1 soc -S -s -l 10 + - ['P SSC1 RE \+SEND:\d+,OK', P SSC1 SL +10] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration + module: TCPIP + steps: '1. get host name "espressif.cn" + + 2. connect, send, recv1. get host name "espressif.cn" + + 2. connect, send, recv' + sub module: DNS + summary: TCP connect to iot.espressif.com + test environment: SSC_T1_2 + test environment description (auto): 'Able to access WAN after connect to AP. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DNS function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_DNS_0103 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: 3/5 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -H -d iot.espressif.cn + - ['R SSC1 A :\+HOSTIP:OK,(.+)\r\n'] + - - SSC SSC1 soc -B -t UDP + - ['R SSC1 A :\+BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p 9003 -l 10 + - ['P SSC1 RE \+SEND:\d+,OK', P SSC1 SL +10] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration + module: TCPIP + steps: '1. get host name "espressif.cn" + + 2. sendto, recvfrom1. get host name "espressif.cn" + + 2. sendto, recvfrom' + sub module: DNS + summary: UDP send to iot.expressif.com + test environment: SSC_T1_2 + test environment description (auto): 'Able to access WAN after connect to AP. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DNS function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_ICMP_0101 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: 1/5 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ping -i + - ['R SSC1 C +PING:OK'] + - - SSC SSC1 ping -i -c 2 + - ['R SSC1 C +PING:OK'] + comment: '' + execution time: 0.0 + expected result: '1.ok + + 2.ok' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration + module: TCPIP + steps: '1.ping -i + + 2.ping -i -c 2' + sub module: ICMP + summary: ping function test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: ping function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_IGMP_0101 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 igmp -J -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 igmp -L -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 igmp -J -h -m 223.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -J -h -m 240.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -J -h 192.168.237.77 -m 224.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -J -h 192.168.237.77 -m 240.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + comment: '' + execution time: 0.0 + expected result: '1. success + + 2. failed + + 3. failed + + 4. failed' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration + module: TCPIP + steps: '1. join group with correct host addr and multicast addr + + 2. join group with correct host addr and wrong multicast addr + + 3. join group with wrong host addr and correct multicast addr + + 4. join group with wrong host addr and wrong multicast addr' + sub module: IGMP + summary: station IGMP join group address check + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: IGMP API parameter check + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_IGMP_0102 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 igmp -J -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 igmp -L -h -m 224.1.1.2 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -L -h 192.168.237.77 -m 224.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -L -h 192.168.237.77 -m 240.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -L -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + comment: '' + execution time: 0.0 + expected result: '1. success + + 2. failed + + 3. failed + + 4. failed + + 5. succeed' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration + module: TCPIP + steps: '1. join group with correct host addr and multicast addr + + 2. leave group with correct host addr and wrong multicast addr + + 3. leave group with wrong host addr and correct multicast addr + + 4. leave group with wrong host addr and wrong multicast addr + + 5. leave group with correct host addr and correct multicast addr' + sub module: IGMP + summary: station IGMP leave group address check + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: IGMP API parameter check + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_IGMP_0103 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 igmp -J -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 igmp -L -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 igmp -J -h -m 223.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -J -h -m 240.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -J -h 192.168.237.77 -m 224.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -J -h 192.168.237.77 -m 240.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + comment: '' + execution time: 0.0 + expected result: '1. success + + 2. failed + + 3. failed + + 4. failed' + initial condition: APSTA2 + initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen + by APM2) + level: Integration + module: TCPIP + steps: '1. join group with correct host addr and multicast addr + + 2. join group with correct host addr and wrong multicast addr + + 3. join group with wrong host addr and correct multicast addr + + 4. join group with wrong host addr and wrong multicast addr' + sub module: IGMP + summary: softAP IGMP join group address check + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: IGMP API parameter check + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_IGMP_0104 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 igmp -J -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 igmp -L -h -m 224.1.1.2 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -L -h 192.168.237.77 -m 224.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -L -h 192.168.237.77 -m 240.1.1.1 + - ['R SSC1 C +IGMP:ERROR'] + - - SSC SSC1 igmp -L -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + comment: '' + execution time: 0.0 + expected result: '1. success + + 2. failed + + 3. failed + + 4. failed + + 5. succeed' + initial condition: APSTA2 + initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen + by APM2) + level: Integration + module: TCPIP + steps: '1. join group with correct host addr and multicast addr + + 2. leave group with correct host addr and wrong multicast addr + + 3. leave group with wrong host addr and correct multicast addr + + 4. leave group with wrong host addr and wrong multicast addr + + 5. leave group with correct host addr and correct multicast addr' + sub module: IGMP + summary: softAP IGMP leave group address check + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: IGMP API parameter check + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_IGMP_0201 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 igmp -J -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 soc -B -t UDP -i 224.1.1.1 -p + - ['R SSC1 A :\+BIND:(\d+),OK'] + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SOC SOC1 SENDTO 1 224.1.1.1 + - [R SSC1 SL +1] + - - SSC SSC1 igmp -L -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. able to recv packet' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration + module: TCPIP + steps: '1. join group + + 2. create UDP socket using multicast addr + + 3. PC send UDP packet to multicast addr' + sub module: IGMP + summary: station IGMP recv packets + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: IGMP send/recv test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_IGMP_0202 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC2 op -S -o 1 + - ['R SSC2 C +MODE:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 igmp -J -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 soc -B -t UDP -i 224.1.1.1 -p + - ['R SSC1 A :\+BIND:(\d+),OK'] + - - SSC SSC2 soc -B -t UDP -p + - ['R SSC2 A :\+BIND:(\d+),OK'] + - - SSC SSC2 soc -S -s -i 224.1.1.1 -p -l 10 + - [R SSC1 SL +1] + - - SSC SSC1 igmp -L -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. succeed + + 4. target1 recv multicast packet' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration + module: TCPIP + steps: '1. target2 set to sta mode and join AP + + 2. target1 join group and create UDP socket using multicast addr + + 3. target2 create UDP socket + + 4. target2 send to multicast addr' + sub module: IGMP + summary: station send multicast packets + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: IGMP send/recv test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_IGMP_0203 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 igmp -J -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 soc -B -t UDP -i 224.1.1.1 -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SOC SOC1 SENDTO 1 224.1.1.1 + - [R SSC1 SL +1] + - - SSC SSC1 igmp -L -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. able to recv packet' + initial condition: APSTA2 + initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen + by APM2) + level: Integration + module: TCPIP + steps: '1. join group + + 2. create UDP socket using multicast addr + + 3. PC send UDP packet to multicast addr' + sub module: IGMP + summary: softAP IGMP recv packets + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: IGMP send/recv test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_IGMP_0204 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 igmp -J -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + - - SSC SSC1 soc -B -t UDP -i 224.1.1.1 -p + - ['R SSC1 A :\+BIND:(\d+),OK'] + - - SSC SSC2 soc -B -t UDP -p + - ['R SSC2 A :\+BIND:(\d+),OK'] + - - SSC SSC2 soc -S -s -i 224.1.1.1 -p -l 10 + - [R SSC1 SL +1] + - - SSC SSC1 igmp -L -h -m 224.1.1.1 + - ['R SSC1 C +IGMP:OK'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. succeed + + 4. target1 recv multicast packet' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration + module: TCPIP + steps: '1. target2 join SoftAP + + 2. target1 join group and create UDP socket using multicast addr + + 3. target2 create UDP socket + + 4. target2 send to multicast addr' + sub module: IGMP + summary: softAP send multicast packets + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: IGMP send/recv test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_IP_0101 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 dhcp -S -o 1 + - ['R SSC1 C +DHCP:STA,OK'] + - - SSC SSC1 ip -S -o 1 -i 192.168.123.123 + - ['R SSC1 C +IP:ERROR'] + - - SSC SSC1 dhcp -E -o 1 + - ['R SSC1 C +DHCP:STA,OK'] + - - SSC SSC1 ip -S -o 1 -i 192.168.123.123 + - ['R SSC1 C +IP:OK'] + - - SSC SSC1 ip -Q -o 1 + - ['R SSC1 C +STAIP:192.168.123.123'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.ERROR + + 3.OK + + 4.OK + + 5.STAIP:192.168.123.123' + initial condition: STAAP1 + initial condition description (auto): testing sta on sta + ap mode, quit AP (autogen + by STAM1) + level: Integration + module: TCPIP + steps: '1.target1 打开DHCP 1 + + 2.target1 设置sta ip 192.168.123.123 + + 4.target1 关闭DHCP 1 + + 5.target1 设置sta ip 192.168.123.123 + + 6.target1 查询 当前sta ip' + sub module: IP + summary: sta set and query static ip test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: set and query static IP + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_IP_0102 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 ip -S -o 2 -i 192.168.123.123 + - ['R SSC1 C +IP:ERROR'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC1 ip -S -o 2 -i 192.168.123.123 + - ['R SSC1 C +IP:OK'] + - - SSC SSC1 ip -Q -o 2 + - ['R SSC1 C +APIP:192.168.123.123'] + - - SSC SSC1 ip -S -o 2 -i + - ['R SSC1 C +IP:OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.ERROR + + 3.OK + + 4.OK + + 5.APIP:192.168.123.123 + + 6.OK' + initial condition: APSTA1 + initial condition description (auto): testing ap on sta + ap mode (autogen by APM1) + level: Integration + module: TCPIP + steps: "1.target1 打开DHCP 2\n2.target1 设置softAP ip 192.168.123.123\n4.target1 关闭DHCP\ + \ 2\n5.target1 设置softAP ip 192.168.123.123\n6.target1 查询 当前sta ip \n7.target1\ + \ 设置softAP ip 为target_ap_ip" + sub module: IP + summary: ap set and query static ip test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: set and query static IP + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0101 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [SOCR SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP -i 0.0.0.0 -p 0 + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,OK', P SOC1 C +ACCEPT] + - - SSC SSC1 soc -B -t TCP -i 0.0.0.0 -p 0 + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i 123.456.678.789 -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.ERROR + + 6.ERROR' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket,bind到本地ip 0.0.0.0,本地端口 0 + + 3.target1上使用步骤2创建的socket,去连接 PC的ip,test_tcp_port1 + + 4.target1上创建TCP socket,bind到本地ip 0.0.0.0,本地端口 0 + + 5.target1上使用步骤4创建的socket,去连接不存在的ip,test_tcp_port1 + + 6.target1上使用步骤2创建的socket,去连接 PC的ip,远端端口不存在。' + sub module: TCP + summary: STA mode, connect test. use different ip, port + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0102 SDK: '8266_NonOS 8266_RTOS @@ -9261,9 +9938,10 @@ test cases: 3.PC TCP client accept 4.error' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration module: TCPIP steps: '1.target1上创建TCP socket,bind到本地端口 @@ -9284,7 +9962,7 @@ test cases: test point 2: use TCP SAP (socket/espconn API) with different parameter version: v1 (2016-8-15) - CI ready: 'Yes' - ID: TCPIP_TCP_0103 + ID: ^TCPIP_TCP_0103 SDK: '8266_NonOS 8266_RTOS @@ -9329,9 +10007,10 @@ test cases: 7.target收到 146000 byte 8.OK,PC 回SOC_RECV=SOC2,RECV_LEN=字节数' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration module: TCPIP steps: '1. PC上建立TCP 监听 test_tcp_port1 @@ -9347,7 +10026,7 @@ test cases: 7. PC send 100 * 1460 data to 8266, - 8.8266 send 100 * 1460 to PC. ' + 8.8266 send 100 * 1460 to PC.' sub module: TCP summary: STA mode, send/recv basic test test environment: SSC_T1_1 @@ -9360,7 +10039,7 @@ test cases: test point 2: use TCP SAP (socket/espconn API) with different parameter version: v1 (2016-8-15) - CI ready: 'Yes' - ID: TCPIP_TCP_0101 + ID: ^TCPIP_TCP_0104 SDK: '8266_NonOS 8266_RTOS @@ -9373,47 +10052,72 @@ test cases: cmd set: - '' - - SOC SOC1 LISTEN - - [SOCR SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP -i 0.0.0.0 -p 0 + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP - ['R SSC1 A :BIND:(\d+),OK'] - - SSC SSC1 soc -C -s -i -p - - ['P SSC1 RE CONNECT:\d+,OK', P SOC1 C +ACCEPT] - - - SSC SSC1 soc -B -t TCP -i 0.0.0.0 -p 0 + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s -h B + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -B -t TCP - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i 123.456.678.789 -p - - ['P SSC1 RE CONNECT:\d+,ERROR'] - - - SSC SSC1 soc -C -s -i -p - - ['P SSC1 RE CONNECT:\d+,ERROR'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s -h W + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s -h R + - ['R SSC1 RE SHUTDOWN:\d+,OK'] comment: '' execution time: 0.0 expected result: '1.OK 2.OK - 3.OK; PC TCP server accept 成功 + 3.OK,pc tcp server accept OK 4.OK - 5.ERROR + 5.OK - 6.ERROR' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 + 6.OK,pc tcp server accept OK + + 7.OK + + 8.OK + + 9.OK,pc tcp server accept OK + + 10.OK' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration module: TCPIP - steps: '1.PC上建立TCP 监听 test_tcp_port1 + steps: '1. PC上建立TCP 监听 test_tcp_port1 - 2.target1上创建TCP socket,bind到本地ip 0.0.0.0,本地端口 0 + 2.target1上创建TCP socket - 3.target1上使用步骤2创建的socket,去连接 PC的ip,test_tcp_port1 + 3.target1上使用步骤2创建的socket,去连接 PC的ip,test_tcp_port1,PC有ACCEPT - 4.target1上创建TCP socket,bind到本地ip 0.0.0.0,本地端口 0 + 4.target1 shutdown socket1 B - 5.target1上使用步骤4创建的socket,去连接不存在的ip,test_tcp_port1 + 5.target1上创建TCP socket - 6.target1上使用步骤2创建的socket,去连接 PC的ip,远端端口不存在。' + 6.target1上使用步骤5创建的socket,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 7.target1 shutdown socket2 W + + 8.target1上创建TCP socket + + 9.target1上使用步骤8创建的socket,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 10.target1 shutdown socket3 R' sub module: TCP - summary: STA mode, connect test. use different ip, port + summary: STA mode, shutdown basic test test environment: SSC_T1_1 test environment description (auto): 'PC has 2 wired NIC connected to AP. @@ -9424,7 +10128,198 @@ test cases: test point 2: use TCP SAP (socket/espconn API) with different parameter version: v1 (2016-8-15) - CI ready: 'Yes' - ID: ^TCPIP_TCP_0116 + ID: ^TCPIP_TCP_0105 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + - - SSC SSC1 soc -B -t TCP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,OK'] + - - SOC SOC2 CONNECT + - ['R SSC1 A :ACCEPT:(\d+),\d+,.+,\d+'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.OK + + 6.OK + + 7.target1关闭socket1 + + 8.target1关闭socket2 + + 9.OK + + 10.OK,pc tcp server accept成功 + + 11.target1关闭socket1 + + 12.OK + + 13.OK,pc tcp server accept成功 + + 14.OK + + 15.target1关闭socket1' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration + module: TCPIP + steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1关闭socket1\n\ + 4.target1上创建TCP socket 端口随机\n5.target1上使用步骤4创建的socket1,去监听\n6.PC CONNECT,\ + \ ,tcp 连接创建成功,创建socket2 \n7.target1关闭socket1\n8.target1关闭socket2\n\ + 9.target1上创建TCP socket1\n10.target1上使用步骤10创建的socket1,去连接 PC的ip,test_tcp_port1,PC有ACCEPT\n\ + 11.target1关闭socket1\n12.target1上创建TCP socket1\n13.target1上使用步骤13创建的socket1,去连接\ + \ PC的ip,test_tcp_port1,PC有ACCEPT\n14.target1shutdown socket1\n15.target1关闭socket1" + sub module: TCP + summary: STA mode, close for different types of TCP sockets test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0106 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK,pc tcp server accept成功 + + 4 OK + + 5.OK,pc tcp server accept成功 + + 6.OK + + 7.OK,pc tcp server accept成功 + + 8 OK + + 9.OK,pc tcp server accept成功 + + 10.OK + + 11.OK,pc tcp server accept成功' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket1 + + 3.target1上使用步骤2创建的socket1,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 4.target1上创建TCP socket2 + + 5.target1上使用步骤4创建的socket2,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 6.target1上创建TCP socket3 + + 7.target1上使用步骤6创建的socket3,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 8.target1上创建TCP socket4 + + 9.target1上使用步骤8创建的socket4,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 10.target1上创建TCP socket5 + + 11.target1上使用步骤10创建的socket5,去连接 PC的ip,test_tcp_port1,PC有ACCEPT' + sub module: TCP + summary: STA mode, create max TCP sockets test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0107 SDK: '8266_NonOS 8266_RTOS @@ -9440,15 +10335,15 @@ test cases: - ['R SSC1 A :BIND:(\d+),OK'] - - SSC SSC1 soc -L -s - ['R SSC1 RE LISTEN:\d+,OK'] - - - SOC SOC2 CONNECT 0 + - - SOC SOC2 CONNECT - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] - - - SOC SOC3 CONNECT 0 + - - SOC SOC3 CONNECT - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] - - - SOC SOC4 CONNECT 0 + - - SOC SOC4 CONNECT - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] - - - SOC SOC5 CONNECT 0 + - - SOC SOC5 CONNECT - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] - - - SOC SOC6 CONNECT 0 + - - SOC SOC6 CONNECT - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] comment: '' execution time: 0.0 @@ -9465,16 +10360,301 @@ test cases: 6.OK,pc tcp server accept成功 7.OK,pc tcp server accept成功' - initial condition: APSTA2 - initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen - by APM2) + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration module: TCPIP steps: "1.target1上创建TCP socket 端口随机\n2.target1上使用步骤4创建的socket1,去监听\n3.PC CONNECT,\ \ ,tcp 连接创建成功,创建socket2 \n4.PC CONNECT, ,tcp 连接创建成功,创建socket3\ \ \n5.PC CONNECT, ,tcp 连接创建成功,创建socket4 \n6.PC CONNECT,\ \ ,tcp 连接创建成功,创建socket5 \n7.PC CONNECT, ,tcp 连接创建成功,创建socket6" sub module: TCP - summary: AP mode, accept max TCP client by server test + summary: STA mode, accept max TCP client by server test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0110 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [SOCR SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP -i 0.0.0.0 -p 0 + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,OK', P SOC1 C +ACCEPT] + - - SSC SSC1 soc -B -t TCP -i 0.0.0.0 -p 0 + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i 123.456.678.789 -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.ERROR + + 6.ERROR' + initial condition: APSTA2 + initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen + by APM2) + level: Integration + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket,bind到本地ip 0.0.0.0,本地端口 0 + + 3.target1上使用步骤2创建的socket,去连接 PC的ip,test_tcp_port1 + + 4.target1上创建TCP socket,bind到本地ip 0.0.0.0,本地端口 0 + + 5.target1上使用步骤4创建的socket,去连接不存在的ip,test_tcp_port1 + + 6.target1上使用步骤2创建的socket,去连接 PC的ip,远端端口不存在。' + sub module: TCP + summary: AP mode, connect test. use different ip, port + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0111 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -B -t TCP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,OK'] + - - SOC SOC1 CONNECT 0 + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+', P SOC_COM C OK] + - - SOC SOC1 CONNECT 0 + - [P SOC_COM C ERROR, P SSC1 NC ACCEPT] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.PC TCP client accept + + 4.error' + initial condition: APSTA2 + initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen + by APM2) + level: Integration + module: TCPIP + steps: '1.target1上创建TCP socket,bind到本地端口 + + 2.target1上使用步骤1创建的socket,创建TCP 监听 + + 3.PC TCP 连接到target1 , + + 4.PC tcp 连接到不存在的port ,' + sub module: TCP + summary: AP mode, server listen test. use different kinds of port + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0112 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SOC SOC2 SEND 5 + - [R SSC1 SL +5] + - - SSC SSC1 soc -S -s -l 5 + - ['P SSC1 RE SEND:\d+,OK', P SOC2 RL 5] + - - SOC SOC2 SEND 146000 + - [R SSC1 SL +146000] + - - SSC SSC1 soc -S -s -l 1460 -n 100 + - ['P SSC1 RE SEND:\d+,OK', P SOC2 RL 146000] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK,pc tcp server accept成功 + + 4.OK + + 5.target收到5byte数据 + + 6.PC收到5byte数据 + + 7.target收到146000 byte数据 + + 8.OK,PC 收到146000 byte数据' + initial condition: APSTA2 + initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen + by APM2) + level: Integration + module: TCPIP + steps: '1. PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket + + 3.target1上使用步骤2创建的socket,去连接 PC的ip,test_tcp_port1 + + 4.PC与target1 创建好TCP 连接,有ACCEPT + + 5.PC send 5 bytes to 8266 + + 6.8266 send 5 bytes to PC + + 7. PC send 100 * 1460 data to 8266, + + 8.8266 send 100 * 1460 to PC.' + sub module: TCP + summary: AP mode, send/recv basic test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0113 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s -h B + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s -h W + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s -h R + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK,pc tcp server accept成功 + + 4.OK + + 5.OK + + 6.OK,pc tcp server accept成功 + + 7.OK + + 8.OK + + 9.OK,pc tcp server accept成功 + + 10.OK' + initial condition: APSTA2 + initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen + by APM2) + level: Integration + module: TCPIP + steps: '1. PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket + + 3.target1上使用步骤2创建的socket,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 4.target1 shutdown socket1 B + + 5.target1上创建TCP socket + + 6.target1上使用步骤5创建的socket,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 7.target1 shutdown socket2 W + + 8.target1上创建TCP socket + + 9.target1上使用步骤8创建的socket,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + + 10.target1 shutdown socket3 R' + sub module: TCP + summary: AP mode, shutdown basic test test environment: SSC_T1_1 test environment description (auto): 'PC has 2 wired NIC connected to AP. @@ -9561,6 +10741,7 @@ test cases: initial condition: APSTA2 initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen by APM2) + level: Integration module: TCPIP steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1关闭socket1\n\ 4.target1上创建TCP socket 端口随机\n5.target1上使用步骤4创建的socket1,去监听\n6.PC CONNECT,\ @@ -9640,6 +10821,7 @@ test cases: initial condition: APSTA2 initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen by APM2) + level: Integration module: TCPIP steps: '1.PC上建立TCP 监听 test_tcp_port1 @@ -9674,235 +10856,7 @@ test cases: test point 2: use TCP SAP (socket/espconn API) with different parameter version: v1 (2016-8-15) - CI ready: 'Yes' - ID: ^TCPIP_TCP_0112 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SOC SOC1 ACCEPT SOC2 - - [R SOC_COM L OK] - - - SOC SOC2 SEND 5 - - [R SSC1 SL +5] - - - SSC SSC1 soc -S -s -l 5 - - ['P SSC1 RE SEND:\d+,OK', P SOC2 RL 5] - - - SOC SOC2 SEND 146000 - - [R SSC1 SL +146000] - - - SSC SSC1 soc -S -s -l 1460 -n 100 - - ['P SSC1 RE SEND:\d+,OK', P SOC2 RL 146000] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK,pc tcp server accept成功 - - 4.OK - - 5.target收到5byte数据 - - 6.PC收到5byte数据 - - 7.target收到146000 byte数据 - - 8.OK,PC 收到146000 byte数据' - initial condition: APSTA2 - initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen - by APM2) - module: TCPIP - steps: '1. PC上建立TCP 监听 test_tcp_port1 - - 2.target1上创建TCP socket - - 3.target1上使用步骤2创建的socket,去连接 PC的ip,test_tcp_port1 - - 4.PC与target1 创建好TCP 连接,有ACCEPT - - 5.PC send 5 bytes to 8266 - - 6.8266 send 5 bytes to PC - - 7. PC send 100 * 1460 data to 8266, - - 8.8266 send 100 * 1460 to PC.' - sub module: TCP - summary: AP mode, send/recv basic test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use TCP SAP (socket/espconn API) with different parameter - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_TCP_0113 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SSC SSC1 soc -D -s -h B - - ['R SSC1 RE SHUTDOWN:\d+,OK'] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SSC SSC1 soc -D -s -h W - - ['R SSC1 RE SHUTDOWN:\d+,OK'] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SSC SSC1 soc -D -s -h R - - ['R SSC1 RE SHUTDOWN:\d+,OK'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK,pc tcp server accept成功 - - 4.OK - - 5.OK - - 6.OK,pc tcp server accept成功 - - 7.OK - - 8.OK - - 9.OK,pc tcp server accept成功 - - 10.OK' - initial condition: APSTA2 - initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen - by APM2) - module: TCPIP - steps: '1. PC上建立TCP 监听 test_tcp_port1 - - 2.target1上创建TCP socket - - 3.target1上使用步骤2创建的socket,去连接 PC的ip,test_tcp_port1,PC有ACCEPT - - 4.target1 shutdown socket1 B - - 5.target1上创建TCP socket - - 6.target1上使用步骤5创建的socket,去连接 PC的ip,test_tcp_port1,PC有ACCEPT - - 7.target1 shutdown socket2 W - - 8.target1上创建TCP socket - - 9.target1上使用步骤8创建的socket,去连接 PC的ip,test_tcp_port1,PC有ACCEPT - - 10.target1 shutdown socket3 R' - sub module: TCP - summary: AP mode, shutdown basic test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use TCP SAP (socket/espconn API) with different parameter - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_TCP_0110 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [SOCR SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP -i 0.0.0.0 -p 0 - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['P SSC1 RE CONNECT:\d+,OK', P SOC1 C +ACCEPT] - - - SSC SSC1 soc -B -t TCP -i 0.0.0.0 -p 0 - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i 123.456.678.789 -p - - ['P SSC1 RE CONNECT:\d+,ERROR'] - - - SSC SSC1 soc -C -s -i -p - - ['P SSC1 RE CONNECT:\d+,ERROR'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK; PC TCP server accept 成功 - - 4.OK - - 5.ERROR - - 6.ERROR' - initial condition: APSTA2 - initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen - by APM2) - module: TCPIP - steps: '1.PC上建立TCP 监听 test_tcp_port1 - - 2.target1上创建TCP socket,bind到本地ip 0.0.0.0,本地端口 0 - - 3.target1上使用步骤2创建的socket,去连接 PC的ip,test_tcp_port1 - - 4.target1上创建TCP socket,bind到本地ip 0.0.0.0,本地端口 0 - - 5.target1上使用步骤4创建的socket,去连接不存在的ip,test_tcp_port1 - - 6.target1上使用步骤2创建的socket,去连接 PC的ip,远端端口不存在。' - sub module: TCP - summary: AP mode, connect test. use different ip, port - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use TCP SAP (socket/espconn API) with different parameter - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_TCP_0111 + ID: ^TCPIP_TCP_0116 SDK: '8266_NonOS 8266_RTOS @@ -9918,32 +10872,42 @@ test cases: - ['R SSC1 A :BIND:(\d+),OK'] - - SSC SSC1 soc -L -s - ['R SSC1 RE LISTEN:\d+,OK'] - - - SOC SOC1 CONNECT 0 - - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+', P SOC_COM C OK] - - - SOC SOC1 CONNECT 0 - - [P SOC_COM C ERROR, P SSC1 NC ACCEPT] + - - SOC SOC2 CONNECT 0 + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] + - - SOC SOC3 CONNECT 0 + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] + - - SOC SOC4 CONNECT 0 + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] + - - SOC SOC5 CONNECT 0 + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] + - - SOC SOC6 CONNECT 0 + - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] comment: '' execution time: 0.0 - expected result: '1.OK + expected result: '1.+BIND:0,OK,0.0.0.0 2.OK - 3.PC TCP client accept + 3.OK,pc tcp server accept成功 - 4.error' + 4.OK,pc tcp server accept成功 + + 5.OK,pc tcp server accept成功 + + 6.OK,pc tcp server accept成功 + + 7.OK,pc tcp server accept成功' initial condition: APSTA2 initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen by APM2) + level: Integration module: TCPIP - steps: '1.target1上创建TCP socket,bind到本地端口 - - 2.target1上使用步骤1创建的socket,创建TCP 监听 - - 3.PC TCP 连接到target1 , - - 4.PC tcp 连接到不存在的port ,' + steps: "1.target1上创建TCP socket 端口随机\n2.target1上使用步骤4创建的socket1,去监听\n3.PC CONNECT,\ + \ ,tcp 连接创建成功,创建socket2 \n4.PC CONNECT, ,tcp 连接创建成功,创建socket3\ + \ \n5.PC CONNECT, ,tcp 连接创建成功,创建socket4 \n6.PC CONNECT,\ + \ ,tcp 连接创建成功,创建socket5 \n7.PC CONNECT, ,tcp 连接创建成功,创建socket6" sub module: TCP - summary: AP mode, server listen test. use different kinds of port + summary: AP mode, accept max TCP client by server test test environment: SSC_T1_1 test environment description (auto): 'PC has 2 wired NIC connected to AP. @@ -9954,1078 +10918,97 @@ test cases: test point 2: use TCP SAP (socket/espconn API) with different parameter version: v1 (2016-8-15) - CI ready: 'Yes' - ID: WIFI_SCAN_0302 - SDK: ESP32_IDF + ID: ^TCPIP_TCP_0201 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' Test App: SSC allow fail: '' auto test: 'Yes' category: Function cmd set: - '' - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:CONNECTED'] - - - SSC SSC1 soc -B -t UDP -p + - - SOC SOC1 LISTEN + - [SOCR SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -i 0.0.0.0 -p - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -S -s -i -p -n 1000000 -j 5 - - [''] - - - SSC SSC2 phy -S -o 1 -m b - - ['R SSC2 C +PHY:OK'] - - - SSC SSC2 sta -S -n - - [R SSC2 P ] - - - SSC SSC2 phy -S -o 1 -m g - - ['R SSC2 C +PHY:OK'] - - - SSC SSC2 sta -S -n - - [R SSC2 P ] - - - SSC SSC2 phy -S -o 1 -m n -b 20 - - ['R SSC2 C +PHY:OK'] - - - SSC SSC2 sta -S -n - - [R SSC2 P ] - - - SSC SSC2 phy -S -o 1 -m n -b 40 - - ['R SSC2 C +PHY:OK'] - - - SSC SSC2 sta -S -n - - [R SSC2 P ] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,OK'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s -h B + - ['P SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 soc -C -s -i -p + - ['P SSC1 RE CONNECT:\d+,ERROR'] comment: '' execution time: 0.0 - expected result: 3. target 2 able to scan AP - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. target 1 connect to AP - - 2. target 1 start sending UDP packets - - 3. target 2 scan in AP channel in 11b.g,n,ht40 mode' - sub module: WIFI Scan - summary: scan in congest channel - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: interaction - test point 2: Scan interact with other WiFi operation - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: TCPIP_UDP_0304 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: 1/5 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 BIND - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -S -s -i -p -l 5 - - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] - - - SSC SSC1 op -S -o 2 - - ['P SSC1 C +MODE:OK'] - - - SSC SSC1 soc -T -s - - ['R SSC1 RE CLOSE:\d+,OK'] - comment: '' - execution time: 0.0 - expected result: '1.OK + expected result: '1.ok 2.OK - 3.OK - - 4.OK - - 5.OK' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: "1.PC上SOC1 UDP传输,bing \n2.target1上UDP传输,Bind socket1,本地ip\ - \ target_udp_port1\n3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据\n\ - 4.修改8266的Mode为softAP mode \n5.关闭建立的socket1连接" - sub module: UDP - summary: close UDP socket after mode changed - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: UDP handling abnormal event - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_UDP_0305 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: 1/5 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 BIND - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -S -s -i -p -l 5 - - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] - - - NIC DISABLED - - [R PC_COM C OK] - - - SSC SSC1 soc -T -s - - ['R SSC1 RE CLOSE:\d+,OK'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK - - 4.OK - - 5.OK' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: "1.PC上SOC1 UDP传输,bing \n2.target1上UDP传输,Bind socket1,本地ip\ - \ target_udp_port1\n3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据\n\ - 4.PC上网卡禁止掉 \n5.关闭建立的socket1连接" - sub module: UDP - summary: close UDP socket after PC NIC disabled - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: UDP handling abnormal event - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_UDP_0306 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: 1/5 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 BIND - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -S -s -i -p -l 5 - - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] - - - SSC SSC1 dhcp -E -o 1 - - ['R SSC1 C +DHCP:STA,OK'] - - - SSC SSC1 ip -S -o 1 -i 192.168.111.210 - - ['P SSC1 C +IP:OK'] - - - SSC SSC1 ip -Q -o 1 - - ['R SSC1 C +STAIP:192.168.111.210'] - - - SSC SSC1 soc -S -s -i -p -l 1 - - ['P SSC1 RE SEND:\d+,OK'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK; PC TCP server accept 成功 + 3.ERROR 4.OK 5.OK - 6.OK - - 7.OK' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: "1.PC上SOC1 UDP传输,bing \n2.target1上UDP传输,Bind socket1,本地ip\ - \ target_udp_port1\n3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据\n\ - 4.关闭8266的DHCP 1\n5.设置sta ip \n6.查询sta ip 地址是否生效\n7.8266往PC上发送5字节数据" - sub module: UDP - summary: do UDP send after IP changed - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: UDP handling abnormal event - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_UDP_0307 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: 1/5 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 BIND - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -S -s -i -p -l 5 - - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] - - - SSC SSC1 dhcp -E -o 1 - - ['R SSC1 C +DHCP:STA,OK'] - - - SSC SSC1 ip -S -o 1 -i 192.168.111.210 - - ['P SSC1 C +IP:OK'] - - - SSC SSC1 ip -Q -o 1 - - ['R SSC1 C +STAIP:192.168.111.210'] - - - SSC SSC1 soc -T -s - - ['R SSC1 RE CLOSE:\d+,OK'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK; PC TCP server accept 成功 - - 4.OK - - 5.OK - - 6.OK - - 7.OK' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: "1.PC上SOC1 UDP传输,bing \n2.target1上UDP传输,Bind socket1,本地ip\ - \ target_udp_port1\n3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据\n\ - 4.关闭8266的DHCP 1\n5.设置sta ip \n6.查询sta ip 地址是否生效\n7.关闭建立的socket1连接" - sub module: UDP - summary: close UDP socket after IP changed - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: UDP handling abnormal event - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_UDP_0301 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: 1/5 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 BIND - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t UDP -i -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -S -s -i -p -l 5 - - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] - - - SSC SSC1 sta -D - - ['P SSC1 C +QAP:OK'] - - - SSC SSC1 soc -S -s -i -p -l 5 - - ['P SSC1 RE SEND:\d+,ERROR'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK - - 4.OK - - 5.ERROR' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: '1.PC上SOC1 UDP传输,bing - - 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - - 3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据 - - 4.断开与AP 连接 - - 5.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据' - sub module: UDP - summary: do UDP send after WIFI disconnected - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: UDP handling abnormal event - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_UDP_0302 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: 1/5 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 BIND - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -S -s -i -p -l 5 - - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] - - - SSC SSC1 sta -D - - ['P SSC1 C +QAP:OK'] - - - SSC SSC1 soc -T -s - - ['R SSC1 RE CLOSE:\d+,OK'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK - - 4.OK - - 5.OK - - ' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: '1.PC上SOC1 UDP传输,bing - - 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - - 3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据 - - 4.断开与AP 连接 - - 5.关闭建立的socket1连接' - sub module: UDP - summary: "close UDP socket after WIFI \ndisconnected" - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: UDP handling abnormal event - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_UDP_0303 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: 1/5 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 BIND - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -S -s -i -p -l 5 - - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] - - - SSC SSC1 op -S -o 2 - - ['P SSC1 C +MODE:OK'] - - - SSC SSC1 soc -S -s -i -p -l 5 - - ['P SSC1 RE SEND:(\d+),OK'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK - - 4.OK - - 5.ERROR' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: "1.PC上SOC1 UDP传输,bing \n2.target1上UDP传输,Bind socket1,本地ip\ - \ target_udp_port1\n3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据\n\ - 4.修改8266的Mode为softAP mode \n5.8266往PC上发送5字节数据" - sub module: UDP - summary: do UDP send after mode changed - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: UDP handling abnormal event - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_CONN_0601 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -p -t - - ['R SSC1 C +SAP:OK'] - - - WIFI CONN - - - ['R PC_COM C +WIFICONN:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC1 ap -L - - ['R SSC1 C +LSTA:', 'R SSC1 C +LSTA:', R SSC1 C +LSTADONE] - comment: '' - execution time: 0.0 - expected result: '1.target1 set AP - - 2.PC WIFI CONNECTED - - 3.target2 jap target 1 - - 4.查询到两个sta 连接到target1 上' - initial condition: T2_1 - initial condition description (auto): target 1 as SoftAP, target 2 as STA, will - autogen a TC with initial condition T2_2 - module: WIFI MAC - steps: '1. target1下设置ssid 和pwd 加密方式 - - 2.PC WIFI CONNECTED target1 - - 3.target2 jap target 1 - - 4.查询到两个sta 连接到target1 上' - sub module: WIFI Connect - summary: list stations connected to soft ap test - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: list SoftAP connected station - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_DHCP_0209 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -p -t 4 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC1 dhcp -E -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 - - ['R SSC1 C +DHCP:LEASE,OK'] - - - SSC SSC1 dhcp -S -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - WIFI CONN 192.168.4.2 - - ['R PC_COM NC ERROR C +WIFICONN:OK'] - - - DELAY 20 - - [''] - - - SSC SSC1 ap -L - - [R SSC1 C 192.168.4.2 C 192.168.4.3 P P ] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 3. succeed - - 4. succeed - - 5. find target2 and PC' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: TCPIP - steps: '1. config softap to a random ssid - - 2. target2 connect to target1 softap - - 3. disable DHCP server, do config and enable - - 4. PC NIC connect to target1 softap - - 5. softap list connected station' - sub module: DHCP - summary: dhcp server reconfig, old client and new client able to get IP - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: DHCP server function test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_DHCP_0208 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -p -t 4 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC1 dhcp -E -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 - - ['R SSC1 C +DHCP:LEASE,OK'] - - - SSC SSC1 dhcp -S -o 2 - - ['P SSC1 C +DHCP:AP,OK', 'P SSC2 C +JAP:DISCONNECTED'] - - - SSC SSC2 sta -D - - ['R SSC2 C +JAP:DISCONNECTED'] - - - SSC SSC1 dhcp -S -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - WIFI CONN 192.168.4.2 - - ['R PC_COM NC ERROR C +WIFICONN:OK'] - - - SSC SSC1 ap -L - - [R SSC1 C 192.168.4.2 P ] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 3. succeed - - 4. get IP 192.168.4.2 - - 5. can only find target2 with IP 192.168.4.2' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: TCPIP - steps: '1. config softap to a random ssid - - 2. PC NIC connect to target1 softap - - 3. disable DHCP server, do config and enable - - 4. target2 connect to target1 softap - - 5. softap list connected station' - sub module: DHCP - summary: dhcp server reconfig and new client able to get first IP in pool - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: DHCP server function test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_DHCP_0207 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -p -t 4 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC1 dhcp -E -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 - - ['R SSC1 C +DHCP:LEASE,OK'] - - - SSC SSC1 dhcp -S -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - WIFI CONN 192.168.4.2 - - ['R PC_COM NC ERROR C +WIFICONN:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - WIFI DISCONN2 - - ['R PC_COM NC ERROR C +WIFIDISCONN:OK'] - - - SSC SSC2 sta -D - - ['R SSC2 C +QAP:OK'] - - - SSC SSC2 mac -S -o 1 -m 10:22:33:44:55:66 - - ['R SSC2 C +MAC:STA,OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC2 ip -Q -o 1 - - ['R SSC2 C +STAIP:192.168.4.2'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 3. get IP 192.168.4.2 - - 4. succeed - - 5. succeed - - 6. get IP 192.168.4.2' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: TCPIP - steps: '1. config softap to a random ssid - - 2. disable DHCP server, do config and enable - - 3. PC WIFI NIC connect to target1 softap - - 4. target2 connect to target1 softap and disnnect - - 5. PC release IP and disconnected - - 6. target2 change mac and connect to target1' - sub module: DHCP - summary: dhcp server prefer assign released IP to new client - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: DHCP server function test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_DHCP_0206 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -p -t 4 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC1 dhcp -E -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 - - ['R SSC1 C +DHCP:LEASE,OK'] - - - SSC SSC1 dhcp -S -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - LOOP 4 4 "['01','02','03','01']" "[2,3,4,2]" - - [''] - - - SSC SSC2 sta -D - - ['R SSC2 C +QAP:OK'] - - - SSC SSC2 mac -S -o 1 -m 10:22:33:44:55:{%s} - - ['R SSC2 C +MAC:STA,OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC2 ip -Q -o 1 - - ['R SSC2 C +STAIP:192.168.4.{%s}'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 4. get IP 192.168.4.2 - 192.168.4.4 - - 5. get IP 192.168.4.2' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: TCPIP - steps: '1. config softap to a random ssid - - 2. disable DHCP server, do config and enable - - 3. target2 change mac, connect to softap, disconnect - - 4. Loop step3 twice - - 5. change to first mac, connect to softap' - sub module: DHCP - summary: dhcp server assign same IP to same MAC when it's not released - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: DHCP server function test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_DHCP_0205 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -p -t 4 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC1 dhcp -E -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.3 -t 1 - - ['P SSC1 C +DHCP:LEASE,OK'] - - - SSC SSC1 dhcp -S -o 2 - - ['P SSC1 C +DHCP:AP,OK', 'P SSC2 C +JAP:DISCONNECTED'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 3. target2 wifi disconnected' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: TCPIP - steps: '1. config softap to a random ssid - - 2. target2 connect to target1 - - 3. disable DHCP server, do config and enable' - sub module: DHCP - summary: disconnect STA if config dhcp server - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: DHCP server function test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_DHCP_0204 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -p -t 4 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC1 dhcp -E -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.3 -t 1 - - ['R SSC1 C +DHCP:LEASE,OK'] - - - SSC SSC1 dhcp -S -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC2 ip -Q -o 1 - - ['R SSC2 C +STAIP:192.168.4.2'] - - - DELAY 90 - - [''] - - - SSC SSC2 ip -Q -o 1 - - ['R SSC2 C +STAIP:192.168.4.2'] - - - SSC SSC2 sta -D - - ['R SSC2 C +JAP:DISCONNECTED'] - - - DELAY 60 - - [''] - - - SSC SSC2 mac -S -o 1 -m 10:22:33:44:55:66 - - ['R SSC2 C +MAC:STA,OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC2 ip -Q -o 1 - - ['R SSC2 C +STAIP:192.168.4.2'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 3. get IP 192.168.4.2 - - 5. succeed - - 6. succeed - - 8. get IP 192.168.4.2' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: TCPIP - steps: '1. config softap to a random ssid - - 2. config DHCP timeout as 1 minute - - 3. target2 connect to target1 - - 4. wait 90 seconds - - 5. check if target2 IP is same - - 6. target2 disconnect - - 7. wait 60s - - 8. target2 change mac and connect to target1' - sub module: DHCP - summary: dhcp server timeout test - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: DHCP server function test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_DHCP_0203 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -p -t 4 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC1 dhcp -E -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.3 - - ['R SSC1 C +DHCP:LEASE,OK'] - - - SSC SSC1 dhcp -S -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - LOOP 2 4 "['01','02']" "[2,3]" - - [''] - - - SSC SSC2 sta -D - - ['R SSC2 C +QAP:OK'] - - - SSC SSC2 mac -S -o 1 -m 10:22:33:44:55:{%s} - - ['R SSC2 C +MAC:STA,OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC2 ip -Q -o 1 - - ['R SSC2 C +STAIP:192.168.4.{%s}'] - - - SSC SSC2 mac -S -o 1 -m 10:22:33:44:55:66 - - ['R SSC2 C +MAC:STA,OK'] - - - DELAY 20 - - [''] - - - SSC SSC2 ip -Q -o 1 - - ['R SSC2 C +STAIP:0.0.0.0'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 3. succeed - - 4.1 succeed - - 4.2 failed' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: TCPIP - steps: '1. config softap to a random ssid - - 2. config DHCP Server on Target1(.4.2 - .4.3) - - 3. target change mac, connect to Target1 - - 4. Loop step3 twice' - sub module: DHCP - summary: dhcp server ip pool empty - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: DHCP server function test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_DHCP_0202 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -p -t 4 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC1 dhcp -E -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 - - ['R SSC1 C +DHCP:LEASE,OK'] - - - SSC SSC1 dhcp -S -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - LOOP 3 4 "['01','02','03']" "[2,3,4]" - - [''] - - - SSC SSC2 sta -D - - ['R SSC2 C +QAP:OK'] - - - SSC SSC2 mac -S -o 1 -m 10:22:33:44:55:{%s} - - ['R SSC2 C +MAC:STA,OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC2 ip -Q -o 1 - - ['R SSC2 C +STAIP:192.168.4.{%s}'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 3,4: get IP from dhcp pool with correct sequence' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: TCPIP - steps: '1. config softap to a random ssid - - 2. config DHCP Server on Target1 - - 3. target change mac, connect to Target1 - - 4. Loop step3' - sub module: DHCP - summary: dhcp server ip pool - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: DHCP server function test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_DHCP_0201 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 dhcp -E -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC1 ip -S -o 2 -i - - ['R SSC1 C +IP:OK'] - - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 - - ['R SSC1 C +DHCP:LEASE,OK'] - - - SSC SSC1 dhcp -L -s 192.168.4.1 -e 192.168.4.10 - - ['R SSC1 C +DHCP:LEASE,ERROR'] - - - SSC SSC1 dhcp -L -s 192.168.4.5 -e 192.168.4.2 - - ['R SSC1 C +DHCP:LEASE,ERROR'] - - - SSC SSC1 dhcp -L -s 192.168.2.2 -e 192.168.2.5 - - ['R SSC1 C +DHCP:LEASE,ERROR'] - - - SSC SSC1 dhcp -S -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - comment: '' - execution time: 0.0 - expected result: '1.target1 关闭DHCP 2 OK - - 2.target1 设置ip 成功 - - 3.设置dhcp 地址池 OK - - 4.ERROR - - 5.ERROR - 6.ERROR - 7.target1 打开DHCP ok' - initial condition: APSTA1 - initial condition description (auto): testing ap on sta + ap mode (autogen by APM1) + 7.OK + + 8.OK + + 9.OK + + 10.OK + + 11.OK + + 12.ERROR' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration module: TCPIP - steps: "1.target1 关闭DHCP 2 \n2.target1 设置ip \n3.设置dhcp 地址池\n4.设置dhcp错误的参数\n5.设置dhcp错误的参数\n\ - 6.设置dhcp错误的参数\n7.target1 打开DHCP ok" - sub module: DHCP - summary: server dhcp lease test + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建UDP传输socket,bind到本地ip 0.0.0.0, + + 3.target1上使用步骤2创建的socket,去连接 PC的ip, + + 4.target1上创建TCP socket + + 5.target1上使用步骤4创建的socket,创建TCP 监听 + + 6.target1上使用步骤4创建的socket,去连接 PC的ip, + + 7.target1上创建TCP socket + + 8.target1上使用步骤7创建的socket,去连接 PC的ip, + + 9.target1上关闭步骤7创建的socket + + 10.target1上使用步骤7创建的socket,去连接 PC的ip, + + 11.target1上关闭所有创建的socket + + 12.target1上使用步骤2创建的socket,去连接 PC的ip,' + sub module: TCP + summary: STA mode, connect test. use socket in state that can't connect test environment: SSC_T1_1 test environment description (auto): 'PC has 2 wired NIC connected to AP. @@ -11033,10 +11016,176 @@ test cases: 1 SSC target connect with PC by UART.' test point 1: basic function - test point 2: DHCP server function test + test point 2: use TCP SAP (socket/espconn API) in different state version: v1 (2016-8-15) - CI ready: 'Yes' - ID: TCPIP_TCP_0204 + ID: ^TCPIP_TCP_0202 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,ERROR'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,ERROR'] + - - SSC SSC1 soc -D -s + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,ERROR'] + - - SSC SSC1 soc -L -s 1000 + - ['R SSC1 RE LISTEN:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.ERROR + + 4.OK + + 5.OK + + 6.ERROR + + 7.OK + + 8.ERROR + + 9.ERROR' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建UDP传输socket,bind到本地ip 0.0.0.0, + + 3.target1上使用步骤2创建的socket,去建立TCP 监听 + + 4.target1上创建TCP socket + + 5.target1上使用步骤4创建的socket,去连接 PC的ip, + + 6.target1上使用步骤4创建的socket,创建TCP 监听 + + 7.target1上shutdown 步骤4的socket + + 8.target1上使用步骤4创建的socket,创建TCP 监听 + + 9.target1上使用不存在socket,创建TCP 监听' + sub module: TCP + summary: STA mode, server listen test. use socket in state that can't listen + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) in different state + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0203 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s + - ['R SSC1 RE SEND:\d+,ERROR'] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s + - ['R SSC1 RE SEND:\d+,ERROR'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -S -s + - ['R SSC1 RE SEND:\d+,ERROR'] + - - SSC SSC1 soc -S -s 1000 + - ['R SSC1 RE SEND:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.ERROR + + 4.OK + + 5.ERROR + + 6.OK + + 7.OK + + 8.ERROR + + 9.ERROR' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建UDP传输socket1, + + 3.target1上使用步骤2创建的socket1,去发送数据 + + 4.target1上创建TCP socket2 + + 5.target1上使用步骤4创建的socket2,去发送数据 + + 6.target1上使用步骤4创建的socket2,创建TCP连接,连接成功 + + 7.target1上shutdown 步骤4的socket2 + + 8.target1往socket2发送错误命令发送数据 + + 9.target1上不指定socket往上发送数据' + sub module: TCP + summary: send test. use socket in state that can't send + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use TCP SAP (socket/espconn API) in different state + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0204 SDK: '8266_NonOS 8266_RTOS @@ -11076,12 +11225,11 @@ test cases: 6.OK - 7.target收到146000 byte - - ' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 + 7.target收到146000 byte' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration module: TCPIP steps: '1. PC上建立TCP 监听 test_tcp_port1 @@ -11108,107 +11256,7 @@ test cases: test point 2: use TCP SAP (socket/espconn API) in different state version: v1 (2016-8-15) - CI ready: 'Yes' - ID: TCPIP_TCP_0207 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [SOCR SOC_COM L OK] - - - SSC SSC1 soc -B -t UDP -i 0.0.0.0 -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['P SSC1 RE CONNECT:\d+,ERROR'] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -L -s - - ['R SSC1 RE LISTEN:\d+,OK'] - - - SSC SSC1 soc -C -s -i -p - - ['P SSC1 RE CONNECT:\d+,ERROR'] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['P SSC1 RE CONNECT:\d+,OK'] - - - SSC SSC1 soc -D -s -h B - - ['P SSC1 RE SHUTDOWN:\d+,OK'] - - - SSC SSC1 soc -C -s -i -p - - ['P SSC1 RE CONNECT:\d+,ERROR'] - - - SSC SSC1 soc -T - - [R SSC1 C +CLOSEALL] - - - SSC SSC1 soc -C -s -i -p - - ['P SSC1 RE CONNECT:\d+,ERROR'] - comment: '' - execution time: 0.0 - expected result: '1.ok - - 2 OK - - 3.ERROR - - 4.OK - - 5.OK - - 6.ERROR - - 7.OK - - 8.OK - - 9.OK - - 10.OK - - 11.OK - - 12.ERROR' - initial condition: APM2 - initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen - a TC with initial condition APSTA2 - module: TCPIP - steps: '1.PC上建立TCP 监听 test_tcp_port1 - - 2.target1上创建UDP传输socket,bind到本地ip 0.0.0.0, - - 3.target1上使用步骤2创建的socket,去连接 PC的ip, - - 4.target1上创建TCP socket - - 5.target1上使用步骤4创建的socket,创建TCP 监听 - - 6.target1上使用步骤4创建的socket,去连接 PC的ip, - - 7.target1上创建TCP socket - - 8.target1上使用步骤7创建的socket,去连接 PC的ip, - - 9.target1上关闭步骤7创建的socket - - 10.target1上使用步骤7创建的socket,去连接 PC的ip, - - 11.target1上关闭所有创建的socket - - 12.target1上使用步骤2创建的socket,去连接 PC的ip,' - sub module: TCP - summary: AP mode, connect test. use socket in state that can't connect - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use TCP SAP (socket/espconn API) in different state - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_TCP_0206 + ID: ^TCPIP_TCP_0206 SDK: '8266_NonOS 8266_RTOS @@ -11271,9 +11319,10 @@ test cases: +SOCINFO:,,, +SOCINF0ALL' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration module: TCPIP steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1,本地ip target_ip\n3.target1上使用步骤2创建的socket1,去连接\ \ PC的ip,test_tcp_port1,PC有ACCEPT\n4.target1上创建TCP socket2,本地ip target_ip\n5.target1上使用步骤4创建的socket2,去连接\ @@ -11292,7 +11341,7 @@ test cases: test point 2: use TCP SAP (socket/espconn API) in different state version: v1 (2016-8-15) - CI ready: 'Yes' - ID: TCPIP_TCP_0201 + ID: ^TCPIP_TCP_0207 SDK: '8266_NonOS 8266_RTOS @@ -11304,35 +11353,35 @@ test cases: category: Function cmd set: - '' - - - SOC SOC1 LISTEN + - - SOC SOC1 LISTEN - [SOCR SOC_COM L OK] - - SSC SSC1 soc -B -t UDP -i 0.0.0.0 -p - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p + - - SSC SSC1 soc -C -s -i -p - ['P SSC1 RE CONNECT:\d+,ERROR'] - - SSC SSC1 soc -B -t TCP - ['R SSC1 A :BIND:(\d+),OK'] - - SSC SSC1 soc -L -s - ['R SSC1 RE LISTEN:\d+,OK'] - - - SSC SSC1 soc -C -s -i -p + - - SSC SSC1 soc -C -s -i -p - ['P SSC1 RE CONNECT:\d+,ERROR'] - - SSC SSC1 soc -B -t TCP - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p + - - SSC SSC1 soc -C -s -i -p - ['P SSC1 RE CONNECT:\d+,OK'] - - SSC SSC1 soc -D -s -h B - ['P SSC1 RE SHUTDOWN:\d+,OK'] - - - SSC SSC1 soc -C -s -i -p + - - SSC SSC1 soc -C -s -i -p - ['P SSC1 RE CONNECT:\d+,ERROR'] - - SSC SSC1 soc -T - [R SSC1 C +CLOSEALL] - - - SSC SSC1 soc -C -s -i -p + - - SSC SSC1 soc -C -s -i -p - ['P SSC1 RE CONNECT:\d+,ERROR'] comment: '' execution time: 0.0 expected result: '1.ok - 2.OK + 2 OK 3.ERROR @@ -11353,9 +11402,10 @@ test cases: 11.OK 12.ERROR' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 + initial condition: APSTA2 + initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen + by APM2) + level: Integration module: TCPIP steps: '1.PC上建立TCP 监听 test_tcp_port1 @@ -11381,7 +11431,7 @@ test cases: 12.target1上使用步骤2创建的socket,去连接 PC的ip,' sub module: TCP - summary: STA mode, connect test. use socket in state that can't connect + summary: AP mode, connect test. use socket in state that can't connect test environment: SSC_T1_1 test environment description (auto): 'PC has 2 wired NIC connected to AP. @@ -11391,875 +11441,6 @@ test cases: test point 1: basic function test point 2: use TCP SAP (socket/espconn API) in different state version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_DHCP_0101 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 dhcp -E -o 1 - - ['R SSC1 C +DHCP:STA,OK'] - - - SSC SSC1 ip -S -i 0.0.0.0 - - ['R SSC1 C +IP:OK'] - - - SSC SSC1 sta -C -s -p - - [''] - - - DELAY 20 - - [P PC_COM C +DELAYDONE, 'P SSC1 NC +JAP:CONNECTED'] - - - SSC SSC1 dhcp -S -o 1 - - ['R SSC1 C +DHCP:STA,OK'] - - - SSC SSC1 ip -Q - - ['R SSC1 C +STAIP:0.0.0.0'] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:CONNECTED'] - - - SSC SSC1 ip -Q - - ['R SSC1 RE "\+STAIP:%%s"%%()'] - comment: '' - execution time: 0.0 - expected result: "1.target1 关闭DHCP OK\n2.target1 设置ip add OK\n3.target1 连接AP fail\n\ - 4.target1 打开DHCP OK\n5.查询到sta ip \n6.target1 连接AP ok\n7.查询到sta ip 为target_ip" - initial condition: STAAP1 - initial condition description (auto): testing sta on sta + ap mode, quit AP (autogen - by STAM1) - module: TCPIP - steps: "1.target1 关闭DHCP OK\n2.target1 设置ip add OK\n3.target1 连接AP fail\n4.target1\ - \ 打开DHCP OK\n5.查询到sta ip \n6.target1 连接AP ok\n7.查询到sta ip 为target_ip" - sub module: DHCP - summary: dhcp client function test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: DHCP client function test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_TCP_0203 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -S -s - - ['R SSC1 RE SEND:\d+,ERROR'] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -S -s - - ['R SSC1 RE SEND:\d+,ERROR'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SSC SSC1 soc -D -s - - ['R SSC1 RE SHUTDOWN:\d+,OK'] - - - SSC SSC1 soc -S -s - - ['R SSC1 RE SEND:\d+,ERROR'] - - - SSC SSC1 soc -S -s 1000 - - ['R SSC1 RE SEND:\d+,ERROR'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.ERROR - - 4.OK - - 5.ERROR - - 6.OK - - 7.OK - - 8.ERROR - - 9.ERROR' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: '1.PC上建立TCP 监听 test_tcp_port1 - - 2.target1上创建UDP传输socket1, - - 3.target1上使用步骤2创建的socket1,去发送数据 - - 4.target1上创建TCP socket2 - - 5.target1上使用步骤4创建的socket2,去发送数据 - - 6.target1上使用步骤4创建的socket2,创建TCP连接,连接成功 - - 7.target1上shutdown 步骤4的socket2 - - 8.target1往socket2发送错误命令发送数据 - - 9.target1上不指定socket往上发送数据' - sub module: TCP - summary: send test. use socket in state that can't send - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use TCP SAP (socket/espconn API) in different state - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_TCP_0202 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -L -s - - ['R SSC1 RE LISTEN:\d+,ERROR'] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SSC SSC1 soc -L -s - - ['R SSC1 RE LISTEN:\d+,ERROR'] - - - SSC SSC1 soc -D -s - - ['R SSC1 RE SHUTDOWN:\d+,OK'] - - - SSC SSC1 soc -L -s - - ['R SSC1 RE LISTEN:\d+,ERROR'] - - - SSC SSC1 soc -L -s 1000 - - ['R SSC1 RE LISTEN:\d+,ERROR'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.ERROR - - 4.OK - - 5.OK - - 6.ERROR - - 7.OK - - 8.ERROR - - 9.ERROR' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: '1.PC上建立TCP 监听 test_tcp_port1 - - 2.target1上创建UDP传输socket,bind到本地ip 0.0.0.0, - - 3.target1上使用步骤2创建的socket,去建立TCP 监听 - - 4.target1上创建TCP socket - - 5.target1上使用步骤4创建的socket,去连接 PC的ip, - - 6.target1上使用步骤4创建的socket,创建TCP 监听 - - 7.target1上shutdown 步骤4的socket - - 8.target1上使用步骤4创建的socket,创建TCP 监听 - - 9.target1上使用不存在socket,创建TCP 监听' - sub module: TCP - summary: STA mode, server listen test. use socket in state that can't listen - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use TCP SAP (socket/espconn API) in different state - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_TCP_0208 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t UDP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -L -s - - ['R SSC1 RE LISTEN:\d+,ERROR'] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SSC SSC1 soc -L -s - - ['R SSC1 RE LISTEN:\d+,ERROR'] - - - SSC SSC1 soc -D -s - - ['R SSC1 RE SHUTDOWN:\d+,OK'] - - - SSC SSC1 soc -L -s - - ['R SSC1 RE LISTEN:\d+,ERROR'] - - - SSC SSC1 soc -L -s 1000 - - ['R SSC1 RE LISTEN:\d+,ERROR'] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.ERROR - - 4 OK - - 5.OK - - 6.ERROR - - 7.OK - - 8.ERROR - - 9.ERROR' - initial condition: APM2 - initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen - a TC with initial condition APSTA2 - module: TCPIP - steps: '1.PC上建立TCP 监听 test_tcp_port1 - - 2.target1上创建UDP传输socket,bind到本地ip 0.0.0.0, - - 3.target1上使用步骤2创建的socket,去建立TCP 监听 - - 4.target1上创建TCP socket - - 5.target1上使用步骤4创建的socket,去连接 PC的ip, - - 6.target1上使用步骤4创建的socket,创建TCP 监听 - - 7.target1上shutdown 步骤4的socket - - 8.target1上使用步骤4创建的socket,创建TCP 监听 - - 9.target1上使用不存在socket,创建TCP 监听' - sub module: TCP - summary: AP mode, server listen test. use socket in state that can't listen - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use TCP SAP (socket/espconn API) in different state - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_DNS_0103 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: 3/5 - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 soc -H -d iot.espressif.cn - - ['R SSC1 A :\+HOSTIP:OK,(.+)\r\n'] - - - SSC SSC1 soc -B -t UDP - - ['R SSC1 A :\+BIND:(\d+),OK'] - - - SSC SSC1 soc -S -s -i -p 9003 -l 10 - - ['P SSC1 RE \+SEND:\d+,OK', P SSC1 SL +10] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK' - initial condition: STAM2 - initial condition description (auto): sta mode, join AP, DHCP on, will autogen a - TC with initial condition STAAP2 - module: TCPIP - steps: '1. get host name "espressif.cn" - - 2. sendto, recvfrom1. get host name "espressif.cn" - - 2. sendto, recvfrom' - sub module: DNS - summary: UDP send to iot.expressif.com - test environment: SSC_T1_2 - test environment description (auto): 'Able to access WAN after connect to AP. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: DNS function test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_DHCP_0206 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -p -t 4 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC1 dhcp -E -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 - - ['R SSC1 C +DHCP:LEASE,OK'] - - - SSC SSC1 dhcp -S -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - LOOP 4 4 "['01','02','03','01']" "[2,3,4,2]" - - [''] - - - SSC SSC2 sta -D - - ['R SSC2 C +QAP:OK'] - - - SSC SSC2 mac -S -o 1 -m 10:22:33:44:55:{%s} - - ['R SSC2 C +MAC:STA,OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC2 ip -Q -o 1 - - ['R SSC2 C +STAIP:192.168.4.{%s}'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 4. get IP 192.168.4.2 - 192.168.4.4 - - 5. get IP 192.168.4.2' - initial condition: T2_1 - initial condition description (auto): target 1 as SoftAP, target 2 as STA, will - autogen a TC with initial condition T2_2 - module: TCPIP - steps: '1. config softap to a random ssid - - 2. disable DHCP server, do config and enable - - 3. target2 change mac, connect to softap, disconnect - - 4. Loop step3 twice - - 5. change to first mac, connect to softap' - sub module: DHCP - summary: dhcp server assign same IP to same MAC when it's not released - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: DHCP server function test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_DHCP_0207 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -p -t 4 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC1 dhcp -E -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 - - ['R SSC1 C +DHCP:LEASE,OK'] - - - SSC SSC1 dhcp -S -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - WIFI CONN 192.168.4.2 - - ['R PC_COM NC ERROR C +WIFICONN:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - WIFI DISCONN2 - - ['R PC_COM NC ERROR C +WIFIDISCONN:OK'] - - - SSC SSC2 sta -D - - ['R SSC2 C +QAP:OK'] - - - SSC SSC2 mac -S -o 1 -m 10:22:33:44:55:66 - - ['R SSC2 C +MAC:STA,OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC2 ip -Q -o 1 - - ['R SSC2 C +STAIP:192.168.4.2'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 3. get IP 192.168.4.2 - - 4. succeed - - 5. succeed - - 6. get IP 192.168.4.2' - initial condition: T2_1 - initial condition description (auto): target 1 as SoftAP, target 2 as STA, will - autogen a TC with initial condition T2_2 - module: TCPIP - steps: '1. config softap to a random ssid - - 2. disable DHCP server, do config and enable - - 3. PC WIFI NIC connect to target1 softap - - 4. target2 connect to target1 softap and disnnect - - 5. PC release IP and disconnected - - 6. target2 change mac and connect to target1' - sub module: DHCP - summary: dhcp server prefer assign released IP to new client - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: DHCP server function test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_DHCP_0204 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -p -t 4 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC1 dhcp -E -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.3 -t 1 - - ['R SSC1 C +DHCP:LEASE,OK'] - - - SSC SSC1 dhcp -S -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC2 ip -Q -o 1 - - ['R SSC2 C +STAIP:192.168.4.2'] - - - DELAY 90 - - [''] - - - SSC SSC2 ip -Q -o 1 - - ['R SSC2 C +STAIP:192.168.4.2'] - - - SSC SSC2 sta -D - - ['R SSC2 C +JAP:DISCONNECTED'] - - - DELAY 60 - - [''] - - - SSC SSC2 mac -S -o 1 -m 10:22:33:44:55:66 - - ['R SSC2 C +MAC:STA,OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC2 ip -Q -o 1 - - ['R SSC2 C +STAIP:192.168.4.2'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 3. get IP 192.168.4.2 - - 5. succeed - - 6. succeed - - 8. get IP 192.168.4.2' - initial condition: T2_1 - initial condition description (auto): target 1 as SoftAP, target 2 as STA, will - autogen a TC with initial condition T2_2 - module: TCPIP - steps: '1. config softap to a random ssid - - 2. config DHCP timeout as 1 minute - - 3. target2 connect to target1 - - 4. wait 90 seconds - - 5. check if target2 IP is same - - 6. target2 disconnect - - 7. wait 60s - - 8. target2 change mac and connect to target1' - sub module: DHCP - summary: dhcp server timeout test - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: DHCP server function test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_DHCP_0205 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -p -t 4 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC1 dhcp -E -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.3 -t 1 - - ['P SSC1 C +DHCP:LEASE,OK'] - - - SSC SSC1 dhcp -S -o 2 - - ['P SSC1 C +DHCP:AP,OK', 'P SSC2 C +JAP:DISCONNECTED'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 3. target2 wifi disconnected' - initial condition: T2_1 - initial condition description (auto): target 1 as SoftAP, target 2 as STA, will - autogen a TC with initial condition T2_2 - module: TCPIP - steps: '1. config softap to a random ssid - - 2. target2 connect to target1 - - 3. disable DHCP server, do config and enable' - sub module: DHCP - summary: disconnect STA if config dhcp server - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: DHCP server function test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_DHCP_0202 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -p -t 4 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC1 dhcp -E -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 - - ['R SSC1 C +DHCP:LEASE,OK'] - - - SSC SSC1 dhcp -S -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - LOOP 3 4 "['01','02','03']" "[2,3,4]" - - [''] - - - SSC SSC2 sta -D - - ['R SSC2 C +QAP:OK'] - - - SSC SSC2 mac -S -o 1 -m 10:22:33:44:55:{%s} - - ['R SSC2 C +MAC:STA,OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC2 ip -Q -o 1 - - ['R SSC2 C +STAIP:192.168.4.{%s}'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 3,4: get IP from dhcp pool with correct sequence' - initial condition: T2_1 - initial condition description (auto): target 1 as SoftAP, target 2 as STA, will - autogen a TC with initial condition T2_2 - module: TCPIP - steps: '1. config softap to a random ssid - - 2. config DHCP Server on Target1 - - 3. target change mac, connect to Target1 - - 4. Loop step3' - sub module: DHCP - summary: dhcp server ip pool - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: DHCP server function test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_DHCP_0203 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -p -t 4 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC1 dhcp -E -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.3 - - ['R SSC1 C +DHCP:LEASE,OK'] - - - SSC SSC1 dhcp -S -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - LOOP 2 4 "['01','02']" "[2,3]" - - [''] - - - SSC SSC2 sta -D - - ['R SSC2 C +QAP:OK'] - - - SSC SSC2 mac -S -o 1 -m 10:22:33:44:55:{%s} - - ['R SSC2 C +MAC:STA,OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC2 ip -Q -o 1 - - ['R SSC2 C +STAIP:192.168.4.{%s}'] - - - SSC SSC2 mac -S -o 1 -m 10:22:33:44:55:66 - - ['R SSC2 C +MAC:STA,OK'] - - - DELAY 20 - - [''] - - - SSC SSC2 ip -Q -o 1 - - ['R SSC2 C +STAIP:0.0.0.0'] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. succeed - - 3. succeed - - 4.1 succeed - - 4.2 failed' - initial condition: T2_1 - initial condition description (auto): target 1 as SoftAP, target 2 as STA, will - autogen a TC with initial condition T2_2 - module: TCPIP - steps: '1. config softap to a random ssid - - 2. config DHCP Server on Target1(.4.2 - .4.3) - - 3. target change mac, connect to Target1 - - 4. Loop step3 twice' - sub module: DHCP - summary: dhcp server ip pool empty - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: DHCP server function test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_TCP_0204 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SOC SOC1 ACCEPT SOC2 - - [R SOC_COM L OK] - - - SSC SSC1 soc -W -s -o 0 - - ['R SSC1 RE WORKTHREAD:\d+,OK'] - - - SOC SOC2 SEND 146000 - - [P SOC_COM R *] - - - SSC SSC1 soc -W -s -o 1 - - ['P SSC1 RE WORKTHREAD:\d+,OK', P SSC1 SL +2920] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK,pc server accept OK - - 4.OK - - 5.OK - - 6.OK - - 7.target收到146000 byte' - initial condition: STAAP2 - initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP - on (autogen by STAM2) - module: TCPIP - steps: '1. PC上建立TCP 监听 test_tcp_port1 - - 2.target1上创建TCP socket - - 3.target1上使用步骤2创建的socket,去连接 PC的ip,test_tcp_port1 - - 4.PC与target1 创建好TCP 连接,有ACCEPT - - 5.target上不进行recv - - 6.PC send 100 * 1460 data to target, - - 7.在target上开始recv' - sub module: TCP - summary: STA mode, recv buffer test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use TCP SAP (socket/espconn API) in different state - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_DHCP_0201 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 dhcp -E -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC1 ip -S -o 2 -i - - ['R SSC1 C +IP:OK'] - - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 - - ['R SSC1 C +DHCP:LEASE,OK'] - - - SSC SSC1 dhcp -L -s 192.168.4.1 -e 192.168.4.10 - - ['R SSC1 C +DHCP:LEASE,ERROR'] - - - SSC SSC1 dhcp -L -s 192.168.4.5 -e 192.168.4.2 - - ['R SSC1 C +DHCP:LEASE,ERROR'] - - - SSC SSC1 dhcp -L -s 192.168.2.2 -e 192.168.2.5 - - ['R SSC1 C +DHCP:LEASE,ERROR'] - - - SSC SSC1 dhcp -S -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - comment: '' - execution time: 0.0 - expected result: '1.target1 关闭DHCP 2 OK - - 2.target1 设置ip 成功 - - 3.设置dhcp 地址池 OK - - 4.ERROR - - 5.ERROR - - 6.ERROR - - 7.target1 打开DHCP ok' - initial condition: APM1 - initial condition description (auto): AP mode, DHCP on, will autogen a TC with initial - condition APSTA1 - module: TCPIP - steps: "1.target1 关闭DHCP 2 \n2.target1 设置ip \n3.设置dhcp 地址池\n4.设置dhcp错误的参数\n5.设置dhcp错误的参数\n\ - 6.设置dhcp错误的参数\n7.target1 打开DHCP ok" - sub module: DHCP - summary: server dhcp lease test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: DHCP server function test - version: v1 (2016-8-15) - CI ready: 'Yes' ID: ^TCPIP_TCP_0208 SDK: '8266_NonOS @@ -12313,6 +11494,7 @@ test cases: initial condition: APSTA2 initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen by APM2) + level: Integration module: TCPIP steps: '1.PC上建立TCP 监听 test_tcp_port1 @@ -12343,7 +11525,7 @@ test cases: test point 2: use TCP SAP (socket/espconn API) in different state version: v1 (2016-8-15) - CI ready: 'Yes' - ID: TCPIP_DHCP_0208 + ID: ^TCPIP_TCP_0210 SDK: '8266_NonOS 8266_RTOS @@ -12355,61 +11537,64 @@ test cases: category: Function cmd set: - '' - - - SSC SSC1 ap -S -s -p -t 4 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC1 dhcp -E -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 - - ['R SSC1 C +DHCP:LEASE,OK'] - - - SSC SSC1 dhcp -S -o 2 - - ['P SSC1 C +DHCP:AP,OK', 'P SSC2 C +JAP:DISCONNECTED'] - - - SSC SSC2 sta -D - - ['R SSC2 C +JAP:DISCONNECTED'] - - - SSC SSC1 dhcp -S -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - WIFI CONN 192.168.4.2 - - ['R PC_COM NC ERROR C +WIFICONN:OK'] - - - SSC SSC1 ap -L - - [R SSC1 C 192.168.4.2 P ] + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SSC SSC1 soc -W -s -o 0 + - ['R SSC1 RE WORKTHREAD:\d+,OK'] + - - SOC SOC2 SEND 146000 + - [P SOC_COM R *] + - - SSC SSC1 soc -W -s -o 1 + - ['P SSC1 RE WORKTHREAD:\d+,OK', P SSC1 SL +2920] comment: '' execution time: 0.0 - expected result: '1. succeed + expected result: '1.OK - 2. succeed + 2.OK - 3. succeed + 3.OK,pc tcp server accept成功 - 4. get IP 192.168.4.2 + 4.OK - 5. can only find target2 with IP 192.168.4.2' - initial condition: T2_1 - initial condition description (auto): target 1 as SoftAP, target 2 as STA, will - autogen a TC with initial condition T2_2 + 6.OK + + 7.收到 146000 数据' + initial condition: APSTA2 + initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen + by APM2) + level: Integration module: TCPIP - steps: '1. config softap to a random ssid + steps: '1. PC上建立TCP 监听 test_tcp_port1 - 2. PC NIC connect to target1 softap + 2.target1上创建TCP socket - 3. disable DHCP server, do config and enable + 3.target1上使用步骤2创建的socket,去连接 PC的ip,test_tcp_port1 - 4. target2 connect to target1 softap + 4.PC与target1 创建好TCP 连接,有ACCEPT - 5. softap list connected station' - sub module: DHCP - summary: dhcp server reconfig and new client able to get first IP in pool - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. + 5.target停止调用recv + + 6.PC send 100 * 1460 data to 8266, + + 7.target重新调用recv' + sub module: TCP + summary: AP mode, recv buffer test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. PC has 1 WiFi NIC. - 2 SSC target connect with PC by UART.' + 1 SSC target connect with PC by UART.' test point 1: basic function - test point 2: DHCP server function test + test point 2: use TCP SAP (socket/espconn API) in different state version: v1 (2016-8-15) - CI ready: 'Yes' - ID: TCPIP_DHCP_0209 + ID: ^TCPIP_TCP_0212 SDK: '8266_NonOS 8266_RTOS @@ -12421,59 +11606,80 @@ test cases: category: Function cmd set: - '' - - - SSC SSC1 ap -S -s -p -t 4 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC1 dhcp -E -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC1 dhcp -L -s 192.168.4.2 -e 192.168.4.100 - - ['R SSC1 C +DHCP:LEASE,OK'] - - - SSC SSC1 dhcp -S -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - WIFI CONN 192.168.4.2 - - ['R PC_COM NC ERROR C +WIFICONN:OK'] - - - DELAY 20 - - [''] - - - SSC SSC1 ap -L - - [R SSC1 C 192.168.4.2 C 192.168.4.3 P P ] + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP -i + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -B -t TCP -i + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 soc -D -s + - ['R SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 soc -B -t TCP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -L -s + - ['R SSC1 RE LISTEN:\d+,OK'] + - - SOC SOC2 CONNECT 0 + - ['R SSC1 A :ACCEPT:(\d+),\d+,.+,\d+'] + - - SSC SSC1 soc -I + - ['P SSC1 RE "SOCINFO:%%s,2,%%s,\d+,%%s,%%d"%%(,,,)', + 'P SSC1 RE "SOCINFO:%%s,2,.+,\d+,.+,\d+"%%()', 'P SSC1 RE "SOCINFO:%%s,82,.+,%%d,.+,\d+"%%(,)', + 'P SSC1 RE "SOCINFO:%%s,2,%%s,%%d,%%s,\d+"%%(,,,)'] comment: '' execution time: 0.0 - expected result: '1. succeed + expected result: '1.OK - 2. succeed + 2.OK - 3. succeed + 3.OK,pc tcp server accept成功 - 4. succeed + 4.OK - 5. find target2 and PC' - initial condition: T2_1 - initial condition description (auto): target 1 as SoftAP, target 2 as STA, will - autogen a TC with initial condition T2_2 + 5.OK + + 6.OK + + 7.OK + + 8.OK + + 9.PC OK, target1 +ACCEPT:3,2,,port + + 10.+SOCINFO:,,, + + +SOCINFO:,,, + + +SOCINFO:, + + +SOCINFO:,,, + + +SOCINF0ALL' + initial condition: APSTA2 + initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen + by APM2) + level: Integration module: TCPIP - steps: '1. config softap to a random ssid - - 2. target2 connect to target1 softap - - 3. disable DHCP server, do config and enable - - 4. PC NIC connect to target1 softap - - 5. softap list connected station' - sub module: DHCP - summary: dhcp server reconfig, old client and new client able to get IP - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. + steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1,本地ip target_ip\n3.target1上使用步骤2创建的socket1,去连接\ + \ PC的ip,test_tcp_port1,PC有ACCEPT\n4.target1上创建TCP socket2,本地ip target_ip\n5.target1上使用步骤4创建的socket2,去连接\ + \ PC的ip,test_tcp_port1,PC有ACCEPT\n6.target1 shutdown socket2 \n7.target1上创建TCP\ + \ socket3,本地端口random_port\n8.target1上使用步骤7创建的socket3,去监听\n9.PC CONNECT,\ + \ ,tcp 连接创建成功,创建socket4 \n10.target1 查询the socket information" + sub module: TCP + summary: AP mode, get active socket info test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. PC has 1 WiFi NIC. - 2 SSC target connect with PC by UART.' + 1 SSC target connect with PC by UART.' test point 1: basic function - test point 2: DHCP server function test + test point 2: use TCP SAP (socket/espconn API) in different state version: v1 (2016-8-15) - CI ready: 'Yes' - ID: ^TCPIP_TCP_0412 + ID: ^TCPIP_TCP_0401 SDK: '8266_NonOS 8266_RTOS @@ -12493,11 +11699,445 @@ test cases: - ['R SSC1 RE CONNECT:\d+,OK'] - - SOC SOC1 ACCEPT SOC2 - [R SOC_COM L OK] + - - SSC SSC1 sta -D + - ['P SSC1 C +QAP:OK', 'P SSC1 RE CLOSED:\d+,0'] + - - SSC SSC1 soc -S -s -l 5 + - ['P SSC1 RE SEND:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.ERROR' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket1 + + 3.target1上使用步骤2创建的socket1,去连接 PC的ip,test_tcp_port1 + + 4.PC与target1创建好TCP 连接,有ACCEPT + + 5.断开与AP 连接 + + 6.8266往PC上发送5字节数据' + sub module: TCP + summary: do TCP send after WIFI disconnected + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: TCP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0402 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SSC SSC1 sta -D + - ['P SSC1 C +QAP:OK', 'P SSC1 RE CLOSED:\d+,0'] - - SSC SSC1 soc -T -s - ['R SSC1 RE CLOSE:\d+,OK'] - - - SSC SSC1 soc -T -s + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.OK' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket1 + + 3.target1上使用步骤2创建的socket1,去连接 PC的ip,test_tcp_port1 + + 4.PC与target1创建好TCP 连接,有ACCEPT + + 5.断开与AP 连接 + + 6.关闭建立的socket1连接' + sub module: TCP + summary: "close TCP socket after WIFI \ndisconnected" + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: TCP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0403 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SSC SSC1 op -S -o 2 + - ['P SSC1 C +MODE:OK', 'P SSC1 RE CLOSED:\d+,0'] + - - SSC SSC1 soc -S -s -l 5 + - ['P SSC1 RE SEND:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.ERROR' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration + module: TCPIP + steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1上使用步骤2创建的socket1,去连接\ + \ PC的ip,test_tcp_port1\n4.PC与target1创建好TCP 连接,有ACCEPT\n5.修改8266的Mode为softAP mode\ + \ \n6.8266往PC上发送5字节数据" + sub module: TCP + summary: do TCP send after mode changed + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: TCP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0404 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SSC SSC1 op -S -o 2 + - ['P SSC1 C +MODE:OK', 'P SSC1 RE CLOSED:\d+,0'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.OK' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration + module: TCPIP + steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1上使用步骤2创建的socket1,去连接\ + \ PC的ip,test_tcp_port1\n4.PC与target1创建好TCP 连接,有ACCEPT\n5.修改8266的Mode为softAP mode\ + \ \n6.关闭建立的socket1连接" + sub module: TCP + summary: close TCP socket after mode changed + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: TCP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0405 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - NIC DISABLED + - [R PC_COM C OK] + - - SSC SSC1 soc -S -s -l 1 + - [''] + - - DELAY 5400 + - ['P SSC1 RE CLOSED:\d+,0'] + comment: '' + execution time: 1.5 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.TCP连接断开' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket1 + + 3.target1上使用步骤2创建的socket1,去连接 PC的ip,test_tcp_port1 + + 4.PC与target1创建好TCP 连接,有ACCEPT + + 5.PC 网卡 disable + + 6.target1上使用socket1发送数据,等待 90 分钟' + sub module: TCP + summary: do TCP send after PC NIC disabled + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: TCP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0406 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - NIC DISABLED + - [R PC_COM C OK] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.OK' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration + module: TCPIP + steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1上使用步骤2创建的socket1,去连接\ + \ PC的ip,test_tcp_port1\n4.PC与target1创建好TCP 连接,有ACCEPT\n5.PC上网卡禁止掉 \n6.关闭建立的socket1连接" + sub module: TCP + summary: close TCP socket after PC NIC disabled + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: TCP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0407 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SSC SSC1 dhcp -E -o 1 + - ['R SSC1 C +DHCP:STA,OK'] + - - SSC SSC1 ip -S -o 1 -i 192.168.111.210 + - ['P SSC1 C +IP:OK', 'P SSC1 RE CLOSED:\d+,0'] + - - SSC SSC1 ip -Q -o 1 + - ['R SSC1 C +STAIP:192.168.111.210'] + - - SSC SSC1 soc -S -s -l 5 + - ['P SSC1 RE SEND:\d+,ERROR'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.OK + + 7.OK + + 8.ERROR' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration + module: TCPIP + steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1上使用步骤2创建的socket1,去连接\ + \ PC的ip,test_tcp_port1\n4.PC与target1创建好TCP 连接,有ACCEPT\n5.关闭8266的DHCP 1\n6.设置sta\ + \ ip \n7.查询sta ip 地址是否生效\n8.8266往PC上发送5字节数据" + sub module: TCP + summary: do TCP send after IP changed + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: TCP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_TCP_0408 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SSC SSC1 dhcp -E -o 1 + - ['R SSC1 C +DHCP:STA,OK'] + - - SSC SSC1 ip -S -o 1 -i 192.168.111.210 + - ['P SSC1 C +IP:OK', 'P SSC1 RE CLOSED:\d+,0'] + - - SSC SSC1 ip -Q -o 1 + - ['R SSC1 C +STAIP:192.168.111.210'] + - - SSC SSC1 soc -T -s - ['R SSC1 RE CLOSE:\d+,OK'] comment: '' execution time: 0.0 @@ -12513,26 +12153,19 @@ test cases: 6.OK - 7.OK' + 7.OK + + 8.OK' initial condition: STAAP2 initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP on (autogen by STAM2) + level: Integration module: TCPIP - steps: '1.PC上建立TCP 监听 test_tcp_port1 - - 2.target1上创建TCP socket1 - - 3.target1上使用步骤2创建的socket1,去连接 PC的ip,test_tcp_port1 - - 4.PC与target1创建好TCP 连接,有ACCEPT - - 5.target1上创建TCP socket2 - - 6.关闭socket1 连接 - - 7.关闭socket2连接' + steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1上使用步骤2创建的socket1,去连接\ + \ PC的ip,test_tcp_port1\n4.PC与target1创建好TCP 连接,有ACCEPT\n5.关闭8266的DHCP 1\n6.设置sta\ + \ ip \n7.查询sta ip 地址是否生效\n8.关闭建立的socket1连接" sub module: TCP - summary: close TCP send after socket changed + summary: close TCP socket after IP changed test environment: SSC_T1_1 test environment description (auto): 'PC has 2 wired NIC connected to AP. @@ -12587,6 +12220,7 @@ test cases: initial condition: STAAP2 initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP on (autogen by STAM2) + level: Integration module: TCPIP steps: '1.PC上建立TCP 监听 test_tcp_port1 @@ -12613,45 +12247,120 @@ test cases: test point 2: TCP handling abnormal event version: v1 (2016-8-15) - CI ready: 'Yes' - ID: WIFI_CONN_0901 + ID: ^TCPIP_TCP_0412 SDK: '8266_NonOS 8266_RTOS ESP32_IDF' - Test App: basic function + Test App: SSC allow fail: '' auto test: 'Yes' category: Function cmd set: - '' - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:CONNECTED'] - - - SSC SSC1 sta -D - - ['R SSC1 RE JAP:DISCONNECTED,\d+,8'] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 RE JAP:DISCONNECTED,\d+,15'] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 RE JAP:DISCONNECTED,\d+,201'] + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -C -s -i -p + - ['R SSC1 RE CONNECT:\d+,OK'] + - - SOC SOC1 ACCEPT SOC2 + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t TCP + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] comment: '' execution time: 0.0 - expected result: '1. disconnect event reason REASON_ASSOC_LEAVE + expected result: '1.OK - 2. disconnect event reason REASON_4WAY_HANDSHAKE_TIMEOUT + 2.OK - 3. disconnect event reason REASON_NO_AP_FOUND' - initial condition: STAM1 - initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a - TC with initial condition STAAP1 - module: WIFI MAC - steps: '1. sta connect to AP, and disconnect + 3.OK; PC TCP server accept 成功 - 2. connect to AP with wrong password + 4.OK - 3. connect to AP not exist' - sub module: WIFI Connect - summary: test wifi disconnect reason REASON_ASSOC_LEAVE, REASON_4WAY_HANDSHAKE_TIMEOUT, - REASON_NO_AP_FOUND + 5.OK + + 6.OK + + 7.OK' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration + module: TCPIP + steps: '1.PC上建立TCP 监听 test_tcp_port1 + + 2.target1上创建TCP socket1 + + 3.target1上使用步骤2创建的socket1,去连接 PC的ip,test_tcp_port1 + + 4.PC与target1创建好TCP 连接,有ACCEPT + + 5.target1上创建TCP socket2 + + 6.关闭socket1 连接 + + 7.关闭socket2连接' + sub module: TCP + summary: close TCP send after socket changed + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: TCP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_UDP_0101 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -i 0.0.0.0 -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 C BIND:ERROR'] + - - SSC SSC1 soc -B -t TCP -p + - ['R SSC1 RE BIND:(\d+),OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.ERROR + + 4.OK' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration + module: TCPIP + steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 2.target1上UDP传输,Bind socket2,本地ip 0.0.0.0 target_udp_port2 + + 3.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 4.target1上创建TCP socket3, target_udp_port1' + sub module: UDP + summary: STA mode, udp bind test. use different ip, port test environment: SSC_T1_1 test environment description (auto): 'PC has 2 wired NIC connected to AP. @@ -12659,198 +12368,58 @@ test cases: 1 SSC target connect with PC by UART.' test point 1: basic function - test point 2: wifi disconnect reason test + test point 2: use UDP SAP (socket/espconn API) with different parameter version: v1 (2016-8-15) - CI ready: 'Yes' - ID: WIFI_CONN_0902 + ID: ^TCPIP_UDP_0102 SDK: '8266_NonOS 8266_RTOS ESP32_IDF' Test App: SSC - allow fail: '' + allow fail: 1/5 auto test: 'Yes' category: Function cmd set: - '' - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:CONNECTED'] - - - APC OFF - - [P PC_COM L OK, 'R SSC1 RE JAP:DISCONNECTED,\d+,200'] - - - APC ON - - [P PC_COM L OK] + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SOC SOC2 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 10 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 10] + - - SSC SSC1 soc -S -s -i -p -l 10 + - ['P SSC1 RE SEND:(\d+),OK', P SOC2 UL 10] comment: '' execution time: 0.0 - expected result: '1. succeed + expected result: '1.OK - 2. disconnect event REASON_BEACON_TIMEOUT' - initial condition: STAM1 - initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a - TC with initial condition STAAP1 - module: WIFI MAC - steps: '1. connect to AP + 2.OK - 2. AP power off' - sub module: WIFI Connect - summary: test wifi disconnect reason REASON_BEACON_TIMEOUT - test environment: SSC_T1_APC - test environment description (auto): "PC has 1 wired NIC connected to AP.\nPC has\ - \ 1 wired NIC connected to APC (static IP within the same subnet with APC). \n\ - APC control AP power supply. \nPC has 1 WiFi NIC. \n1 SSC target connect with\ - \ PC by UART." - test point 1: basic function - test point 2: wifi disconnect reason test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_CONN_0903 - SDK: '8266_NonOS + 3.OK - 8266_RTOS + 4.OK - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 sta -C -s -p bacfd - - ['R SSC1 RE JAP:DISCONNECTED,\d+,2'] - comment: '' - execution time: 0.0 - expected result: 1. disconect event reason REASON_AUTH_EXPIRE - initial condition: STAM1 - initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a - TC with initial condition STAAP1 - module: WIFI MAC - steps: 1. connect WEP ap with error password (valid wep password) - sub module: WIFI Connect - summary: test wifi disconnect reason REASON_AUTH_EXPIRE - test environment: SSC_T1_WEP - test environment description (auto): '1 SSC target connect with PC by UART. + 5.OK' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration + module: TCPIP + steps: '1.PC上SOC1 UDP传输,bing - One WEP share key AP placed near SSC1.' - test point 1: basic function - test point 2: wifi disconnect reason test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_SCAN_0201 - SDK: ESP32_IDF - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m b - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 sta -S - - [R SSC1 P P P P ] - - - SSC SSC1 phy -S -o 1 -m g - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 sta -S - - [R SSC1 P P P P ] - - - SSC SSC1 phy -S -o 1 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 sta -S - - [R SSC1 P P P P ] - - - SSC SSC1 phy -S -o 1 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 sta -S - - [R SSC1 P P P P ] - comment: '' - execution time: 0.0 - expected result: '3. find all 3 ext APs + 2.PC上SOC2 UDP传输,bing - 5. find all 3 ext APs + 3.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - 7. find all 3 ext APs + 4.target1上使用步骤3创建的socket1,往pc_ip,test_tcp_port1上发送10字节数据 - 9. find all 3 ext APs' - initial condition: STAM1 - initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a - TC with initial condition STAAP1 - module: WIFI MAC - steps: '1. 3 ext APs in 11b, 11g, 11n mode - - 2. STA in 11b mode - - 3. do all channel scan - - 4. STA in 11g mode - - 5. do all channel scan - - 6. STA in 11n ht20 mode - - 7. do all channel scan - - 8. STA in 11n ht40 mode - - 9. do all channel scan' - sub module: WIFI Scan - summary: STA in differnt PHY mode to scan AP in different PHY mode - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: Scan in different mode and channel - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: WIFI_CONN_0503 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 sta -R -r 0 - - [R SSC1 C OK] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:OK', 'R SSC1 NC +JAP:DISCONNECTED,1 C +JAP:DISCONNECTED,3'] - - - DELAY 5 - - ['R SSC1 NC +JAP:DISCONNECTED', P PC_COM C +DELAYDONE] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:OK', 'R SSC1 NC +JAP:DISCONNECTED,1 C +JAP:DISCONNECTED,2'] - - - DELAY 5 - - ['R SSC1 NC +JAP:DISCONNECTED', P PC_COM C +DELAYDONE] - - - SSC SSC1 sta -R -r 1 - - [SSC SSC1 C OK] - comment: '' - execution time: 0.0 - expected result: '1. succeed - - 2. not reconnect when connect failed, status when recv disconnect event is correct - - 3. not reconnect when connect failed, status when recv disconnect event is correct - - 4. succeed' - initial condition: STAM1 - initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a - TC with initial condition STAAP1 - module: WIFI MAC - steps: '1. set sta reconnect policy as not reconnect - - 2. sta connect to ap not exist - - 3. sta connect to ap with wrong password - - 4. reset sta reconnect policy as auto reconnect - - ' - sub module: WIFI Connect - summary: reconnect policy interact with failed STA connect/reconnect + 5.target1上使用步骤3创建的socket1,往pc_ip2,test_tcp_port2上发送10字节数据' + sub module: UDP + summary: STA mode, sendto test. use different ip, port test environment: SSC_T1_1 test environment description (auto): 'PC has 2 wired NIC connected to AP. @@ -12858,287 +12427,404 @@ test cases: 1 SSC target connect with PC by UART.' test point 1: basic function - test point 2: reconnect policy test + test point 2: use UDP SAP (socket/espconn API) with different parameter version: v1 (2016-8-15) - CI ready: 'Yes' - ID: WIFI_PHY_0402 - SDK: ESP32_IDF + ID: ^TCPIP_UDP_0103 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' Test App: SSC - allow fail: '' + allow fail: 1/5 auto test: 'Yes' category: Function cmd set: - '' - - - SSC SSC1 phy -S -o 1 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m n -b 20 - - ['R SSC2 C +PHY:OK'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED'] - - - SSC SSC1 sta -C -s -p - - [''] - - - DELAY 10 - - ['P SSC2 NC +JAP:DISCONNECTED', 'P SSC1 C +JAP:CONNECTED'] + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 1 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 1] + - - SSC SSC1 soc -S -s -i -p -l 1472 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 1472] + - - SSC SSC1 soc -S -s -i -p -l 1473 + - ['P SSC1 RE SEND:(\d+),OK', P SOC_COM NC SOC_RECVFROM] + - - SSC SSC1 soc -S -s -i -p -l 1472 -n 10 -j 20 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 14720] comment: '' execution time: 0.0 - expected result: 3. SoftAP and STA in channel2, both bandwidth 20M, SoftAP not get - disconnected - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. SoftAP 11n ht20, in channel1, ext AP 11n ht20, in channel2 + expected result: '1.OK - 2. AP get connected + 2.OK - 3. STA connect to ext AP' - sub module: Phy Mode - summary: SoftAP ext AP in defferent channel, both bandwidth 20M, Softap get connected - than STA connect to AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. + 3.OK - PC has one WiFi NIC support capture wlan packet using libpcap. + 4.OK - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + 5.OK,没有到UDP包 - Put 4 APs near SSC targets.' + 6.OK' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration + module: TCPIP + steps: '1.PC上SOC1 UDP传输,bing + + 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1字节数据 + + 4.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1472字节数据 + + 5.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1473字节数据 + + 6.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1472*10字节数据' + sub module: UDP + summary: STA mode, sendto test with different length + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' test point 1: basic function - test point 2: STA+SoftAP initial channel test - version: v1 (2015-8-15) + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) - CI ready: 'Yes' - ID: WIFI_PHY_0401 - SDK: ESP32_IDF + ID: ^TCPIP_UDP_0104 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' Test App: SSC - allow fail: '' + allow fail: 1/5 auto test: 'Yes' category: Function cmd set: - '' - - - SSC SSC1 phy -S -o 1 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m n -b 20 - - ['R SSC2 C +PHY:OK'] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:CONNECTED'] - - - SSC SSC2 sta -C -s -p - - [''] - - - DELAY 10 - - ['P SSC1 NC +JAP:DISCONNECTED', 'P SSC2 C +JAP:CONNECTED'] + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SOC SOC1 SENDTO 1 + - [R SSC1 SL +1] + - - SOC SOC1 SENDTO 1472 + - ['R SSC1 RE "RECVFROM:%%s,1472,%%s,%%u"%%(,,)'] + - - SOC SOC1 SENDTO 1473 + - [P SSC1 NC +RECVFROM, P SOC_COM C OK] + - - SOC SOC2 BIND + - [R SOC_COM L OK] + - - SOC SOC2 SENDTO 1472 + - ['R SSC1 RE "RECVFROM:%%s,1472,%%s,%%u"%%(,,)'] comment: '' execution time: 0.0 - expected result: 3. SoftAP and STA in channel2, both bandwidth 20M, STA not disconnected - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. SoftAP 11n ht20, in channel1, ext AP 11n ht20, in channel2 + expected result: '1.OK - 2. STA connect to ext AP + 2.OK - 3. AP get connected' - sub module: Phy Mode - summary: SoftAP ext AP in defferent channel, both bandwidth 20M, STA connect to - AP then Softap get connected - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. + 3.OK - PC has one WiFi NIC support capture wlan packet using libpcap. + 4.OK - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + 5.OK,没收到UDP包 - Put 4 APs near SSC targets.' + 6.OK + + 7.OK' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration + module: TCPIP + steps: '1.PC上SOC1 UDP传输,bing + + 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 3.PC往8266上发送1字节数据 + + 4.PC往8266上发送1472字节数据 + + 5.PC往8266上发送1473字节数据 + + 6.PC上SOC2 UDP传输,bing + + 7.PC往8266上发送1472字节数据' + sub module: UDP + summary: STA mode, recvfrom basic test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' test point 1: basic function - test point 2: STA+SoftAP initial channel test - version: v1 (2015-8-15) + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) - CI ready: 'Yes' - ID: WIFI_PHY_0407 - SDK: ESP32_IDF + ID: ^TCPIP_UDP_0105 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' Test App: SSC allow fail: '' auto test: 'Yes' category: Function cmd set: - '' - - - SSC SSC1 phy -S -o 1 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m n -b 40 - - ['R SSC2 C +PHY:OK'] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:CONNECTED'] - - - SSC SSC2 sta -C -s -p - - [''] - - - DELAY 10 - - ['P SSC1 NC +JAP:DISCONNECTED', 'P SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+'] comment: '' execution time: 0.0 - expected result: 3. SoftAP and STA in channel2, SoftAP 40M, STA 20M, STA not disconnected - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. SoftAP 11n ht40, in channel1, ext AP 11n ht20, in channel2 + expected result: '1.OK - 2. STA connect to ext AP + 2.OK' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration + module: TCPIP + steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - 3. AP get connected' - sub module: Phy Mode - summary: SoftAP ext AP in defferent channel, SoftAP 40M, ext AP 20M, STA connect - to AP then Softap get connected - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. + 2.关闭socket1' + sub module: UDP + summary: STA mode, close UDP sockets test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. - PC has one WiFi NIC support capture wlan packet using libpcap. + PC has 1 WiFi NIC. - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' + 1 SSC target connect with PC by UART.' test point 1: basic function - test point 2: STA+SoftAP initial channel test - version: v1 (2015-8-15) + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) - CI ready: 'Yes' - ID: WIFI_PHY_0406 - SDK: ESP32_IDF + ID: ^TCPIP_UDP_0106 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' Test App: SSC allow fail: '' auto test: 'Yes' category: Function cmd set: - '' - - - SSC SSC1 phy -S -o 1 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m n -b 40 - - ['R SSC2 C +PHY:OK'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED'] - - - SSC SSC1 sta -C -s -p - - [''] - - - DELAY 10 - - ['P SSC2 NC +JAP:DISCONNECTED', 'P SSC1 C +JAP:CONNECTED'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] comment: '' execution time: 0.0 - expected result: 3. SoftAP and STA in channel2, both bandwidth 40M, SoftAP not get - disconnected - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. SoftAP 11n ht40, in channel1, ext AP 11n ht40, in channel2 + expected result: '1.ok - 2. AP get connected + 2.ok - 3. STA connect to ext AP' - sub module: Phy Mode - summary: SoftAP ext AP in defferent channel, both bandwidth 40M, Softap get connected - than STA connect to AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. + 3.ok - PC has one WiFi NIC support capture wlan packet using libpcap. + 4.ok - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + 5.ok' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration + module: TCPIP + steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - Put 4 APs near SSC targets.' + 2.target1上UDP传输,Bind socket2,本地ip target_udp_port2 + + 3.target1上UDP传输,Bind socket3,本地ip target_udp_port3 + + 4.target1上UDP传输,Bind socket4,本地ip target_udp_port4 + + 5.target1上UDP传输,Bind socket5,本地ip target_udp_port5' + sub module: UDP + summary: STA mode, create max udp socket test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' test point 1: basic function - test point 2: STA+SoftAP initial channel test - version: v1 (2015-8-15) + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) - CI ready: 'Yes' - ID: WIFI_PHY_0405 - SDK: ESP32_IDF + ID: ^TCPIP_UDP_0107 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' Test App: SSC allow fail: '' auto test: 'Yes' category: Function cmd set: - '' - - - SSC SSC1 phy -S -o 1 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m n -b 40 - - ['R SSC2 C +PHY:OK'] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:CONNECTED'] - - - SSC SSC2 sta -C -s -p - - [''] - - - DELAY 10 - - ['P SSC1 NC +JAP:DISCONNECTED', 'P SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -I + - ['P SSC1 RE "SOCINFO:%%s,1,.+,%%d"%%(,)'] comment: '' execution time: 0.0 - expected result: 3. SoftAP and STA in channel2, both bandwidth 40M, STA not disconnected - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. SoftAP 11n ht40, in channel1, ext AP 11n ht40, in channel2 + expected result: '1.OK - 2. STA connect to ext AP + 2.OK' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration + module: TCPIP + steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - 3. AP get connected' - sub module: Phy Mode - summary: SoftAP ext AP in defferent channel, both bandwidth 40M, STA connect to - AP then Softap get connected - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. + 2.target1上查询创建socket信息' + sub module: UDP + summary: STA mode, get active socket info test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. - PC has one WiFi NIC support capture wlan packet using libpcap. + PC has 1 WiFi NIC. - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' + 1 SSC target connect with PC by UART.' test point 1: basic function - test point 2: STA+SoftAP initial channel test - version: v1 (2015-8-15) + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) - CI ready: 'Yes' - ID: WIFI_PHY_0404 - SDK: ESP32_IDF + ID: ^TCPIP_UDP_0108 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' Test App: SSC allow fail: '' auto test: 'Yes' category: Function cmd set: - '' - - - SSC SSC1 phy -S -o 1 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m n -b 20 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m n -b 20 - - ['R SSC2 C +PHY:OK'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED'] - - - SSC SSC1 sta -C -s -p - - [''] - - - DELAY 10 - - ['P SSC2 NC +JAP:DISCONNECTED', 'P SSC1 C +JAP:CONNECTED'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -i 0.0.0.0 -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 C BIND:ERROR'] + - - SSC SSC1 soc -B -t TCP -p + - ['R SSC1 RE BIND:(\d+),OK'] comment: '' execution time: 0.0 - expected result: 3. SoftAP and STA in channel2, SoftAP 20M, STA 40M, SoftAP not - get disconnected - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. SoftAP 11n ht20, in channel1, ext AP 11n ht40, in channel2 + expected result: '1.OK - 2. AP get connected + 2.OK - 3. STA connect to ext AP' - sub module: Phy Mode - summary: SoftAP ext AP in defferent channel, SoftAP 20M, ext AP 40M, Softap get - connected than STA connect to AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. + 3.ERROR - PC has one WiFi NIC support capture wlan packet using libpcap. + 4.OK' + initial condition: APSTA2 + initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen + by APM2) + level: Integration + module: TCPIP + steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + 2.target1上UDP传输,Bind socket2,本地ip 0.0.0.0 target_udp_port2 - Put 4 APs near SSC targets.' + 3.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 4.target1上创建TCP socket3, target_udp_port1' + sub module: UDP + summary: AP mode, udp bind test. use different ip, port + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' test point 1: basic function - test point 2: STA+SoftAP initial channel test - version: v1 (2015-8-15) + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_UDP_0110 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: 1/5 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 1 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 1] + - - SSC SSC1 soc -S -s -i -p -l 1472 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 1472] + - - SSC SSC1 soc -S -s -i -p -l 1473 + - ['P SSC1 RE SEND:(\d+),OK', P SOC_COM NC SOC_RECVFROM] + - - SSC SSC1 soc -S -s -i -p -l 1472 -n 10 + -j 20 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 14720] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.OK,没收到UDP包 + + 6.OK' + initial condition: APSTA2 + initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen + by APM2) + level: Integration + module: TCPIP + steps: '1.PC上SOC1 UDP传输,bing + + 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1字节数据 + + 4.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1472字节数据 + + 5.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1473字节数据 + + 6.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送1472*10字节数据' + sub module: UDP + summary: AP mode, sendto test with different length + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) - CI ready: 'Yes' ID: ^TCPIP_UDP_0112 SDK: '8266_NonOS @@ -13164,6 +12850,7 @@ test cases: initial condition: APSTA2 initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen by APM2) + level: Integration module: TCPIP steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 @@ -13180,52 +12867,64 @@ test cases: test point 2: use UDP SAP (socket/espconn API) with different parameter version: v1 (2016-8-15) - CI ready: 'Yes' - ID: WIFI_PHY_0408 - SDK: ESP32_IDF + ID: ^TCPIP_UDP_0113 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' Test App: SSC allow fail: '' auto test: 'Yes' category: Function cmd set: - '' - - - SSC SSC1 phy -S -o 1 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 phy -S -o 1 -m n -b 40 - - ['R SSC2 C +PHY:OK'] - - - SSC SSC2 sta -C -s -p - - ['P SSC2 C +JAP:CONNECTED'] - - - SSC SSC1 sta -C -s -p - - [''] - - - DELAY 10 - - ['P SSC2 NC +JAP:DISCONNECTED', 'P SSC1 C +JAP:CONNECTED'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 RE BIND:(\d+),OK'] comment: '' execution time: 0.0 - expected result: 3. SoftAP and STA in channel2, SoftAP 40M, STA 20M, SoftAP not - get disconnected - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1. SoftAP 11n ht40, in channel1, ext AP 11n ht20, in channel2 + expected result: '1.ok - 2. AP get connected + 2.ok - 3. STA connect to ext AP' - sub module: Phy Mode - summary: SoftAP ext AP in defferent channel, SoftAP 40M, ext AP 20M, Softap get - connected than STA connect to AP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. + 3.ok - PC has one WiFi NIC support capture wlan packet using libpcap. + 4.ok - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + 5.ok' + initial condition: APSTA2 + initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen + by APM2) + level: Integration + module: TCPIP + steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - Put 4 APs near SSC targets.' + 2.target1上UDP传输,Bind socket2,本地ip target_udp_port2 + + 3.target1上UDP传输,Bind socket3,本地ip target_udp_port3 + + 4.target1上UDP传输,Bind socket4,本地ip target_udp_port4 + + 5.target1上UDP传输,Bind socket5,本地ip target_udp_port5' + sub module: UDP + summary: AP mode, create max udp socket test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' test point 1: basic function - test point 2: STA+SoftAP initial channel test - version: v1 (2015-8-15) + test point 2: use UDP SAP (socket/espconn API) with different parameter + version: v1 (2016-8-15) - CI ready: 'Yes' ID: ^TCPIP_UDP_0114 SDK: '8266_NonOS @@ -13251,6 +12950,7 @@ test cases: initial condition: APSTA2 initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen by APM2) + level: Integration module: TCPIP steps: '1.target1上UDP传输,Bind socket1,本地ip target_udp_port1 @@ -13267,7 +12967,7 @@ test cases: test point 2: use UDP SAP (socket/espconn API) with different parameter version: v1 (2016-8-15) - CI ready: 'Yes' - ID: ^WIFI_CONN_0104 + ID: ^TCPIP_UDP_0201 SDK: '8266_NonOS 8266_RTOS @@ -13279,45 +12979,69 @@ test cases: category: Function cmd set: - '' - - - SSC SSC1 ap -S -s -p -t -m - 1 - - ['R SSC1 C +SAP:OK'] - - - WIFI DISCONN - - ['R PC_COM C +WIFIDISCONN:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] - - - WIFI CONN - - - ['R PC_COM C +WIFICONN:ERROR'] + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -W -s -o 0 + - ['R SSC1 RE WORKTHREAD:\d+,OK'] + - - SOC SOC1 SENDTO 1472 + - [''] + - - SOC SOC1 SENDTO 1472 + - [''] + - - SOC SOC1 SENDTO 1472 + - [''] + - - SOC SOC1 SENDTO 1472 + - [''] + - - SOC SOC1 SENDTO 1472 + - [''] comment: '' execution time: 0.0 - expected result: '1. target1 set AP,set max allowed sta as 1 + expected result: '1.OK - 2. use PC disconnect, + 2.OK - 3.target 2 jap succeed + 3.OK - 4.PC WIFI can not CONN' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - module: WIFI MAC - steps: '1.target1下设置ssid 和pwd 加密方式,set max allowed sta as 1 + 4.PC OK - 2.use PC disconnect target1 + 5.PC OK - 3.target 2 jap target1 + 6.PC OK - 4.PC WIFI CONNECT target1' - sub module: WIFI Connect - summary: station SAP test, max allowed sta - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. + 7.PC OK + + 8.PC OK SOC_CLOSE=SOC1' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration + module: TCPIP + steps: '1.PC上SOC1 UDP传输,bing + + 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 3.target1上关闭工作线程 + + 4.PC往8266上发送1472字节数据 + + 5.PC往8266上发送1472字节数据 + + 6.PC往8266上发送1472字节数据 + + 7.PC往8266上发送1472字节数据 + + 8.PC往8266上发送1472字节数据' + sub module: UDP + summary: STA mode, recv buffer test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. PC has 1 WiFi NIC. - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: SAP/JAP with different config + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: use UDP SAP (socket/espconn API) in different state version: v1 (2016-8-15) - CI ready: 'Yes' ID: ^TCPIP_UDP_0202 @@ -13368,6 +13092,7 @@ test cases: initial condition: APSTA2 initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen by APM2) + level: Integration module: TCPIP steps: '1.PC上SOC1 UDP传输,bing @@ -13396,364 +13121,406 @@ test cases: test point 2: use UDP SAP (socket/espconn API) in different state version: v1 (2016-8-15) - CI ready: 'Yes' - ID: ^TCPIP_IGMP_0103 + ID: ^TCPIP_UDP_0301 SDK: '8266_NonOS 8266_RTOS ESP32_IDF' Test App: SSC - allow fail: '' + allow fail: 1/5 auto test: 'Yes' category: Function cmd set: - '' - - - SSC SSC1 igmp -J -h -m 224.1.1.1 - - ['R SSC1 C +IGMP:OK'] - - - SSC SSC1 igmp -L -h -m 224.1.1.1 - - ['R SSC1 C +IGMP:OK'] - - - SSC SSC1 igmp -J -h -m 223.1.1.1 - - ['R SSC1 C +IGMP:ERROR'] - - - SSC SSC1 igmp -J -h -m 240.1.1.1 - - ['R SSC1 C +IGMP:ERROR'] - - - SSC SSC1 igmp -J -h 192.168.237.77 -m 224.1.1.1 - - ['R SSC1 C +IGMP:ERROR'] - - - SSC SSC1 igmp -J -h 192.168.237.77 -m 240.1.1.1 - - ['R SSC1 C +IGMP:ERROR'] - comment: '' - execution time: 0.0 - expected result: '1. success - - 2. failed - - 3. failed - - 4. failed' - initial condition: APSTA2 - initial condition description (auto): testing ap on sta + ap mode, PC join AP (autogen - by APM2) - module: TCPIP - steps: '1. join group with correct host addr and multicast addr - - 2. join group with correct host addr and wrong multicast addr - - 3. join group with wrong host addr and correct multicast addr - - 4. join group with wrong host addr and wrong multicast addr' - sub module: IGMP - summary: softAP IGMP join group address check - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: IGMP API parameter check - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_CONN_0101 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -t 0 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] - - - SSC SSC1 ap -S -s -p -t 2 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] - - - SSC SSC1 ap -S -s -p -t - - ['R SSC1 C +SAP:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] - - - SSC SSC1 ap -S -s -p -t 4 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] - - - SSC SSC1 ap -S -s -p -t 1 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC2 sta -S - - ['R SSC2 RE "\+SCAN:%%s,.+,0,\d+"%%()'] - - - SSC SSC1 ap -S -s -p -t 5 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC2 sta -S - - ['R SSC2 RE "\+SCAN:%%s,.+,0,\d+"%%()'] - comment: '' - execution time: 0.0 - expected result: "1.target1 set AP,open, \n2.target 2 jap succeed\n3.target1 set\ - \ AP,wpa_psk \n4.target 2 jap succeed\n5.target1 set AP, wpa2_psk \n6.target 2\ - \ jap succeed\n7.target1 set AP,wap_wpa2_psk\n8.target 2 jap succeed\n9.target1\ - \ set AP,加密方式为t 1\n10.target 2 上查询到target_ssid\n11.target1 set AP,加密方式为t 5\n12.target\ - \ 2 上查询到target_ssid" - initial condition: T2_1 - initial condition description (auto): target 1 as SoftAP, target 2 as STA, will - autogen a TC with initial condition T2_2 - module: WIFI MAC - steps: "1.target1下设置ssid 和pwd,加密方式 open\n2.target2 jap target1\n3.target1下设置ssid\ - \ 和pwd,加密方式 wpa_psk \n4.target2 jap target1\n5.target1下设置ssid 和pwd,加密方式 wpa2_psk\ - \ \n6.target 2 jap target1\n7.target1下设置ssid 和pwd,加密方式 wap_wpa2_psk\n8.target2\ - \ jap target1\n9.target1下设置ssid 和pwd,加密方式 wep \n10.target2上查询target_ssid\n11.target1下设置ssid\ - \ 和pwd,加密方式 t 5 错误的加密方式\n12.target2上查询 target_ssid" - sub module: WIFI Connect - summary: station SAP+JAP test, different encryption - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: SAP/JAP with different config - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_CONN_0102 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -t 0 -n 1 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] - - - SSC SSC1 ap -S -s -t 0 -n 13 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] - - - SSC SSC1 ap -S -s -n 15 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC2 sta -S - - ['R SSC2 RE "\+SCAN:%%s,.+,\d+,1"%%()'] - comment: '' - execution time: 0.0 - expected result: '1. target1 set AP,set channel 1 - - 2.target 2 jap succeed - - 3.target1 set AP,set channel 10 - - 4.target 2 jap succeed - - 5.target1 set AP,set channel 15 - - 6.target 2 上查询到target_ssid' - initial condition: T2O_1 - initial condition description (auto): same as T2_1 but will NOT autogen a TC with - initial condition T2_2 - module: WIFI MAC - steps: '1. target1下设置ssid 和pwd 加密方式,set channel 1 - - 2.target2 jap target 1 - - 3.target1下设置ssid 和pwd 加密方式,set channel 10 - - 4.target2 jap target 1 - - 5.target1下设置ssid 和pwd 加密方式,set channel 15 - - 6.target 2 上查询target_ssid' - sub module: WIFI Connect - summary: station SAP+JAP test, different channel - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: SAP/JAP with different config - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_CONN_0103 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -p -t -h - 0 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC2 sta -S -h 0 - - [R SSC2 P , R SSC2 C +SCANDONE] - - - SSC SSC1 ap -S -s -p -t -h - 1 - - ['R SSC1 C +SAP:OK'] - - - DELAY 3 - - [''] - - - SSC SSC2 sta -S -h 0 - - [R SSC2 C +SCANDONE] - - - DELAY 3 - - [''] - - - SSC SSC2 sta -S -h 0 - - [R SSC2 NP C +SCANDONE] - comment: '' - execution time: 0.0 - expected result: '1.target1 set AP,set ssid broad cast - - 2.target 2上scan target_ap_mac - - 3.target1 set AP,set ssid hidden, - - 4.target 2上不能scan target_ap_mac' - initial condition: T2_1 - initial condition description (auto): target 1 as SoftAP, target 2 as STA, will - autogen a TC with initial condition T2_2 - module: WIFI MAC - steps: '1. target1下设置ssid 和pwd 加密方式,set ssid broad cast - - 2.target 2上scan target_ap_mac - - 3. target1下设置ssid 和pwd 加密方式,set ssid hidden, - - 4.target 2上scan target_ap_mac' - sub module: WIFI Connect - summary: station SAP+JAP test, ssid hidden - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: SAP/JAP with different config - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: WIFI_PHY_0504 - SDK: ESP32_IDF - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 phy -S -o 1 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC1 phy -S -o 2 -m n -b 40 - - ['R SSC1 C +PHY:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:CONNECTED'] - - - SSC SSC3 sta -C -s -p - - ['R SSC3 C +JAP:CONNECTED'] - - - SSC SSC2 sta -C -s -p - - [''] - - - DELAY 10 - - ['P SSC2 C +JAP:CONNECTED', 'P SSC[1,3] NC +JAP:DISCONNECTED'] - comment: '' - execution time: 0.0 - expected result: 4. all STA not get disconnected; target 1 SoftAP and STA both in - channel2 20M - initial condition: T3_PHY1 - initial condition description (auto): '1. target 1 and target 2 set to AP+STA mode, - target 3 set to STA mode - - 2. all interface of target 2,3 set to 11n ht40 - - 3. config softAP of target 1 and target 2' - module: WIFI MAC - steps: '1. target 1 STA and SoftAP set to 40M - - 2. target 2 STA connect to ap_channel1_40 - - 3. target 1/3 STA connect to target 2/1 SoftAP - - 4. target 2 STA connect to ap_channel2_20' - sub module: Phy Mode - summary: SoftAP STA in channel1, SoftAP 20M, STA 40M, STA changed to channel2 40M - test environment: SSC_T3_PhyMode - test environment description (auto): '3 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with (HT20, channel1), (HT20, channel2), (HT40, channel1), (HT40, channel2). - - Put 4 APs near SSC targets.' - test point 1: basic function - test point 2: STA+SoftAP dynamic channel switch test - version: v1 (2015-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_IP_0101 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 dhcp -S -o 1 - - ['R SSC1 C +DHCP:STA,OK'] - - - SSC SSC1 ip -S -o 1 -i 192.168.123.123 - - ['R SSC1 C +IP:ERROR'] - - - SSC SSC1 dhcp -E -o 1 - - ['R SSC1 C +DHCP:STA,OK'] - - - SSC SSC1 ip -S -o 1 -i 192.168.123.123 - - ['R SSC1 C +IP:OK'] - - - SSC SSC1 ip -Q -o 1 - - ['R SSC1 C +STAIP:192.168.123.123'] + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -i -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 5 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] + - - SSC SSC1 sta -D + - ['P SSC1 C +QAP:OK'] + - - SSC SSC1 soc -S -s -i -p -l 5 + - ['P SSC1 RE SEND:\d+,ERROR'] comment: '' execution time: 0.0 expected result: '1.OK - 2.ERROR + 2.OK 3.OK 4.OK - 5.STAIP:192.168.123.123' - initial condition: STAAP1 - initial condition description (auto): testing sta on sta + ap mode, quit AP (autogen - by STAM1) + 5.ERROR' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration module: TCPIP - steps: '1.target1 打开DHCP 1 + steps: '1.PC上SOC1 UDP传输,bing - 2.target1 设置sta ip 192.168.123.123 + 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 - 4.target1 关闭DHCP 1 + 3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据 - 5.target1 设置sta ip 192.168.123.123 + 4.断开与AP 连接 - 6.target1 查询 当前sta ip' - sub module: IP - summary: sta set and query static ip test + 5.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据' + sub module: UDP + summary: do UDP send after WIFI disconnected test environment: SSC_T1_1 test environment description (auto): 'PC has 2 wired NIC connected to AP. PC has 1 WiFi NIC. 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: set and query static IP + test point 1: abnormal/special use + test point 2: UDP handling abnormal event version: v1 (2016-8-15) - CI ready: 'Yes' - ID: WIFI_CONN_0801 + ID: ^TCPIP_UDP_0302 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: 1/5 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 5 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] + - - SSC SSC1 sta -D + - ['P SSC1 C +QAP:OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.OK' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration + module: TCPIP + steps: '1.PC上SOC1 UDP传输,bing + + 2.target1上UDP传输,Bind socket1,本地ip target_udp_port1 + + 3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据 + + 4.断开与AP 连接 + + 5.关闭建立的socket1连接' + sub module: UDP + summary: "close UDP socket after WIFI \ndisconnected" + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: UDP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_UDP_0303 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: 1/5 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 5 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] + - - SSC SSC1 op -S -o 2 + - ['P SSC1 C +MODE:OK'] + - - SSC SSC1 soc -S -s -i -p -l 5 + - ['P SSC1 RE SEND:(\d+),OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.ERROR' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration + module: TCPIP + steps: "1.PC上SOC1 UDP传输,bing \n2.target1上UDP传输,Bind socket1,本地ip\ + \ target_udp_port1\n3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据\n\ + 4.修改8266的Mode为softAP mode \n5.8266往PC上发送5字节数据" + sub module: UDP + summary: do UDP send after mode changed + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: UDP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_UDP_0304 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: 1/5 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 5 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] + - - SSC SSC1 op -S -o 2 + - ['P SSC1 C +MODE:OK'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.OK' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration + module: TCPIP + steps: "1.PC上SOC1 UDP传输,bing \n2.target1上UDP传输,Bind socket1,本地ip\ + \ target_udp_port1\n3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据\n\ + 4.修改8266的Mode为softAP mode \n5.关闭建立的socket1连接" + sub module: UDP + summary: close UDP socket after mode changed + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: UDP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_UDP_0305 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: 1/5 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 5 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] + - - NIC DISABLED + - [R PC_COM C OK] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK + + 4.OK + + 5.OK' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration + module: TCPIP + steps: "1.PC上SOC1 UDP传输,bing \n2.target1上UDP传输,Bind socket1,本地ip\ + \ target_udp_port1\n3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据\n\ + 4.PC上网卡禁止掉 \n5.关闭建立的socket1连接" + sub module: UDP + summary: close UDP socket after PC NIC disabled + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: UDP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_UDP_0306 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: 1/5 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 5 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] + - - SSC SSC1 dhcp -E -o 1 + - ['R SSC1 C +DHCP:STA,OK'] + - - SSC SSC1 ip -S -o 1 -i 192.168.111.210 + - ['P SSC1 C +IP:OK'] + - - SSC SSC1 ip -Q -o 1 + - ['R SSC1 C +STAIP:192.168.111.210'] + - - SSC SSC1 soc -S -s -i -p -l 1 + - ['P SSC1 RE SEND:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.OK + + 7.OK' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration + module: TCPIP + steps: "1.PC上SOC1 UDP传输,bing \n2.target1上UDP传输,Bind socket1,本地ip\ + \ target_udp_port1\n3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据\n\ + 4.关闭8266的DHCP 1\n5.设置sta ip \n6.查询sta ip 地址是否生效\n7.8266往PC上发送5字节数据" + sub module: UDP + summary: do UDP send after IP changed + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: UDP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_UDP_0307 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: 1/5 + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SOC SOC1 BIND + - [R SOC_COM L OK] + - - SSC SSC1 soc -B -t UDP -p + - ['R SSC1 A :BIND:(\d+),OK'] + - - SSC SSC1 soc -S -s -i -p -l 5 + - ['P SSC1 RE SEND:(\d+),OK', P SOC1 UL 5] + - - SSC SSC1 dhcp -E -o 1 + - ['R SSC1 C +DHCP:STA,OK'] + - - SSC SSC1 ip -S -o 1 -i 192.168.111.210 + - ['P SSC1 C +IP:OK'] + - - SSC SSC1 ip -Q -o 1 + - ['R SSC1 C +STAIP:192.168.111.210'] + - - SSC SSC1 soc -T -s + - ['R SSC1 RE CLOSE:\d+,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.OK + + 3.OK; PC TCP server accept 成功 + + 4.OK + + 5.OK + + 6.OK + + 7.OK' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration + module: TCPIP + steps: "1.PC上SOC1 UDP传输,bing \n2.target1上UDP传输,Bind socket1,本地ip\ + \ target_udp_port1\n3.target1上使用步骤2创建的socket1,往pc_ip,test_tcp_port1上发送5字节数据\n\ + 4.关闭8266的DHCP 1\n5.设置sta ip \n6.查询sta ip 地址是否生效\n7.关闭建立的socket1连接" + sub module: UDP + summary: close UDP socket after IP changed + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: UDP handling abnormal event + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^WIFI_ADDR_0101 SDK: '8266_NonOS 8266_RTOS @@ -13765,48 +13532,40 @@ test cases: category: Function cmd set: - '' - - - SSC SSC1 ap -S -s -p -t 0 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC1 ap -S -s -p -t 2 - - ['P SSC1 C +SAP:OK', 'P SSC2 C +JAP:AUTHCHANGED,2,0'] - - - SSC SSC1 ap -S -s -p -t 3 - - ['P SSC1 C +SAP:OK', 'P SSC2 C +JAP:AUTHCHANGED,3,2'] - - - SSC SSC1 ap -S -s -p -t 4 - - ['P SSC1 C +SAP:OK', 'P SSC2 C +JAP:AUTHCHANGED,4,3'] - - - SSC SSC1 ap -S -s -p -t 0 - - ['P SSC1 C +SAP:OK', 'P SSC2 C +JAP:AUTHCHANGED,0,4'] + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 mac -S -o 1 -m 44:55:66:77:88:99 + - ['R SSC1 C +MAC:STA,OK'] + - - SSC SSC1 mac -S -o 2 -m 22:33:44:55:66:77 + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC1 mac -Q -o 3 + - ['R SSC1 C +STAMAC:44:55:66:77:88:99 C +APMAC:22:33:44:55:66:77'] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] comment: '' execution time: 0.0 - expected result: '1. succeed + expected result: '1.OK - 2. succeed + 2.ok - 3. auth change event old mode 0 new mode 2 + 3.ok - 4. auth change event old mode 2 new mode 3 + 4.ok - 5. auth change event old mode 3 new mode 4 + 5.ok - 6. auth change event old mode 4 new mode 0' - initial condition: T2_1 - initial condition description (auto): target 1 as SoftAP, target 2 as STA, will - autogen a TC with initial condition T2_2 + 6.ok' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration module: WIFI MAC - steps: '1. set target1 softap auth mode 0 - - 2. target2 connect to target1 - - 3. set target1 softap auth mode 2, wait sta connected - - 4. set target1 softap auth mode 3, wait sta connected - - 5. set target1 softap auth mode 4, wait sta connected - - 6. set target1 softap auth mode 0, wait sta connected' - sub module: WIFI Connect - summary: test auth change event + steps: "1.target1 设置mode 为sta+softAP mode\n2.target1 设置sta mode 下的mac \n3.target1\ + \ 设置softAP mode 下的mac\n4.target1 查询softAP+sta 下的mac\n5.target1 设置sta mode 下的mac\ + \ 为target1_mac\n6.target1 设置softAP mode 下的mac 为target1_ap_mac" + sub module: MAC Address + summary: set mac, query mac test environment: SSC_T2_1 test environment description (auto): 'PC has 1 wired NIC connected to AP. @@ -13814,7 +13573,76 @@ test cases: 2 SSC target connect with PC by UART.' test point 1: basic function - test point 2: wifi auth changed event test + test point 2: mac address function test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^WIFI_ADDR_0102 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 mac -S -o 2 -m 44:55:66:77:88:99 + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC1 ap -S -s -p -t + - [''] + - - SSC SSC2 sta -S -b 44:55:66:77:88:99 + - ['R SSC2 RE \+SCAN:.+,44:55:66:77:88:99,'] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC2 mac -Q -o 1 + - ['R SSC2 A :\+STAMAC:(.+)\r\n'] + - - SSC SSC2 mac -S -o 1 -m 22:33:44:55:66:77 + - ['R SSC2 C +MAC:STA,OK'] + - - SSC SSC2 sta -C -s -p + - ['P SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 ap -L + - ['R SSC1 C +LSTA:22:33:44:55:66:77'] + - - SSC SSC2 mac -S -o 1 -m + - ['R SSC2 C +MAC:STA,OK'] + comment: '' + execution time: 0.0 + expected result: '1.OK + + 2.ok + + 3.ok + + 4.ok + + 5.ok + + 6.ok + + 7.ok + + 8.ok + + 9.ok' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration + module: WIFI MAC + steps: "1.target1 设置sta mode下的mac 44:55:66:77:88:99\n2.target1下设置ssid 和pwd 加密方式\n\ + 3.target2 查询mac为44:55:66:77:88:99的ssid\n4.target1 设置sta mode下的mac target_ap_mac\n\ + 5.target2 查询sta mode 下的mac 为target2_mac_tmp\n6.target2 设置sta mode 下的mac 为22:33:44:55:66:77\n\ + 7.target2 jap target1\n8.target1 查询连接到的sta \n9.target2 设置sta mode 下的mac 为 target2_mac" + sub module: MAC Address + summary: set mac and do scan/JAP/SAP + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: mac address function test version: v1 (2016-8-15) - CI ready: 'Yes' ID: ^WIFI_CONN_0101 @@ -13862,6 +13690,7 @@ test cases: \ 2 上查询到target_ssid" initial condition: T2_2 initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration module: WIFI MAC steps: "1.target1下设置ssid 和pwd,加密方式 open\n2.target2 jap target1\n3.target1下设置ssid\ \ 和pwd,加密方式 wpa_psk \n4.target2 jap target1\n5.target1下设置ssid 和pwd,加密方式 wpa2_psk\ @@ -13880,7 +13709,7 @@ test cases: test point 2: SAP/JAP with different config version: v1 (2016-8-15) - CI ready: 'Yes' - ID: ^WIFI_CONN_0503 + ID: ^WIFI_CONN_0103 SDK: '8266_NonOS 8266_RTOS @@ -13892,40 +13721,151 @@ test cases: category: Function cmd set: - '' - - - SSC SSC1 sta -R -r 0 - - [R SSC1 C OK] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:OK', 'R SSC1 NC +JAP:DISCONNECTED,1 C +JAP:DISCONNECTED,3'] - - - DELAY 5 - - ['R SSC1 NC +JAP:DISCONNECTED', P PC_COM C +DELAYDONE] - - - SSC SSC1 sta -C -s -p - - ['R SSC1 C +JAP:OK', 'R SSC1 NC +JAP:DISCONNECTED,1 C +JAP:DISCONNECTED,2'] - - - DELAY 5 - - ['R SSC1 NC +JAP:DISCONNECTED', P PC_COM C +DELAYDONE] - - - SSC SSC1 sta -R -r 1 - - [SSC SSC1 C OK] + - - SSC SSC1 ap -S -s -p -t -h + 0 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -S -h 0 + - [R SSC2 P , R SSC2 C +SCANDONE] + - - SSC SSC1 ap -S -s -p -t -h + 1 + - ['R SSC1 C +SAP:OK'] + - - DELAY 3 + - [''] + - - SSC SSC2 sta -S -h 0 + - [R SSC2 C +SCANDONE] + - - DELAY 3 + - [''] + - - SSC SSC2 sta -S -h 0 + - [R SSC2 NP C +SCANDONE] comment: '' execution time: 0.0 - expected result: '1. succeed + expected result: '1.target1 set AP,set ssid broad cast - 2. not reconnect when connect failed, status when recv disconnect event is correct + 2.target 2上scan target_ap_mac - 3. not reconnect when connect failed, status when recv disconnect event is correct + 3.target1 set AP,set ssid hidden, - 4. succeed' + 4.target 2上不能scan target_ap_mac' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration + module: WIFI MAC + steps: '1. target1下设置ssid 和pwd 加密方式,set ssid broad cast + + 2.target 2上scan target_ap_mac + + 3. target1下设置ssid 和pwd 加密方式,set ssid hidden, + + 4.target 2上scan target_ap_mac' + sub module: WIFI Connect + summary: station SAP+JAP test, ssid hidden + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: SAP/JAP with different config + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^WIFI_CONN_0104 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t -m + 1 + - ['R SSC1 C +SAP:OK'] + - - WIFI DISCONN + - ['R PC_COM C +WIFIDISCONN:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] + - - WIFI CONN + + - ['R PC_COM C +WIFICONN:ERROR'] + comment: '' + execution time: 0.0 + expected result: '1. target1 set AP,set max allowed sta as 1 + + 2. use PC disconnect, + + 3.target 2 jap succeed + + 4.PC WIFI can not CONN' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration + module: WIFI MAC + steps: '1.target1下设置ssid 和pwd 加密方式,set max allowed sta as 1 + + 2.use PC disconnect target1 + + 3.target 2 jap target1 + + 4.PC WIFI CONNECT target1' + sub module: WIFI Connect + summary: station SAP test, max allowed sta + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: SAP/JAP with different config + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^WIFI_CONN_0201 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC1 sta -Q + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:OK'] + - - SSC SSC1 sta -Q + - ['R SSC1 C +JAP:DISCONNECTED'] + comment: '' + execution time: 0.0 + expected result: '1.target1 jion AP 成功 + + 2.查询JAP的状态 + + 3.target1 断开AP + + 4.查询target1 JAP 是DISCONN' initial condition: STAAP1 initial condition description (auto): testing sta on sta + ap mode, quit AP (autogen by STAM1) + level: Integration module: WIFI MAC - steps: '1. set sta reconnect policy as not reconnect + steps: '1.target1 jion AP 成功 - 2. sta connect to ap not exist + 2.查询JAP的状态 - 3. sta connect to ap with wrong password + 3.target1 断开AP - 4. reset sta reconnect policy as auto reconnect' + 4.查询target1 JAP 是DISCONN' sub module: WIFI Connect - summary: reconnect policy interact with failed STA connect/reconnect + summary: JAP query test test environment: SSC_T1_1 test environment description (auto): 'PC has 2 wired NIC connected to AP. @@ -13933,10 +13873,10 @@ test cases: 1 SSC target connect with PC by UART.' test point 1: basic function - test point 2: reconnect policy test + test point 2: query JAP status version: v1 (2016-8-15) - CI ready: 'Yes' - ID: ^WIFI_CONN_0502 + ID: ^WIFI_CONN_0301 SDK: '8266_NonOS 8266_RTOS @@ -13948,61 +13888,106 @@ test cases: category: Function cmd set: - '' - - - SSC SSC1 ap -S -s -p -t + - - SSC SSC1 ap -S -s -p -t -h + 0 -m 8 - ['R SSC1 C +SAP:OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC2 sta -R -r 1 - - ['R SSC2 C +RECONN:OK'] - - - SSC SSC1 op -S -o 1 - - ['R SSC1 C +MODE:OK'] - - - DELAY 5 - - ['R SSC2 C +JAP:DISCONNECTED'] - - - SSC SSC1 op -S -o 2 - - ['R SSC1 C +MODE:OK'] - - - DELAY 10 - - ['R SSC2 C +JAP:CONNECTED'] - - - SSC SSC2 sta -D - - ['R SSC2 C +QAP:OK'] - - - DELAY 10 - - [P PC_COM C +DELAYDONE, 'P SSC2 NC +JAP:CONNECTED'] + - - SSC SSC1 ap -Q + - ['R SSC1 RE "\+APCONFIG:%%s,%%s,\d+,3,0,8,\d+"%%(,)'] comment: '' execution time: 0.0 - expected result: '1.target1 set AP + expected result: '1. target1 set AP - 2.target2 jap target 1 - - 3.设置reconn,开启(此功能不需要重启系统) - - 4.target2 断开target1 连接 - - 5.等待10s,target2 自动重连target1 - - 6.target2 断开target1 连接' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + 2.target 1上查询到跟设置AP时一致' + initial condition: APSTA1 + initial condition description (auto): testing ap on sta + ap mode (autogen by APM1) + level: Integration module: WIFI MAC - steps: '1.target1下设置ssid 和pwd 加密方式 + steps: '1. target1 set AP - 2.target2 jap target 1 - - 3.设置reconn,开启(此功能不需要重启系统) - - 4.target2 断开target1 连接 - - 5.等待10s,target2 自动重连target1 - - 6.target2 断开target1 连接' + 2.target 1上查询到跟设置AP时一致' sub module: WIFI Connect - summary: will not do reconnect after manually disconnected - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. + summary: AP config query test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. PC has 1 WiFi NIC. - 2 SSC target connect with PC by UART.' - test point 1: abnormal/special use - test point 2: reconnect policy test + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: query AP config + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^WIFI_CONN_0401 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -R -a 0 + - ['R SSC1 C +AUTORECONN:OK'] + - - SSC SSC1 sta -R -a 2 + - ['R SSC1 C +AUTORECONN:0'] + - - SSC SSC1 reboot + - [''] + - - DELAY 15 + - [''] + - - SSC SSC1 sta -Q + - ['R SSC1 C JAP:DISCONNECTED'] + - - SSC SSC1 sta -R -a 1 + - ['R SSC1 C +AUTORECONN:OK'] + - - SSC SSC1 sta -R -a 2 + - ['R SSC1 C +AUTORECONN:1'] + - - SSC SSC1 reboot + - ['R SSC1 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: '1.设置autoreconn,关闭 + + 2.查询当前autoreconn状态是否关闭 + + 3.重启系统,等待15s + + 4.查询target1 未自动重连AP + + 5.设置autoreconn,开启 + + 6.查询当前autoreconn状态是否开启 + + 7.系统重启后target1 自动重连AP' + initial condition: STAAP2 + initial condition description (auto): testing sta on sta + ap mode, join AP, DHCP + on (autogen by STAM2) + level: Integration + module: WIFI MAC + steps: '1.设置autoreconn,关闭 + + 2.查询当前autoreconn状态是否关闭 + + 3.重启系统,等待15s + + 4.查询target1 未自动重连AP + + 5.设置autoreconn,开启 + + 6.查询当前autoreconn状态是否开启 + + 7.系统重启后target1 自动重连AP' + sub module: WIFI Connect + summary: auto reconnect test + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: power on auto reconnect test version: v1 (2016-8-15) - CI ready: 'Yes' ID: ^WIFI_CONN_0501 @@ -14066,6 +14051,7 @@ test cases: 9.等待15s,target2 不会自动重连target1' initial condition: T2_2 initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration module: WIFI MAC steps: "1.设置reconn,开启(此功能不需要重启系统)\n2.target1下设置ssid 和pwd 加密方式\n3.target2 JAP target1\ \ \n4.target1 修改mode 为sta mode\n5.等待10s,target1 修改mode 为softAP mode\n6.设置reconn,关闭\n\ @@ -14082,7 +14068,7 @@ test cases: test point 2: reconnect policy test version: v1 (2016-8-15) - CI ready: 'Yes' - ID: TCPIP_TCP_0115 + ID: ^WIFI_CONN_0502 SDK: '8266_NonOS 8266_RTOS @@ -14094,78 +14080,221 @@ test cases: category: Function cmd set: - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC2 sta -R -r 1 + - ['R SSC2 C +RECONN:OK'] + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - DELAY 5 + - ['R SSC2 C +JAP:DISCONNECTED'] + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - DELAY 10 + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:OK'] + - - DELAY 10 + - [P PC_COM C +DELAYDONE, 'P SSC2 NC +JAP:CONNECTED'] comment: '' execution time: 0.0 - expected result: '1.OK + expected result: '1.target1 set AP - 2.OK + 2.target2 jap target 1 - 3.OK,pc tcp server accept成功 + 3.设置reconn,开启(此功能不需要重启系统) - 4 OK + 4.target2 断开target1 连接 - 5.OK,pc tcp server accept成功 + 5.等待10s,target2 自动重连target1 - 6.OK + 6.target2 断开target1 连接' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration + module: WIFI MAC + steps: '1.target1下设置ssid 和pwd 加密方式 - 7.OK,pc tcp server accept成功 + 2.target2 jap target 1 - 8 OK + 3.设置reconn,开启(此功能不需要重启系统) - 9.OK,pc tcp server accept成功 + 4.target2 断开target1 连接 - 10.OK + 5.等待10s,target2 自动重连target1 - 11.OK,pc tcp server accept成功' - initial condition: APM2 - initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen - a TC with initial condition APSTA2 - module: TCPIP - steps: '1.PC上建立TCP 监听 test_tcp_port1 + 6.target2 断开target1 连接' + sub module: WIFI Connect + summary: will not do reconnect after manually disconnected + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. - 2.target1上创建TCP socket1 + PC has 1 WiFi NIC. - 3.target1上使用步骤2创建的socket1,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + 2 SSC target connect with PC by UART.' + test point 1: abnormal/special use + test point 2: reconnect policy test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^WIFI_CONN_0601 + SDK: '8266_NonOS - 4.target1上创建TCP socket2 + 8266_RTOS - 5.target1上使用步骤4创建的socket2,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - WIFI CONN + + - ['R PC_COM C +WIFICONN:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 ap -L + - ['R SSC1 C +LSTA:', 'R SSC1 C +LSTA:', R SSC1 C +LSTADONE] + comment: '' + execution time: 0.0 + expected result: '1.target1 set AP - 6.target1上创建TCP socket3 + 2.PC WIFI CONNECTED - 7.target1上使用步骤6创建的socket3,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + 3.target2 jap target 1 - 8.target1上创建TCP socket4 + 4.查询到两个sta 连接到target1 上' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration + module: WIFI MAC + steps: '1. target1下设置ssid 和pwd 加密方式 - 9.target1上使用步骤8创建的socket4,去连接 PC的ip,test_tcp_port1,PC有ACCEPT + 2.PC WIFI CONNECTED target1 - 10.target1上创建TCP socket5 + 3.target2 jap target 1 - 11.target1上使用步骤10创建的socket5,去连接 PC的ip,test_tcp_port1,PC有ACCEPT' - sub module: TCP - summary: AP mode, create max TCP sockets test + 4.查询到两个sta 连接到target1 上' + sub module: WIFI Connect + summary: list stations connected to soft ap test + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: list SoftAP connected station + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^WIFI_CONN_0801 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 0 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 ap -S -s -p -t 2 + - ['P SSC1 C +SAP:OK', 'P SSC2 C +JAP:AUTHCHANGED,2,0'] + - - SSC SSC1 ap -S -s -p -t 3 + - ['P SSC1 C +SAP:OK', 'P SSC2 C +JAP:AUTHCHANGED,3,2'] + - - SSC SSC1 ap -S -s -p -t 4 + - ['P SSC1 C +SAP:OK', 'P SSC2 C +JAP:AUTHCHANGED,4,3'] + - - SSC SSC1 ap -S -s -p -t 0 + - ['P SSC1 C +SAP:OK', 'P SSC2 C +JAP:AUTHCHANGED,0,4'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. succeed + + 3. auth change event old mode 0 new mode 2 + + 4. auth change event old mode 2 new mode 3 + + 5. auth change event old mode 3 new mode 4 + + 6. auth change event old mode 4 new mode 0' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration + module: WIFI MAC + steps: '1. set target1 softap auth mode 0 + + 2. target2 connect to target1 + + 3. set target1 softap auth mode 2, wait sta connected + + 4. set target1 softap auth mode 3, wait sta connected + + 5. set target1 softap auth mode 4, wait sta connected + + 6. set target1 softap auth mode 0, wait sta connected' + sub module: WIFI Connect + summary: test auth change event + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: wifi auth changed event test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^WIFI_CONN_0901 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: basic function + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - SSC SSC1 sta -D + - ['R SSC1 RE JAP:DISCONNECTED,\d+,8'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE JAP:DISCONNECTED,\d+,15'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE JAP:DISCONNECTED,\d+,201'] + comment: '' + execution time: 0.0 + expected result: '1. disconnect event reason REASON_ASSOC_LEAVE + + 2. disconnect event reason REASON_4WAY_HANDSHAKE_TIMEOUT + + 3. disconnect event reason REASON_NO_AP_FOUND' + initial condition: STAAP1 + initial condition description (auto): testing sta on sta + ap mode, quit AP (autogen + by STAM1) + level: Integration + module: WIFI MAC + steps: '1. sta connect to AP, and disconnect + + 2. connect to AP with wrong password + + 3. connect to AP not exist' + sub module: WIFI Connect + summary: test wifi disconnect reason REASON_ASSOC_LEAVE, REASON_4WAY_HANDSHAKE_TIMEOUT, + REASON_NO_AP_FOUND test environment: SSC_T1_1 test environment description (auto): 'PC has 2 wired NIC connected to AP. @@ -14173,7 +14302,153 @@ test cases: 1 SSC target connect with PC by UART.' test point 1: basic function - test point 2: use TCP SAP (socket/espconn API) with different parameter + test point 2: wifi disconnect reason test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^WIFI_CONN_0902 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -C -s -p + - ['R SSC1 C +JAP:CONNECTED'] + - - APC OFF + - [P PC_COM L OK, 'R SSC1 RE JAP:DISCONNECTED,\d+,200'] + - - APC ON + - [P PC_COM L OK] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. disconnect event REASON_BEACON_TIMEOUT' + initial condition: STAAP1 + initial condition description (auto): testing sta on sta + ap mode, quit AP (autogen + by STAM1) + level: Integration + module: WIFI MAC + steps: '1. connect to AP + + 2. AP power off' + sub module: WIFI Connect + summary: test wifi disconnect reason REASON_BEACON_TIMEOUT + test environment: SSC_T1_APC + test environment description (auto): "PC has 1 wired NIC connected to AP.\nPC has\ + \ 1 wired NIC connected to APC (static IP within the same subnet with APC). \n\ + APC control AP power supply. \nPC has 1 WiFi NIC. \n1 SSC target connect with\ + \ PC by UART." + test point 1: basic function + test point 2: wifi disconnect reason test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^WIFI_CONN_0903 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 sta -C -s -p bacfd + - ['R SSC1 RE JAP:DISCONNECTED,\d+,2'] + comment: '' + execution time: 0.0 + expected result: 1. disconect event reason REASON_AUTH_EXPIRE + initial condition: STAAP1 + initial condition description (auto): testing sta on sta + ap mode, quit AP (autogen + by STAM1) + level: Integration + module: WIFI MAC + steps: 1. connect WEP ap with error password (valid wep password) + sub module: WIFI Connect + summary: test wifi disconnect reason REASON_AUTH_EXPIRE + test environment: SSC_T1_WEP + test environment description (auto): '1 SSC target connect with PC by UART. + + One WEP share key AP placed near SSC1.' + test point 1: basic function + test point 2: wifi disconnect reason test + version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^WIFI_CONN_0904 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t 3 -m 1 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p 1234567890 + - ['R SSC2 RE JAP:DISCONNECTED,\d+,204'] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:OK'] + - - WIFI CONN + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 RE JAP:DISCONNECTED,\d+,5'] + - - WIFI DISCONN + - [P PC_COM C OK, 'R SSC2 C +JAP:CONNECTED'] + - - SSC SSC1 ap -S -s -p -t 3 -m 1 + - ['P SSC1 C +SAP:OK', 'P SSC2 RE JAP:DISCONNECTED,\d+,4'] + comment: '' + execution time: 0.0 + expected result: '1. succeed + + 2. disconnect event REASON_HANDSHAKE_TIMEOUT + + 3. succeed + + 4. succeed + + 5. disconnect event REASON_ASSOC_TOOMANY + + 6. succeed, target2 connect succeed + + 7. disconnect event REASON_ASSOC_EXPIRE' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration + module: WIFI MAC + steps: '1. config target1 softap max sta allowed 1 + + 2. target2 connect to target1 with wrong password + + 3. target2 disconnect + + 4. PC WIFI NIC connect to target1 + + 5. target2 connect to target1 with correct password + + 6. PC WIFI NIC disconnect + + 7. reconfig softap' + sub module: WIFI Connect + summary: test wifi disconnect reason REASON_ASSOC_TOOMANY, REASON_HANDSHAKE_TIMEOUT, + REASON_ASSOC_EXPIRE + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: wifi disconnect reason test version: v1 (2016-8-15) - CI ready: 'Yes' ID: ^WIFI_SCAN_0101 @@ -14203,6 +14478,7 @@ test cases: 3.target2上查询到' initial condition: T2_2 initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration module: WIFI MAC steps: '1.target 2 scan .,juhg123 @@ -14221,7 +14497,7 @@ test cases: test point 2: scan with different config version: v1 (2016-8-15) - CI ready: 'Yes' - ID: TCPIP_TCP_0114 + ID: ^WIFI_SCAN_0102 SDK: '8266_NonOS 8266_RTOS @@ -14233,90 +14509,35 @@ test cases: category: Function cmd set: - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -T -s - - ['R SSC1 RE CLOSE:\d+,OK'] - - - SSC SSC1 soc -B -t TCP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -L -s - - ['R SSC1 RE LISTEN:\d+,OK'] - - - SOC SOC2 CONNECT 0 - - ['R SSC1 A :ACCEPT:(\d+),\d+,.+,\d+'] - - - SSC SSC1 soc -T -s - - ['R SSC1 RE CLOSE:\d+,OK'] - - - SSC SSC1 soc -T -s - - ['R SSC1 RE CLOSE:\d+,OK'] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SSC SSC1 soc -T -s - - ['R SSC1 RE CLOSE:\d+,OK'] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SSC SSC1 soc -D -s - - ['R SSC1 RE SHUTDOWN:\d+,OK'] - - - SSC SSC1 soc -T -s - - ['R SSC1 RE CLOSE:\d+,OK'] + - - SSC SSC2 sta -S -b ff:ff:ff:ff:ff:11 + - ['R SSC2 NC +SCAN: C +SCANDONE'] + - - SSC SSC2 sta -S -b + - ['R SSC2 RE "\+SCAN:.+,%%s"%%()', 'R SSC2 NC +SCAN: C +SCANDONE'] comment: '' execution time: 0.0 - expected result: '1.OK + expected result: '1.target2 上不能查询到此mac - 2.OK + 2.target2上查询到' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration + module: WIFI MAC + steps: '1.target2 上查询此macff:ff:ff:ff:ff:11 - 3.OK - - 4.OK - - 5.OK - - 6.OK,target1上accept 成功 - - 7.target1关闭socket1 - - 8.target1关闭socket2 - - 9.OK - - 10.OK,pc tcp server accept成功 - - 11.target1关闭socket1 - - 12.OK - - 13.OK,pc tcp server accept成功 - - 14.OK - - 15.target1关闭socket1' - initial condition: APM2 - initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen - a TC with initial condition APSTA2 - module: TCPIP - steps: "1.PC上建立TCP 监听 test_tcp_port1\n2.target1上创建TCP socket1\n3.target1关闭socket1\n\ - 4.target1上创建TCP socket 端口随机\n5.target1上使用步骤4创建的socket1,去监听\n6.PC CONNECT,\ - \ ,tcp 连接创建成功,创建socket2 \n7.target1关闭socket1\n8.target1关闭socket2\n\ - 9.target1上创建TCP socket1\n10.target1上使用步骤10创建的socket1,去连接 PC的ip,test_tcp_port1,PC有ACCEPT\n\ - 11.target1关闭socket1\n12.target1上创建TCP socket1\n13.target1上使用步骤13创建的socket1,去连接\ - \ PC的ip,test_tcp_port1,PC有ACCEPT\n14.target1shutdown socket1\n15.target1关闭socket1" - sub module: TCP - summary: AP mode, close for different types of TCP sockets test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. + 2.target2上查询' + sub module: WIFI Scan + summary: scan with scan config bssid + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. PC has 1 WiFi NIC. - 1 SSC target connect with PC by UART.' + 2 SSC target connect with PC by UART.' test point 1: basic function - test point 2: use TCP SAP (socket/espconn API) with different parameter + test point 2: scan with different config version: v1 (2016-8-15) - CI ready: 'Yes' - ID: TCPIP_TCP_0116 + ID: ^WIFI_SCAN_0103 SDK: '8266_NonOS 8266_RTOS @@ -14328,57 +14549,47 @@ test cases: category: Function cmd set: - '' - - - SSC SSC1 soc -B -t TCP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -L -s - - ['R SSC1 RE LISTEN:\d+,OK'] - - - SOC SOC2 CONNECT 0 - - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] - - - SOC SOC3 CONNECT 0 - - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] - - - SOC SOC4 CONNECT 0 - - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] - - - SOC SOC5 CONNECT 0 - - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] - - - SOC SOC6 CONNECT 0 - - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+'] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:'] + - - SSC SSC1 ap -S -s -p 123456789 -t 3 -n 6 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -S -n 5 + - [R SSC2 NP C +SCANDONE] + - - SSC SSC2 sta -S -n 6 + - ['R SSC2 C +SCAN:', R SSC2 P ] comment: '' execution time: 0.0 - expected result: '1.+BIND:0,OK,0.0.0.0 + expected result: '1.target1 QAP - 2.OK + 2. target1 set AP,set channel 6 - 3.OK,pc tcp server accept成功 + 3.target2 上scan不到 channel 5 - 4.OK,pc tcp server accept成功 + 4.target2 上查询channel 6的' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration + module: WIFI MAC + steps: '1.target1 断开连接AP - 5.OK,pc tcp server accept成功 + 2.target1下设置ssid 和pwd 加密方式,set channel 6 - 6.OK,pc tcp server accept成功 + 3.target2 上scan channel 5 - 7.OK,pc tcp server accept成功' - initial condition: APM2 - initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen - a TC with initial condition APSTA2 - module: TCPIP - steps: "1.target1上创建TCP socket 端口随机\n2.target1上使用步骤4创建的socket1,去监听\n3.PC CONNECT,\ - \ ,tcp 连接创建成功,创建socket2 \n4.PC CONNECT, ,tcp 连接创建成功,创建socket3\ - \ \n5.PC CONNECT, ,tcp 连接创建成功,创建socket4 \n6.PC CONNECT,\ - \ ,tcp 连接创建成功,创建socket5 \n7.PC CONNECT, ,tcp 连接创建成功,创建socket6\ - \ " - sub module: TCP - summary: AP mode, accept max TCP client by server test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. + 4.target2 上查询channel 6的' + sub module: WIFI Scan + summary: scan with scan config channel + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. PC has 1 WiFi NIC. - 1 SSC target connect with PC by UART.' + 2 SSC target connect with PC by UART.' test point 1: basic function - test point 2: use TCP SAP (socket/espconn API) with different parameter + test point 2: scan with different config version: v1 (2016-8-15) - CI ready: 'Yes' - ID: TCPIP_TCP_0111 + ID: ^WIFI_SCAN_0104 SDK: '8266_NonOS 8266_RTOS @@ -14390,47 +14601,59 @@ test cases: category: Function cmd set: - '' - - - SSC SSC1 soc -B -t TCP -p - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -L -s - - ['R SSC1 RE LISTEN:\d+,OK'] - - - SOC SOC1 CONNECT 0 - - ['R SSC1 RE ACCEPT:(\d+),\d+,.+,\d+', P SOC_COM C OK] - - - SOC SOC1 CONNECT 0 - - [P SOC_COM C ERROR, P SSC1 NC ACCEPT] + - - SSC SSC1 ap -S -s -p 123456789 -t 3 -h 0 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -S -h 0 + - [R SSC2 P C +SCANDONE] + - - SSC SSC2 sta -S -h 1 + - [R SSC2 P C +SCANDONE] + - - SSC SSC1 ap -S -s -p 123456789 -h 1 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -S -h 0 + - [R SSC2 NP C +SCANDONE] + - - SSC SSC2 sta -S -h 1 + - [R SSC2 P C +SCANDONE] comment: '' execution time: 0.0 - expected result: '1.OK + expected result: '1.target1 set AP,set ssid broad cast - 2.OK + 2.target 2上scan - 3.PC TCP client accept + 3.target 2上scan - 4.error' - initial condition: APM2 - initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen - a TC with initial condition APSTA2 - module: TCPIP - steps: '1.target1上创建TCP socket,bind到本地端口 + 4.target1 set AP,set ssid hidden, - 2.target1上使用步骤1创建的socket,创建TCP 监听 + 5.target 2上不能查询到 - 3.PC TCP 连接到target1 , + 6.target 2上查询到' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration + module: WIFI MAC + steps: '1.target1下设置ssid 和pwd 加密方式,set ssid broad cast - 4.PC tcp 连接到不存在的port ,' - sub module: TCP - summary: AP mode, server listen test. use different kinds of port - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. + 2.target 2上scan + + 3.target 2上scan + + 4.target1下设置ssid 和pwd 加密方式,set ssid hidden, + + 5.target 2上查询 + + 6.target 2上查询' + sub module: WIFI Scan + summary: scan with scan config show hidden + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. PC has 1 WiFi NIC. - 1 SSC target connect with PC by UART.' + 2 SSC target connect with PC by UART.' test point 1: basic function - test point 2: use TCP SAP (socket/espconn API) with different parameter + test point 2: scan with different config version: v1 (2016-8-15) - CI ready: 'Yes' - ID: TCPIP_TCP_0113 + ID: ^WIFI_SCAN_0105 SDK: '8266_NonOS 8266_RTOS @@ -14442,154 +14665,54 @@ test cases: category: Function cmd set: - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SSC SSC1 soc -D -s -h B - - ['R SSC1 RE SHUTDOWN:\d+,OK'] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SSC SSC1 soc -D -s -h W - - ['R SSC1 RE SHUTDOWN:\d+,OK'] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SSC SSC1 soc -D -s -h R - - ['R SSC1 RE SHUTDOWN:\d+,OK'] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:'] + - - SSC SSC1 ap -S -s -p 123456789 -t 3 -h 0 -n 11 + - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -S -s -b -n 11 + - [R SSC2 P C +SCANDONE] + - - SSC SSC2 sta -S -s -b -n 11 + - [R SSC2 NP C +SCANDONE] + - - SSC SSC2 sta -S -s -b ff:ff:ff:ff:ff:11 -n 11 + - [R SSC2 P , R SSC2 NP C +SCANDONE] + - - SSC SSC2 sta -S -s -b -n 10 + - [R SSC2 P , R SSC2 NP C +SCANDONE] comment: '' execution time: 0.0 - expected result: '1.OK + expected result: '1.target1 QAP - 2.OK + 2. target1 set AP,set ssid broad cast,set channel 11 - 3.OK,pc tcp server accept成功 + 3.target2 上查询到 - 4.OK + 4.target2 上查询不到 - 5.OK + 5.target2 上查询不到 - 6.OK,pc tcp server accept成功 + 6.target2 上查询不到' + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration + module: WIFI MAC + steps: '1.target1 QAP - 7.OK + 2. target1 set AP,set ssid broad cast,set channel 11 - 8.OK + 3.target2 上查询到 - 9.OK,pc tcp server accept成功 + 4.target2 上查询不到 - 10.OK' - initial condition: APM2 - initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen - a TC with initial condition APSTA2 - module: TCPIP - steps: '1. PC上建立TCP 监听 test_tcp_port1 + 5.target2 上查询不到 - 2.target1上创建TCP socket - - 3.target1上使用步骤2创建的socket,去连接 PC的ip,test_tcp_port1,PC有ACCEPT - - 4.target1 shutdown socket1 B - - 5.target1上创建TCP socket - - 6.target1上使用步骤5创建的socket,去连接 PC的ip,test_tcp_port1,PC有ACCEPT - - 7.target1 shutdown socket2 W - - 8.target1上创建TCP socket - - 9.target1上使用步骤8创建的socket,去连接 PC的ip,test_tcp_port1,PC有ACCEPT - - 10.target1 shutdown socket3 R' - sub module: TCP - summary: AP mode, shutdown basic test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. + 6.target2 上查询不到' + sub module: WIFI Scan + summary: scan with several configs + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. PC has 1 WiFi NIC. - 1 SSC target connect with PC by UART.' + 2 SSC target connect with PC by UART.' test point 1: basic function - test point 2: use TCP SAP (socket/espconn API) with different parameter - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_TCP_0112 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SOC SOC1 LISTEN - - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP - - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -C -s -i -p - - ['R SSC1 RE CONNECT:\d+,OK'] - - - SOC SOC1 ACCEPT SOC2 - - [R SOC_COM L OK] - - - SOC SOC2 SEND 5 - - [R SSC1 SL +5] - - - SSC SSC1 soc -S -s -l 5 - - ['P SSC1 RE SEND:\d+,OK', P SOC2 RL 5] - - - SOC SOC2 SEND 146000 - - [R SSC1 SL +146000] - - - SSC SSC1 soc -S -s -l 1460 -n 100 - - ['P SSC1 RE SEND:\d+,OK', P SOC2 RL 146000] - comment: '' - execution time: 0.0 - expected result: '1.OK - - 2.OK - - 3.OK,pc tcp server accept成功 - - 4.OK - - 5.target收到5byte数据 - - 6.PC收到5byte数据 - - 7.target收到146000 byte数据 - - 8.OK,PC 收到146000 byte数据' - initial condition: APM2 - initial condition description (auto): AP mode, PC join AP, DHCP on, will autogen - a TC with initial condition APSTA2 - module: TCPIP - steps: '1. PC上建立TCP 监听 test_tcp_port1 - - 2.target1上创建TCP socket - - 3.target1上使用步骤2创建的socket,去连接 PC的ip,test_tcp_port1 - - 4.PC与target1 创建好TCP 连接,有ACCEPT - - 5.PC send 5 bytes to 8266 - - 6.8266 send 5 bytes to PC - - 7. PC send 100 * 1460 data to 8266, - - 8.8266 send 100 * 1460 to PC. ' - sub module: TCP - summary: AP mode, send/recv basic test - test environment: SSC_T1_1 - test environment description (auto): 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: use TCP SAP (socket/espconn API) with different parameter + test point 2: scan with different config version: v1 (2016-8-15) diff --git a/components/test/TestEnvAll.yml b/components/idf_test/integration_test/TestEnvAll.yml similarity index 100% rename from components/test/TestEnvAll.yml rename to components/idf_test/integration_test/TestEnvAll.yml index a978f5f73a..afa6cb812a 100644 --- a/components/test/TestEnvAll.yml +++ b/components/idf_test/integration_test/TestEnvAll.yml @@ -1,82 +1,18 @@ test environment: -- {PC OS: '', Special: N, Target Count: 2.0, script path: EnvBase.py, tag: SSC_T2_SmartConfig, - test environment detail: '2 SSC target connect with PC by UART. - - PC has 1 WiFi NIC. - - One HT20 AP and One HT40 AP are placed near target.', test script: EnvBase} -- {PC OS: '', Special: N, Target Count: 2.0, script path: EnvBase.py, tag: AT_T2_SmartConfig, - test environment detail: '2 AT target connect with PC by UART (AT and LOG port). - - PC has 1 WiFi NIC. - - One HT20 AP and One HT40 AP are placed near target.', test script: EnvBase} -- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_IOT1, - test environment detail: 'PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART. - - AP todo IOT test are placed near SSC1.', test script: EnvBase} -- {PC OS: '', Special: Y, Target Count: 2.0, UART ports: 'SSC1 - - SSC2', additional param list: '', basic param list: '', script path: EnvBase.py, - tag: SSC_T2_GPIO3, test environment detail: '[TBD] 2个ESP_8266通过UART连到PC, ESP_8266之间需要测试的Target_GPIO相连', - test script: EnvBase} -- {PC OS: linux, Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: WebServer_T1_1, - test environment detail: 'Web Server target connect with PC by UART. - - PC has 1 wired NIC connected to switch. - - APC, AP also connect with swtich. - - All devices connected with switch use same IP subnet. - - APC control AP power supply.', test script: EnvBase} -- {PC OS: linux, Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: WebServer_T1_2, - test environment detail: 'Web Server target connect with PC by UART. - - 4 PC with WiFi NIC placed near WebServer1.', test script: EnvBase} -- {PC OS: '', Special: Y, Target Count: 2.0, UART ports: 'SSC1 - - SSC2', additional param list: '', basic param list: '', script path: EnvBase.py, - tag: SSC_T2_GPIO1, test environment detail: '[TBD] 2个ESP_8266通过UART连到PC, ESP_8266的 - GPIO_6相连', test script: EnvBase} -- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_Enterprise, - test environment detail: "AP use WPA2-Etherprise is placed near SSC1. \n1 SSC target\ - \ connect with PC by UART.", test script: EnvBase} -- {PC OS: '', Special: Y, Target Count: 2.0, UART ports: 'SSC1 - - SSC2', additional param list: '', basic param list: '', script path: EnvBase.py, - tag: SSC_T2_GPIO2, test environment detail: '[TBD] 1. 2个ESP_8266通过UART连到PC, ESP_8266的 - GPIO_15通过面包板相连 - - 2. 可借助面包板, 将GPIO_15, 以及中断函数被打开的8266板的GPIO_2 相连', test script: EnvBase} -- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: AT_T1_HighSpeedUART, +- {PC OS: '', Special: N, Target Count: 1.0, script path: EnvBase.py, tag: AT_T1_1, test environment detail: 'PC has 2 wired NIC connected to AP. PC has 1 WiFi NIC. - 1 AT target connect with PC by high speed UART (AT and LOG port).', test script: EnvBase} -- {PC OS: '', Special: Y, Target Count: 2.0, script path: EnvBase.py, tag: SSC_T2_ShieldBox, - test environment detail: '2 SSC target connect with PC by UART. - - Put them to Shield box.', test script: EnvBase} -- {PC OS: '', Special: N, Target Count: 1.0, script path: EnvBase.py, tag: AT_T1_3, - test environment detail: 'Able to access WAN after connect to AP. - 1 AT target connect with PC by UART (AT and LOG port).', test script: EnvBase} - {PC OS: '', Special: N, Target Count: 1.0, script path: EnvBase.py, tag: AT_T1_2, test environment detail: 'PC has 1 WiFi NIC. 1 AT target connect with PC by UART (AT and LOG port).', test script: EnvBase} -- {PC OS: '', Special: Y, Target Count: 1.0, UART ports: 'SSC1 +- {PC OS: '', Special: N, Target Count: 1.0, script path: EnvBase.py, tag: AT_T1_3, + test environment detail: 'Able to access WAN after connect to AP. - SSC2', additional param list: '', basic param list: '', script path: EnvBase.py, - tag: UART_T1_2, test environment detail: '[TBD] ESP_8266通过UART_0通过USB, UART_1 TXD - 通过 TTLcable 连到PC', test script: EnvBase} -- {PC OS: '', Special: Y, Target Count: 1.0, UART ports: SSC_1, additional param list: '', - basic param list: '', script path: EnvBase.py, tag: UART_T1_1, test environment detail: '[TBD] - 将ESP_8266通过UART连到PC', test script: EnvBase} + 1 AT target connect with PC by UART (AT and LOG port).', test script: EnvBase} - {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: AT_T1_ADC, test environment detail: 'PC has 1 wired NIC connected to AP. @@ -85,10 +21,88 @@ test environment: Multimeter connect to input, able to measure input voltage. 1 AT target connect with PC by UART (AT and LOG port).', test script: EnvBase} -- {PC OS: '', Special: N, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_WEP, - test environment detail: '1 SSC target connect with PC by UART. +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: AT_T1_APC1, + test environment detail: "PC has 1 wired NIC connected to AP.\nPC has 1 wired NIC\ + \ connected to APC (static IP within the same subnet with APC). \nAPC control\ + \ AP power supply. \nPC has 1 WiFi NIC. \n1 AT target connect with PC by UART\ + \ (AT and LOG port).", test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: AT_T1_APC2, + test environment detail: "Able to access WAN after connect to AP.\nPC has 1 wired\ + \ NIC connected to APC (static IP within the same subnet with APC). \nAPC control\ + \ AP power supply.\nPC has 1 WiFi NIC.\n1 AT target connect with PC by UART (AT\ + \ and LOG port).", test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: AT_T1_HighSpeedUART, + test environment detail: 'PC has 2 wired NIC connected to AP. - One WEP share key AP placed near SSC1.', test script: EnvBase} + PC has 1 WiFi NIC. + + 1 AT target connect with PC by high speed UART (AT and LOG port).', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: AT_T1_SmartConfigIOT, + test environment detail: '1 AT target connect with PC by UART (AT and LOG port). + + PC has 1 wired NIC connect to Common AP. + + Several AP are placed near AT target. + + Several smart phone installed test APK are placed near AT target.', test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 2.0, script path: EnvBase.py, tag: AT_T2_1, + test environment detail: 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 AT target connect with PC by UART (AT and LOG port).', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 2.0, script path: EnvBase.py, tag: AT_T2_JAP, + test environment detail: "Several AP are placed near AT target.\nPC has 1 wired\ + \ NIC connected to APC (static IP within the same subnet with APC).\nAPC control\ + \ power supply for all APs. \n2 AT target connect with PC by UART (AT and LOG\ + \ port).", test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 2.0, script path: EnvBase.py, tag: AT_T2_Sleep, + test environment detail: 'AP support DTIM placed with AT target. + + 2 AT target connect with PC by UART (AT and LOG port). + + Multimeter connect with PC via GPIB. + + Series multimeter between GND and VCC of AT1. + + AT1''s light sleep wakeup pin and wakeup indication connect with AT2''s GPIO.', + test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 2.0, script path: EnvBase.py, tag: AT_T2_SmartConfig, + test environment detail: '2 AT target connect with PC by UART (AT and LOG port). + + PC has 1 WiFi NIC. + + One HT20 AP and One HT40 AP are placed near target.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, UART ports: 'SSC1 + + SSC2', additional param list: '', basic param list: '', script path: EnvBase.py, + tag: IR_T2_1, test environment detail: '[TBD] 本测试为非自动测试, 红外能够做到数据收发吻合即可通过', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 2.0, script path: EnvBase.py, tag: NVS_T1_1, + test environment detail: '1 NVS target connect with PC by UART. + + 1 SSC target connect with PC by UART. + + SSC2 GPIO connect to NVS1 power control pin.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, UART ports: SSC_1, additional param list: '', + basic param list: '', script path: EnvBase.py, tag: PWM_T1_1, test environment detail: "[TBD]\ + \ 1. PWM OS SDK 以及 Non-OS SDK的测试建议分开进行, 放在不同的文件夹, 防止文件命名混淆\n2. 分析CSV文件的Python脚本只能分析单个channel\ + \ \n3. 如果Init脚本打印\"Network Error\" 检查TCP Server是不是正常发送data", test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_1, + test environment detail: 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.', test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_2, + test environment detail: 'Able to access WAN after connect to AP. + + 1 SSC target connect with PC by UART.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_8089, + test environment detail: 'PC has 1 wired NIC connected to AP. + + 1 8089 tablet able to run iperf test placed near SSC1. + + 1 SSC target connect with PC by UART.', test script: EnvBase} - {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_ADC, test environment detail: 'PC has 1 wired NIC connected to AP. @@ -102,12 +116,15 @@ test environment: \ connected to APC (static IP within the same subnet with APC). \nAPC control\ \ AP power supply. \nPC has 1 WiFi NIC. \n1 SSC target connect with PC by UART.", test script: EnvBase} -- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_8089, - test environment detail: 'PC has 1 wired NIC connected to AP. +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_Enterprise, + test environment detail: "AP use WPA2-Etherprise is placed near SSC1. \n1 SSC target\ + \ connect with PC by UART.", test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_IOT1, + test environment detail: 'PC has 1 WiFi NIC. - 1 8089 tablet able to run iperf test placed near SSC1. + 1 SSC target connect with PC by UART. - 1 SSC target connect with PC by UART.', test script: EnvBase} + AP todo IOT test are placed near SSC1.', test script: EnvBase} - {PC OS: '', Special: Y, Target Count: 2.0, script path: EnvBase.py, tag: SSC_T1_InitData, test environment detail: '2 SSC target connect with PC by UART. @@ -116,30 +133,6 @@ test environment: SSC2 use normal 26M crystal oscillator. SSC2 GPIO connect to SSC1 power control pin.', test script: EnvBase} -- {PC OS: '', Special: Y, Target Count: 1.0, UART ports: SSC_1, additional param list: '', - basic param list: '', script path: EnvBase.py, tag: SSC_T1_Timer, test environment detail: '[TBD] - 通过串口工具调节Timer, 将GPIO_13端口连接到逻辑分析仪', test script: EnvBase} -- {PC OS: '', Special: N, Target Count: 3.0, script path: EnvBase.py, tag: SSC_T3_PhyMode, - test environment detail: '3 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with (HT20, channel1), (HT20, channel2), (HT40, channel1), (HT40, channel2). - - Put 4 APs near SSC targets.', test script: EnvBase} -- {PC OS: '', Special: Y, Target Count: 2.0, script path: EnvBase.py, tag: AT_T2_JAP, - test environment detail: "Several AP are placed near AT target.\nPC has 1 wired\ - \ NIC connected to APC (static IP within the same subnet with APC).\nAPC control\ - \ power supply for all APs. \n2 AT target connect with PC by UART (AT and LOG\ - \ port).", test script: EnvBase} -- {PC OS: '', Special: N, Target Count: 2.0, script path: EnvBase.py, tag: SSC_T2_PhyMode, - test environment detail: '2 SSC target connect with PC by UART. - - PC has one WiFi NIC support capture wlan packet using libpcap. - - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.', test script: EnvBase} - {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_ShieldBox, test environment detail: 'refer to figure. @@ -148,12 +141,100 @@ test environment: PC wired NIC should set static IP address within the same subnet with AP. Must use onboard wired NIC.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_TempBox, + test environment detail: '1 SSC target connect with PC by UART. + + Put SSC target to temperature box.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, UART ports: SSC_1, additional param list: '', + basic param list: '', script path: EnvBase.py, tag: SSC_T1_Timer, test environment detail: '[TBD] + 通过串口工具调节Timer, 将GPIO_13端口连接到逻辑分析仪', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_VDD33, + test environment detail: '1 SSC target connect with PC by UART. + + Multimeter connect to VDD33, able to measure voltage.', test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_WEP, + test environment detail: '1 SSC target connect with PC by UART. + + One WEP share key AP placed near SSC1.', test script: EnvBase} - {PC OS: '', Special: N, Target Count: 2.0, script path: EnvBase.py, tag: SSC_T2_1, test environment detail: 'PC has 1 wired NIC connected to AP. PC has 1 WiFi NIC. 2 SSC target connect with PC by UART.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 2.0, UART ports: 'SSC1 + + SSC2', additional param list: '', basic param list: '', script path: EnvBase.py, + tag: SSC_T2_GPIO1, test environment detail: '[TBD] 2个ESP_8266通过UART连到PC, ESP_8266的 + GPIO_6相连', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 2.0, UART ports: 'SSC1 + + SSC2', additional param list: '', basic param list: '', script path: EnvBase.py, + tag: SSC_T2_GPIO2, test environment detail: '[TBD] 1. 2个ESP_8266通过UART连到PC, ESP_8266的 + GPIO_15通过面包板相连 + + 2. 可借助面包板, 将GPIO_15, 以及中断函数被打开的8266板的GPIO_2 相连', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 2.0, UART ports: 'SSC1 + + SSC2', additional param list: '', basic param list: '', script path: EnvBase.py, + tag: SSC_T2_GPIO3, test environment detail: '[TBD] 2个ESP_8266通过UART连到PC, ESP_8266之间需要测试的Target_GPIO相连', + test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 2.0, script path: EnvBase.py, tag: SSC_T2_PhyMode, + test environment detail: '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 2.0, script path: EnvBase.py, tag: SSC_T2_ShieldBox, + test environment detail: '2 SSC target connect with PC by UART. + + Put them to Shield box.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 2.0, script path: EnvBase.py, tag: SSC_T2_Sleep1, + test environment detail: 'AP support DTIM placed with AT target. + + 2 SSC target connect with PC by UART. + + Multimeter connect with PC via GPIB. + + Series multimeter between GND and VCC of SSC1. + + SSC1''s light sleep wakeup pin and wakeup indication connect with AT2''s GPIO. + + SSC1''s XPD connect with RSTB.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 2.0, script path: EnvBase.py, tag: SSC_T2_Sleep2, + test environment detail: 'AP support DTIM placed with AT target. + + 2 SSC target connect with PC by UART. + + Multimeter connect with PC via GPIB. + + Series multimeter between GND and VCC of SSC1. + + SSC1''s RSTB pin connect with AT2''s GPIO.', test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 2.0, script path: EnvBase.py, tag: SSC_T2_SmartConfig, + test environment detail: '2 SSC target connect with PC by UART. + + PC has 1 WiFi NIC. + + One HT20 AP and One HT40 AP are placed near target.', test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 3.0, script path: EnvBase.py, tag: SSC_T3_PhyMode, + test environment detail: '3 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with (HT20, channel1), (HT20, channel2), (HT40, channel1), (HT40, channel2). + + Put 4 APs near SSC targets.', test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 5.0, script path: EnvBase.py, tag: SSC_T5_1, + test environment detail: 5 SSC target connect with PC by UART., test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T6_1, + test environment detail: 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 6 SSC target connect with PC by UART.', test script: EnvBase} - {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: TempSensor_T1_1, test environment detail: 'Tempeture sensor target connect with PC by UART. @@ -170,106 +251,25 @@ test environment: All devices connected with switch use the same IP subnet. APC control AP power supply.', test script: EnvBase} -- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: AT_T1_SmartConfigIOT, - test environment detail: '1 AT target connect with PC by UART (AT and LOG port). - - PC has 1 wired NIC connect to Common AP. - - Several AP are placed near AT target. - - Several smart phone installed test APK are placed near AT target.', test script: EnvBase} -- {PC OS: '', Special: Y, Target Count: 2.0, script path: EnvBase.py, tag: AT_T2_Sleep, - test environment detail: 'AP support DTIM placed with AT target. - - 2 AT target connect with PC by UART (AT and LOG port). - - Multimeter connect with PC via GPIB. - - Series multimeter between GND and VCC of AT1. - - AT1''s light sleep wakeup pin and wakeup indication connect with AT2''s GPIO.', - test script: EnvBase} -- {PC OS: '', Special: N, Target Count: 5.0, script path: EnvBase.py, tag: SSC_T5_1, - test environment detail: 5 SSC target connect with PC by UART., test script: EnvBase} -- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_TempBox, - test environment detail: '1 SSC target connect with PC by UART. - - Put SSC target to temperature box.', test script: EnvBase} -- {PC OS: '', Special: N, Target Count: 1.0, script path: EnvBase.py, tag: AT_T1_1, - test environment detail: 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 AT target connect with PC by UART (AT and LOG port).', test script: EnvBase} -- {PC OS: '', Special: N, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T6_1, - test environment detail: 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 6 SSC target connect with PC by UART.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, UART ports: SSC_1, additional param list: '', + basic param list: '', script path: EnvBase.py, tag: UART_T1_1, test environment detail: '[TBD] + 将ESP_8266通过UART连到PC', test script: EnvBase} - {PC OS: '', Special: Y, Target Count: 1.0, UART ports: 'SSC1 SSC2', additional param list: '', basic param list: '', script path: EnvBase.py, - tag: IR_T2_1, test environment detail: '[TBD] 本测试为非自动测试, 红外能够做到数据收发吻合即可通过', test script: EnvBase} -- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_VDD33, - test environment detail: '1 SSC target connect with PC by UART. + tag: UART_T1_2, test environment detail: '[TBD] ESP_8266通过UART_0通过USB, UART_1 TXD + 通过 TTLcable 连到PC', test script: EnvBase} +- {PC OS: linux, Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: WebServer_T1_1, + test environment detail: 'Web Server target connect with PC by UART. - Multimeter connect to VDD33, able to measure voltage.', test script: EnvBase} -- {PC OS: '', Special: Y, Target Count: 1.0, UART ports: SSC_1, additional param list: '', - basic param list: '', script path: EnvBase.py, tag: PWM_T1_1, test environment detail: "[TBD]\ - \ 1. PWM OS SDK 以及 Non-OS SDK的测试建议分开进行, 放在不同的文件夹, 防止文件命名混淆\n2. 分析CSV文件的Python脚本只能分析单个channel\ - \ \n3. 如果Init脚本打印\"Network Error\" 检查TCP Server是不是正常发送data", test script: EnvBase} -- {PC OS: '', Special: Y, Target Count: 2.0, script path: EnvBase.py, tag: NVS_T1_1, - test environment detail: '1 NVS target connect with PC by UART. + PC has 1 wired NIC connected to switch. - 1 SSC target connect with PC by UART. + APC, AP also connect with swtich. - SSC2 GPIO connect to NVS1 power control pin.', test script: EnvBase} -- {PC OS: '', Special: Y, Target Count: 2.0, script path: EnvBase.py, tag: SSC_T2_Sleep2, - test environment detail: 'AP support DTIM placed with AT target. + All devices connected with switch use same IP subnet. - 2 SSC target connect with PC by UART. + APC control AP power supply.', test script: EnvBase} +- {PC OS: linux, Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: WebServer_T1_2, + test environment detail: 'Web Server target connect with PC by UART. - Multimeter connect with PC via GPIB. - - Series multimeter between GND and VCC of SSC1. - - SSC1''s RSTB pin connect with AT2''s GPIO.', test script: EnvBase} -- {PC OS: '', Special: Y, Target Count: 2.0, script path: EnvBase.py, tag: SSC_T2_Sleep1, - test environment detail: 'AP support DTIM placed with AT target. - - 2 SSC target connect with PC by UART. - - Multimeter connect with PC via GPIB. - - Series multimeter between GND and VCC of SSC1. - - SSC1''s light sleep wakeup pin and wakeup indication connect with AT2''s GPIO. - - SSC1''s XPD connect with RSTB.', test script: EnvBase} -- {PC OS: '', Special: N, Target Count: 2.0, script path: EnvBase.py, tag: AT_T2_1, - test environment detail: 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 AT target connect with PC by UART (AT and LOG port).', test script: EnvBase} -- {PC OS: '', Special: N, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_1, - test environment detail: 'PC has 2 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 1 SSC target connect with PC by UART.', test script: EnvBase} -- {PC OS: '', Special: N, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_2, - test environment detail: 'Able to access WAN after connect to AP. - - 1 SSC target connect with PC by UART.', test script: EnvBase} -- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: AT_T1_APC2, - test environment detail: "Able to access WAN after connect to AP.\nPC has 1 wired\ - \ NIC connected to APC (static IP within the same subnet with APC). \nAPC control\ - \ AP power supply.\nPC has 1 WiFi NIC.\n1 AT target connect with PC by UART (AT\ - \ and LOG port).", test script: EnvBase} -- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: AT_T1_APC1, - test environment detail: "PC has 1 wired NIC connected to AP.\nPC has 1 wired NIC\ - \ connected to APC (static IP within the same subnet with APC). \nAPC control\ - \ AP power supply. \nPC has 1 WiFi NIC. \n1 AT target connect with PC by UART\ - \ (AT and LOG port).", test script: EnvBase} + 4 PC with WiFi NIC placed near WebServer1.', test script: EnvBase} diff --git a/components/idf_test/uint_test/InitialConditionAll.yml b/components/idf_test/uint_test/InitialConditionAll.yml new file mode 100644 index 0000000000..ba06af9f87 --- /dev/null +++ b/components/idf_test/uint_test/InitialConditionAll.yml @@ -0,0 +1,2935 @@ +initial condition: +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:2'] + - - SSC SSC1 ap -Q + - ['R SSC1 RE "\+APCONFIG:%%s,%%s,\d+,\d+,\d+,4,"%%(,)'] + - - SSC SSC1 dhcp -Q -o 2 + - ['R SSC1 C +DHCP:AP,STARTED'] + - - SSC SSC1 mac -Q -o 2 + - [R SSC1 P ] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + initial condition detail: AP mode, DHCP on, will autogen a TC with initial condition + APSTA1 + restore cmd set: + - '' + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 ram + - ['R SSC1 C +FREEHEAP:'] + script path: InitCondBase.py + start: 31.0 + tag: APM1 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:2'] + - - SSC SSC1 ap -Q + - ['R SSC1 RE "\+APCONFIG:%%s,%%s,\d+,\d+,\d+,4,"%%(,)'] + - - SSC SSC1 ap -L + - ['R SSC1 RE "\+LSTA:.+,%%s"%%()'] + - - SSC SSC1 dhcp -Q -o 2 + - ['R SSC1 C +DHCP:AP,STARTED'] + - - SSC SSC1 mac -Q -o 2 + - [R SSC1 P ] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - WIFI CONN + + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + initial condition detail: AP mode, PC join AP, DHCP on, will autogen a TC with initial + condition APSTA2 + restore cmd set: + - '' + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - WIFI CONN + + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 ram + - ['R SSC1 C +FREEHEAP:'] + script path: InitCondBase.py + start: 38.0 + tag: APM2 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:2'] + - - SSC SSC1 ap -Q + - ['R SSC1 RE "\+APCONFIG:%%s,%%s,\d+,\d+,\d+,4,"%%(,)'] + - - SSC SSC1 dhcp -Q -o 2 + - ['R SSC1 C +DHCP:AP,STARTED'] + - - SSC SSC1 mac -Q -o 2 + - [R SSC1 P ] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + initial condition detail: AP mode, will NOT autogen a TC with initial condition + APSTA1 + restore cmd set: + - '' + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 ram + - ['R SSC1 C +FREEHEAP:'] + script path: InitCondBase.py + start: 31.0 + tag: APO1 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:2'] + - - SSC SSC1 ap -Q + - ['R SSC1 RE "\+APCONFIG:%%s,%%s,\d+,\d+,\d+,4,"%%(,)'] + - - SSC SSC1 ap -L + - ['R SSC1 RE "\+LSTA:.+,%%s"%%()'] + - - SSC SSC1 dhcp -Q -o 2 + - ['R SSC1 C +DHCP:AP,STARTED'] + - - SSC SSC1 mac -Q -o 2 + - [R SSC1 P ] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - WIFI CONN + + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + initial condition detail: AP mode, will NOT autogen a TC with initial condition + APSTA2 + restore cmd set: + - '' + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - WIFI CONN + + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 ram + - ['R SSC1 C +FREEHEAP:'] + script path: InitCondBase.py + start: 38.0 + tag: APO2 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 upgrade -Q -t 1 + - ['R SSC1 C BIN_ID,0'] + - - SSC SSC1 upgrade -Q -t 2 -b 0 + - ['R SSC1 C BIN_INFO,0'] + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + force restore cmd set: + - '' + - - SSC SSC1 upgrade -R -r 1 -s + - [R SSC1 NC ERROR C !!!ready!!!] + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SOC SOC1 ULISTEN + - [R SOC_COM L OK] + - - SOC SOC1 SETOPT REPLY BIN + - [R SOC_COM C OK] + - - SSC SSC1 upgrade -I -b 0 -f 0 + - ['P SSC1 C +UPGRADE:OK'] + - - SSC SSC1 upgrade -U -i -p -u + - ['P SSC1 C +UPGRADE:SUCCEED'] + - - SSC SSC1 upgrade -R -b 0 + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + initial condition detail: AP only mode, running BIN0 (located on flash id 0) + restore cmd set: + - '' + - - SSC SSC1 upgrade -Q -t 2 -b 0 + - ['R SSC1 C BIN_INFO,0'] + - - SSC SSC1 upgrade -R -b 0 + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + restore post cmd set: + - '' + - - SSC SSC1 upgrade -D + - ['R SSC1 C +UPGRADE:OK'] + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 31.0 + tag: APOBIN0 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:3'] + - - SSC SSC1 ap -Q + - ['R SSC1 RE "\+APCONFIG:%%s,%%s,\d+,\d+,\d+,4,"%%(,)'] + - - SSC SSC1 dhcp -Q -o 2 + - ['R SSC1 C +DHCP:AP,STARTED'] + - - SSC SSC1 mac -Q -o 2 + - [R SSC1 P ] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + initial condition detail: testing ap on sta + ap mode (autogen by APM1) + restore cmd set: + - '' + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 ram + - ['R SSC1 C +FREEHEAP:'] + script path: InitCondBase.py + start: 59.0 + tag: APSTA1 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:3'] + - - SSC SSC1 ap -Q + - ['R SSC1 RE "\+APCONFIG:%%s,%%s,\d+,\d+,\d+,4,"%%(,)'] + - - SSC SSC1 ap -L + - ['R SSC1 RE "\+LSTA:.+,%%s"%%()'] + - - SSC SSC1 dhcp -Q -o 2 + - ['R SSC1 C +DHCP:AP,STARTED'] + - - SSC SSC1 mac -Q -o 2 + - [R SSC1 P ] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - WIFI CONN + + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + initial condition detail: testing ap on sta + ap mode, PC join AP (autogen by APM2) + restore cmd set: + - '' + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - WIFI CONN + + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 ram + - ['R SSC1 C +FREEHEAP:'] + script path: InitCondBase.py + start: 66.0 + tag: APSTA2 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:3'] + - - ATS AT1 AT+CWLIF + - [R AT1 P ] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - DELAY 5 + - [''] + - - ATC AT1 CWSAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + - - WIFI CONN + + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - ATS AT1 AT+CWLIF + - [R AT1 P ] + initial condition detail: StationSoftAP mode + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATS AT1 AT+CWLIF + - [R AT1 P ] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 24.0 + tag: ATAP1 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 C +CWMODE_CUR:3 L OK'] + - - ATS AT1 AT+CWLIF + - [R AT1 P ] + - - ATS AT1 AT+CIPMUX? + - ['R AT1 L +CIPMUX:1'] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - DELAY 5 + - [''] + - - ATC AT1 CWSAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + - - WIFI CONN + + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - ATS AT1 AT+CWLIF + - [R AT1 P ] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=1 + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + initial condition detail: StationSoftAP mode, PC join Target AP, multi link, use + dhcp + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=1 + - [R AT1 R *] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CWLIF + - [R AT1 P ] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 31.0 + tag: ATAP3 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 C +CWMODE_CUR:3 L OK'] + - - ATS AT1 AT+CWLIF + - [R AT1 P ] + - - ATS AT1 AT+CIPMUX? + - ['R AT1 L +CIPMUX:0'] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - DELAY 10 + - [''] + - - ATC AT1 CWSAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + - - WIFI CONN + + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - ATS AT1 AT+CWLIF + - [R AT1 P ] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=0 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + initial condition detail: StationSoftAP mode, PC join Target AP, single link, use + dhcp + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=0 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATS AT1 AT+CWLIF + - [R AT1 P ] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 45.0 + tag: ATAP4 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT + - [R AT1 L OK] + - - ATS AT1 AT + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+RST + - [R AT1 L OK] + initial condition detail: StationSoftAP mode, both PC join Target AP, single link, + use dhcp + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 3.0 + tag: ATAP5 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT + - [R AT1 L OK] + - - ATS AT1 AT + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+RST + - [R AT1 L OK] + initial condition detail: StationSoftAP mode, both PC join Target AP, multi link, + use dhcp + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 3.0 + tag: ATAP6 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:2'] + - - ATS AT1 AT+CWDHCP_DEF=0,1 + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=2 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=0,1 + - [R AT1 R *] + initial condition detail: SoftAP mode, use dhcp + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=2 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=0,1 + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 59.0 + tag: ATAPO1 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 C +CWMODE_CUR:2 L OK'] + - - ATS AT1 AT+CWLIF + - [R AT1 P ] + - - ATS AT1 AT+CIPMUX? + - ['R AT1 L +CIPMUX:1'] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CWDHCP_DEF=0,1 + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=2 + - [R AT1 L OK] + - - ATC AT1 CWSAP_DEF + - [R AT1 L OK] + - - WIFI CONN + + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - ATS AT1 AT+CWLIF + - [R AT1 P ] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=1 + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CWDHCP_DEF=0,1 + - [R AT1 R *] + initial condition detail: SoftAP mode, PC join Target AP, multi link, use dhcp + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=2 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=1 + - [R AT1 R *] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CWLIF + - [R AT1 P ] + - - ATS AT1 AT+CWDHCP_DEF=0,1 + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 66.0 + tag: ATAPO3 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 C +CWMODE_CUR:2 L OK'] + - - ATS AT1 AT+CWLIF + - [R AT1 P ] + - - ATS AT1 AT+CIPMUX? + - ['R AT1 L +CIPMUX:0'] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATS AT1 AT+CWDHCP_DEF=0,1 + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=2 + - [R AT1 L OK] + - - ATC AT1 CWSAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=0,1 + - [R AT1 R *] + - - WIFI CONN + + - ['R PC_COM NC ERROR C +WIFICONN:OK'] + - - ATS AT1 AT+CWLIF + - [R AT1 P ] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=0 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + initial condition detail: SoftAP mode, PC join Target AP, single link, use dhcp + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=2 + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=0 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATS AT1 AT+CWLIF + - [R AT1 P ] + - - ATS AT1 AT+CWDHCP_DEF=0,1 + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 73.0 + tag: ATAPO4 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT + - [R AT1 L OK] + - - ATS AT1 AT + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+RST + - [R AT1 L OK] + initial condition detail: SoftAP mode, both PC join Target AP, single link, use + dhcp + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 3.0 + tag: ATAPO5 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT + - [R AT1 L OK] + - - ATS AT1 AT + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+RST + - [R AT1 L OK] + initial condition detail: SoftAP mode, both PC join Target AP, multi link, use dhcp + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 3.0 + tag: ATAPO6 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:3'] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + initial condition detail: StationSoftAP mode + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 87.0 + tag: ATAPSTA1 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:3'] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + initial condition detail: StationSoftAP mode, DHCP client on + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 87.0 + tag: ATAPSTA2 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:3'] + - - ATS AT1 AT+CWJAP_CUR? + - ['R AT1 C +CWJAP_CUR:', R AT1 P ] + - - ATS AT1 AT+CIPMUX? + - ['R AT1 L +CIPMUX:1'] + - - ATS AT1 AT+CWDHCP_CUR? + - ['R AT1 C DHCP:3'] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=1 + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + initial condition detail: StationSoftAP mode, connected to AP, multi link, use dhcp + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=1 + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 94.0 + tag: ATAPSTA3 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:3'] + - - ATS AT1 AT+CWJAP_CUR? + - ['R AT1 C +CWJAP_CUR:', R AT1 P ] + - - ATS AT1 AT+CIPMUX? + - ['R AT1 L +CIPMUX:0'] + - - ATS AT1 AT+CWDHCP_CUR? + - ['R AT1 C DHCP:3'] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=0 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + initial condition detail: StationSoftAP mode, connected to AP, single link, use + dhcp + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=0 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATS AT1 AT+CWDHCP_DEF=2,1 + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 101.0 + tag: ATAPSTA4 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:3'] + - - ATS AT1 AT+CWJAP_CUR? + - ['R AT1 C +CWJAP_CUR:', R AT1 P ] + - - ATS AT1 AT+CIPMUX? + - ['R AT1 L +CIPMUX:1'] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATC AT1 CIPSTA_DEF + - [R AT1 L OK] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=1 + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATC AT1 CIPSTA_DEF + - [R AT1 L OK] + initial condition detail: StationSoftAP mode, connected to AP, multi link, use static + ip + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=1 + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATC AT1 CIPSTA_DEF + - [R AT1 L OK] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 129.0 + tag: ATAPSTA5 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:3'] + - - ATS AT1 AT+CWJAP_CUR? + - ['R AT1 C +CWJAP_CUR:', R AT1 P ] + - - ATS AT1 AT+CIPMUX? + - ['R AT1 L +CIPMUX:0'] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATC AT1 CIPSTA_DEF + - [R AT1 L OK] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=0 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATC AT1 CIPSTA_DEF + - [R AT1 L OK] + initial condition detail: StationSoftAP mode, connected to AP, single link, use + static ip + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=0 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATC AT1 CIPSTA_DEF + - [R AT1 L OK] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 136.0 + tag: ATAPSTA6 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT + - [R AT1 L OK] + - - ATS AT1 AT+RESTORE + - [R AT1 L OK, R AT1 C ready] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT + - [R AT1 L OK] + - - ATS AT1 AT+RESTORE + - [R AT1 L OK, R AT1 C ready] + initial condition detail: 'first time usage. Use restore function. ' + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+RESTORE + - [R AT1 L OK, R AT1 C ready] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 143.0 + tag: ATFTU + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT + - [R AT1 L OK] + - - ATS AT1 AT + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+RST + - [R AT1 L OK] + initial condition detail: none + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 3.0 + tag: ATNone + test script: InitCondBase +- check cmd set: + - '' + - - DELAY 0.1 + - [dummy] + force restore cmd set: + - '' + - - DELAY 0.1 + - [dummy] + initial condition detail: none 2 + restore cmd set: + - '' + - - DELAY 0.1 + - [dummy] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 108.0 + tag: ATNone2 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:1'] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 L OK] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 L OK] + initial condition detail: same as STA1, but will not autogen STA+AP STA test case + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 L OK] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 10.0 + tag: ATOSTA1 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:1'] + - - ATS AT1 AT+CWJAP_CUR? + - ['R AT1 C +CWJAP_CUR:', R AT1 P ] + - - ATS AT1 AT+CIPMUX? + - ['R AT1 L +CIPMUX:0'] + - - ATS AT1 AT+CWDHCP_CUR? + - ['R AT1 C DHCP:3'] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 R *] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=0 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + initial condition detail: same as STA4, but will not autogen STA+AP STA test case + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 R *] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=0 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 17.0 + tag: ATOSTA4 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 C +CWMODE_CUR:3 C OK'] + - - ATS AT2 AT+CWMODE_CUR? + - ['R AT2 C +CWMODE_CUR:1 C OK'] + - - ATS AT1 AT+CWJAP_CUR? + - [R AT1 NC OK L ERROR] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATS AT2 AT+CWMODE_DEF=1 + - [R AT2 L OK] + - - ATS AT1 AT+CWQAP + - [R AT1 L OK] + initial condition detail: same as OT2_1, but will not autogen STA+AP STA test case + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATS AT2 AT+CWMODE_DEF=1 + - [R AT2 L OK] + - - ATS AT1 AT+CWQAP + - [R AT1 L OK] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 52.0 + tag: ATOT2_1 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:1'] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 L OK] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 L OK] + initial condition detail: station mode, use dhcp + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 L OK] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 10.0 + tag: ATSTA1 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:1'] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 L OK] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 L OK] + initial condition detail: station mode, DHCP client on, use dhcp + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 L OK] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 10.0 + tag: ATSTA2 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:1'] + - - ATS AT1 AT+CWJAP_CUR? + - ['R AT1 C +CWJAP_CUR:', R AT1 P ] + - - ATS AT1 AT+CIPMUX? + - ['R AT1 L +CIPMUX:1'] + - - ATS AT1 AT+CWDHCP_CUR? + - ['R AT1 C DHCP:3'] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 R *] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=1 + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + initial condition detail: station mode, connected to AP, multi link, use dhcp + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 R *] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=1 + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 38.0 + tag: ATSTA3 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:1'] + - - ATS AT1 AT+CWJAP_CUR? + - ['R AT1 C +CWJAP_CUR:', R AT1 P ] + - - ATS AT1 AT+CIPMUX? + - ['R AT1 L +CIPMUX:0'] + - - ATS AT1 AT+CWDHCP_CUR? + - ['R AT1 C DHCP:3'] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 R *] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=0 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + initial condition detail: station mode, connected to AP, single link, use dhcp + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATS AT1 AT+CWDHCP_DEF=1,1 + - [R AT1 R *] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=0 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 17.0 + tag: ATSTA4 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:1'] + - - ATS AT1 AT+CWJAP_CUR? + - ['R AT1 C +CWJAP_CUR:', R AT1 P ] + - - ATS AT1 AT+CIPMUX? + - ['R AT1 L +CIPMUX:1'] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATC AT1 CIPSTA_DEF + - [R AT1 L OK] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=1 + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATC AT1 CIPSTA_DEF + - [R AT1 L OK] + initial condition detail: station mode, connected to AP, multi link, use static + ip + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=1 + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATC AT1 CIPSTA_DEF + - [R AT1 L OK] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 115.0 + tag: ATSTA5 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 L +CWMODE_CUR:1'] + - - ATS AT1 AT+CWJAP_CUR? + - ['R AT1 C +CWJAP_CUR:', R AT1 P ] + - - ATS AT1 AT+CIPMUX? + - ['R AT1 L +CIPMUX:0'] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATC AT1 CIPSTA_DEF + - [R AT1 L OK] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=0 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATC AT1 CIPSTA_DEF + - [R AT1 L OK] + initial condition detail: station mode, connected to AP, single link, use static + ip + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=1 + - [R AT1 L OK] + - - ATC AT1 CWJAP_DEF + - [R AT1 L OK] + - - ATS AT1 AT+CIPSERVER=0 + - [R AT1 R *] + - - ATC AT1 CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMUX=0 + - [R AT1 L OK] + - - ATS AT1 AT+CIPCLOSE + - [R AT1 R *] + - - ATS AT1 AT+CIPMODE=0 + - [R AT1 R *] + - - ATC AT1 CIPSTA_DEF + - [R AT1 L OK] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 122.0 + tag: ATSTA6 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 C +CWMODE_CUR:3 C OK'] + - - ATS AT2 AT+CWMODE_CUR? + - ['R AT2 C +CWMODE_CUR:1 C OK'] + - - ATS AT1 AT+CWJAP_CUR? + - [R AT1 NC OK L ERROR] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATS AT2 AT+CWMODE_DEF=1 + - [R AT2 L OK] + - - ATS AT1 AT+CWQAP + - [R AT1 L OK] + initial condition detail: Target 1 in StationSoftAP mode, Target 2 in station mode, + use dhcp + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=3 + - [R AT1 L OK] + - - ATS AT2 AT+CWMODE_DEF=1 + - [R AT2 L OK] + - - ATS AT1 AT+CWQAP + - [R AT1 L OK] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 52.0 + tag: ATT2_1 + test script: InitCondBase +- check cmd set: + - '' + - - ATS AT1 AT+CWMODE_CUR? + - ['R AT1 C +CWMODE_CUR:2 C OK'] + - - ATS AT2 AT+CWMODE_CUR? + - ['R AT2 C +CWMODE_CUR:3 C OK'] + - - ATS AT1 AT+CWJAP_CUR? + - [R AT1 NC OK L ERROR] + force restore cmd set: + - '' + - - ATS AT1 AT+RST + - [R AT1 C ready] + - - ATS AT1 AT+CWMODE_DEF=2 + - [R AT1 L OK] + - - ATS AT2 AT+CWMODE_DEF=3 + - [R AT2 L OK] + initial condition detail: Target 1 in SoftAP mode, Target 2 in StationSoftAP mode, + use dhcp + restore cmd set: + - '' + - - ATSO AT1 +++ + - [''] + - - ATS AT1 AT + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - ATS AT1 AT+CWMODE_DEF=2 + - [R AT1 L OK] + - - ATS AT2 AT+CWMODE_DEF=3 + - [R AT2 L OK] + restore post cmd set: + - '' + - - ATS AT1 AT+CWSTOPSMART + - [R AT1 R *] + - - ATS AT1 AT+SAVETRANSLINK=0 + - [R AT1 R *] + - - AT+SYSRAM + - ['R AT1 A :(\d+)'] + script path: InitCondBase.py + start: 80.0 + tag: ATT2_2 + test script: InitCondBase +- check cmd set: + - '' + - - ASSERT + - [dummy] + force restore cmd set: + - '' + - - SSC SSC[1-] reboot + - ['P SSC[1-] C !!!ready!!!'] + - - SSC SSC[1-] mesh -E -o 0 + - ['P SSC[1-] C +MESH:DISABLED'] + - - SSC SSC[1-] op -S -o 1 + - ['P SSC[1-] C +MODE:OK'] + - - SSC SSC[1-] sta -D + - ['P SSC[1-] C +QAP:OK'] + initial condition detail: all mesh node disabled + restore cmd set: + - '' + - - SSC SSC[1-] mesh -E -o 0 + - ['P SSC[1-] C +MESH:DISABLED'] + - - SSC SSC[1-] op -S -o 1 + - ['P SSC[1-] C +MODE:OK'] + - - SSC SSC[1-] sta -D + - ['P SSC[1-] C +QAP:OK'] + restore post cmd set: + - '' + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 31.0 + tag: DISABLED + test script: InitCondBase +- check cmd set: + - '' + - - ASSERT + - [dummy] + - - SSC SSC[1-] mesh -Q -t 4 + - ['R SSC[1-] T '] + - - MESHTREE + - ['R PC_COM RE "MESHTREE:%%s%20nodes"%%()'] + force restore cmd set: + - '' + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC[1-] mesh -E -o 0 + - ['P SSC[1-] C +MESH:DISABLED'] + - - SSC SSC[1-] mesh -I -g -a 4 -k -i + -p -h 5 + - ['P SSC[1-] C ENCRYPTION,OK C GROUP,OK C SERVER,OK C HOP,OK'] + - - SSC SSC[1-] mesh -A -s -k + - ['P SSC[1-] C +MESHINIT:AP,OK'] + - - SSC SSC1 mesh -E -o 1 -t 2 + - ['P SSC1 C +MESH:ENABLED'] + - - SOC SOC1 MACCEPT GSOC1 + - [R SOC_COM L OK] + - - SSC SSC[2-] mesh -E -o 1 -t 2 + - ['P SSC[2-] C +MESH:ENABLED'] + - - DELAY 60 + - [''] + - - SSC SSC[1-] mesh -C + - ['P SSC[1-] C +MESH:CONNECTED'] + - - SSC SSC[1-] mesh -Q -t 4 + - ['R SSC[1-] T '] + - - MESHTREE + - ['R PC_COM RE "MESHTREE:%%s%20nodes"%%()'] + - - SSC SSC[1-] mesh -O -t 1 -o 1 + - ['P SSC[1-] C +MESH:OK'] + initial condition detail: all mesh node enabled as ONLINE, mesh network established + restore cmd set: + - '' + - - SSC SSC[1-] reboot + - ['P SSC[1-] C !!!ready!!!'] + - - SOC SOC1 LISTEN + - [R SOC_COM L OK] + - - SSC SSC[1-] mesh -E -o 0 + - ['P SSC[1-] C +MESH:DISABLED'] + - - SSC SSC[1-] mesh -I -g -a 4 -k -i + -p -h 5 + - ['P SSC[1-] C ENCRYPTION,OK C GROUP,OK C SERVER,OK C HOP,OK'] + - - SSC SSC[1-] mesh -A -s -k + - ['P SSC[1-] C +MESHINIT:AP,OK'] + - - SSC SSC1 mesh -E -o 1 -t 2 + - ['P SSC1 C +MESH:ENABLED'] + - - SOC SOC1 MACCEPT GSOC1 + - [R SOC_COM L OK] + - - SSC SSC[2-] mesh -E -o 1 -t 2 + - ['P SSC[2-] C +MESH:ENABLED'] + - - DELAY 60 + - [''] + - - SSC SSC[1-] mesh -C + - ['P SSC[1-] C +MESH:CONNECTED'] + - - SSC SSC[1-] mesh -Q -t 4 + - ['R SSC[1-] T '] + - - MESHTREE + - ['R PC_COM RE "MESHTREE:%%s%20nodes"%%()'] + - - SSC SSC[1-] mesh -O -t 1 -o 1 + - ['P SSC[1-] C +MESH:OK'] + restore post cmd set: + - '' + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 17.0 + tag: ENABLED_1 + test script: InitCondBase +- check cmd set: + - '' + - - ASSERT + - [dummy] + - - SSC SSC[1-] mesh -Q -t 4 + - ['R SSC[1-] T '] + - - MESHTREE + - ['R PC_COM RE "MESHTREE:%%s%20nodes"%%()'] + force restore cmd set: + - '' + - - SSC SSC[1-] reboot + - ['P SSC[1-] C !!!ready!!!'] + - - SSC SSC[1-] mesh -I -g -a 4 -k -i + -p -h 5 + - ['P SSC[1-] C ENCRYPTION,OK C GROUP,OK C SERVER,OK C HOP,OK'] + - - SSC SSC1 mesh -A -s -k + - ['P SSC1 C +MESHINIT:AP,OK'] + - - SSC SSC1 mesh -E -o 1 -t 1 + - ['P SSC1 C +MESH:ENABLED'] + - - SSC SSC[2-] mesh -E -o 1 -t 2 + - [''] + - - DELAY 60 + - ['P SSC[2-] C +MESH:ENABLED'] + - - SSC SSC[1-] mesh -C + - ['P SSC[1-] C +MESH:CONNECTED'] + - - SSC SSC[1-] mesh -Q -t 4 + - ['R SSC[1-] T '] + - - MESHTREE + - ['R PC_COM RE "MESHTREE:%%s%20nodes"%%()'] + initial condition detail: root as LOCAL, rest node as ONLINE, mesh network established + restore cmd set: + - '' + - - SSC SSC[1-] mesh -E -o 0 + - ['P SSC[1-] C +MESH:DISABLED'] + - - SSC SSC[1-] mesh -I -g -a 4 -k -i + -p -h 5 + - ['P SSC[1-] C ENCRYPTION,OK C GROUP,OK C SERVER,OK C HOP,OK'] + - - SSC SSC1 mesh -A -s -k + - ['P SSC1 C +MESHINIT:AP,OK'] + - - SSC SSC1 mesh -E -o 1 -t 1 + - ['P SSC1 C +MESH:ENABLED'] + - - SSC SSC[2-] mesh -E -o 1 -t 2 + - [''] + - - DELAY 60 + - ['P SSC[2-] C +MESH:ENABLED'] + - - SSC SSC[1-] mesh -C + - ['P SSC[1-] C +MESH:CONNECTED'] + - - SSC SSC[1-] mesh -Q -t 4 + - ['R SSC[1-] T '] + - - MESHTREE + - ['R PC_COM RE "MESHTREE:%%s%20nodes"%%()'] + restore post cmd set: + - '' + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 24.0 + tag: ENABLED_2 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:2'] + - - SSC SSC1 mac -Q -o 2 + - [R SSC1 P ] + - - SSC SSC1 espnow -D + - ['R SSC1 C +ESPNOW:'] + force restore cmd set: + - '' + - - SSC SSC[1-] reboot + - ['R SSC[1-] C !!!ready!!!'] + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 mac -S -m -o 2 + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC1 espnow -D + - ['R SSC1 C +ESPNOW:'] + initial condition detail: one target in AP mode and espnow is de-initialized + restore cmd set: + - '' + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 mac -S -m -o 2 + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC1 espnow -D + - ['R SSC1 C +ESPNOW:'] + restore post cmd set: + - '' + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 17.0 + tag: NOW1 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC[1-] op -Q + - ['R SSC[1-] C +CURMODE:2'] + - - SSC SSC[1-] mac -Q -o 3 + - ['R SSC[1-] P ]_ap_mac> P ]_mac>'] + - - SSC SSC[1-] espnow -D + - ['R SSC[1-] C +ESPNOW:'] + - - SSC SSC[1-] espnow -I + - ['R SSC[1-] C +ESPNOW:OK'] + - - SSC SSC[1-] espnow -R -t Set -r 2 + - ['R SSC[1-] C +ESPNOW:OK'] + force restore cmd set: + - '' + - - SSC SSC[1-] reboot + - ['R SSC[1-] C !!!ready!!!'] + - - SSC SSC[1-] op -S -o 3 + - ['R SSC[1-] C +MODE:OK'] + - - SSC SSC[1-] mac -S -m ]_ap_mac> -o 2 + - ['R SSC[1-] C +MAC:AP,OK'] + - - SSC SSC[1-] mac -S -m ]_mac> -o 1 + - ['R SSC[1-] C +MAC:STA,OK'] + - - SSC SSC[1-] op -S -o 2 + - ['R SSC[1-] C +MODE:OK'] + - - SSC SSC[1-] espnow -D + - ['R SSC[1-] C +ESPNOW:'] + - - SSC SSC[1-] espnow -I + - ['R SSC[1-] C +ESPNOW:OK'] + - - SSC SSC[1-] espnow -R -t Set -r 2 + - ['R SSC[1-] C +ESPNOW:OK'] + initial condition detail: multiple () targets in AP mode, espnow is initialized + with self role slave + restore cmd set: + - '' + - - SSC SSC[1-] op -S -o 3 + - ['R SSC[1-] C +MODE:OK'] + - - SSC SSC[1-] mac -S -m ]_ap_mac> -o 2 + - ['R SSC[1-] C +MAC:AP,OK'] + - - SSC SSC[1-] mac -S -m ]_mac> -o 1 + - ['R SSC[1-] C +MAC:STA,OK'] + - - SSC SSC[1-] op -S -o 2 + - ['R SSC[1-] C +MODE:OK'] + - - SSC SSC[1-] espnow -D + - ['R SSC[1-] C +ESPNOW:'] + - - SSC SSC[1-] espnow -I + - ['R SSC[1-] C +ESPNOW:OK'] + - - SSC SSC[1-] espnow -R -t Set -r 2 + - ['R SSC[1-] C +ESPNOW:OK'] + restore post cmd set: + - '' + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 24.0 + tag: NOW2 + test script: InitCondBase +- check cmd set: + - '' + - - DELAY 0.1 + - [dummy] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + initial condition detail: none + restore cmd set: + - '' + - - DELAY 0.1 + - [dummy] + restore post cmd set: + - '' + - - DELAY 0.1 + - [dummy] + script path: InitCondBase.py + start: 10.0 + tag: None + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 sp -D + - ['R SSC1 C +SP:OK'] + force restore cmd set: + - '' + - - SSC SSC1 sp -D + - ['R SSC1 C +SP:OK'] + initial condition detail: one target and simple is de-inited + restore cmd set: + - '' + - - SSC SSC1 sp -D + - ['R SSC1 C +SP:OK'] + restore post cmd set: + - '' + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 31.0 + tag: PAIR1 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC[1,2] op -Q + - ['R SSC[1,2] C +MODE:[2,1]'] + - - SSC SSC[1,2] mac -Q -o 3 + - ['R SSC[1,2] P P '] + - - SSC SSC[1,2] sp -D + - ['R SSC[1,2] C +SP:OK'] + - - SSC SSC[1,2] sp -I + - ['R SSC[1,2] C +SP:OK'] + force restore cmd set: + - '' + - - SSC SSC[1,2] reboot + - ['R SSC[1,2] C !!!ready!!!'] + - - SSC SSC[1,2] op -S -o 3 + - ['R SSC[1,2] C +MODE:OK'] + - - SSC SSC[1,2] mac -S -m -o 2 + - ['R SSC[1,2] C +MAC:AP,OK'] + - - SSC SSC[1,2] mac -S -m -o 1 + - ['R SSC[1,2] C +MAC:STA,OK'] + - - SSC SSC[1,2] op -S -o [2,1] + - ['R SSC[1,2] C +MODE:OK'] + - - SSC SSC[1,2] sp -D + - ['R SSC[1,2] C +SP:OK'] + - - SSC SSC[1,2] sp -I + - ['R SSC[1,2] C +SP:OK'] + initial condition detail: target1 in AP mode, target2 in STA mode, two targets de-init + and init simple pair + restore cmd set: + - '' + - - SSC SSC[1,2] op -S -o 3 + - ['R SSC[1,2] C +MODE:OK'] + - - SSC SSC[1,2] mac -S -m -o 2 + - ['R SSC[1,2] C +MAC:AP,OK'] + - - SSC SSC[1,2] mac -S -m -o 1 + - ['R SSC[1,2] C +MAC:STA,OK'] + - - SSC SSC[1,2] op -S -o [2,1] + - ['R SSC[1,2] C +MODE:OK'] + - - SSC SSC[1,2] sp -D + - ['R SSC[1,2] C +SP:OK'] + - - SSC SSC[1,2] sp -I + - ['R SSC[1,2] C +SP:OK'] + restore post cmd set: + - '' + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 38.0 + tag: PAIR2 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC[1,2] op -Q + - ['R SSC[1,2] C +MODE:[3,3]'] + - - SSC SSC[1,2] mac -Q -o 3 + - ['R SSC[1,2] P P '] + - - SSC SSC[1,2] sp -D + - ['R SSC[1,2] C +SP:OK'] + - - SSC SSC[1,2] sp -I + - ['R SSC[1,2] C +SP:OK'] + force restore cmd set: + - '' + - - SSC SSC[1,2] reboot + - ['R SSC[1,2] C !!!ready!!!'] + - - SSC SSC[1,2] op -S -o [3,3] + - ['R SSC[1,2] C +MODE:OK'] + - - SSC SSC[1,2] mac -S -m -o 2 + - ['R SSC[1,2] C +MAC:AP,OK'] + - - SSC SSC[1,2] mac -S -m -o 1 + - ['R SSC[1,2] C +MAC:STA,OK'] + - - SSC SSC[1,2] sp -D + - ['R SSC[1,2] C +SP:OK'] + - - SSC SSC[1,2] sp -I + - ['R SSC[1,2] C +SP:OK'] + initial condition detail: target1 and target2 in STA+AP mode, two targets de-init + and init simple pair + restore cmd set: + - '' + - - SSC SSC[1,2] op -S -o [3,3] + - ['R SSC[1,2] C +MODE:OK'] + - - SSC SSC[1,2] mac -S -m -o 2 + - ['R SSC[1,2] C +MAC:AP,OK'] + - - SSC SSC[1,2] mac -S -m -o 1 + - ['R SSC[1,2] C +MAC:STA,OK'] + - - SSC SSC[1,2] sp -D + - ['R SSC[1,2] C +SP:OK'] + - - SSC SSC[1,2] sp -I + - ['R SSC[1,2] C +SP:OK'] + restore post cmd set: + - '' + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 45.0 + tag: PAIR3 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:3'] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:'] + - - SSC SSC1 dhcp -Q -o 1 + - ['R SSC1 C +DHCP:STA,STARTED'] + - - SSC SSC1 mac -Q -o 1 + - [R SSC1 P ] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + initial condition detail: testing sta on sta + ap mode, quit AP (autogen by STAM1) + restore cmd set: + - '' + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 ram + - ['R SSC1 C +FREEHEAP:'] + script path: InitCondBase.py + start: 45.0 + tag: STAAP1 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:3'] + - - SSC SSC1 sta -Q + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC1 dhcp -Q -o 1 + - ['R SSC1 C +DHCP:STA,STARTED'] + - - SSC SSC1 mac -Q -o 1 + - [R SSC1 P ] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + initial condition detail: testing sta on sta + ap mode, join AP, DHCP on (autogen + by STAM2) + restore cmd set: + - '' + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 ram + - ['R SSC1 C +FREEHEAP:'] + script path: InitCondBase.py + start: 52.0 + tag: STAAP2 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 upgrade -Q -t 1 + - ['R SSC1 C BIN_ID,0'] + - - SSC SSC1 upgrade -Q -t 2 -b 0 + - ['R SSC1 C BIN_INFO,0'] + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + force restore cmd set: + - '' + - - SSC SSC1 upgrade -R -r 1 -s + - [R SSC1 NC ERROR C !!!ready!!!] + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SOC SOC1 ULISTEN + - [R SOC_COM L OK] + - - SOC SOC1 SETOPT REPLY BIN + - [R SOC_COM C OK] + - - SSC SSC1 upgrade -I -b 0 -f 0 + - ['P SSC1 C +UPGRADE:OK'] + - - SSC SSC1 upgrade -U -i -p -u + - ['P SSC1 C +UPGRADE:SUCCEED'] + - - SSC SSC1 upgrade -R -b 0 + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + initial condition detail: APSTA mode, connected to AP, running BIN0 (located on + flash id 0) + restore cmd set: + - '' + - - SSC SSC1 upgrade -Q -t 2 -b 0 + - ['R SSC1 C BIN_INFO,0'] + - - SSC SSC1 upgrade -R -b 0 + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + restore post cmd set: + - '' + - - SSC SSC1 upgrade -D + - ['R SSC1 C +UPGRADE:OK'] + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 24.0 + tag: STAAPBIN0 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:1'] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:'] + - - SSC SSC1 dhcp -Q -o 1 + - ['R SSC1 C +DHCP:STA,STARTED'] + - - SSC SSC1 mac -Q -o 1 + - [R SSC1 P ] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + initial condition detail: sta mode, quit AP, DHCP on, will autogen a TC with initial + condition STAAP1 + restore cmd set: + - '' + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 ram + - ['R SSC1 C +FREEHEAP:'] + script path: InitCondBase.py + start: 17.0 + tag: STAM1 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:1'] + - - SSC SSC1 sta -Q + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC1 dhcp -Q -o 1 + - ['R SSC1 C +DHCP:STA,STARTED'] + - - SSC SSC1 mac -Q -o 1 + - [R SSC1 P ] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + initial condition detail: sta mode, join AP, DHCP on, will autogen a TC with initial + condition STAAP2 + restore cmd set: + - '' + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 ram + - ['R SSC1 C +FREEHEAP:'] + script path: InitCondBase.py + start: 24.0 + tag: STAM2 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 upgrade -Q -t 1 + - ['R SSC1 C BIN_ID,0'] + - - SSC SSC1 upgrade -Q -t 2 -b 0 + - ['R SSC1 C BIN_INFO,0'] + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + force restore cmd set: + - '' + - - SSC SSC1 upgrade -R -r 1 -s + - [R SSC1 NC ERROR C !!!ready!!!] + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SOC SOC1 ULISTEN + - [R SOC_COM L OK] + - - SOC SOC1 SETOPT REPLY BIN + - [R SOC_COM C OK] + - - SSC SSC1 upgrade -I -b 0 -f 0 + - ['P SSC1 C +UPGRADE:OK'] + - - SSC SSC1 upgrade -U -i -p -u + - ['P SSC1 C +UPGRADE:SUCCEED'] + - - SSC SSC1 upgrade -R -b 0 + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + initial condition detail: STA mode, connected to AP, running BIN0 (located on flash + id 0) + restore cmd set: + - '' + - - SSC SSC1 upgrade -Q -t 2 -b 0 + - ['R SSC1 C BIN_INFO,0'] + - - SSC SSC1 upgrade -R -b 0 + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + restore post cmd set: + - '' + - - SSC SSC1 upgrade -D + - ['R SSC1 C +UPGRADE:OK'] + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 17.0 + tag: STAMBIN0 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:1'] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:'] + - - SSC SSC1 dhcp -Q -o 1 + - ['R SSC1 C +DHCP:STA,STARTED'] + - - SSC SSC1 mac -Q -o 1 + - [R SSC1 P ] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + initial condition detail: sta mode, quit AP, will NOT autogen a TC with initial + condition STAAP1 + restore cmd set: + - '' + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 sta -D + - ['R SSC1 C +QAP:'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 ram + - ['R SSC1 C +FREEHEAP:'] + script path: InitCondBase.py + start: 17.0 + tag: STAO1 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:1'] + - - SSC SSC1 sta -Q + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + - - SSC SSC1 dhcp -Q -o 1 + - ['R SSC1 C +DHCP:STA,STARTED'] + - - SSC SSC1 mac -Q -o 1 + - [R SSC1 P ] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + initial condition detail: sta mode, join AP, DHCP on, will NOT autogen a TC with + initial condition STAAP2 + restore cmd set: + - '' + - - SSC SSC1 op -S -o 1 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC1 dhcp -S -o 1 + - [R SSC1 C +DHCP] + - - SSC SSC1 mac -S -o 1 -m + - ['R SSC1 C +MAC:STA,OK'] + - - SSC SSC1 sta -C -s -p + - ['R SSC1 RE "\+JAP:CONNECTED,%%s"%%()'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 ram + - ['R SSC1 C +FREEHEAP:'] + script path: InitCondBase.py + start: 24.0 + tag: STAO2 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:2'] + - - SSC SSC2 op -Q + - ['R SSC2 C +CURMODE:1'] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:'] + - - SSC SSC2 soc -T + - [''] + - - SSC SSC1 dhcp -Q -o 2 + - ['R SSC1 C +DHCP:AP,STARTED'] + - - SSC SSC2 dhcp -Q -o 1 + - ['R SSC2 C +DHCP:STA,STARTED'] + - - SSC SSC1 mac -Q -o 2 + - [R SSC1 P ] + - - SSC SSC2 mac -Q -o 1 + - [R SSC2 P ] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC2 reboot + - [R SSC2 C !!!ready!!!] + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC2 op -S -o 1 + - ['R SSC2 C +MODE:OK'] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:'] + - - SSC SSC2 soc -T + - [''] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC2 dhcp -S -o 1 + - [R SSC2 C +DHCP] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC2 mac -S -o 1 -m + - ['R SSC2 C +MAC:STA,OK'] + initial condition detail: same as T2_1 but will NOT autogen a TC with initial condition + T2_2 + restore cmd set: + - '' + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC2 op -S -o 1 + - ['R SSC2 C +MODE:OK'] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:'] + - - SSC SSC2 soc -T + - [''] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC2 dhcp -S -o 1 + - [R SSC2 C +DHCP] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC2 mac -S -o 1 -m + - ['R SSC2 C +MAC:STA,OK'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 ram + - ['R SSC1 C +FREEHEAP:'] + script path: InitCondBase.py + start: 73.0 + tag: T2O_1 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:2'] + - - SSC SSC2 op -Q + - ['R SSC2 C +CURMODE:1'] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:'] + - - SSC SSC2 soc -T + - [''] + - - SSC SSC1 dhcp -Q -o 2 + - ['R SSC1 C +DHCP:AP,STARTED'] + - - SSC SSC2 dhcp -Q -o 1 + - ['R SSC2 C +DHCP:STA,STARTED'] + - - SSC SSC1 mac -Q -o 2 + - [R SSC1 P ] + - - SSC SSC2 mac -Q -o 1 + - [R SSC2 P ] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC2 reboot + - [R SSC2 C !!!ready!!!] + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC2 op -S -o 1 + - ['R SSC2 C +MODE:OK'] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:'] + - - SSC SSC2 soc -T + - [''] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC2 dhcp -S -o 1 + - [R SSC2 C +DHCP] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC2 mac -S -o 1 -m + - ['R SSC2 C +MAC:STA,OK'] + initial condition detail: target 1 as SoftAP, target 2 as STA, will autogen a TC + with initial condition T2_2 + restore cmd set: + - '' + - - SSC SSC1 op -S -o 2 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC2 op -S -o 1 + - ['R SSC2 C +MODE:OK'] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:'] + - - SSC SSC2 soc -T + - [''] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC2 dhcp -S -o 1 + - [R SSC2 C +DHCP] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC2 mac -S -o 1 -m + - ['R SSC2 C +MAC:STA,OK'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 ram + - ['R SSC1 C +FREEHEAP:'] + script path: InitCondBase.py + start: 73.0 + tag: T2_1 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC1 op -Q + - ['R SSC1 C +CURMODE:3'] + - - SSC SSC2 op -Q + - ['R SSC2 C +CURMODE:3'] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:'] + - - SSC SSC2 soc -T + - [R SSC2 C +CLOSEALL] + - - SSC SSC1 dhcp -Q -o 2 + - ['R SSC1 C +DHCP:AP,STARTED'] + - - SSC SSC2 dhcp -Q -o 1 + - ['R SSC2 C +DHCP:STA,STARTED'] + - - SSC SSC1 mac -Q -o 2 + - [R SSC1 P ] + - - SSC SSC2 mac -Q -o 1 + - [R SSC2 P ] + force restore cmd set: + - '' + - - SSC SSC1 reboot + - [R SSC1 C !!!ready!!!] + - - SSC SSC2 reboot + - [R SSC2 C !!!ready!!!] + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC2 op -S -o 3 + - ['R SSC2 C +MODE:OK'] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:'] + - - SSC SSC2 soc -T + - [R SSC2 C +CLOSEALL] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC2 dhcp -S -o 1 + - [R SSC2 C +DHCP] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC2 mac -S -o 1 -m + - ['R SSC2 C +MAC:STA,OK'] + initial condition detail: target 1 as AP+STA, target 2 as AP+STA (autogen) + restore cmd set: + - '' + - - SSC SSC1 op -S -o 3 + - ['R SSC1 C +MODE:OK'] + - - SSC SSC2 op -S -o 3 + - ['R SSC2 C +MODE:OK'] + - - SSC SSC2 sta -D + - ['R SSC2 C +QAP:'] + - - SSC SSC2 soc -T + - [R SSC2 C +CLOSEALL] + - - SSC SSC1 dhcp -S -o 2 + - [R SSC1 C +DHCP] + - - SSC SSC2 dhcp -S -o 1 + - [R SSC2 C +DHCP] + - - SSC SSC1 mac -S -o 2 -m + - ['R SSC1 C +MAC:AP,OK'] + - - SSC SSC2 mac -S -o 1 -m + - ['R SSC2 C +MAC:STA,OK'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 ram + - ['R SSC1 C +FREEHEAP:'] + script path: InitCondBase.py + start: 80.0 + tag: T2_2 + test script: InitCondBase +- check cmd set: + - '' + - - SSC SSC[1-3] op -Q + - ['R SSC[1-3] C +CURMODE:3'] + - - SSC SSC[1-3] phy -Q -o 3 + - ['R SSC[1-3] C STA,n,40 C AP,n,40'] + force restore cmd set: + - '' + - - SSC SSC[1-3] reboot + - ['R SSC[1-3] C !!!ready!!!'] + - - SSC SSC[1-3] op -S -o 3 + - ['R SSC[1-3] C +MODE:OK'] + - - SSC SSC[1-3] phy -S -o 3 -m n -b 40 + - ['R SSC[1-3] C +PHY:OK'] + initial condition detail: '1. target 1 and target 2 set to AP+STA mode, target 3 + set to STA mode + + 2. all interface of target 2,3 set to 11n ht40 + + 3. config softAP of target 1 and target 2' + restore cmd set: + - '' + - - SSC SSC[1-3] op -S -o 3 + - ['R SSC[1-3] C +MODE:OK'] + - - SSC SSC[1-3] phy -S -o 3 -m n -b 40 + - ['R SSC[1-3] C +PHY:OK'] + restore post cmd set: + - '' + - - SSC SSC1 soc -T + - [R SSC1 C +CLOSEALL] + - - SSC SSC1 sta -R -r 1 + - [R SSC1 C OK] + - - SSC SSC1 ram + - ['R SSC1 A :(\d+)'] + script path: InitCondBase.py + start: 87.0 + tag: T3_PHY1 + test script: InitCondBase diff --git a/components/idf_test/uint_test/TestCaseAll.yml b/components/idf_test/uint_test/TestCaseAll.yml new file mode 100644 index 0000000000..2b2c65e0bd --- /dev/null +++ b/components/idf_test/uint_test/TestCaseAll.yml @@ -0,0 +1 @@ +test cases: [] diff --git a/components/idf_test/uint_test/TestEnvAll.yml b/components/idf_test/uint_test/TestEnvAll.yml new file mode 100644 index 0000000000..afa6cb812a --- /dev/null +++ b/components/idf_test/uint_test/TestEnvAll.yml @@ -0,0 +1,275 @@ +test environment: +- {PC OS: '', Special: N, Target Count: 1.0, script path: EnvBase.py, tag: AT_T1_1, + test environment detail: 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 AT target connect with PC by UART (AT and LOG port).', test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 1.0, script path: EnvBase.py, tag: AT_T1_2, + test environment detail: 'PC has 1 WiFi NIC. + + 1 AT target connect with PC by UART (AT and LOG port).', test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 1.0, script path: EnvBase.py, tag: AT_T1_3, + test environment detail: 'Able to access WAN after connect to AP. + + 1 AT target connect with PC by UART (AT and LOG port).', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: AT_T1_ADC, + test environment detail: 'PC has 1 wired NIC connected to AP. + + Analog input connect to AT1 TOUT. + + Multimeter connect to input, able to measure input voltage. + + 1 AT target connect with PC by UART (AT and LOG port).', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: AT_T1_APC1, + test environment detail: "PC has 1 wired NIC connected to AP.\nPC has 1 wired NIC\ + \ connected to APC (static IP within the same subnet with APC). \nAPC control\ + \ AP power supply. \nPC has 1 WiFi NIC. \n1 AT target connect with PC by UART\ + \ (AT and LOG port).", test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: AT_T1_APC2, + test environment detail: "Able to access WAN after connect to AP.\nPC has 1 wired\ + \ NIC connected to APC (static IP within the same subnet with APC). \nAPC control\ + \ AP power supply.\nPC has 1 WiFi NIC.\n1 AT target connect with PC by UART (AT\ + \ and LOG port).", test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: AT_T1_HighSpeedUART, + test environment detail: 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 AT target connect with PC by high speed UART (AT and LOG port).', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: AT_T1_SmartConfigIOT, + test environment detail: '1 AT target connect with PC by UART (AT and LOG port). + + PC has 1 wired NIC connect to Common AP. + + Several AP are placed near AT target. + + Several smart phone installed test APK are placed near AT target.', test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 2.0, script path: EnvBase.py, tag: AT_T2_1, + test environment detail: 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 AT target connect with PC by UART (AT and LOG port).', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 2.0, script path: EnvBase.py, tag: AT_T2_JAP, + test environment detail: "Several AP are placed near AT target.\nPC has 1 wired\ + \ NIC connected to APC (static IP within the same subnet with APC).\nAPC control\ + \ power supply for all APs. \n2 AT target connect with PC by UART (AT and LOG\ + \ port).", test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 2.0, script path: EnvBase.py, tag: AT_T2_Sleep, + test environment detail: 'AP support DTIM placed with AT target. + + 2 AT target connect with PC by UART (AT and LOG port). + + Multimeter connect with PC via GPIB. + + Series multimeter between GND and VCC of AT1. + + AT1''s light sleep wakeup pin and wakeup indication connect with AT2''s GPIO.', + test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 2.0, script path: EnvBase.py, tag: AT_T2_SmartConfig, + test environment detail: '2 AT target connect with PC by UART (AT and LOG port). + + PC has 1 WiFi NIC. + + One HT20 AP and One HT40 AP are placed near target.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, UART ports: 'SSC1 + + SSC2', additional param list: '', basic param list: '', script path: EnvBase.py, + tag: IR_T2_1, test environment detail: '[TBD] 本测试为非自动测试, 红外能够做到数据收发吻合即可通过', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 2.0, script path: EnvBase.py, tag: NVS_T1_1, + test environment detail: '1 NVS target connect with PC by UART. + + 1 SSC target connect with PC by UART. + + SSC2 GPIO connect to NVS1 power control pin.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, UART ports: SSC_1, additional param list: '', + basic param list: '', script path: EnvBase.py, tag: PWM_T1_1, test environment detail: "[TBD]\ + \ 1. PWM OS SDK 以及 Non-OS SDK的测试建议分开进行, 放在不同的文件夹, 防止文件命名混淆\n2. 分析CSV文件的Python脚本只能分析单个channel\ + \ \n3. 如果Init脚本打印\"Network Error\" 检查TCP Server是不是正常发送data", test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_1, + test environment detail: 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.', test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_2, + test environment detail: 'Able to access WAN after connect to AP. + + 1 SSC target connect with PC by UART.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_8089, + test environment detail: 'PC has 1 wired NIC connected to AP. + + 1 8089 tablet able to run iperf test placed near SSC1. + + 1 SSC target connect with PC by UART.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_ADC, + test environment detail: 'PC has 1 wired NIC connected to AP. + + Analog input connect to SSC1 TOUT. + + Multimeter connect to input, able to measure input voltage. + + 1 SSC target connect with PC by UART.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_APC, + test environment detail: "PC has 1 wired NIC connected to AP.\nPC has 1 wired NIC\ + \ connected to APC (static IP within the same subnet with APC). \nAPC control\ + \ AP power supply. \nPC has 1 WiFi NIC. \n1 SSC target connect with PC by UART.", + test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_Enterprise, + test environment detail: "AP use WPA2-Etherprise is placed near SSC1. \n1 SSC target\ + \ connect with PC by UART.", test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_IOT1, + test environment detail: 'PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART. + + AP todo IOT test are placed near SSC1.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 2.0, script path: EnvBase.py, tag: SSC_T1_InitData, + test environment detail: '2 SSC target connect with PC by UART. + + SSC1 use 40M crystal oscillator. + + SSC2 use normal 26M crystal oscillator. + + SSC2 GPIO connect to SSC1 power control pin.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_ShieldBox, + test environment detail: 'refer to figure. + + All APs and APC should be set to the same IP subnet. + + PC wired NIC should set static IP address within the same subnet with AP. + + Must use onboard wired NIC.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_TempBox, + test environment detail: '1 SSC target connect with PC by UART. + + Put SSC target to temperature box.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, UART ports: SSC_1, additional param list: '', + basic param list: '', script path: EnvBase.py, tag: SSC_T1_Timer, test environment detail: '[TBD] + 通过串口工具调节Timer, 将GPIO_13端口连接到逻辑分析仪', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_VDD33, + test environment detail: '1 SSC target connect with PC by UART. + + Multimeter connect to VDD33, able to measure voltage.', test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_WEP, + test environment detail: '1 SSC target connect with PC by UART. + + One WEP share key AP placed near SSC1.', test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 2.0, script path: EnvBase.py, tag: SSC_T2_1, + test environment detail: 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 2.0, UART ports: 'SSC1 + + SSC2', additional param list: '', basic param list: '', script path: EnvBase.py, + tag: SSC_T2_GPIO1, test environment detail: '[TBD] 2个ESP_8266通过UART连到PC, ESP_8266的 + GPIO_6相连', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 2.0, UART ports: 'SSC1 + + SSC2', additional param list: '', basic param list: '', script path: EnvBase.py, + tag: SSC_T2_GPIO2, test environment detail: '[TBD] 1. 2个ESP_8266通过UART连到PC, ESP_8266的 + GPIO_15通过面包板相连 + + 2. 可借助面包板, 将GPIO_15, 以及中断函数被打开的8266板的GPIO_2 相连', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 2.0, UART ports: 'SSC1 + + SSC2', additional param list: '', basic param list: '', script path: EnvBase.py, + tag: SSC_T2_GPIO3, test environment detail: '[TBD] 2个ESP_8266通过UART连到PC, ESP_8266之间需要测试的Target_GPIO相连', + test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 2.0, script path: EnvBase.py, tag: SSC_T2_PhyMode, + test environment detail: '2 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. + + Put 4 APs near SSC targets.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 2.0, script path: EnvBase.py, tag: SSC_T2_ShieldBox, + test environment detail: '2 SSC target connect with PC by UART. + + Put them to Shield box.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 2.0, script path: EnvBase.py, tag: SSC_T2_Sleep1, + test environment detail: 'AP support DTIM placed with AT target. + + 2 SSC target connect with PC by UART. + + Multimeter connect with PC via GPIB. + + Series multimeter between GND and VCC of SSC1. + + SSC1''s light sleep wakeup pin and wakeup indication connect with AT2''s GPIO. + + SSC1''s XPD connect with RSTB.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 2.0, script path: EnvBase.py, tag: SSC_T2_Sleep2, + test environment detail: 'AP support DTIM placed with AT target. + + 2 SSC target connect with PC by UART. + + Multimeter connect with PC via GPIB. + + Series multimeter between GND and VCC of SSC1. + + SSC1''s RSTB pin connect with AT2''s GPIO.', test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 2.0, script path: EnvBase.py, tag: SSC_T2_SmartConfig, + test environment detail: '2 SSC target connect with PC by UART. + + PC has 1 WiFi NIC. + + One HT20 AP and One HT40 AP are placed near target.', test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 3.0, script path: EnvBase.py, tag: SSC_T3_PhyMode, + test environment detail: '3 SSC target connect with PC by UART. + + PC has one WiFi NIC support capture wlan packet using libpcap. + + Set 4 AP with (HT20, channel1), (HT20, channel2), (HT40, channel1), (HT40, channel2). + + Put 4 APs near SSC targets.', test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 5.0, script path: EnvBase.py, tag: SSC_T5_1, + test environment detail: 5 SSC target connect with PC by UART., test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T6_1, + test environment detail: 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 6 SSC target connect with PC by UART.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: TempSensor_T1_1, + test environment detail: 'Tempeture sensor target connect with PC by UART. + + AP support DTIM placed with AT target. + + Multimeter connect with PC via GPIB. + + Series multimeter between GND and VCC of TempSensor1. + + PC has 1 wired NIC connected to switch. + + APC, AP also connect with swtich. + + All devices connected with switch use the same IP subnet. + + APC control AP power supply.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, UART ports: SSC_1, additional param list: '', + basic param list: '', script path: EnvBase.py, tag: UART_T1_1, test environment detail: '[TBD] + 将ESP_8266通过UART连到PC', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, UART ports: 'SSC1 + + SSC2', additional param list: '', basic param list: '', script path: EnvBase.py, + tag: UART_T1_2, test environment detail: '[TBD] ESP_8266通过UART_0通过USB, UART_1 TXD + 通过 TTLcable 连到PC', test script: EnvBase} +- {PC OS: linux, Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: WebServer_T1_1, + test environment detail: 'Web Server target connect with PC by UART. + + PC has 1 wired NIC connected to switch. + + APC, AP also connect with swtich. + + All devices connected with switch use same IP subnet. + + APC control AP power supply.', test script: EnvBase} +- {PC OS: linux, Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: WebServer_T1_2, + test environment detail: 'Web Server target connect with PC by UART. + + 4 PC with WiFi NIC placed near WebServer1.', test script: EnvBase} diff --git a/components/test/CIConfigs/Function_TCPIP_01.yml b/components/test/CIConfigs/Function_TCPIP_01.yml deleted file mode 100644 index e947b0c5c7..0000000000 --- a/components/test/CIConfigs/Function_TCPIP_01.yml +++ /dev/null @@ -1,10 +0,0 @@ -Config: {execute count: 1, execute order: in order} -DUT: [SSC2, SSC1] -Filter: -- Add: - ID: [^TCPIP_DHCP_0302, ^TCPIP_DHCP_0301, ^TCPIP_UDP_0113, TCPIP_DHCP_0302, TCPIP_DHCP_0301, - TCPIP_TCP_0412, TCPIP_TCP_0403, TCPIP_TCP_0402, TCPIP_TCP_0401, TCPIP_TCP_0407, - TCPIP_TCP_0406, TCPIP_TCP_0404, TCPIP_TCP_0408, ^TCPIP_TCP_0202, TCPIP_TCP_0110, - ^TCPIP_TCP_0203, TCPIP_DHCP_0101, TCPIP_DHCP_0103, TCPIP_DHCP_0102, TCPIP_IP_0101, - TCPIP_IP_0102, ^TCPIP_IGMP_0102, ^TCPIP_IGMP_0101, ^TCPIP_IGMP_0104, TCPIP_IGMP_0104, - TCPIP_IGMP_0103, TCPIP_IGMP_0102, TCPIP_IGMP_0101, ^TCPIP_UDP_0201, TCPIP_UDP_0108] diff --git a/components/test/CIConfigs/Function_TCPIP_02.yml b/components/test/CIConfigs/Function_TCPIP_02.yml deleted file mode 100644 index 6a3cb08d6d..0000000000 --- a/components/test/CIConfigs/Function_TCPIP_02.yml +++ /dev/null @@ -1,10 +0,0 @@ -Config: {execute count: 1, execute order: in order} -DUT: [SSC2, SSC1] -Filter: -- Add: - ID: [TCPIP_UDP_0106, TCPIP_UDP_0107, TCPIP_UDP_0105, TCPIP_UDP_0101, TCPIP_IGMP_0204, - TCPIP_IGMP_0201, TCPIP_IGMP_0202, TCPIP_IGMP_0203, ^TCPIP_TCP_0404, ^TCPIP_TCP_0406, - ^TCPIP_TCP_0407, ^TCPIP_TCP_0401, ^TCPIP_TCP_0402, ^TCPIP_TCP_0403, ^TCPIP_TCP_0408, - TCPIP_UDP_0201, ^TCPIP_TCP_0101, ^TCPIP_TCP_0103, ^TCPIP_TCP_0102, ^TCPIP_TCP_0105, - ^TCPIP_TCP_0104, ^TCPIP_TCP_0107, ^TCPIP_TCP_0106, ^TCPIP_DHCP_0210, ^TCPIP_DHCP_0211, - TCPIP_TCP_0212, TCPIP_TCP_0210, ^TCPIP_TCP_0210, ^TCPIP_TCP_0212, TCPIP_DHCP_0211] diff --git a/components/test/CIConfigs/Function_TCPIP_03.yml b/components/test/CIConfigs/Function_TCPIP_03.yml deleted file mode 100644 index 0c4ac37524..0000000000 --- a/components/test/CIConfigs/Function_TCPIP_03.yml +++ /dev/null @@ -1,10 +0,0 @@ -Config: {execute count: 1, execute order: in order} -DUT: [SSC2, SSC1] -Filter: -- Add: - ID: [TCPIP_DHCP_0210, TCPIP_UDP_0202, TCPIP_TCP_0411, ^TCPIP_IP_0102, ^TCPIP_UDP_0105, - ^TCPIP_UDP_0107, ^TCPIP_UDP_0106, ^TCPIP_UDP_0101, ^TCPIP_DHCP_0102, ^TCPIP_DHCP_0103, - ^TCPIP_UDP_0108, ^TCPIP_IGMP_0201, ^TCPIP_IGMP_0203, ^TCPIP_IGMP_0202, ^TCPIP_IGMP_0204, - TCPIP_UDP_0114, TCPIP_UDP_0113, TCPIP_UDP_0112, ^TCPIP_TCP_0201, ^TCPIP_TCP_0206, - ^TCPIP_TCP_0207, TCPIP_TCP_0106, TCPIP_TCP_0107, TCPIP_TCP_0104, TCPIP_TCP_0105, - TCPIP_TCP_0102, TCPIP_TCP_0103, TCPIP_TCP_0101, ^TCPIP_TCP_0116, ^TCPIP_TCP_0114] diff --git a/components/test/CIConfigs/Function_TCPIP_04.yml b/components/test/CIConfigs/Function_TCPIP_04.yml deleted file mode 100644 index f8bdb264b9..0000000000 --- a/components/test/CIConfigs/Function_TCPIP_04.yml +++ /dev/null @@ -1,10 +0,0 @@ -Config: {execute count: 1, execute order: in order} -DUT: [SSC2, SSC1] -Filter: -- Add: - ID: [^TCPIP_TCP_0115, ^TCPIP_TCP_0112, ^TCPIP_TCP_0113, ^TCPIP_TCP_0110, ^TCPIP_TCP_0111, - ^TCPIP_DHCP_0209, ^TCPIP_DHCP_0208, ^TCPIP_DHCP_0207, ^TCPIP_DHCP_0206, ^TCPIP_DHCP_0205, - ^TCPIP_DHCP_0204, ^TCPIP_DHCP_0203, ^TCPIP_DHCP_0202, ^TCPIP_DHCP_0201, TCPIP_TCP_0204, - TCPIP_TCP_0207, TCPIP_TCP_0206, TCPIP_TCP_0201, ^TCPIP_DHCP_0101, TCPIP_TCP_0203, - TCPIP_TCP_0202, TCPIP_TCP_0208, TCPIP_DHCP_0206, TCPIP_DHCP_0207, TCPIP_DHCP_0204, - TCPIP_DHCP_0205, TCPIP_DHCP_0202, TCPIP_DHCP_0203, ^TCPIP_TCP_0204, TCPIP_DHCP_0201] diff --git a/components/test/CIConfigs/Function_TCPIP_05.yml b/components/test/CIConfigs/Function_TCPIP_05.yml deleted file mode 100644 index 21b3b7a6d8..0000000000 --- a/components/test/CIConfigs/Function_TCPIP_05.yml +++ /dev/null @@ -1,8 +0,0 @@ -Config: {execute count: 1, execute order: in order} -DUT: [SSC2, SSC1] -Filter: -- Add: - ID: [^TCPIP_TCP_0208, TCPIP_DHCP_0208, TCPIP_DHCP_0209, ^TCPIP_TCP_0412, ^TCPIP_TCP_0411, - ^TCPIP_UDP_0112, ^TCPIP_UDP_0114, ^TCPIP_UDP_0202, ^TCPIP_IGMP_0103, ^TCPIP_IP_0101, - TCPIP_TCP_0115, TCPIP_TCP_0114, TCPIP_TCP_0116, TCPIP_TCP_0111, TCPIP_TCP_0113, - TCPIP_TCP_0112] diff --git a/components/test/CIConfigs/Function_TCPIP_07.yml b/components/test/CIConfigs/Function_TCPIP_07.yml deleted file mode 100644 index 2a047b8e16..0000000000 --- a/components/test/CIConfigs/Function_TCPIP_07.yml +++ /dev/null @@ -1,10 +0,0 @@ -Config: {execute count: 1, execute order: in order} -DUT: [SSC1] -Filter: -- Add: - ID: [TCPIP_ICMP_0101, TCPIP_ICMP_0101, TCPIP_ICMP_0101, TCPIP_ICMP_0101, TCPIP_ICMP_0101, - ^TCPIP_UDP_0303, ^TCPIP_UDP_0303, ^TCPIP_UDP_0303, ^TCPIP_UDP_0303, ^TCPIP_UDP_0303, - ^TCPIP_UDP_0302, ^TCPIP_UDP_0302, ^TCPIP_UDP_0302, ^TCPIP_UDP_0302, ^TCPIP_UDP_0302, - ^TCPIP_UDP_0301, ^TCPIP_UDP_0301, ^TCPIP_UDP_0301, ^TCPIP_UDP_0301, ^TCPIP_UDP_0301, - TCPIP_DNS_0102, TCPIP_DNS_0102, TCPIP_DNS_0102, TCPIP_DNS_0102, TCPIP_DNS_0102, - TCPIP_DNS_0101, TCPIP_DNS_0101, TCPIP_DNS_0101, TCPIP_DNS_0101, TCPIP_DNS_0101] diff --git a/components/test/CIConfigs/Function_TCPIP_12.yml b/components/test/CIConfigs/Function_TCPIP_12.yml deleted file mode 100644 index e9f5b72a51..0000000000 --- a/components/test/CIConfigs/Function_TCPIP_12.yml +++ /dev/null @@ -1,6 +0,0 @@ -Config: {execute count: 1, execute order: in order} -DUT: [SSC1] -Filter: -- Add: - ID: [TCPIP_UDP_0303, TCPIP_UDP_0303, TCPIP_UDP_0303, TCPIP_UDP_0303, TCPIP_UDP_0303, - TCPIP_DNS_0103, TCPIP_DNS_0103, TCPIP_DNS_0103, TCPIP_DNS_0103, TCPIP_DNS_0103] diff --git a/components/test/CIConfigs/Function_WIFI_01.yml b/components/test/CIConfigs/Function_WIFI_01.yml deleted file mode 100644 index da9bfecd5d..0000000000 --- a/components/test/CIConfigs/Function_WIFI_01.yml +++ /dev/null @@ -1,10 +0,0 @@ -Config: {execute count: 1, execute order: in order} -DUT: [SSC2, SSC1] -Filter: -- Add: - ID: [^WIFI_CONN_0601, ^WIFI_ADDR_0101, WIFI_SCAN_0103, WIFI_SCAN_0102, WIFI_SCAN_0101, - WIFI_SCAN_0105, WIFI_SCAN_0104, WIFI_CONN_0201, WIFI_CONN_0904, ^WIFI_CONN_0201, - ^WIFI_SCAN_0102, ^WIFI_SCAN_0103, ^WIFI_SCAN_0104, ^WIFI_SCAN_0105, ^WIFI_ADDR_0102, - WIFI_CONN_0401, ^WIFI_CONN_0103, WIFI_ADDR_0101, WIFI_ADDR_0102, WIFI_CONN_0301, - ^WIFI_CONN_0801, WIFI_CONN_0104, ^WIFI_CONN_0301, WIFI_CONN_0501, WIFI_CONN_0502, - ^WIFI_CONN_0401, WIFI_MODE_0101, WIFI_MODE_0103, WIFI_MODE_0102, ^WIFI_CONN_0904] diff --git a/components/test/CIConfigs/Function_WIFI_02.yml b/components/test/CIConfigs/Function_WIFI_02.yml deleted file mode 100644 index e1b61a20e9..0000000000 --- a/components/test/CIConfigs/Function_WIFI_02.yml +++ /dev/null @@ -1,7 +0,0 @@ -Config: {execute count: 1, execute order: in order} -DUT: [SSC2, SSC1] -Filter: -- Add: - ID: [^WIFI_CONN_0901, WIFI_CONN_0601, WIFI_CONN_0901, WIFI_CONN_0503, ^WIFI_CONN_0104, - WIFI_CONN_0101, WIFI_CONN_0102, WIFI_CONN_0103, WIFI_CONN_0801, ^WIFI_CONN_0101, - ^WIFI_CONN_0503, ^WIFI_CONN_0502, ^WIFI_CONN_0501, ^WIFI_SCAN_0101] diff --git a/components/test/CIConfigs/Function_WIFI_06.yml b/components/test/CIConfigs/Function_WIFI_06.yml deleted file mode 100644 index f3db504c9f..0000000000 --- a/components/test/CIConfigs/Function_WIFI_06.yml +++ /dev/null @@ -1,7 +0,0 @@ -Config: {execute count: 1, execute order: in order} -DUT: [SSC2, SSC1] -Filter: -- Add: - ID: [WIFI_PHY_0403, WIFI_SCAN_0301, WIFI_SCAN_0303, WIFI_SCAN_0304, WIFI_SCAN_0302, - WIFI_SCAN_0201, WIFI_PHY_0402, WIFI_PHY_0401, WIFI_PHY_0407, WIFI_PHY_0406, - WIFI_PHY_0405, WIFI_PHY_0404, WIFI_PHY_0408] diff --git a/components/test/README.md b/components/test/README.md deleted file mode 100644 index 1d0c4cfbd1..0000000000 --- a/components/test/README.md +++ /dev/null @@ -1,4 +0,0 @@ - -# Note: The test cases in this folder are for Espressif internal use. - -# Goto internal project wiki Testing page for detail about this folder. diff --git a/components/test/TestCaseScript/ATFunc/CmdInterruptTest.py b/components/test/TestCaseScript/ATFunc/CmdInterruptTest.py deleted file mode 100755 index e11ae6f1d8..0000000000 --- a/components/test/TestCaseScript/ATFunc/CmdInterruptTest.py +++ /dev/null @@ -1,130 +0,0 @@ -from TCAction import TCActionBase -from NativeLog import NativeLog -from TCAction import CmdHandler -import time - - -ATCmdList = ["GMR", - "UART=115200,8,1,0,0", - "CWMODE=3", - "CWJAP=\"TL_WR845N_T\",\"1234567890\"", - "CWLAP", - "CWQAP", - "CWSAP=\"asdf\",\"123456789\",5,3", - "CWLIF", - "CWDHCP=3", - "AT+CWAUTOCONN", - "CIPSTAMAC=\"18:fe:34:97:f3:43\"", - "CIPAPMAC=\"1a:fe:34:97:f3:43\"", - "CIPSTA=\"192.168.1.2\"", - "CIPAP=\"192.168.4.1\"", - "CIPSTATUS", - "CIPSTART=\"UDP\",\"192.168.1.4\",6531,7895,1", - "CIPSTART=\"TCP\",\"192.168.1.4\",6531", - "CIPCLOSE", - "CIFSR", - "CIPMUX=1", - "CIPSERVER=1,4567", - "CIPMODE=0", - "CIPSTO=7200", - "PING=\"192.168.1.4\""] - - -class CmdInterruptTest(TCActionBase.CommonTCActionBase): - - def __init__(self, name, test_env, cmd_set, timeout=20, log_path=TCActionBase.LOG_PATH): - TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - - self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) - pass - - def load_and_exe_one_step(self, checker_stings, test_action_strings, fail_string, - check_freq=0.1, check_time=50, sleep_time=0.1): - # set checker for next executing step - checkers = CmdHandler.parse_results(checker_stings, self.test_env) - self.result_cntx.set_next_step(checkers, check_time, check_freq) - # execute 1 step - for action_string in test_action_strings: - test_action = CmdHandler.parse_action(action_string, self.test_env) - CmdHandler.do_actions(test_action, self.test_env) - time.sleep(sleep_time) - - ret = self.wait_to_execute() - - if ret is False: # # timeout - self.result_cntx.set_result(fail_string) - if ret == check_time: - self.result_cntx.set_result(fail_string) - ret = False - - self.require_waiting() - - return ret - - def execute(self): - TCActionBase.TCActionBase.execute(self) - self.result_cntx.start() - - # step 1, sleep time 0.1 - for cmd1 in ATCmdList: - # check if match CMD - AT - busy - OK/ERROR pattern - checker_stings = ["ATR AT1 C busy", "ATR AT1 R *"] - test_action_string = ["ATS AT1 AT+%s" % cmd1, "ATS AT1 AT"] - fail_string = "Fail, Fail on step 1" - if self.load_and_exe_one_step(checker_stings, test_action_string, - fail_string, sleep_time=0.1) is False: - # check again if match CMD - OK/ERROR - AT - OK pattern - checker_stings = ["ATR AT1 R *", "ATR AT1 C AT L OK"] - test_action_string = ["ATS AT1 AT+%s" % cmd1, "ATS AT1 AT"] - fail_string = "Fail, Fail on step 1" - if self.load_and_exe_one_step(checker_stings, test_action_string, - fail_string, sleep_time=0.1) is False: - NativeLog.add_trace_critical("CMD Fail: AT+%s; sleep time is 0.1" % cmd1) - - # step 2, sleep time 0 - for cmd1 in ATCmdList: - # check if match CMD - AT - busy - OK/ERROR pattern - checker_stings = ["ATR AT1 C busy", "ATR AT1 R *"] - test_action_string = ["ATS AT1 AT+%s" % cmd1, "ATS AT1 AT"] - fail_string = "Fail, Fail on step 1" - if self.load_and_exe_one_step(checker_stings, test_action_string, - fail_string, sleep_time=0.1) is False: - # check again if match CMD - OK/ERROR - AT - OK pattern - checker_stings = ["ATR AT1 R *", "ATR AT1 C AT L OK"] - test_action_string = ["ATS AT1 AT+%s" % cmd1, "ATS AT1 AT"] - fail_string = "Fail, Fail on step 1" - if self.load_and_exe_one_step(checker_stings, test_action_string, - fail_string, sleep_time=0.1) is False: - NativeLog.add_trace_critical("CMD Fail: AT+%s; sleep time is 0" % cmd1) - - # step 3, cat string - for cmd1 in ATCmdList: - # check if match CMD - AT - busy - OK/ERROR pattern - checker_stings = ["ATR AT1 C busy", "ATR AT1 R *"] - test_action_string = ["ATSO AT1 AT+%s\r\nAT\r\n" % cmd1] - fail_string = "Fail, Fail on step 1" - if self.load_and_exe_one_step(checker_stings, test_action_string, - fail_string, sleep_time=0.1) is False: - # check again if match CMD - OK/ERROR - AT - OK pattern - checker_stings = ["ATR AT1 R *", "ATR AT1 C AT L OK"] - test_action_string = ["ATS AT1 AT+%s" % cmd1, "ATS AT1 AT"] - fail_string = "Fail, Fail on step 1" - if self.load_and_exe_one_step(checker_stings, test_action_string, - fail_string, sleep_time=0.1) is False: - NativeLog.add_trace_critical("CMD Fail: AT+%s; cat string" % cmd1) - - # finally, execute done - self.result_cntx.set_result("Succeed") - - def result_check(self, port_name, data): - TCActionBase.CommonTCActionBase.result_check(self, port_name, data) - self.result_cntx.append_data(port_name, data) - - -def main(): - pass - -if __name__ == '__main__': - main() - diff --git a/components/test/TestCaseScript/ATFunc/LAP.py b/components/test/TestCaseScript/ATFunc/LAP.py deleted file mode 100644 index b389e48c04..0000000000 --- a/components/test/TestCaseScript/ATFunc/LAP.py +++ /dev/null @@ -1,64 +0,0 @@ -from TCAction import TCActionBase -import time -import re - - -class LAP(TCActionBase.CommonTCActionBase): - def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): - TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) - pass - - def cleanup(self): - # restore set LAPOPT - if self.load_and_exe_one_step(["R AT1 L OK"], - ["ATS AT1 AT+CWLAPOPT=0,127"], - "Failed to set LAP option") is False: - return - - def execute(self): - TCActionBase.TCActionBase.execute(self) - self.result_cntx.start() - - # step 1. set LAPOPT - if self.load_and_exe_one_step(["R AT1 L OK"], - ["ATS AT1 AT+CWLAPOPT=1,4"], - "Failed to set LAP option") is False: - return - - # step 2. LAP - if self.load_and_exe_one_step(["R AT1 A :([[^OK]]+)OK"], # [] is list generator, use [[]] for [] - ["ATS AT1 AT+CWLAP"], - "Failed to LAP") is False: - return - lap_result = self.get_parameter("lap_result") - rssi_list = re.findall("CWLAP:\((-\d+)\)", lap_result) - if len(rssi_list) > 1: - for i in range(len(rssi_list)-1): - if int(rssi_list[i]) < int(rssi_list[i+1]): - break - else: - self.result_cntx.set_result("Succeed") - else: - self.result_cntx.set_result("Succeed") - pass - - def result_check(self, port_name, data): - TCActionBase.CommonTCActionBase.result_check(self, port_name, data) - self.result_cntx.append_data(port_name, data) - pass - pass - - -def main(): - pass - - -if __name__ == '__main__': - main() diff --git a/components/test/TestCaseScript/ATFunc/SendDataValidation.py b/components/test/TestCaseScript/ATFunc/SendDataValidation.py deleted file mode 100755 index 27f1e7f7c1..0000000000 --- a/components/test/TestCaseScript/ATFunc/SendDataValidation.py +++ /dev/null @@ -1,161 +0,0 @@ -from TCAction import TCActionBase -from TCAction import CmdHandler -from NativeLog import NativeLog -import time -import threading -import sys -reload(sys) -sys.setdefaultencoding('iso-8859-1') # # use encoding that with 1 Byte length and contain 256 chars - - -VALIDATION_STRING = "".join([chr((m+65) % 256) for m in range(256)]) # make it start from 'A' - - -class ResultCheckCntx(TCActionBase.ResultCheckContext): - - def __init__(self, test_action, test_env, name): - TCActionBase.ResultCheckContext.__init__(self, test_action, test_env, name) - pass - - def run(self): - tx_result = -1 - rx_result = -1 - - while True: - exit_flag = self.wait_exit_event(2) - # force exit - if exit_flag is True: - break - try: - self.lock_data() - rx_port = filter(lambda x: x[0] == "AT1", self.data_cache) - tx_port = filter(lambda x: x[0] == "SOC2", self.data_cache) - finally: - self.unlock_data() - - if len(rx_port) == 1: - data = rx_port[0][1] - rx_result = data.find(VALIDATION_STRING) - if len(tx_port) == 1: - data = tx_port[0][1] - tx_result = data.find(VALIDATION_STRING) - - if tx_result != -1: - self.test_action.tx_check_done.set() - if rx_result != -1: - self.test_action.rx_check_done.set() - - -class SendDataValidation(TCActionBase.CommonTCActionBase): - - def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): - TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) - self.timestamp = time.strftime("%d%H%M%S", time.localtime()) - self.tx_check_done = threading.Event() - self.rx_check_done = threading.Event() - - pass - - def execute(self): - TCActionBase.TCActionBase.execute(self) - self.result_cntx.start() - - try: - # configurable params - # enable target TCP TX - tx_enable = self.tx_enable - # enable target TCP RX - rx_enable = self.rx_enable - # transparent mode select - is_transparent_mode = self.is_transparent_mode - # configurable params - except StandardError, e: - NativeLog.add_trace_critical("Error configuration for TCPTransparent script, error is %s" % e) - raise StandardError("Error configuration") - - # step1 create PC server - checker_stings = ["SOCR SOC_COM L OK"] - test_action_string = ["SOC SOC1 LISTEN "] - fail_string = "Fail, Fail on create PC server" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - # step2 target connect, switch to transparent - checker_stings = ["SOCR SOC1 C +ACCEPT", "ATR AT1 NC CLOSE L OK"] - test_action_strings = ["ATC AT1 CIPSTART \"TCP\" "] - fail_string = "Fail, Fail on connect to PC server" - if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: - return - - checker_stings = ["SOCR SOC_COM L OK"] - test_action_strings = ["SOC SOC1 ACCEPT SOC2"] - if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: - return - - # set to transparent mode - if is_transparent_mode is True: - checker_stings = ["ATR AT1 L OK"] - test_action_strings = ["ATS AT1 AT+CIPMODE=1"] - if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: - return - - checker_stings = ["ATR AT1 C >"] - test_action_strings = ["ATS AT1 AT+CIPSEND"] - if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: - return - else: - checker_stings = ["ATR AT1 C >"] - test_action_strings = ["ATS AT1 AT+CIPSEND=256"] - if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: - return - - # step 3 - - # switch to new result check context - self.result_cntx.stop_thread() - self.result_cntx.join() - self.result_cntx = ResultCheckCntx(self, self.test_env, self.tc_name) - self.result_cntx.start() - - # step 3 send data - if rx_enable is True: - test_action = CmdHandler.parse_action("SOC SOC2 SEND 256", self.test_env) - CmdHandler.do_actions(test_action[0], self.test_env) - self.rx_check_done.wait(5) - if self.rx_check_done.isSet() is False: - # rx fail - return - # flush all data - self.result_cntx.data_flush() - self.tx_check_done.clear() - - if tx_enable is True: - test_action = CmdHandler.parse_action("ATSN AT1 256", self.test_env) - CmdHandler.do_actions(test_action[0], self.test_env) - self.tx_check_done.wait(5) - if self.tx_check_done.isSet() is False: - # tx fail - return - - # finally, execute done - self.result_cntx.set_result("Succeed") - - def result_check(self, port_name, data): - TCActionBase.CommonTCActionBase.result_check(self, port_name, data) - self.result_cntx.append_data(port_name, data) - pass - - -def main(): - pass - -if __name__ == '__main__': - main() - diff --git a/components/test/TestCaseScript/ATFunc/UARTTest.py b/components/test/TestCaseScript/ATFunc/UARTTest.py deleted file mode 100644 index 184f440d49..0000000000 --- a/components/test/TestCaseScript/ATFunc/UARTTest.py +++ /dev/null @@ -1,164 +0,0 @@ -import socket -import serial - -from TCAction import PerformanceTCBase -from TCAction import TCActionBase -from NativeLog import NativeLog - - -class UARTTest(PerformanceTCBase.PerformanceTCBase): - def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): - PerformanceTCBase.PerformanceTCBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - self.test_mode = "command" - self.baudrate = None - self.bytesize = None - self.parity = None - self.stopbits = None - self.xonxoff = None - self.rtscts = None - - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) - pass - - def cleanup(self): - # restore UART config - self.restore_serial_port("AT1") - PerformanceTCBase.PerformanceTCBase.cleanup(self) - - STOP_BITS = { - 1: serial.STOPBITS_ONE, - 2: serial.STOPBITS_ONE_POINT_FIVE, - 3: serial.STOPBITS_TWO, - } - BYTE_SIZE = { - 5: serial.FIVEBITS, - 6: serial.SIXBITS, - 7: serial.SEVENBITS, - 8: serial.EIGHTBITS, - } - PARITY = { - 0: serial.PARITY_NONE, - 1: serial.PARITY_ODD, - 2: serial.PARITY_EVEN, - } - RTSCTS = {} - - def config_serial_port(self): - port = self.test_env.get_port_by_name("AT1") - kwargs = dict() - if self.baudrate is not None: - kwargs["baudrate"] = self.baudrate - if self.bytesize is not None: - kwargs["bytesize"] = self.BYTE_SIZE[self.bytesize] - if self.parity is not None: - kwargs["parity"] = self.PARITY[self.parity] - if self.stopbits is not None: - kwargs["stopbits"] = self.STOP_BITS[self.stopbits] - if self.xonxoff is not None: - kwargs["xonxoff"] = self.xonxoff - if self.rtscts is not None: - kwargs["rtscts"] = self.rtscts - NativeLog.add_prompt_trace("[change PC UART config] %s" % kwargs) - port.reconfig(**kwargs) - - def send_commands(self): - # first change UART config - self.config_serial_port() - # do send commands - for i in range(1, 256): - cmd = bytes().join([chr(x % 256) for x in range(i)]) - try: - self.serial_write_line("AT1", cmd) - except StandardError, e: - NativeLog.add_exception_log(e) - pass - self.flush_data("AT1") - # restore UART config - self.restore_serial_port("AT1") - - def send_data(self): - # create TCP connection and enter send mode - pc_ip = self.get_parameter("pc_ip") - tcp_port = self.get_parameter("test_tcp_port1") - server_sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) - server_sock.bind((pc_ip, tcp_port)) - server_sock.settimeout(10) - server_sock.listen(5) - self.serial_write_line("AT1", "AT+CIPSTART=\"TCP\",\"%s\",%s" % (pc_ip, tcp_port)) - self.check_response("AT1", "OK") - sock, addr = server_sock.accept() - server_sock.close() - self.serial_write_line("AT1", "AT+CIPSEND=1460") - self.check_response("AT1", ">") - # change UART config - self.config_serial_port() - # send data - try: - self.serial_write("AT1", bytes().join([chr(x % 256) for x in range(146000)])) - except StandardError, e: - NativeLog.add_exception_log(e) - pass - sock.send("A"*1460) - # restore UART config - sock.close() - self.restore_serial_port("AT1") - - def pass_through_mode(self): - # create TCP connection and enter pass through mode - pc_ip = self.get_parameter("pc_ip") - tcp_port = self.get_parameter("test_tcp_port1") - server_sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) - server_sock.bind((pc_ip, tcp_port)) - server_sock.settimeout(10) - server_sock.listen(5) - self.serial_write_line("AT1", "AT+CIPMODE=1") - self.check_response("AT1", "OK") - self.serial_write_line("AT1", "AT+CIPSTART=\"TCP\",\"%s\",%s" % (pc_ip, tcp_port)) - self.check_response("AT1", "OK") - sock, addr = server_sock.accept() - server_sock.close() - self.serial_write_line("AT1", "AT+CIPSEND") - self.check_response("AT1", ">") - # change UART config - self.config_serial_port() - # send data - try: - self.serial_write("AT1", bytes().join([chr(x % 256) for x in range(146000)])) - except StandardError, e: - NativeLog.add_exception_log(e) - pass - sock.send("A" * 1460) - # restore UART config - sock.close() - self.restore_serial_port("AT1") - - def execute(self): - TCActionBase.TCActionBase.execute(self) - # test sending command - try: - if self.test_mode == "command": - self.send_commands() - elif self.test_mode == "send_data": - self.send_data() - elif self.test_mode == "pass_through": - self.pass_through_mode() - else: - raise StandardError("test mode not supported: %s" % self.test_mode) - self.set_result("Succeed") - except StandardError, e: - NativeLog.add_exception_log(e) - self.set_result("Failed") - - -def main(): - pass - - -if __name__ == '__main__': - main() diff --git a/components/test/TestCaseScript/ATFunc/__init__.py b/components/test/TestCaseScript/ATFunc/__init__.py deleted file mode 100755 index 5a3bbc44dd..0000000000 --- a/components/test/TestCaseScript/ATFunc/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -__all__ = ["TCPClientMulti", "TCPClientSingle", "TCPServerMulti", - "TCPTransparent", "UDPMulti", "UDPSingle"] \ No newline at end of file diff --git a/components/test/TestCaseScript/ATStress/ATPassThrough.py b/components/test/TestCaseScript/ATStress/ATPassThrough.py deleted file mode 100755 index 5149ffe3de..0000000000 --- a/components/test/TestCaseScript/ATStress/ATPassThrough.py +++ /dev/null @@ -1,179 +0,0 @@ -import time - -from TCAction import TCActionBase -from NativeLog import NativeLog - - -BEACON_TIMEOUT = 3 -WAIT_FOR_RECONNECT = 20 - - -class ATPassThrough(TCActionBase.CommonTCActionBase): - - def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): - TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - self.do_scan = True - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - - self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) - pass - - def cleanup(self): - TCActionBase.CommonTCActionBase.cleanup(self) - # turn on logging - self.test_env.uart_ports["AT1"].set_uart_logging_flag(True) - - def execute(self): - TCActionBase.TCActionBase.execute(self) - self.result_cntx.start() - - # configurable params - try: - at_send_length = self.at_send_length - soc_send_length = self.soc_send_length - test_count = self.test_count - tx_enable = self.tx_enable - rx_enable = self.rx_enable - att_set = self.att_set - do_scan = self.do_scan - except StandardError, e: - NativeLog.add_trace_critical("Error configuration for TCPClientMulti script, error is %s" % e) - raise StandardError("Error configuration") - # configurable params - - # step0, set att and join ap - fail_string = "Fail, Fail on JAP, set to single link mode" - - checker_stings = ["R PC_COM L OK"] - test_action_string = ["ATT 1"] - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - checker_stings = ["R AT1 C ready"] - test_action_string = ["ATS AT1 AT+RST"] - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - checker_stings = ["R AT1 L OK"] - test_action_string = ["ATS AT1 AT+CWMODE=1"] - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - checker_stings = ["R AT1 L OK"] - test_action_string = ["ATC AT1 CWJAP "] - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - checker_stings = ["R AT1 L OK"] - test_action_string = ["ATS AT1 AT+CIPMUX=0"] - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - # step1, create TCP connection and enter pass through mode - fail_string = "Fail, Fail on create server, create connection or enter pass through mode" - - checker_stings = ["R SOC_COM L OK"] - test_action_string = ["SOC SOC1 LISTEN "] - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - checker_stings = ["R SOC1 C +ACCEPT", "R AT1 NC CLOSE L OK"] - test_action_string = ["ATC AT1 CIPSTART \"TCP\" "] - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - checker_stings = ["R AT1 L OK"] - test_action_strings = ["ATS AT1 AT+CIPMODE=1"] - if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: - return - - checker_stings = ["R AT1 C >"] - test_action_strings = ["ATS AT1 AT+CIPSEND"] - if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: - return - - checker_stings = ["R SOC_COM L OK"] - test_action_strings = ["SOC SOC1 ACCEPT SOC2"] - if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: - return - - # step2 - # while - # set att from, send data on both direction - # if TCP connection disconnected, then set att to 1, wait reconnect succeed, continue test - for i in xrange(test_count): - for _att in att_set: - - # set att - checker_stings = ["R PC_COM L OK"] - test_action_string = ["ATT %d" % _att] - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - time.sleep(BEACON_TIMEOUT) - - # do scan to get ssid - if do_scan is True: - checker_stings = [] - test_action_string = ["ATSO AT1 +++"] - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - checker_stings = ["R AT1 L OK"] - test_action_string = ["ATC AT1 CWLAP "] - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - checker_stings = ["R AT1 C >"] - test_action_strings = ["ATS AT1 AT+CIPSEND"] - if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: - return - - # send data - checker_stings = [] - test_action_string = [] - if tx_enable is True: - checker_stings += ["P SOC2 RL %d" % at_send_length] - test_action_string += ["ATSN AT1 %d" % at_send_length] - if rx_enable is True: - checker_stings += ["P AT1 RL %d" % soc_send_length] - test_action_string += ["SOC SOC2 SEND %d" % soc_send_length] - - if len(test_action_string) > 0: - if self.load_and_exe_one_step(checker_stings, test_action_string, "", - check_freq=1, check_time=30) is False: - # send data fail - NativeLog.add_prompt_trace("Failed to send data @ att %d" % _att) - # set att back to 1 - checker_stings = ["R PC_COM L OK"] - test_action_string = ["ATT 1"] - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - # wait for reconnect - time.sleep(WAIT_FOR_RECONNECT) - fail_string = "Failed, failed to accept socket" - checker_stings = ["SOCR SOC_COM L OK"] - test_action_strings = ["SOC SOC1 ACCEPT SOC2"] - if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: - return - break - pass - - # finally, execute done - self.result_cntx.set_result("Succeed") - - def result_check(self, port_name, data): - TCActionBase.CommonTCActionBase.result_check(self, port_name, data) - self.result_cntx.append_data(port_name, data) - - -def main(): - pass - -if __name__ == '__main__': - main() - diff --git a/components/test/TestCaseScript/ATStress/ATSleep.py b/components/test/TestCaseScript/ATStress/ATSleep.py deleted file mode 100644 index 586862a777..0000000000 --- a/components/test/TestCaseScript/ATStress/ATSleep.py +++ /dev/null @@ -1,251 +0,0 @@ -import random -import os -import time - -from TCAction import TCActionBase, PerformanceTCBase -from NativeLog import NativeLog -from Utility import MakeFolder -from Utility import MultimeterUtil - -LOG_PATH = os.path.join("AT_LOG", "SLEEP") - -SLEEP_MODE_LIST = ["none_sleep", "light_sleep", "modem_sleep"] -SLEEP_MODE = dict(zip(SLEEP_MODE_LIST, range(len(SLEEP_MODE_LIST)))) - -SAMPLE_RATE_SLEEP_MODE_CHANGE = 0.002 -SAMPLE_NUM_SLEEP_MODE_CHANGE = 256 - -SAMPLE_RATE = 0.002 -SAMPLE_NUM = 512 -MAX_VALUE = 1 -Y_AXIS_LABEL = "Current (mA)" -GPIO_EDGE_DELAY = 120 # 20 ms - -NONE_SLEEP_MIN_CUR = 30 -LIGHT_SLEEP_MIN_CUR = 1.5 -MODEM_SLEEP_MIN_CUR = 20 - -GPIO_WAKE_UP = 15 - -AT_WAKE_UP_IND_PIN = 14 -AT_WAKE_UP_PIN = 12 - - -class ATSleep(PerformanceTCBase.PerformanceTCBase): - - def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): - PerformanceTCBase.PerformanceTCBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - self.test_mode = "mode_change" - self.test_count = 100 - self.sleep_mode = SLEEP_MODE_LIST - self.sleep_wake_pin = AT_WAKE_UP_PIN - self.sleep_wakeup_ind_pin = AT_WAKE_UP_IND_PIN - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - self.log_folder = MakeFolder.make_folder(os.path.join(LOG_PATH, - "AT_AUTO_SLEEP_%s_%s" % - (self.test_mode, - time.strftime("%d%H%M%S", time.localtime())))) - self.multimeter = MultimeterUtil.MultimeterUtil(self.log_folder) - - @staticmethod - def find_min_items(item_list, count): - assert count < len(item_list) - min_items = [] - for i in range(count): - min_val = min(item_list) - min_items.append(min_val) - item_list.remove(min_val) - return min_items - - def sleep_mode_change(self, sleep_mode): - result = True - NativeLog.add_prompt_trace("[AutoSleep][ModeChange] %s start" % sleep_mode) - # choose sleep mode - sleep_mode_enum = SLEEP_MODE[sleep_mode] - # change GPIO to make sure target exit sleep mode, so it can process SSC commands - self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) - # set sleep mode - self.serial_write_line("AT1", "AT+SLEEP=%d" % sleep_mode_enum) - self.check_response("AT1", "OK") - self.check_response("SSC2", "+GPIO_SET:OK") - - NativeLog.add_prompt_trace("[AutoSleep][ModeChange] mode set") - time.sleep(10) - # measure current - current_line = self.multimeter.measure_current(sample_rate=SAMPLE_RATE_SLEEP_MODE_CHANGE, - sample_num=SAMPLE_NUM_SLEEP_MODE_CHANGE, - max_value=MAX_VALUE) - # do check measure - min_items = self.find_min_items(current_line, 10) - average_val = float(0) - for val in min_items: - average_val += val - average_val /= 10 - - NativeLog.add_prompt_trace("[AutoSleep][ModeChange] measure done, average min current %f" % average_val) - - if sleep_mode == "none_sleep": - if average_val < NONE_SLEEP_MIN_CUR: - result = False - elif sleep_mode == "light_sleep": - if average_val > LIGHT_SLEEP_MIN_CUR: - result = False - elif sleep_mode == "modem_sleep": - if average_val > MODEM_SLEEP_MIN_CUR or average_val < LIGHT_SLEEP_MIN_CUR: - result = False - if result is False: - NativeLog.add_trace_critical("[AutoSleep][ModeChange] %s failed" % sleep_mode) - self.multimeter.draw_graph(current_line, SAMPLE_RATE, "%s_fail" % sleep_mode, Y_AXIS_LABEL) - - time.sleep(5) - return result - - def sleep_current_measure(self, sleep_mode): - result = True - - NativeLog.add_prompt_trace("[AutoSleep][CurrentMeasure] %s start" % sleep_mode) - # choose sleep mode - sleep_mode_enum = SLEEP_MODE[sleep_mode] - # change GPIO to make sure target exit sleep mode, so it can process SSC commands - self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) - # set sleep mode - self.serial_write_line("AT1", "AT+SLEEP=%d" % sleep_mode_enum) - self.check_response("AT1", "OK") - self.check_response("SSC2", "+GPIO_SET:OK") - - NativeLog.add_prompt_trace("[AutoSleep][CurrentMeasure] set mode done") - time.sleep(10) - # measure current - current_line = self.multimeter.measure_current(sample_rate=SAMPLE_RATE, - sample_num=SAMPLE_NUM, - max_value=MAX_VALUE) - self.multimeter.draw_graph(current_line, SAMPLE_RATE, sleep_mode, Y_AXIS_LABEL) - NativeLog.add_prompt_trace("[AutoSleep][CurrentMeasure] measure done") - return result - - def light_sleep_wakeup(self): - result = True - NativeLog.add_prompt_trace("[AutoSleep][LightSleepWakeup] start") - - self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) - time.sleep(1) - self.serial_write_line("AT1", "") - time.sleep(1) - self.check_response("SSC2", "+GPIO_SET:OK", timeout=1) - - for i in range(10): - self.serial_write_line("SSC2", "gpio -G -p %d" % self.sleep_wakeup_ind_pin) - if self.check_response("SSC2", "+GPIO_GET:0", timeout=0.73) is True: - break - else: - NativeLog.add_prompt_trace("AT Sleep wakeup pin is not correct when in sleep") - - # check if respond to uart - self.flush_data("AT1") - for i in range(60): - self.serial_write("AT1", "a") - time.sleep(0.43) - time.sleep(0.1) - respond_data = self.serial_read_data("AT1") - if len(respond_data) >= 60: - NativeLog.add_trace_critical("[AutoSleep][light sleep wakeup] " - "Failed when recving data during sleep, %d" % len(respond_data)) - result = False - - NativeLog.add_prompt_trace("[AutoSleep][LightSleepWakeup] check on sleep mode done") - - # change GPIO to make target wakeup - self.serial_write_line("SSC2", "gpio -L -p %d -t 0" % GPIO_WAKE_UP) - self.check_response("SSC2", "+GPIO_SET:OK") - time.sleep(0.01) - - for i in range(3): - self.serial_write_line("SSC2", "gpio -G -p %d" % self.sleep_wakeup_ind_pin) - if self.check_response("SSC2", "+GPIO_GET:1") is False: - NativeLog.add_prompt_trace("AT Sleep wakeup pin is not correct when wakeup") - - self.serial_write_line("AT1", "") - time.sleep(1) - self.flush_data("AT1") - for i in range(60): - self.serial_write("AT1", "a") - time.sleep(0.043) - time.sleep(0.1) - respond_data = self.serial_read_data("AT1") - if len(respond_data) < 60: - NativeLog.add_trace_critical("[AutoSleep][light sleep wakeup] " - "Failed when recving data during wakeup, %d" % len(respond_data)) - result = False - - NativeLog.add_prompt_trace("[AutoSleep][LightSleepWakeup] check on wakeup mode done") - self.serial_write_line("AT1", "") - # restore GPIO level - self.serial_write_line("SSC2", "gpio -L -p %d -t 1" % GPIO_WAKE_UP) - time.sleep(2) - return result - - def cleanup(self): - self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) - self.serial_write_line("AT1", "") - self.serial_write_line("AT1", "AT+RST") - self.check_response("SSC2", "+GPIO_SET:OK") - self.check_response("AT1", "ready") - - def execute(self): - TCActionBase.TCActionBase.execute(self) - - try: - test_mode = self.test_mode - test_count = self.test_count - sleep_mode = self.sleep_mode - except StandardError, e: - return - - # make sure enter modem sleep mode before start test - self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) - self.serial_write_line("AT1", "AT+RST") - self.check_response("SSC2", "+GPIO_SET:OK") - self.check_response("AT1", "ready") - self.check_response("AT1", "WIFI GOT IP") - # set AT light sleep wakeup pin - self.serial_write_line("AT1", "AT+WAKEUPGPIO=1,%d,0" % self.sleep_wake_pin) - self.check_response("AT1", "OK") - - # start test - if "mode_change" in test_mode: - for i in range(test_count): - result = self.sleep_mode_change(random.choice(SLEEP_MODE_LIST)) - - elif "measure_current" in test_mode: - for i in range(test_count): - for mode in sleep_mode: - result = self.sleep_current_measure(mode) - pass - elif "gpio_wakeup" in test_mode: - # change GPIO to make sure target exit sleep mode, so it can process SSC commands - self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) - # config wakeup gpio - self.serial_write_line("AT1", "AT+WAKEUPGPIO=1,%d,0,%d,1" % (self.sleep_wake_pin, self.sleep_wakeup_ind_pin)) - self.check_response("AT1", "OK") - # set sleep mode - self.serial_write_line("AT1", "AT+SLEEP=%d" % SLEEP_MODE["light_sleep"]) - self.check_response("AT1", "OK") - self.check_response("SSC2", "+GPIO_SET:OK") - - for i in range(test_count): - result = self.light_sleep_wakeup() - pass - pass - - -def main(): - pass - - -if __name__ == '__main__': - main() diff --git a/components/test/TestCaseScript/ATStress/SoftAPServer.py b/components/test/TestCaseScript/ATStress/SoftAPServer.py deleted file mode 100755 index 7522658f15..0000000000 --- a/components/test/TestCaseScript/ATStress/SoftAPServer.py +++ /dev/null @@ -1,308 +0,0 @@ -from TCAction import PerformanceTCBase -import time -import socket -import threading -import Queue -import re -import random -from NativeLog import NativeLog - - -SEND_CMD = ("CIPSEND, CIPSENDBUF", "CIPSENDEX") - - -class RecvThread(threading.Thread): - def __init__(self, test_action): - threading.Thread.__init__(self) - self.setDaemon(True) - self.test_action = test_action - self.exit_flag = threading.Event() - pass - - def run(self): - data = "" - ipd_line = re.compile("IPD,\d,\d+:") - recv_bytes_line = re.compile("Recv \d+ bytes") - allow_send_line = re.compile("OK\r\n>") - send_ok_line = re.compile("SEND OK") - while self.exit_flag.is_set() is False: - flush_pos = 0 - data += self.test_action.serial_read_data("AT1") - # do process IPD data - match_set = ipd_line.findall(data) - for match_line in match_set: - link_id = match_line[4] - flush_pos = data.find(match_line) + len(match_line) - self.test_action.send_queue.put(link_id, 1) - pass - # do process send > - match = allow_send_line.search(data) - if match is not None: - match_line = match.group() - self.test_action.add_info_log("find OK >") - self.test_action.send_allow_evt.set() - pos = data.find(match_line) + len(match_line) - flush_pos = pos if pos > flush_pos else flush_pos - # do process Recv xx bytes - match = recv_bytes_line.search(data) - if match is not None: - match_line = match.group() - self.test_action.add_info_log("find Recv xx bytes") - self.test_action.recv_data_evt.set() - pos = data.find(match_line) + len(match_line) - flush_pos = pos if pos > flush_pos else flush_pos - - match = send_ok_line.search(data) - if match is not None: - match_line = match.group() - self.test_action.add_info_log("find send ok") - self.test_action.send_ok_evt.set() - pos = data.find(match_line) + len(match_line) - flush_pos = pos if pos > flush_pos else flush_pos - # pass - - # flush processed data - if flush_pos > 0: - data = data[flush_pos:] - - pass - - def exit(self): - self.exit_flag.set() - pass - - -class TCPClientThread(threading.Thread): - send_char = "A" - sync_lock = threading.Lock() - - def __init__(self, test_action, pc_ip, target_ip, target_port, request_len, response_len, client_id, - connect_timeout, recv_timeout): - threading.Thread.__init__(self) - self.setDaemon(True) - self.exit_flag = threading.Event() - self.test_action = test_action - self.pc_ip = pc_ip - self.target_ip = target_ip - self.target_port = target_port - self.request_len = request_len - self.response_len = response_len - self.client_id = client_id - self.connect_timeout = connect_timeout - self.recv_timeout = recv_timeout - pass - - @classmethod - def get_send_char(cls): - with cls.sync_lock: - send_char = cls.send_char - cls.send_char = chr(ord(send_char) + 1) if ord(send_char) < ord("Z") else "A" - return send_char - pass - - def run(self): - while self.exit_flag.is_set() is False: - exception_occurred = False - client_sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) - client_sock.bind((self.pc_ip, 0)) - client_sock.settimeout(20) - time1 = time.time() - name = client_sock.getsockname() - - try: - client_sock.connect((self.target_ip, self.target_port)) - except StandardError, e: - exception_occurred = True - self.test_action.add_critical_log("failed to connect succeed within 2 seconds %s, %d" - % (name[0], name[1])) - client_sock.close() - - time2 = time.time() - time1 - if exception_occurred is True: - self.test_action.add_critical_log("connect timeout %f; ip is %s, port is %d" - % (time2, name[0], name[1])) - continue - if time2 > self.connect_timeout: - self.test_action.add_critical_log("connect time too long %f; ip is %s, port is %d" - % (time2, name[0], name[1])) - - time.sleep(float(random.randint(0, 30))/100) - send_char = self.get_send_char() - data = send_char * self.request_len - try: - client_sock.send(data) - except StandardError: - NativeLog.add_trace_critical("send fail") - # try: - # data = client_sock.recv(1) - # except socket.error, e: - # self.handle_processing_fail("failed to receive data within 2 seconds") - data_received = 0 - time1 = time.time() - while data_received < self.response_len: - try: - data = client_sock.recv(4*1024) - except StandardError, e: - exception_occurred = True - break - data_received += len(data) - - time2 = time.time() - time1 - if exception_occurred is True or time2 > self.recv_timeout: - self.test_action.add_critical_log("receive time too long %f; ip is %s, port is %d"\ - % (time2, name[0], name[1])) - client_sock.close() - time.sleep(float(random.randint(0, 30))/100) - pass - pass - - def exit(self): - self.exit_flag.set() - pass - - -class SendThread(threading.Thread): - def __init__(self, test_action, test_count, send_cmd, response_len, check_send_ok): - threading.Thread.__init__(self) - self.setDaemon(True) - self.test_action = test_action - self.test_count = test_count - self.send_cmd = send_cmd - self.response_len = response_len - self.check_send_ok = check_send_ok - pass - - def run(self): - send_char = "a" - for i in xrange(self.test_count): - link_id = self.test_action.send_queue.get(1) - - self.test_action.send_allow_evt.clear() - self.test_action.serial_write_line("AT1", "AT+%s=%s,%d" % (self.send_cmd, link_id, self.response_len)) - self.test_action.add_info_log("write CIPSEND cmd") - - self.test_action.send_allow_evt.wait(10) - if self.test_action.send_allow_evt.is_set() is False: - self.test_action.add_critical_log("Failed to find OK > in 10s, test break") - break - self.test_action.send_allow_evt.clear() - - data = send_char * self.response_len - send_char = chr(ord(send_char) + 1) if ord(send_char) < ord("z") else "a" - self.test_action.recv_data_evt.clear() - self.test_action.send_ok_evt.clear() - self.test_action.serial_write("AT1", data) - self.test_action.add_info_log("data write done") - self.test_action.recv_data_evt.wait(10) - if self.test_action.recv_data_evt.is_set() is False: - self.test_action.add_critical_log("Failed to find Recv xx bytes in 10s, test break") - break - self.test_action.recv_data_evt.clear() - # if self.test_action.send_cmd == "CIPSEND": - if self.check_send_ok is True: - self.test_action.send_ok_evt.wait(10) - if self.test_action.send_ok_evt.is_set() is False: - self.test_action.add_critical_log("Failed to find SEND OK in 10s, test break") - break - self.test_action.add_info_log("send ok") - self.test_action.send_ok_evt.clear() - pass - pass - - -class SoftAPServer(PerformanceTCBase.PerformanceTCBase): - def __init__(self, name, test_env, cmd_set, timeout=120, log_path=None): - PerformanceTCBase.PerformanceTCBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - # init value for ip and port - self.pc_ip = "pc_ip" - self.server_port = "test_tcp_port1" - self.send_cmd = "CIPSEND" - self.baudrate = 115200 - self.rtscts = 3 - self.test_count = 1000 - self.request_len = 500 - self.response_len = 1600 - self.check_send_ok = True - self.concurrent_connections = 5 - self.connect_timeout = 3 - self.receive_timeout = 2 - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - self.send_queue = Queue.Queue(maxsize=100) - self.send_allow_evt = threading.Event() - self.recv_data_evt = threading.Event() - self.send_ok_evt = threading.Event() - - pass - - @staticmethod - def add_critical_log(data): - NativeLog.add_trace_critical(data+"\r\n") - pass - - @staticmethod - def add_info_log(data): - NativeLog.add_trace_info(data) - - def process(self): - # step0, use initial condition AP3 (8266 as AP, PC connected to 8266, multiple connection) - pc_ip = self.get_parameter(self.pc_ip) - target_ip = self.get_parameter("target_ip") - server_port = self.get_parameter(self.server_port) - send_cmd = self.send_cmd - test_count = self.test_count - baudrate = self.baudrate - rtscts = self.rtscts - concurrent_connections = self.concurrent_connections - check_send_ok = self.check_send_ok - connect_timeout = self.connect_timeout - receive_timeout = self.receive_timeout - - self.serial_write_line("AT1", "AT+UART_CUR=%d,8,1,0,%d" % (baudrate, rtscts)) - self.check_response("AT1", "OK\r\n") - self.reconfig_serial_port("AT1", baudrate, rtscts) - # step1, create server on 8266, create client thread - self.serial_write_line("AT1", "AT+CIPSERVER=1,%d" % server_port) - self.check_response("AT1", "OK") - - recv_thread = RecvThread(self) - send_thread = SendThread(self, test_count, send_cmd, self.response_len, check_send_ok) - send_thread.start() - recv_thread.start() - client_thread_list = [None] * concurrent_connections - for i in range(concurrent_connections): - client_thread_list[i] = TCPClientThread(self, pc_ip, target_ip, server_port, - self.request_len, self.response_len, i, - connect_timeout, receive_timeout) - client_thread_list[i].start() - pass - - # step3, wait sending thread join - send_thread.join() - - recv_thread.exit() - recv_thread.join() - - for i in range(concurrent_connections): - client_thread_list[i].exit() - client_thread_list[i].join() - pass - - self.serial_write_line("AT1", "AT+UART_CUR=115200,8,1,0,3") - self.check_response("AT1", "OK\r\n") - self.restore_serial_port("AT1") - self.set_result("Succeed") - pass - pass - - -def main(): - pass - - -if __name__ == '__main__': - main() diff --git a/components/test/TestCaseScript/ATStress/TCPClientMulti.py b/components/test/TestCaseScript/ATStress/TCPClientMulti.py deleted file mode 100755 index 610a55cbc4..0000000000 --- a/components/test/TestCaseScript/ATStress/TCPClientMulti.py +++ /dev/null @@ -1,116 +0,0 @@ -from TCAction import TCActionBase -from NativeLog import NativeLog - - -class TCPClientMulti(TCActionBase.CommonTCActionBase): - - def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): - TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - - self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) - self.max_conn = test_env.get_variable_by_name("max_conn")[1] - pass - - def cleanup(self): - TCActionBase.CommonTCActionBase.cleanup(self) - # turn on logging - self.test_env.uart_ports["AT1"].set_uart_logging_flag(True) - - def execute(self): - TCActionBase.TCActionBase.execute(self) - self.result_cntx.start() - - # configurable params - try: - at_send_length = self.at_send_length - soc_send_length = self.soc_send_length - test_count = self.test_count - tx_enable = self.tx_enable - rx_enable = self.rx_enable - enable_log = self.enable_log - except StandardError, e: - NativeLog.add_trace_critical("Error configuration for TCPClientMulti script, error is %s" % e) - raise StandardError("Error configuration") - # configurable params - - # step1 - checker_stings = ["R SOC_COM L OK"] - test_action_string = ["SOC SOC1 LISTEN "] - fail_string = "Fail, Fail on create PC server" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - # step2 - for i in range(0, self.max_conn): - checker_stings = ["R SOC1 C +ACCEPT", "R AT1 NC CLOSE L OK"] - test_action_strings = ["ATC AT1 CIPSTART %d \"TCP\" " % i] - fail_string = "Fail, Fail on connect to PC server" - if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: - return - - checker_stings = ["R SOC_COM L OK"] - test_action_strings = ["SOC SOC1 ACCEPT SOC%d" % (i+2)] - if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: - return - - # step 3 - # turn off AT UART logging - if enable_log is False: - self.test_env.uart_ports["AT1"].set_uart_logging_flag(False) - - data = "A" * at_send_length - fail_string = "Fail, Fail on send and recv data" - - for j in range(0, test_count): - - if tx_enable is True: - for i in range(0, self.max_conn): - checker_stings = ["P AT1 C >"] - test_action_strings = ["ATS AT1 AT+CIPSEND=%d,%d" % (i, at_send_length)] - if self.load_and_exe_one_step(checker_stings, test_action_strings, - fail_string, check_time=50) is False: - NativeLog.add_trace_critical("Fail on target send command for link %d" % i) - NativeLog.add_trace_critical("Test count is %d" % j) - return - - checker_stings = ["P SOC%d RL %d" % ((i+2), at_send_length), "P AT1 C OK"] - test_action_strings = ["ATSO AT1 %s" % data] - if self.load_and_exe_one_step(checker_stings, test_action_strings, - fail_string, check_time=50) is False: - NativeLog.add_trace_critical("Fail on target send for link %d, send or recv error" % i) - NativeLog.add_trace_critical("Test count is %d" % j) - return - - if rx_enable is True: - checker_stings = [] - test_action_strings = [] - for i in range(0, self.max_conn): - checker_stings.extend(["P AT1 DL %d+%d" % (i, soc_send_length)]) - test_action_strings.extend(["SOC SOC%d SEND %d %s" % (i+2, soc_send_length, data)]) - - if self.load_and_exe_one_step(checker_stings, test_action_strings, - fail_string, check_time=50) is False: - NativeLog.add_trace_critical("Fail to receive PC sent data") - NativeLog.add_trace_critical("Test count is %d" % j) - return - - # finally, execute done - self.result_cntx.set_result("Succeed") - - def result_check(self, port_name, data): - TCActionBase.CommonTCActionBase.result_check(self, port_name, data) - self.result_cntx.append_data(port_name, data) - - -def main(): - pass - -if __name__ == '__main__': - main() - diff --git a/components/test/TestCaseScript/ATStress/TCPClientSingle.py b/components/test/TestCaseScript/ATStress/TCPClientSingle.py deleted file mode 100755 index 7127c3d0f1..0000000000 --- a/components/test/TestCaseScript/ATStress/TCPClientSingle.py +++ /dev/null @@ -1,123 +0,0 @@ -from TCAction import TCActionBase -from NativeLog import NativeLog - - -class TCPClientSingle(TCActionBase.CommonTCActionBase): - - def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): - TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - self.link_type = "TCP" - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - - self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) - pass - - def cleanup(self): - TCActionBase.CommonTCActionBase.cleanup(self) - # turn on logging - self.test_env.uart_ports["AT1"].set_uart_logging_flag(True) - - def execute(self): - TCActionBase.TCActionBase.execute(self) - self.result_cntx.start() - - # configurable params - try: - at_send_length = self.at_send_length - soc_send_length = self.soc_send_length - test_count = self.test_count - tx_enable = self.tx_enable - rx_enable = self.rx_enable - enable_log = self.enable_log - link_type = self.link_type - except StandardError, e: - NativeLog.add_trace_critical("Error configuration for TCPClientSingle script, error is %s" % e) - raise StandardError("Error configuration") - # configurable params - - # step1 - checker_stings = ["R SOC_COM L OK"] - if link_type == "TCP": - test_action_string = ["SOC SOC1 LISTEN "] - elif link_type == "SSL": - test_action_string = ["SOC SOC1 SLISTEN "] - pass - else: - raise StandardError() - fail_string = "Fail, Fail on create PC server" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - # step2 - if link_type == "TCP": - checker_stings = ["R SOC1 C +ACCEPT", "R AT1 NC CLOSE L OK"] - test_action_strings = ["ATC AT1 CIPSTART \"TCP\" "] - elif link_type == "SSL": - checker_stings = ["R SOC1 C +SACCEPT", "R AT1 NC CLOSE L OK"] - test_action_strings = ["ATC AT1 CIPSTART \"SSL\" "] - else: - raise StandardError() - fail_string = "Fail, Fail on connect to PC server" - if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: - return - - checker_stings = ["R SOC_COM L OK"] - test_action_strings = ["SOC SOC1 ACCEPT SOC2"] - if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: - return - - # step 3 - # turn off AT UART logging - if enable_log is False: - self.test_env.uart_ports["AT1"].set_uart_logging_flag(False) - - for j in range(0, test_count): - data = "A" * at_send_length - fail_string = "Fail, Fail on send and recv data" - - if tx_enable is True: - checker_stings = ["P AT1 C >"] - test_action_strings = ["ATS AT1 AT+CIPSEND=%d" % at_send_length] - if self.load_and_exe_one_step(checker_stings, test_action_strings, - fail_string, check_time=20) is False: - NativeLog.add_trace_critical("Fail on target send command") - NativeLog.add_trace_critical("Test count is %d" % j) - return - - checker_stings = ["P SOC2 RL %d" % at_send_length, "P AT1 C OK"] - test_action_strings = ["ATSO AT1 %s" % data] - if self.load_and_exe_one_step(checker_stings, test_action_strings, - fail_string, check_time=20) is False: - NativeLog.add_trace_critical("Fail on target send, send or recv error") - NativeLog.add_trace_critical("Test count is %d" % j) - return - - if rx_enable is True: - checker_stings = ["P AT1 DL S+%d" % soc_send_length] - test_action_strings = ["SOC SOC2 SEND %d" % soc_send_length] - - if self.load_and_exe_one_step(checker_stings, test_action_strings, - fail_string, check_time=20) is False: - NativeLog.add_trace_critical("Fail to receive PC sent data") - NativeLog.add_trace_critical("Test count is %d" % j) - return - - # finally, execute done - self.result_cntx.set_result("Succeed") - - def result_check(self, port_name, data): - TCActionBase.CommonTCActionBase.result_check(self, port_name, data) - self.result_cntx.append_data(port_name, data) - - -def main(): - pass - -if __name__ == '__main__': - main() - diff --git a/components/test/TestCaseScript/ATStress/TCPSendPerf.py b/components/test/TestCaseScript/ATStress/TCPSendPerf.py deleted file mode 100755 index a2f6e1a060..0000000000 --- a/components/test/TestCaseScript/ATStress/TCPSendPerf.py +++ /dev/null @@ -1,148 +0,0 @@ -import time -import os -import socket -import ssl - -from NativeLog import NativeLog -from TCAction import PerformanceTCBase -from Utility import MakeFolder - - -SEND_CMD = ("CIPSEND, CIPSENDBUF", "CIPSENDEX") - -LOG_PATH = os.path.join("AT_LOG", "Performance", "AT_SEND") - - -class TCPSendPerf(PerformanceTCBase.PerformanceTCBase): - def __init__(self, name, test_env, cmd_set, timeout=120, log_path=None): - PerformanceTCBase.PerformanceTCBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - # init value for ip and port - self.pc_ip = "pc_ip" - self.server_port = "test_tcp_port1" - self.packet_len = 1 - self.test_count = 100 - self.send_cmd = "CIPSEND" - self.baudrate = 115200 - self.rtscts = 0 - self.link_type = "TCP" - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - pass - - def process(self): - pc_ip = self.get_parameter(self.pc_ip) - server_port = self.get_parameter(self.server_port) - packet_len = self.packet_len - test_count = self.test_count - send_cmd = self.send_cmd - baudrate = self.baudrate - rtscts = self.rtscts - result = True - link_type = self.link_type - - # create TCP connection - sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) - sock.bind((pc_ip, server_port)) - sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - sock.settimeout(10) - sock.listen(1) - - self.serial_write_line("AT1", "AT+CIPSTART=0,\"%s\",\"%s\",%d" % (link_type, pc_ip, server_port)) - sock_client = sock.accept()[0] - if link_type == "SSL": - sock_client = ssl.wrap_socket(sock_client, - server_side=True, - certfile=os.path.join("Certificate", "default.cer"), - keyfile=os.path.join("Certificate", "default.key")) - pass - if self.check_response("AT1", "OK") is False: - result = False - - self.serial_write_line("AT1", "AT+UART_CUR=%d,8,1,0,%d" % (baudrate, rtscts)) - if self.check_response("AT1", "OK\r\n") is False: - result = False - - self.reconfig_serial_port("AT1", baudrate, rtscts) - - # restore to read line mode - self.test_env.uart_ports["AT1"].set_performance_flag(flag=True) - - sock_client.settimeout(0) - - for _dummy in range(1): - if result is False: - NativeLog.add_trace_critical("Fail to create TCP connection") - break - # send TCP packets - data = "A" * packet_len - time1 = time.time() - - i = 0 - data_recv_len = 0 - while i < test_count: - self.serial_write_line("AT1", "AT+%s=0,%d" % (send_cmd, packet_len)) - if self.check_response("AT1", ">", 0.05) is False: - continue - - i += 1 - self.serial_write("AT1", data) - if send_cmd == "CIPSENDBUF": - result = self.check_response("AT1", "Recv %d bytes" % packet_len, 3) - else: - result = self.check_response("AT1", "SEND OK", 3) - if result is False: - NativeLog.add_trace_critical("Fail during sending data") - break - try: - if link_type == "TCP": - data_recv = sock_client.recv(10*1460) - elif link_type == "SSL": - data_recv = sock_client.read(10*1024) - else: - raise StandardError() - data_recv_len += len(data_recv) - except socket.error, e: - if e.errno == 10035: - pass - elif e.message == "The read operation timed out": - pass - else: - NativeLog.add_exception_log(e) - else: - self.set_result("Succeed") - - time2 = time.time() - - folder_path = MakeFolder.make_folder(LOG_PATH) - file_name = os.path.join(folder_path, - "%s_%s_%s.log" % (send_cmd, - packet_len, - time.strftime("%d%H%M%S", time.localtime()))) - with open(file_name, "ab+") as f: - f.write("\r\n[performance] %f packets per second " - "(including failed send operation)" - % (test_count/(time2-time1))) - f.write("\r\n[performance] %f Kbps" % (data_recv_len/(125*(time2-time1)))) - - self.serial_write_line("AT1", "AT+UART_CUR=115200,8,1,0,3") - self.check_response("AT1", "OK\r\n") - self.restore_serial_port("AT1") - - # restore to read line mode - self.test_env.uart_ports["AT1"].set_performance_flag(flag=False) - # close socket - sock.close() - sock_client.close() - pass - - -def main(): - pass - - -if __name__ == '__main__': - main() diff --git a/components/test/TestCaseScript/ATStress/TCPServerMulti.py b/components/test/TestCaseScript/ATStress/TCPServerMulti.py deleted file mode 100755 index c317bc9749..0000000000 --- a/components/test/TestCaseScript/ATStress/TCPServerMulti.py +++ /dev/null @@ -1,126 +0,0 @@ -from TCAction import TCActionBase -from NativeLog import NativeLog - - -class TCPServerMulti(TCActionBase.CommonTCActionBase): - - def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): - TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - - self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) - self.max_conn = test_env.get_variable_by_name("max_conn")[1] - pass - - def cleanup(self): - TCActionBase.CommonTCActionBase.cleanup(self) - self.test_env.uart_ports["AT1"].set_uart_logging_flag(True) - - def execute(self): - TCActionBase.TCActionBase.execute(self) - self.result_cntx.start() - - # configurable params - try: - at_send_length = self.at_send_length - soc_send_length = self.soc_send_length - test_count = self.test_count - target_ip_str = self.target_ip_str - enable_log = self.enable_log - except StandardError, e: - NativeLog.add_trace_critical("Error configuration for TCPSeverMulti script, error is %s" % e) - raise StandardError("Error configuration") - # configurable params - - # turn off AT UART logging - if enable_log is False: - self.test_env.uart_ports["AT1"].set_uart_logging_flag(False) - - # step1 create TCP server on target - checker_stings = ["R AT1 L OK"] - test_action_string = ["ATC AT1 CIPSERVER 1 "] - fail_string = "Fail, Fail on create target TCP server" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - # step2 PC connect to target server - for j in range(0, test_count): - data = "A" * at_send_length - fail_string = "Fail, Fail on connect to target server" - - # check if all connection can send data on target - checker_stings = ["P AT1 C OK"] - test_action_strings = ["ATS AT1 AT+CIPCLOSE=%d" % self.max_conn] - if self.load_and_exe_one_step(checker_stings, test_action_strings, - fail_string, check_time=100) is False: - NativeLog.add_trace_critical("Fail to close all connection") - NativeLog.add_trace_critical("Test count is %d" % j) - continue # if fail on this step, we can recover and continue - - # a) do connect - fail_flag = False - for i in range(0, self.max_conn): - checker_stings = ["P SOC_COM C OK", "P AT1 C CONNECT"] - test_action_strings = ["SOC SOC%d CONNECT %s" % (i+1, target_ip_str)] - if self.load_and_exe_one_step(checker_stings, test_action_strings, - fail_string, check_time=50) is False: - NativeLog.add_trace_critical("Fail to connect to target for link %d" % i) - NativeLog.add_trace_critical("Test count is %d" % j) - # if fail on this step, we can recover and continue - fail_flag = True - break - - if fail_flag is True: - # fail on step a) - continue - - # b) check if all connection can recv data on target - checker_stings = [] - test_action_strings = [] - for i in range(0, self.max_conn): - checker_stings.extend(["P AT1 DL %d+%d" % (i, soc_send_length)]) - test_action_strings.extend(["SOC SOC%d SEND %d" % (i+1, soc_send_length)]) - - if self.load_and_exe_one_step(checker_stings, test_action_strings, - fail_string, check_time=50) is False: - NativeLog.add_trace_critical("Fail to receive data from PC") - NativeLog.add_trace_critical("Test count is %d" % j) - continue # if fail on this step, we can recover and continue - - # c) check if all connection can send data on target - for i in range(0, self.max_conn): - checker_stings = ["P AT1 C >"] - test_action_strings = ["ATS AT1 AT+CIPSEND=%d,%d" % (i, at_send_length)] - if self.load_and_exe_one_step(checker_stings, test_action_strings, - fail_string, check_time=50) is False: - NativeLog.add_trace_critical("Fail on target send command for link %d" % i) - NativeLog.add_trace_critical("Test count is %d" % j) - return - - checker_stings = ["P SOC%d RL %d" % ((i+1), at_send_length), "P AT1 C OK"] - test_action_strings = ["ATSO AT1 %s" % data] - if self.load_and_exe_one_step(checker_stings, test_action_strings, - fail_string, check_time=50) is False: - NativeLog.add_trace_critical("Fail on target send for link %d, send or recv error" % i) - NativeLog.add_trace_critical("Test count is %d" % j) - return - - # finally, execute done - self.result_cntx.set_result("Succeed") - - def result_check(self, port_name, data): - TCActionBase.CommonTCActionBase.result_check(self, port_name, data) - self.result_cntx.append_data(port_name, data) - - -def main(): - pass - -if __name__ == '__main__': - main() - diff --git a/components/test/TestCaseScript/ATStress/TCPTransparent.py b/components/test/TestCaseScript/ATStress/TCPTransparent.py deleted file mode 100755 index d116923bf5..0000000000 --- a/components/test/TestCaseScript/ATStress/TCPTransparent.py +++ /dev/null @@ -1,280 +0,0 @@ -from TCAction import TCActionBase -from TCAction import CmdHandler -from NativeLog import NativeLog -import time -import random -import string -import os - - -class TransparentResultCheckCntx(TCActionBase.ResultCheckContext): - - def __init__(self, test_action, test_env, name): - TCActionBase.ResultCheckContext.__init__(self, test_action, test_env, name) - self.result_array = [] - self.at_data_recv_total = 0 - self.pc_data_recv_total = 0 - self.temp_data_at2wifi = "" - self.temp_data_wifi2at = "" - pass - - def run(self): - validation_required = self.test_action.data_validation - path = os.path.split(self.test_action.log_file_name) - file_name_at2wifi = os.path.join(path[0], "%s_at2wifi_pc.bin" % self.test_action.timestamp) - file_name_wifi2at = os.path.join(path[0], "%s_wifi2at_at.bin" % self.test_action.timestamp) - - while True: - exit_flag = self.wait_exit_event(2) - # force exit - if exit_flag is True: - break - rx_len = 0 - tx_len = 0 - try: - self.lock_data() - rx_port = filter(lambda x: x[0] == "AT1", self.data_cache) - tx_port = filter(lambda x: x[0] == "SOC2", self.data_cache) - self.data_cache = [] - finally: - self.unlock_data() - - if len(rx_port) == 1: - rx_len = len(rx_port[0][1]) - self.at_data_recv_total += rx_len - if validation_required is True: - self.temp_data_wifi2at += rx_port[0][1] - if len(tx_port) == 1: - tx_len = len(tx_port[0][1]) - self.pc_data_recv_total += tx_len - if validation_required is True: - self.temp_data_at2wifi += tx_port[0][1] - - self.result_array.append(["TX %8d %s" % - (tx_len/2, time.strftime("%m-%d %H:%M:%S", time.localtime()))]) - self.result_array.append(["RX %8d %s" % - (rx_len/2, time.strftime("%m-%d %H:%M:%S", time.localtime()))]) - - if validation_required is True: - with open(file_name_at2wifi, "ab+") as f: - f.write(self.temp_data_at2wifi) - with open(file_name_wifi2at, "ab+") as f: - f.write(self.temp_data_wifi2at) - - def get_validation_data(self): - return self.temp_data_at2wifi, self.temp_data_wifi2at - - def get_test_results(self): - return self.result_array, self.at_data_recv_total, self.pc_data_recv_total - - -class TCPTransparent(TCActionBase.CommonTCActionBase): - - def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): - TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) - self.timestamp = time.strftime("%d%H%M%S", time.localtime()) - - pass - - def cleanup(self): - # close current result check context - self.result_cntx.stop_thread() - self.result_cntx.join() - # turn on logging - self.test_env.uart_ports["AT1"].set_uart_logging_flag(True) - # restore to read line mode - self.test_env.uart_ports["AT1"].set_performance_flag(flag=False) - - # make sure enter condition that can respond to AT command - self.result_cntx = TCActionBase.ResultCheckContext(self, self.test_env, self.tc_name) - TCActionBase.TCActionBase.execute(self) - self.result_cntx.start() - - checker_stings = ["ATR AT1 R *"] - test_action_string = ["ATSO AT1 +++", "DELAY 0.1", "ATS AT1 AT"] - fail_string = "Fail, Fail to reconfig UART" - - result = False - - while result is False: - result = self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) - - # reset baudrate - - checker_stings = ["ATR AT1 L OK"] - test_action_string = ["ATS AT1 AT+UART_CUR=%d,8,1,0,3" % 115200] - fail_string = "Fail, Fail to reconfig UART" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - test_action = CmdHandler.parse_action("UART AT1 %d" % 115200, self.test_env) - CmdHandler.do_actions(test_action, self.test_env) - TCActionBase.CommonTCActionBase.cleanup(self) - - def execute(self): - TCActionBase.TCActionBase.execute(self) - self.result_cntx.start() - - try: - # configurable params - # at send data len - at_send_data_len = self.at_send_data_len - # pc send data len - pc_send_data_len = self.pc_send_data_len - # sleep time between each send, test count - test_dispatch = self.test_dispatch - # enable target TCP TX - tx_enable = self.tx_enable - # enable target TCP RX - rx_enable = self.rx_enable - # if need to record tx/rx data to file - data_validation = self.data_validation - # UART baudrate - baudrate = self.baudrate - # HW flow control - rtscts = self.rtscts - # configurable params - except StandardError, e: - NativeLog.add_trace_critical("Error configuration for TCPTransparent script, error is %s" % e) - raise StandardError("Error configuration") - - # step0 reconfig baudrate - if baudrate != 0: - checker_stings = ["R AT1 L OK"] - test_action_string = ["ATS AT1 AT+UART_CUR=%d,8,1,0,%d" % (baudrate, rtscts)] - fail_string = "Fail, Fail to reconfig UART" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - test_action = CmdHandler.parse_action("UART AT1 %d %d" % (baudrate, rtscts), self.test_env) - CmdHandler.do_actions(test_action, self.test_env) - - # step1 create PC server - checker_stings = ["R SOC_COM L OK"] - test_action_string = ["SOC SOC1 LISTEN "] - fail_string = "Fail, Fail on create PC server" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - # step2 target connect, switch to transparent - checker_stings = ["R SOC1 C +ACCEPT", "R AT1 NC CLOSE L OK"] - test_action_strings = ["ATC AT1 CIPSTART \"TCP\" "] - fail_string = "Fail, Fail on connect to PC server" - if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: - return - - checker_stings = ["R SOC_COM L OK"] - test_action_strings = ["SOC SOC1 ACCEPT SOC2"] - if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: - return - - checker_stings = ["R AT1 L OK"] - test_action_strings = ["ATS AT1 AT+CIPMODE=1"] - if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: - return - - checker_stings = ["R AT1 C >"] - test_action_strings = ["ATS AT1 AT+CIPSEND"] - if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: - return - - # step 3 - # turn off AT UART logging - self.test_env.uart_ports["AT1"].set_uart_logging_flag(False) - # uart try to return data ASAP - self.test_env.uart_ports["AT1"].set_performance_flag(flag=True) - - # switch to new result check context - self.result_cntx.stop_thread() - self.result_cntx.join() - self.result_cntx = TransparentResultCheckCntx(self, self.test_env, self.tc_name) - self.result_cntx.start() - - at_data_sent_total = 0 - pc_data_sent_total = 0 - at2wifi_data = "" - wifi2at_data = "" - - for j in range(0, len(at_send_data_len) * len(pc_send_data_len)): - at_data_len = at_send_data_len[j / len(pc_send_data_len)] - pc_data_len = pc_send_data_len[j % len(pc_send_data_len)] - # data = "".join(["A"] * at_data_len) - chars = string.ascii_lowercase - data_list = ["".join([random.choice(chars) for m in range(at_data_len-16)])] - chars = string.ascii_uppercase - data_list.append("".join([random.choice(chars) for m in range(at_data_len-16)])) - chars = string.digits - data_list.append("".join([random.choice(chars) for m in range(at_data_len-16)])) - - for i in range(0, len(test_dispatch)): - for k in range(0, test_dispatch[i][1]): - data_str = "%.2d%.2d%.10d%s\r\n" % (j, i, k, data_list[k % 3]) - # time1 = time.time() - if tx_enable is True: - test_action = CmdHandler.parse_action("ATSO AT1 %s" % data_str, self.test_env) - CmdHandler.do_actions(test_action, self.test_env) - at_data_sent_total += at_data_len - if data_validation is True: - at2wifi_data += data_str - # time2 = time.time() - if rx_enable is True: - if tx_enable is True: - test_action = CmdHandler.parse_action("SOC SOC2 SENDNB %d %s" % (pc_data_len, data_str), - self.test_env) - else: - test_action = CmdHandler.parse_action("SOC SOC2 SEND %d %s" % (pc_data_len, data_str), - self.test_env) - sent_len = CmdHandler.do_action(test_action[0], self.test_env) - pc_data_sent_total += sent_len - if data_validation is True: - wifi2at_data += data_str[:sent_len] - # time3 = time.time() - # if time3-time2 > 0.1: - # break - if test_dispatch[i][0] != 0: - time.sleep(test_dispatch[i][0]) - time.sleep(3) # wait 3 seconds - - # write send data to file for data validation - if data_validation is True: - path = os.path.split(self.log_file_name) - with open(os.path.join(path[0], "%s_at2wifi_at.bin" % self.timestamp), "ab+") as f: - f.write(at2wifi_data) - with open(os.path.join(path[0], "%s_wifi2at_pc.bin" % self.timestamp), "ab+") as f: - f.write(wifi2at_data) - - temp_data_at2wifi, temp_data_wifi2at = self.result_cntx.get_validation_data() - if temp_data_at2wifi != at2wifi_data: - NativeLog.add_prompt_trace("[Validation Fail] at2wifi") - if temp_data_wifi2at != wifi2at_data: - NativeLog.add_prompt_trace("[Validation Fail] wifi2at") - - throughput_results, at_data_recv_total, pc_data_recv_total = self.result_cntx.get_test_results() - result_str = "AT sent %15d\r\n" % at_data_sent_total - result_str += "PC recv %15d\r\n" % pc_data_recv_total - result_str += "PC sent %15d\r\n" % pc_data_sent_total - result_str += "AT recv %15d\r\n" % at_data_recv_total - for _result in throughput_results: - result_str += "%s\r\n" % _result - with open(self.log_file_name, "ab+") as f: - f.write(result_str) - - # finally, execute done - self.result_cntx.set_result("Succeed") - - def result_check(self, port_name, data): - self.result_cntx.append_data(port_name, data) - - -def main(): - pass - -if __name__ == '__main__': - main() - diff --git a/components/test/TestCaseScript/ATStress/UDPMulti.py b/components/test/TestCaseScript/ATStress/UDPMulti.py deleted file mode 100755 index 4423db3ce3..0000000000 --- a/components/test/TestCaseScript/ATStress/UDPMulti.py +++ /dev/null @@ -1,113 +0,0 @@ -from TCAction import TCActionBase -from NativeLog import NativeLog -import time - - -class UDPMulti(TCActionBase.CommonTCActionBase): - - def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): - TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - - self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) - self.max_conn = test_env.get_variable_by_name("max_conn")[1] - pass - - def cleanup(self): - TCActionBase.CommonTCActionBase.cleanup(self) - # turn on logging - self.test_env.uart_ports["AT1"].set_uart_logging_flag(True) - - def execute(self): - TCActionBase.TCActionBase.execute(self) - self.result_cntx.start() - - # configurable params - try: - at_send_length = self.at_send_length - soc_send_length = self.soc_send_length - test_count = self.test_count - target_ip_str = self.target_ip_str - tx_enable = self.tx_enable - rx_enable = self.rx_enable - enable_log = self.enable_log - except StandardError, e: - NativeLog.add_trace_critical("Error configuration for UDPMulti script, error is %s" % e) - raise StandardError("Error configuration") - # configurable params - - # step1, bind one PC UDP port - checker_stings = ["R SOC_COM L OK"] - test_action_string = ["SOC SOC1 BIND "] - fail_string = "Fail, Fail on binding socket" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - # step 2 create 5 UDP link on target - for i in range(0, self.max_conn): - checker_stings = ["R AT1 C CONNECT L OK"] - test_action_strings = ["ATC AT1 CIPSTART %d \"UDP\" 1" - % (i, i+1)] - fail_string = "Fail, Fail on create UDP link" - if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: - return - - # step 3 send recv data - # turn off AT UART logging - if enable_log is False: - self.test_env.uart_ports["AT1"].set_uart_logging_flag(False) - - for j in range(0, test_count): - data = "A" * at_send_length - fail_string = "Fail, Fail on send/recv data" - - if tx_enable is True: - # target link 0-5 sendto PC - for i in range(0, self.max_conn): - checker_stings = ["P AT1 C >"] - test_action_strings = ["ATS AT1 AT+CIPSEND=%d,%d" % (i, at_send_length)] - if self.load_and_exe_one_step(checker_stings, test_action_strings, - fail_string, check_time=20) is False: - NativeLog.add_trace_critical("Target fail on send cmd on link %d" % i) - NativeLog.add_trace_critical("Test count is %d" % j) - - checker_stings = ["P SOC_COM C RECV_LEN=%d P " % (at_send_length, i+1), - "P AT1 C OK"] - test_action_strings = ["ATSO AT1 %s" % data] - if self.load_and_exe_one_step(checker_stings, test_action_strings, - fail_string, check_time=20) is False: - NativeLog.add_trace_critical("Target sent UDP packet error on link %d" % i) - NativeLog.add_trace_critical("Test count is %d" % j) - - if rx_enable is True: - # PC send to target - checker_stings = [] - test_action_strings = [] - for i in range(0, self.max_conn): - checker_stings.extend(["P AT1 DL %d+%d" % (i, soc_send_length)]) - test_action_strings.extend(["SOC SOC1 SENDTO %d %s" - % (soc_send_length, i+1, target_ip_str)]) - - if self.load_and_exe_one_step(checker_stings, test_action_strings, - fail_string, check_time=20) is False: - NativeLog.add_trace_critical("PC sent UDP packet error") - NativeLog.add_trace_critical("Test count is %d" % j) - - # finally, execute done - self.result_cntx.set_result("Succeed") - - def result_check(self, port_name, data): - self.result_cntx.append_data(port_name, data) - - -def main(): - pass - -if __name__ == '__main__': - main() - diff --git a/components/test/TestCaseScript/ATStress/UDPSingle.py b/components/test/TestCaseScript/ATStress/UDPSingle.py deleted file mode 100755 index 0f30330ab6..0000000000 --- a/components/test/TestCaseScript/ATStress/UDPSingle.py +++ /dev/null @@ -1,105 +0,0 @@ -from TCAction import TCActionBase -from NativeLog import NativeLog - - -class UDPSingle(TCActionBase.CommonTCActionBase): - - def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): - TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - - self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) - pass - - def cleanup(self): - TCActionBase.CommonTCActionBase.cleanup(self) - # turn on logging - self.test_env.uart_ports["AT1"].set_uart_logging_flag(True) - - def execute(self): - TCActionBase.TCActionBase.execute(self) - self.result_cntx.start() - - # configurable params - try: - at_send_length = self.at_send_length - soc_send_length = self.soc_send_length - test_count = self.test_count - target_ip_str = self.target_ip_str - tx_enable = self.tx_enable - rx_enable = self.rx_enable - enable_log = self.enable_log - except StandardError, e: - NativeLog.add_trace_critical("Error configuration for UDPSingle script, error is %s" % e) - raise StandardError("Error configuration") - # configurable params - - # step1, bind one PC UDP port - checker_stings = ["R SOC_COM L OK"] - test_action_string = ["SOC SOC1 BIND "] - fail_string = "Fail, Fail on binding UDP socket" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - # step 2 create UDP link on target - checker_stings = ["R AT1 C CONNECT L OK"] - test_action_strings = ["ATC AT1 CIPSTART \"UDP\" 1"] - fail_string = "Fail, Fail on create UDP link" - if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: - return - - # step 3 send recv data - # turn off AT UART logging - if enable_log is False: - self.test_env.uart_ports["AT1"].set_uart_logging_flag(False) - - for j in range(0, test_count): - data = "A" * at_send_length - fail_string = "Fail, Fail on send recv data" - - # target sendto PC - if tx_enable is True: - checker_stings = ["P AT1 C >"] - test_action_strings = ["ATS AT1 AT+CIPSEND=%d" % at_send_length] - if self.load_and_exe_one_step(checker_stings, test_action_strings, - fail_string, check_time=20) is False: - NativeLog.add_trace_critical("Target fail on send cmd") - NativeLog.add_trace_critical("Test count is %d" % j) - - checker_stings = ["P SOC_COM C RECV_LEN=%d P " % at_send_length, - "P AT1 C OK"] - test_action_strings = ["ATSO AT1 %s" % data] - if self.load_and_exe_one_step(checker_stings, test_action_strings, - fail_string, check_time=20) is False: - NativeLog.add_trace_critical("Target sent UDP packet error") - NativeLog.add_trace_critical("Test count is %d" % j) - - # PC send to target - if rx_enable is True: - checker_stings = (["P AT1 DL S+%d" % soc_send_length]) - test_action_strings = (["SOC SOC1 SENDTO %d %s" % (soc_send_length, target_ip_str)]) - - if self.load_and_exe_one_step(checker_stings, test_action_strings, - fail_string, check_time=20) is False: - NativeLog.add_trace_critical("PC sent UDP packet error") - NativeLog.add_trace_critical("Test count is %d" % j) - - # finally, execute done - self.result_cntx.set_result("Succeed") - - def result_check(self, port_name, data): - TCActionBase.CommonTCActionBase.result_check(self, port_name, data) - self.result_cntx.append_data(port_name, data) - - -def main(): - pass - -if __name__ == '__main__': - main() - diff --git a/components/test/TestCaseScript/ATStress/UDPTransparent.py b/components/test/TestCaseScript/ATStress/UDPTransparent.py deleted file mode 100755 index 699d2b1ad8..0000000000 --- a/components/test/TestCaseScript/ATStress/UDPTransparent.py +++ /dev/null @@ -1,262 +0,0 @@ -from TCAction import TCActionBase -from TCAction import CmdHandler -from NativeLog import NativeLog -import time -import random -import string -import os - - -class TransparentResultCheckCntx(TCActionBase.ResultCheckContext): - - def __init__(self, test_action, test_env, name): - TCActionBase.ResultCheckContext.__init__(self, test_action, test_env, name) - self.result_array = [] - self.at_data_recv_total = 0 - self.pc_data_recv_total = 0 - pass - - def run(self): - validation_required = self.test_action.data_validation - temp_data_at2wifi = "" - temp_data_wifi2at = "" - path = os.path.split(self.test_action.log_file_name) - file_name_at2wifi = os.path.join(path[0], "%s_at2wifi_pc.bin" % self.test_action.timestamp) - file_name_wifi2at = os.path.join(path[0], "%s_wifi2at_at.bin" % self.test_action.timestamp) - - while True: - exit_flag = self.wait_exit_event(2) - # force exit - if exit_flag is True: - break - rx_len = 0 - tx_len = 0 - try: - self.lock_data() - rx_port = filter(lambda x: x[0] == "AT1", self.data_cache) - tx_port = filter(lambda x: x[0] == "SOC1", self.data_cache) - self.data_cache = [] - finally: - self.unlock_data() - - if len(rx_port) == 1: - rx_len = len(rx_port[0][1]) - self.at_data_recv_total += rx_len - if validation_required is True: - temp_data_wifi2at += rx_port[0][1] - if len(tx_port) == 1: - tx_len = len(tx_port[0][1]) - self.pc_data_recv_total += tx_len - if validation_required is True: - temp_data_at2wifi += tx_port[0][1] - - self.result_array.append(["TX %8d %s" % - (tx_len/2, time.strftime("%m-%d %H:%M:%S", time.localtime()))]) - self.result_array.append(["RX %8d %s" % - (rx_len/2, time.strftime("%m-%d %H:%M:%S", time.localtime()))]) - - if validation_required is True: - with open(file_name_at2wifi, "ab+") as f: - f.write(temp_data_at2wifi) - with open(file_name_wifi2at, "ab+") as f: - f.write(temp_data_wifi2at) - - def get_test_results(self): - return self.result_array, self.at_data_recv_total, self.pc_data_recv_total - - -class UDPTransparent(TCActionBase.CommonTCActionBase): - - def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): - TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) - self.timestamp = time.strftime("%d%H%M%S", time.localtime()) - - pass - - def cleanup(self): - # close current result check context - self.result_cntx.stop_thread() - self.result_cntx.join() - # turn on logging - self.test_env.uart_ports["AT1"].set_uart_logging_flag(True) - # restore to read line mode - self.test_env.uart_ports["AT1"].set_performance_flag(flag=False) - - # make sure enter condition that can respond to AT command - self.result_cntx = TCActionBase.ResultCheckContext(self, self.test_env, self.tc_name) - TCActionBase.TCActionBase.execute(self) - self.result_cntx.start() - - checker_stings = ["R AT1 R *"] - test_action_string = ["ATSO AT1 +++", "DELAY 0.1", "ATS AT1 AT"] - fail_string = "Fail, Fail to reconfig UART" - - result = False - - while result is False: - result = self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) - - # reset baudrate - - checker_stings = ["R AT1 L OK"] - test_action_string = ["ATS AT1 AT+UART_CUR=%d,8,1,0,3" % 115200] - fail_string = "Fail, Fail to reconfig UART" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - test_action = CmdHandler.parse_action("UART AT1 %d" % 115200, self.test_env) - CmdHandler.do_actions(test_action, self.test_env) - TCActionBase.CommonTCActionBase.cleanup(self) - - def execute(self): - TCActionBase.TCActionBase.execute(self) - self.result_cntx.start() - - try: - # configurable params - # at send data len - at_send_data_len = self.at_send_data_len - # pc send data len - pc_send_data_len = self.pc_send_data_len - # sleep time between each send, test count - test_dispatch = self.test_dispatch - # enable target TCP TX - tx_enable = self.tx_enable - # enable target TCP RX - rx_enable = self.rx_enable - # if need to record tx/rx data to file - data_validation = self.data_validation - # UART baudrate - baudrate = self.baudrate - # HW flow control - rtscts = self.rtscts - # configurable params - except StandardError, e: - NativeLog.add_trace_critical("Error configuration for TCPTransparent script, error is %s" % e) - raise StandardError("Error configuration") - - # step0 reconfig baudrate - if baudrate != 0: - checker_stings = ["R AT1 L OK"] - test_action_string = ["ATS AT1 AT+UART_CUR=%d,8,1,0,%d" % (baudrate, rtscts)] - fail_string = "Fail, Fail to reconfig UART" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - test_action = CmdHandler.parse_action("UART AT1 %d %d" % (baudrate, rtscts), self.test_env) - CmdHandler.do_actions(test_action, self.test_env) - - # step1 create PC server - checker_stings = ["R SOC_COM L OK"] - test_action_string = ["SOC SOC1 BIND "] - fail_string = "Fail, Fail on create PC server" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - # step2 target connect, switch to transparent - checker_stings = ["R AT1 NC CLOSE L OK"] - test_action_strings = ["ATC AT1 CIPSTART \"UDP\" 0"] - fail_string = "Fail, Fail on connect to PC server" - if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: - return - - checker_stings = ["R AT1 L OK"] - test_action_strings = ["ATS AT1 AT+CIPMODE=1"] - if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: - return - - checker_stings = ["R AT1 C >"] - test_action_strings = ["ATS AT1 AT+CIPSEND"] - if self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) is False: - return - - # step 3 - # turn off AT UART logging - self.test_env.uart_ports["AT1"].set_uart_logging_flag(False) - # restore to read data asap - self.test_env.uart_ports["AT1"].set_performance_flag(flag=True) - - # switch to new result check context - self.result_cntx.stop_thread() - self.result_cntx.join() - self.result_cntx = TransparentResultCheckCntx(self, self.test_env, self.tc_name) - self.result_cntx.start() - - at_data_sent_total = 0 - pc_data_sent_total = 0 - at2wifi_data = "" - wifi2at_data = "" - - for j in range(0, len(at_send_data_len) * len(pc_send_data_len)): - at_data_len = at_send_data_len[j / len(pc_send_data_len)] - pc_data_len = pc_send_data_len[j % len(pc_send_data_len)] - # data = "".join(["A"] * at_data_len) - chars = string.ascii_lowercase - data_list = ["".join([random.choice(chars) for m in range(at_data_len-16)])] - chars = string.ascii_uppercase - data_list.append("".join([random.choice(chars) for m in range(at_data_len-16)])) - chars = string.digits - data_list.append("".join([random.choice(chars) for m in range(at_data_len-16)])) - - for i in range(0, len(test_dispatch)): - for k in range(0, test_dispatch[i][1]): - data_str = "%.2d%.2d%.10d%s\r\n" % (j, i, k, data_list[k % 3]) - # time1 = time.time() - if tx_enable is True: - test_action = CmdHandler.parse_action("ATSO AT1 %s" % data_str, self.test_env) - CmdHandler.do_actions(test_action, self.test_env) - at_data_sent_total += at_data_len - if data_validation is True: - at2wifi_data += data_str - # time2 = time.time() - if rx_enable is True: - test_action = CmdHandler.parse_action("SOC SOC1 SENDTO %d %s %s %s" - % (pc_data_len, "", - "", data_str), self.test_env) - CmdHandler.do_actions(test_action, self.test_env) - pc_data_sent_total += pc_data_len - if data_validation is True: - wifi2at_data += data_str - # time3 = time.time() - # if time3-time2 > 0.1: - # pass - if test_dispatch[i][0] != 0: - time.sleep(test_dispatch[i][0]) - time.sleep(3) # wait 3 seconds - - # write send data to file for data validation - if data_validation is True: - path = os.path.split(self.log_file_name) - with open(os.path.join(path[0], "%s_at2wifi_at.bin" % self.timestamp), "ab+") as f: - f.write(at2wifi_data) - with open(os.path.join(path[0], "%s_wifi2at_pc.bin" % self.timestamp), "ab+") as f: - f.write(wifi2at_data) - throughput_results, at_data_recv_total, pc_data_recv_total = self.result_cntx.get_test_results() - result_str = "AT sent %15d\r\n" % at_data_sent_total - result_str += "PC recv %15d\r\n" % pc_data_recv_total - result_str += "PC sent %15d\r\n" % pc_data_sent_total - result_str += "AT recv %15d\r\n" % at_data_recv_total - for _result in throughput_results: - result_str += "%s\r\n" % _result - with open(self.log_file_name, "ab+") as f: - f.write(result_str) - - # finally, execute done - self.result_cntx.set_result("Succeed") - - def result_check(self, port_name, data): - self.result_cntx.append_data(port_name, data) - - -def main(): - pass - -if __name__ == '__main__': - main() - diff --git a/components/test/TestCaseScript/ATStress/__init__.py b/components/test/TestCaseScript/ATStress/__init__.py deleted file mode 100755 index 5a3bbc44dd..0000000000 --- a/components/test/TestCaseScript/ATStress/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -__all__ = ["TCPClientMulti", "TCPClientSingle", "TCPServerMulti", - "TCPTransparent", "UDPMulti", "UDPSingle"] \ No newline at end of file diff --git a/components/test/TestCaseScript/IOT/SCIOT.py b/components/test/TestCaseScript/IOT/SCIOT.py deleted file mode 100755 index 5ced3ef121..0000000000 --- a/components/test/TestCaseScript/IOT/SCIOT.py +++ /dev/null @@ -1,357 +0,0 @@ -import Queue - -from TCAction import TCActionBase -from NativeLog import NativeLog -from SCUDPServer import * -from TCAction.CmdExecutor import CmdExecutorBasic -from Utility import MakeFolder - -TEST_RESULT_CATEGORY = ("AP", "Phone") -TEST_RESULT_PROPERTY = ("model", "total", "succeed", "failed", "total time1", "total time2") -SINGLE_TEST_RESULT = ("AP", "Phone", "result", "time1", "time2") - -LOG_FILES = ("by_ap.tmp", "by_phone.tmp", "failed_item.tmp", "disqualified_item.tmp", "total.tmp") - -LOG_PATH = os.path.join("AT_LOG", "IOT") - - -def make_session_id(mac, test_id): - return mac_to_bytes(mac) + chr((test_id & 0xFF00) >> 8) + chr(test_id & 0xFF) - - -class TestHandler(threading.Thread): - def __init__(self, session_id, ap, phone, udp_server, test_action): - threading.Thread.__init__(self) - self.setDaemon(True) - self.udp_server = udp_server - self.session_id = session_id - self.ap = ap - self.phone = phone - self.test_action = test_action - self.recv_queue = Queue.Queue(10) - self.abort_event = threading.Event() - self.start_time = time.time() - self.test_result = None - udp_server.register_test_handler(session_id, self) - pass - - def req_receiver(self, msg, address): - self.recv_queue.put([msg, address]) - pass - - def res_receiver(self, msg, address): - self.recv_queue.put([msg, address]) - pass - - def abort_handler(self): - NativeLog.add_prompt_trace("[Test Handler][Debug] test aborted") - self.abort_event.set() - self.test_action.remove_from_available_list(self.phone) - pass - - def wait_result(self, event, timeout=None): - time_start = time.time() - while True: - if self.abort_event.isSet() is True: - return False - - if time.time() - self.start_time > ABORT_TIMEOUT: - return False - - if timeout is not None: - if time.time() - time_start > timeout: - return False - - if event == "ACK" or event == "result": - try: - ret = self.recv_queue.get(timeout=0.5) - except Queue.Empty, e: - continue - else: - msg = ret[0] - value_list = get_value_from_msg("type", msg) - msg_typ = ord(value_list[0]) - if msg_typ == TYPE_VAL[event]: - NativeLog.add_prompt_trace("[Test Handler][Debug] wait message succeed") - return msg - elif (msg_typ & 0x80) == 0: # invalid request - self.udp_server.send_response([[VALUE_NAME["type"], TYPE_VAL["Not support"]], - [VALUE_NAME["session id"], self.session_id]], - ret[1]) - pass - else: - pass - pass - - def run(self): - for i in range(1): - # step1 send broadcast to SP - msg = [[VALUE_NAME["type"], TYPE_VAL["Init new test"]], - [VALUE_NAME["session id"], self.session_id]] - self.udp_server.send_request(("", self.udp_server.udp_port), self.session_id, msg) - # wait response - if self.wait_result("ACK") is False: - break - NativeLog.add_prompt_trace("[Step1] Initial new test succeed") - - # step2 start smart config - checker_stings = ["ATR AT1 L OK"] - test_action_string = ["ATS AT1 AT+CWSTOPSMART"] - fail_string = "Fail, Failed to start smart config" - if self.test_action.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - NativeLog.add_prompt_trace(fail_string) - break - checker_stings = ["ATR AT1 L OK"] - test_action_string = ["ATS AT1 AT+CWSTARTSMART=1"] - if self.test_action.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - NativeLog.add_prompt_trace(fail_string) - break - NativeLog.add_prompt_trace("[Step2] Start smart config succeed") - - # step3 send test request to SP - msg = [[VALUE_NAME["type"], TYPE_VAL["test request"]], - [VALUE_NAME["session id"], self.session_id], - [VALUE_NAME["ap ssid"], self.ap["ssid"]], - [VALUE_NAME["ap password"], self.ap["password"]], - [VALUE_NAME["ap bssid"], mac_to_bytes(self.ap["bssid"])], - # [VALUE_NAME["ET version"], 0x20], - [VALUE_NAME["ssid hidden"], self.ap["is_hidden"]], - [VALUE_NAME["ap encryption"], AP_ENCRYPTION_VAL[self.ap["encryption"]]] - ] - self.udp_server.send_request((self.phone["ip"], self.udp_server.udp_port), self.session_id, msg) - # wait SP reply - if self.wait_result("ACK") is False: - break - NativeLog.add_prompt_trace("[Step3] Send test request succeed") - time_base = time.time() - - # step4 wait target smart config succeed - checker_stings = ["ATR AT1 C get%%20wifi%%20info C %s C %s" - % (self.ap["ssid"], self.ap["password"])] - test_action_string = [] - fail_string = "Fail, Fail to get ap info" - # if check target get smart config result fail, continue and get result from SP - ret = self.test_action.load_and_exe_one_step(checker_stings, test_action_string, - fail_string, check_time=600) - if ret is False: - NativeLog.add_prompt_trace("[Step4] Target smart config fail") - step_4_fail = True - else: - NativeLog.add_prompt_trace("[Step4] Target smart config succeed") - step_4_fail = False - time_target_succeed = time.time() - time_base - - # step5 wait SP result - msg = self.wait_result("result") - if msg is False: - NativeLog.add_prompt_trace("[Test Handler][Debug] Failed to get result from SP") - break - else: - self.udp_server.send_response([[VALUE_NAME["type"], TYPE_VAL["ACK"]], - [VALUE_NAME["session id"], self.session_id]], - (self.phone["ip"], self.udp_server.udp_port)) - tmp = get_value_from_msg(["result code", "start SC time", "recv UDP time"], msg) - result_code = ord(tmp[0]) - if result_code == RESULT_CODE_VAL["OK"]: - sp_start_time = bytes_to_time(tmp[1]) - sp_recv_udp_time = bytes_to_time(tmp[2]) - smart_config_protocol_cost = time_target_succeed - sp_start_time - user_experience_time = sp_recv_udp_time - sp_start_time - self.test_result = ["Succeed", smart_config_protocol_cost, user_experience_time] - elif result_code == RESULT_CODE_VAL["recv UDP fail"]: - sp_start_time = bytes_to_time(tmp[1]) - if step_4_fail is True: - smart_config_protocol_cost = 0 - else: - smart_config_protocol_cost = time_target_succeed - sp_start_time - self.test_result = ["Failed", smart_config_protocol_cost, 0] - pass - else: - NativeLog.add_prompt_trace("[Test Handler][Debug] Disqualified message: %s" % tmp) - - for k in range(RETRANSMIT_COUNT - 1): - if self.wait_result("result", RETRANSMIT_TIMEOUT) is not False: - self.udp_server.send_response([[VALUE_NAME["type"], TYPE_VAL["ACK"]], - [VALUE_NAME["session id"], self.session_id]], - (self.phone["ip"], self.udp_server.udp_port)) - - NativeLog.add_prompt_trace("[Step5] Receive test result from SP") - - if self.test_result is None: - self.test_result = ["Disqualified", 0, 0] - self.udp_server.deregister_test_handler(self.session_id) - NativeLog.add_prompt_trace("One Test Done") - pass - - def get_result(self): - if self.test_result is None: - NativeLog.add_trace_critical("Get result before test finish") - return self.test_result - pass - - -class SCIOT(TCActionBase.CommonTCActionBase): - def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): - TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - self.ap_list = [] - self.test_result = dict.fromkeys(TEST_RESULT_CATEGORY) - self.test_result["AP"] = [] - self.test_result["Phone"] = [] - self.available_phone_list = [] - self.pc_ip = "" - self.udp_port = "" - self.test_id = 0x00 - self.resource_lock = threading.Lock() - self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy" and cmd_set[i][0] != "": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - - for i in range(1, len(cmd_set)): - for j in range(len(cmd_set[i][1])): - if cmd_set[i][1][j] != "": - cmd_string = "self.ap_list.append(dict(zip(AP_PROPERTY, " + cmd_set[i][1][j] + ")))" - exec cmd_string - for ap in self.ap_list: - self.test_result["AP"].append(dict(zip(TEST_RESULT_PROPERTY, [ap["ssid"], 0, 0, 0, 0, 0]))) - - self.log_folder = MakeFolder.make_folder(os.path.join(LOG_PATH, "TEST_%s" - % (time.strftime("%y%m%d%H%M%S", time.localtime())))) - self.log_files = dict.fromkeys(LOG_FILES) - for _file in self.log_files: - self.log_files[_file] = os.path.join(self.log_folder, - (time.strftime("%H%M%S", time.localtime())) + _file) - pass - - def update_phone_list(self, phone): - with self.resource_lock: - tmp = filter(lambda x: x["model"] == phone["model"], self.available_phone_list) - if len(tmp) == 1: - tmp[0]["ip"] = phone["ip"] - else: - self.available_phone_list.append(phone) - - tmp = filter(lambda x: x["model"] == phone["model"], self.test_result["Phone"]) - if len(tmp) == 0: - self.test_result["Phone"].append(dict(zip(TEST_RESULT_PROPERTY, [phone["model"], 0, 0, 0, 0, 0]))) - pass - - def remove_from_available_list(self, phone): - with self.resource_lock: - tmp = filter(lambda x: x["model"] == phone["model"], self.available_phone_list) - if len(tmp) == 1: - self.available_phone_list.remove(tmp[0]) - pass - - def allocate_test(self): - phone = None - test_count = 0xFFFF - with self.resource_lock: - for _phone in self.available_phone_list: - tmp = filter(lambda x: x["model"] == _phone["model"], self.test_result["Phone"]) - if len(tmp) == 1: - _count = tmp[0]["total"] - if _count < test_count: - test_count = _count - phone = _phone - ap_list = self.ap_list[test_count % len(self.ap_list):] - return phone, ap_list - pass - - def output_test_result(self, ap, phone, test_result): - result_str = "Time stamp" + ":\t" + NativeLog.generate_timestamp() + "\r\n" - result_str += "AP model" + ":\t" + str(ap["ssid"]) + "\r\n" - result_str += "AP encryption" + ":\t" + str(ap["encryption"]) + "\r\n" - result_str += "AP HT" + ":\t" + str(ap["ht"]) + "\r\n" - result_str += "AP ssid hidden" + ":\t" + str(ap["is_hidden"]) + "\r\n" - result_str += "Phone model" + ":\t" + str(phone["model"]) + "\r\n" - result_str += "Result" + ":\t" + str(test_result[0]) + "\r\n" - result_str += "Time1" + ":\t" + str(test_result[1]) + "\r\n" - result_str += "Time2" + ":\t" + str(test_result[2]) + "\r\n" - - with self.resource_lock: - tmp = [filter(lambda x: x["model"] == ap["ssid"], self.test_result["AP"])[0], - filter(lambda x: x["model"] == phone["model"], self.test_result["Phone"])[0]] - if test_result[0] == "Succeed": - for _tmp in tmp: - _tmp["total"] += 1 - _tmp["succeed"] += 1 - _tmp["total time1"] += test_result[1] - _tmp["total time2"] += test_result[2] - pass - elif test_result[0] == "Disqualified": - for _tmp in tmp: - _tmp["total"] += 1 - pass - else: - for _tmp in tmp: - _tmp["total"] += 1 - _tmp["failed"] += 1 - pass - tmp_result = dict(zip(TEST_RESULT_CATEGORY, ["", ""])) - for category in self.test_result: - for _result in self.test_result[category]: - for n in _result: - tmp_result[category] += str(n) + ":\t" + str(_result[n]) + "\r\n" - - # update to log file - with open(self.log_files["by_ap.tmp"], "wb+") as f: - f.write(tmp_result["AP"]) - with open(self.log_files["by_phone.tmp"], "wb+") as f: - f.write(tmp_result["Phone"]) - - with open(self.log_files["total.tmp"], "ab+") as f: - f.write(result_str) - if test_result[0] == "Failed": - with open(self.log_files["failed_item.tmp"], "ab+") as f: - f.write(result_str) - elif test_result[0] == "Disqualified": - with open(self.log_files["disqualified_item.tmp"], "ab+") as f: - f.write(result_str) - - pass - - def execute(self): - TCActionBase.TCActionBase.execute(self) - self.result_cntx.start() - - pc_ip = CmdExecutorBasic.extract_parameter(self.pc_ip, self.test_env) - if isinstance(self.udp_port, int) is False: - udp_port = CmdExecutorBasic.extract_parameter(self.udp_port, self.test_env) - else: - udp_port = self.udp_port - - server = UDPServer(pc_ip, udp_port, self.update_phone_list) - server.start() - - while True: - phone, ap_list = self.allocate_test() - if phone is None: - time.sleep(5) - continue - for ap in ap_list: - NativeLog.add_prompt_trace("AP is %s, Phone is %s" % (ap["ssid"], phone["model"])) - session_id = make_session_id(phone["mac"], self.test_id) - self.test_id += 1 - test_handler = TestHandler(session_id, ap, phone, server, self) - test_handler.start() - test_handler.join() - result = test_handler.get_result() - self.output_test_result(ap, phone, result) - - # finally, execute done - server.join() - self.result_cntx.set_result("Succeed") - - def result_check(self, port_name, data): - TCActionBase.CommonTCActionBase.result_check(self, port_name, data) - self.result_cntx.append_data(port_name, data) - - -def main(): - pass - -if __name__ == '__main__': - main() diff --git a/components/test/TestCaseScript/IOT/SCUDPServer.py b/components/test/TestCaseScript/IOT/SCUDPServer.py deleted file mode 100755 index 75f24f79ac..0000000000 --- a/components/test/TestCaseScript/IOT/SCUDPServer.py +++ /dev/null @@ -1,378 +0,0 @@ -import socket -import time -import os -import threading - -from NativeLog import NativeLog - - -RETRANSMIT_COUNT = 5 -RETRANSMIT_TIMEOUT = 0.5 -ABORT_TIMEOUT = 120 -BEACON_SEND_RATE = 30 - - -VALUE_NAME = {"type": 0x00, - "session id": 0x01, - "result code": 0x02, - "ap ssid": 0x03, - "ap password": 0x04, - "start SC time": 0x05, - "recv UDP time": 0x06, - "SP model": 0x07, - "SP mac": 0x08, - "ET version": 0x09, - "ap bssid": 0x0A, - "ssid hidden": 0x0B, - "ap encryption": 0x0C, - } - -TYPE_VAL = {"Init new test": 0x00, - "test request": 0x01, - "result": 0x02, - "query phone": 0x03, - "ACK": 0x80, - "phone report": 0x81, - "Not support": 0xFF, - "invalid session": 0xFE, - } - -RESULT_CODE_VAL = {"OK": 0x80, - "JAP fail": 0x81, # SP join AP fail, should disqualify this result - "recv UDP fail": 0x82, # SP did not receive UDP sent by target - } - -AP_ENCRYPTION_VAL = {"OPEN": 0x00, - "WEP": 0x01, - "WPA": 0x02, - } - -AP_PROPERTY = ("ssid", "password", "bssid", "is_hidden", "encryption", "ht") -PHONE_PROPERTY = ("ip", "mac", "model") - - -SERIAL_PORT_NUM = 3 -LOG_FILE_PREFIX = "SC_IOT" -LOG_FOLDER = os.path.join("AT_LOG", "TEMP") -LOG_FILE_NAME = os.path.join(LOG_FOLDER, "%s_%s.log" % (LOG_FILE_PREFIX, time.strftime("%d%H%M%S", time.localtime()))) - - -REQUEST_LOCK = threading.Lock() -HANDLER_LOCK = threading.Lock() - - -def sync_request_list(func): - def handle_args(*args, **kwargs): - with REQUEST_LOCK: - ret = func(*args, **kwargs) - return ret - return handle_args - - -def sync_handler_list(func): - def handle_args(*args, **kwargs): - with HANDLER_LOCK: - ret = func(*args, **kwargs) - return ret - return handle_args - - -def _process_one_tlv_pair(data): - typ = ord(data[0]) - length = ord(data[1]) - value = data[2:2+length] - processed_data = data[2+length:] - return (typ, value), processed_data - pass - - -def bytes_to_msg(data): - data_to_process = data - msg = [] - while True: - one_pair, data_to_process = _process_one_tlv_pair(data_to_process) - msg.append(one_pair) - if len(data_to_process) == 0: - break - return msg - pass - - -def msg_to_bytes(msg): - byte_str = "" - for pair in msg: - byte_str += chr(pair[0]) - if isinstance(pair[1], list) is True: - byte_str += chr(len(pair[1])) - byte_str.join([chr(m) for m in pair[1]]) - elif isinstance(pair[1], str) is True: - byte_str += chr(len(pair[1])) - byte_str += pair[1] - elif isinstance(pair[1], int) is True: - byte_str += chr(1) - byte_str += chr(pair[1]) - else: - raise TypeError("msg content only support list and string type") - return byte_str - - -def get_value_from_msg(type_list, msg): - if isinstance(type_list, str) is True: - type_list = [type_list] - ret = [""] * len(type_list) - for pair in msg: - for i in range(len(type_list)): - if pair[0] == VALUE_NAME[type_list[i]]: - ret[i] = pair[1] - if "" not in ret: - # all type value found - break - else: - NativeLog.add_prompt_trace("missing required type in msg") - return ret - - -def bytes_to_time(bytes_in): - if len(bytes_in) != 4: - return 0 - t = float(ord(bytes_in[0])*256*256*256 + ord(bytes_in[1])*256*256 - + ord(bytes_in[2])*256 + ord(bytes_in[2]))/1000 - return t - pass - - -def mac_to_bytes(mac): - tmp = mac.split(':') - return "".join([chr(int(m[:2], base=16)) for m in tmp]) - pass - - -def bytes_to_mac(bytes_in): - mac = "".join(["%x:" % ord(m) for m in bytes_in] ) - return mac[:-1] - - -class RetransmitHandler(threading.Thread): - def __init__(self, udp_server): - threading.Thread.__init__(self) - self.setDaemon(True) - self.udp_server = udp_server - self.exit_event = threading.Event() - pass - - @sync_request_list - def find_required_retransmit_msg(self): - time_now = time.time() - aborted_sessions = [] - retransmit_msg = [] - msgs = filter(lambda x: time_now - x[4] >= RETRANSMIT_TIMEOUT, self.udp_server.unconfirmed_request) - for msg in msgs: - if msg[3] == 0: - aborted_sessions.append(msg[0]) - self.udp_server.unconfirmed_request.remove(msg) - else: - msg[3] -= 1 - msg[4] = time_now - retransmit_msg.append(msg) - pass - return aborted_sessions, retransmit_msg - pass - - def run(self): - while True: - self.exit_event.wait(0.1) - if self.exit_event.isSet() is True: - break - aborted_sessions, retransmit_msg = self.find_required_retransmit_msg() - for msg in retransmit_msg: - self.udp_server.udp_socket.sendto(msg[1], msg[2]) - for session_id in aborted_sessions: - self.udp_server.session_aborted(session_id) - - def exit(self): - self.exit_event.set() - pass - - -class SendBeacon(threading.Thread): - def __init__(self, sock, udp_port): - threading.Thread.__init__(self) - self.setDaemon(True) - self.udp_sock = sock - self.udp_port = udp_port - self.exit_event = threading.Event() - - def run(self): - while True: - msg = [[VALUE_NAME["type"], TYPE_VAL["query phone"]]] - data = msg_to_bytes(msg) - self.udp_sock.sendto(data, ("", self.udp_port)) - for i in range(BEACON_SEND_RATE): - self.exit_event.wait(1) - if self.exit_event.isSet() is True: - return - pass - - def exit(self): - self.exit_event.set() - pass - - -class UDPServer(threading.Thread): - def __init__(self, pc_ip, udp_port, update_phone_handler): - threading.Thread.__init__(self) - self.setDaemon(True) - sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM) - sock.bind((pc_ip, udp_port)) - sock.settimeout(1) - sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) - self.udp_socket = sock - self.unconfirmed_request = [] - self.test_handler_list = [] - self.pc_ip = pc_ip - self.udp_port = udp_port - self.update_phone_handler = update_phone_handler - self.retransmit_thread = RetransmitHandler(self) - self.beacon_thread = SendBeacon(self.udp_socket, self.udp_port) - self.retransmit_thread.start() - self.beacon_thread.start() - self.exit_event = threading.Event() - pass - - @sync_handler_list - def register_test_handler(self, session_id, test_handler): - tmp = filter(lambda x: x[0] == session_id, self.test_handler_list) - if len(tmp) > 0: - NativeLog.add_prompt_trace("handler with same session id exist") - else: - self.test_handler_list.append([session_id, test_handler]) - pass - - @sync_handler_list - def deregister_test_handler(self, session_id): - tmp = filter(lambda x: x[0] == session_id, self.test_handler_list) - if len(tmp) > 1: - NativeLog.add_prompt_trace("deregister test handler fail") - elif len(tmp) == 1: - self.test_handler_list.remove(tmp[0]) - pass - - @sync_handler_list - def get_test_handler(self, session_id): - ret = None - tmp = filter(lambda x: x[0] == session_id, self.test_handler_list) - if len(tmp) != 1: - NativeLog.add_prompt_trace("failed to get test handler, " - "%d handler found, session id %s" % (len(tmp), session_id)) - elif len(tmp) == 1: - ret = tmp[0][1] - return ret - pass - - def session_aborted(self, session_id): - test_handler = self.get_test_handler(session_id) - if test_handler is not None: - test_handler.abort_handler() - pass - - def confirm_request(self, session_id, msg, address): - test_handler = self.get_test_handler(session_id) - if test_handler is not None: - test_handler.res_receiver(msg, address) - self.remove_pending_request(session_id) - pass - - def receive_request(self, msg, address): - result = get_value_from_msg(["type", "session id"], msg) - msg_type = ord(result[0]) - session_id = result[1] - if msg_type != TYPE_VAL["result"]: - self.send_response([[VALUE_NAME["type"], TYPE_VAL["Not support"]]], address) - else: - test_handler = self.get_test_handler(session_id) - if test_handler is None: - self.send_response([[VALUE_NAME["type"], TYPE_VAL["invalid session"]], - [VALUE_NAME["session id"], session_id]], - address) - pass - else: - test_handler.req_receiver(msg, address) - pass - - @sync_request_list - def add_request_to_queue(self, dest_addr, session_id, data): - tmp = filter(lambda x: x[0] == session_id, self.unconfirmed_request) - if len(tmp) != 0: - NativeLog.add_prompt_trace("One pending request belong to same session id %s" % session_id) - pass - else: - self.unconfirmed_request.append([session_id, data, - dest_addr, RETRANSMIT_COUNT-1, time.time()]) - - def send_request(self, dest_addr, session_id, msg): - data = msg_to_bytes(msg) - self.add_request_to_queue(dest_addr, session_id, data) - self.udp_socket.sendto(data, dest_addr) - pass - - def send_response(self, msg, address): - self.udp_socket.sendto(msg_to_bytes(msg), address) - - @sync_request_list - def remove_pending_request(self, session_id): - tmp = filter(lambda x: x[0] == session_id, self.unconfirmed_request) - if len(tmp) > 0: - self.unconfirmed_request.remove(tmp[0]) - pass - pass - - def handle_response(self, msg, address): - result = get_value_from_msg(["type", "session id"], msg) - msg_type = ord(result[0]) - session_id = result[1] - if msg_type == TYPE_VAL["ACK"]: - self.confirm_request(session_id, msg, address) - elif msg_type == TYPE_VAL["phone report"]: - # add new available phone - tmp = get_value_from_msg(["SP model", "SP mac"], msg) - phone = dict(zip(PHONE_PROPERTY, [address[0], bytes_to_mac(tmp[1]), tmp[0]])) - self.update_phone_handler(phone) - pass - elif msg_type == TYPE_VAL["Not support"] or msg_type == TYPE_VAL["invalid session"]: - self.session_aborted(session_id) - pass - - def run(self): - while self.exit_event.isSet() is False: - try: - data, address = self.udp_socket.recvfrom(65535) - except socket.error, e: - continue - - if address[0] == self.pc_ip: - continue - - msg = bytes_to_msg(data) - msg_type = get_value_from_msg(["type"], msg)[0] - - if msg_type is None: - NativeLog.add_prompt_trace("invalid incoming msg: %s" % "".join(["0x%X, " % m for m in data])) - else: - msg_type = ord(msg_type) - # check if request or reply - if (msg_type & 0x80) != 0: - self.handle_response(msg, address) - else: - self.receive_request(msg, address) - pass - - self.retransmit_thread.exit() - self.beacon_thread.exit() - self.retransmit_thread.join() - self.beacon_thread.join() - pass - - def exit(self): - self.exit_event.set() - pass diff --git a/components/test/TestCaseScript/IOT/WifiConnUtility.py b/components/test/TestCaseScript/IOT/WifiConnUtility.py deleted file mode 100755 index d50474561b..0000000000 --- a/components/test/TestCaseScript/IOT/WifiConnUtility.py +++ /dev/null @@ -1,244 +0,0 @@ -from NativeLog import NativeLog -import time -import random -import string - - -ERROR_AP_PROP = {"ssid": "123456789012345678901234567890", - "ssid_len": 30, - "pwd": "12345678901234567890", - "pwd_len": 20, - "channel": 10, - "enc": 3, - "apc": 9, # invalid apc count - } - - -class WifiConnUtilError(StandardError): - pass - - -class WifiConnUtility(object): - - def __init__(self, tc_action): - self.tc_action = tc_action - self.target_type = tc_action.target_type - pass - - def set_mode(self, mode): - ret = True - fail_string = "set mode fail" - cmd = [] - checker_stings = [] - for i in range(2): - if self.target_type[0] == "SSC": - cmd.append("SSCC SSC%d op -S -o %d" % (i+1, mode[i])) - checker_stings.append("SSCP SSC%d C cur_mode C %d" % (i+1, mode[i])) - pass - else: - cmd.append("ATC AT%d CWMODE %d" % (i+1, mode[i])) - checker_stings.append("ATP AT%d L OK" % (i+1)) - pass - if self.tc_action.load_and_exe_one_step(checker_stings, cmd, - fail_string, check_time=50) is False: - NativeLog.add_trace_critical("Failed to set mode") - ret = False - return ret - pass - - def _apc_switch(self, outlet_list, action_list): - checker_stings = ["R PC_COM C OK"] - switch_cmd = "APC APC1" - fail_string = "Error when switching APC" - ret = True - - for [_outlet, _action] in zip(action_list, outlet_list): - switch_cmd += " %s %d" % (_action, _outlet) - - if self.tc_action.load_and_exe_one_step(checker_stings, [switch_cmd], - fail_string, check_time=50) is False: - NativeLog.add_trace_critical("Error when switching APC") - ret = False - return ret - pass - - def _set_target_ap(self, ap_prop): - ret = True - fail_string = "set target ap fail, %s, %s" % (ap_prop["ssid"], ap_prop["pwd"]) - if self.target_type[1] == "SSC": - if ap_prop["pwd"] == "": - cmd = ["SSCC SSC2 ap -S -s %s -t %d" % (ap_prop["ssid"], - ap_prop["enc"]) - ] - else: - cmd = ["SSCC SSC2 ap -S -s %s -p %s -t %d" % (ap_prop["ssid"], - ap_prop["pwd"], - ap_prop["enc"]) - ] - checker_stings = ["SSCP SSC2 C +SAP:OK"] - pass - else: - cmd = ["ATC AT2 CWSAP \"%s\" \"%s\" %d %d" % (ap_prop["ssid"], - ap_prop["pwd"], - ap_prop["channel"], - ap_prop["enc"]) - ] - checker_stings = ["ATR AT2 L OK"] - pass - if self.tc_action.load_and_exe_one_step(checker_stings, cmd, - fail_string, check_time=50) is False: - NativeLog.add_trace_critical("set target ap fail") - ret = False - return ret - pass - - def setup_ap(self, ap_type, ap_prop): - if ap_type == "target": - ret = self._set_target_ap(ap_prop) - pass - else: - ret = self._apc_switch(["ON"], [ap_prop["apc"]]) - # delay for 5 seconds, wait AP ready - time.sleep(5) - pass - return ret - - def do_scan(self, ap_prop): - fail_string = "Scan fail" - ret = True - # do not check if the set AP can be scanned - if self.target_type[1] == "SSC": - cmd = ["SSCC SSC1 sta -S"] - checker_stings = ["SSCR SSC1 C ssc%20scan%20done"] - pass - else: - cmd = ["ATS AT1 AT+CWLAP"] - checker_stings = ["ATR AT1 L OK"] - pass - if self.tc_action.load_and_exe_one_step(checker_stings, cmd, - fail_string, check_time=100) is False: - NativeLog.add_trace_critical("Scan fail") - ret = False - return ret - pass - - def _switch_off_target_ap(self, delay): - time.sleep(delay) - self._set_target_ap(ERROR_AP_PROP) - pass - - def _switch_on_target_ap(self, ap_prop, delay): - time.sleep(delay) - self._set_target_ap(ap_prop) - pass - - def _switch_off_ap(self, ap_type, ap_prop, delay_range): - delay = random.randint(delay_range[0]*10, delay_range[1]*10)/10 - if ap_type == "target": - self._switch_off_target_ap(delay) - else: - delay -= 1.5 - time.sleep(delay if delay > 0 else 0) - self._apc_switch(["OFF"], [ap_prop["apc"]]) - pass - - def _switch_on_ap(self, ap_type, ap_prop, delay_range): - delay = random.randint(delay_range[0]*10, delay_range[1]*10)/10 - if ap_type == "target": - self._switch_on_target_ap(ap_prop, delay) - else: - delay -= 1.5 - time.sleep(delay if delay > 0 else 0) - self._apc_switch(["ON"], [ap_prop["apc"]]) - pass - - def _join_ap(self, ap_prop, test_method): - fail_string = "join target ap fail, %s, %s" % (ap_prop["ssid"], ap_prop["pwd"]) - if self.target_type[1] == "SSC": - cmd = ["SSCC SSC1 ap -C -s %s -p %s" % (ap_prop["ssid"], - ap_prop["pwd"],) - ] - checker_stings = ["SSCR SSC1 C %s" % ap_prop["ssid"], - "SSCR SSC1 C dhcp%20client%20start", - "SSCR SSC1 C ip C mask C gw"] - pass - else: - cmd = ["ATC AT1 CWJAP \"%s\" \"%s\"" % (ap_prop["ssid"], - ap_prop["pwd"]) - ] - checker_stings = ["ATR AT1 NC ERROR NC FAIL L OK"] - pass - if test_method == "Normal": - ret = self.tc_action.load_and_exe_one_step(checker_stings, cmd, - fail_string, check_freq=0.1, check_time=350) - if ret is not False: - ret *= 0.1 - else: - ret = self.tc_action.load_and_exe_one_step([], cmd, fail_string) - return ret - pass - - def _check_join_ap_result(self, ap_prop): - ret = False - fail_string = "join ap fail, %s, %s" % (ap_prop["ssid"], ap_prop["pwd"]) - - if self.target_type[1] == "SSC": - checker_stings = ["SSCR SSC1 C dhcp%20client%20start", - "SSCR SSC1 C ip C mask C gw"] - ret = self.tc_action.load_and_exe_one_step(checker_stings, ["DELAY 0"], - fail_string, check_freq=1, check_time=120) - pass - else: - cmd = ["ATS AT1 AT+CWJAP?"] - checker_stings = ["ATR AT1 NC busy NC No%20AP C +CWJAP"] - for i in range(3): - ret = self.tc_action.load_and_exe_one_step(checker_stings, cmd, - fail_string, check_freq=1, check_time=2) - if ret is not False: - break - time.sleep(15) - - return ret - pass - - def join_ap(self, join_test_method, ap_type, ap_prop, delay): - - if join_test_method == "WRONG_PROP": - _prop = ERROR_AP_PROP - else: - _prop = ap_prop - - ret = self._join_ap(_prop, join_test_method) - - if join_test_method == "OFF_ON": - self._switch_off_ap(ap_type, ap_prop, delay[0]) - self._switch_on_ap(ap_type, ap_prop, delay[1]) - ret = self._check_join_ap_result(_prop) - pass - elif join_test_method == "OFF": - self._switch_off_ap(ap_type, ap_prop, delay[0]) - time.sleep(25) - pass - - return ret - pass - - def do_reconnect(self, reconnect_test_method, ap_type, ap_prop, delay): - ret = True - if reconnect_test_method == "OFF_ON": - self._switch_off_ap(ap_type, ap_prop, delay[0]) - self._switch_on_ap(ap_type, ap_prop, delay[1]) - ret = self._check_join_ap_result(ap_prop) - pass - elif reconnect_test_method == "OFF": - self._switch_off_ap(ap_type, ap_prop, delay[0]) - pass - return ret - pass - - -def main(): - pass - -if __name__ == '__main__': - main() diff --git a/components/test/TestCaseScript/IOT/WifiJAP.py b/components/test/TestCaseScript/IOT/WifiJAP.py deleted file mode 100755 index 0bb6292955..0000000000 --- a/components/test/TestCaseScript/IOT/WifiJAP.py +++ /dev/null @@ -1,183 +0,0 @@ -import os -import random -import time - -import WifiConnUtility -from NativeLog import NativeLog -from TCAction import TCActionBase -from Utility import Encoding -from Utility import MakeFolder - -STEPS = {"SCAN1": 0x01, "JAP": 0x02, "SCAN2": 0x04, "RECONNECT": 0x08} - -AP_PROP = ("ssid", "ssid_len", "pwd", - "pwd_len", "channel", "enc", "apc") - -JAP_TEST_METHOD = ("Normal", "OFF_ON", "OFF", "WRONG_PROP") - -RECONNECT_TEST_METHOD = ("OFF_ON", "OFF") - -LOG_FOLDER = os.path.join("AT_LOG", "Performance", "JAP") - - -SSID_LEN_RANGE = (1, 32) # in bytes -ENC_TYPE = (0, 2, 3, 4) # do not support WEP for 8266 soft AP -PWD_RANGE = {0: [0, 0], - 1: [5, 5], - 2: [8, 63], - 3: [8, 63], - 4: [8, 63], - } - - -class WifiJAP(TCActionBase.CommonTCActionBase): - - def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): - TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - # default value for optional configurable params - self.pwd_len = [8, 64] - self.step_config = [0x03, 0x01, 0x02, 0x0B, 0x0F] - self.join_test_method = ["Normal"] - self.join_delay = [[1.5, 5], [1.5, 5]] - self.reconnect_test_method = ["OFF_ON"] - self.reconnect_delay = [[1.5, 5], [1.5, 6]] - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy" and cmd_set[i][0] != "": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - # read AP list - self.ap_list = [] - for i in range(1, len(cmd_set)): - for j in range(len(cmd_set[i][1])): - if cmd_set[i][1][j] != "": - cmd_string = "self.ap_list.append(dict(zip(AP_PROP, " + cmd_set[i][1][j] + ")))" - exec cmd_string - - folder_path = MakeFolder.make_folder(LOG_FOLDER) - file_name = "JAP_log_%s.log" % (time.strftime("%m%d%H%M%S", time.localtime())) - self._performance_log_file = os.path.join(folder_path, file_name) - - # test statistics - self._succeed_count = self._fail_count = self._time_cost_count = 0 - self._total_time = self._longest_time = 0 - - self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) - # get target type "SSC" or "AT" - self.target_type = ["SSC" if test_env.get_port_by_name("AT1") is None else "AT"] - self.target_type.append("SSC" if test_env.get_port_by_name("AT1") is None else "AT") - self._utility = WifiConnUtility.WifiConnUtility(self) - pass - - def _generate_random_ap_prop(self): - ap_prop = dict.fromkeys(AP_PROP) - # generate target ap_value - ap_prop["ssid_len"] = random.randint(SSID_LEN_RANGE[0], SSID_LEN_RANGE[1]) - ap_prop["channel"] = random.choice(range(1, 14)) - ap_prop["enc"] = random.choice(ENC_TYPE) - ap_prop["pwd_len"] = random.randint(PWD_RANGE[ap_prop["enc"]][0], PWD_RANGE[ap_prop["enc"]][1]) - # generate string - if self.target_type[0] == self.target_type[1] == "AT": - ap_prop["ssid"] = Encoding.generate_random_utf8_str(ap_prop["ssid_len"]) - ap_prop["pwd"] = Encoding.generate_random_utf8_str(ap_prop["pwd_len"]) - # NativeLog.add_trace_info("ssid hex is : %x" % ap_prop["ssid"]) - # NativeLog.add_trace_info("pwd hex is : %x" % ap_prop["pwd"]) - else: - ap_prop["ssid"] = Encoding.generate_random_printable_str(ap_prop["ssid_len"]) - ap_prop["pwd"] = Encoding.generate_random_printable_str(ap_prop["pwd_len"]) - - return ap_prop - - def _logging_performance(self, ssid, join_method="Normal", time_cost=0): - # log performance to performance log file - with open(self._performance_log_file, "ab+") as f: - # log time and ssid - f.write("\r\n[%s]:\r\n[AP name] %s\r\n" % - (time.strftime("%m-%d %H:%M:%S", time.localtime()), ssid)) - if join_method == "Normal" or join_method == "OFF_ON": - if time_cost is not False: - self._succeed_count += 1 - if join_method == "Normal": - f.write("[Succeed][%f]\r\n" % time_cost) - self._longest_time = (time_cost > self._longest_time and - [time_cost] or [self._longest_time])[0] - self._time_cost_count += 1 - self._total_time += time_cost - else: - f.write("[Succeed][%s]\r\n" % join_method) - else: - self._fail_count += 1 - f.write("[Fail][%s]\r\n" % join_method) - pass - - def _logging_fail_step(self, ssid, step): - with open(self._performance_log_file, "ab+") as f: - f.write("\r\n[%s]:\r\n[AP name] %s\r\n" % - (time.strftime("%m-%d %H:%M:%S", time.localtime()), ssid)) - f.write("[Fail][%s]\r\n" % step) - pass - - def _generate_performance_report(self): - with open(self._performance_log_file, "ab+") as f: - f.write("[Test report] Succeed: %d\r\n" % self._succeed_count) - f.write("[Test report] Failed: %d\r\n" % self._fail_count) - if self._succeed_count > 0 or self._fail_count > 0: - f.write("[Test report] Pass Rate: %f\r\n" % - (self._succeed_count/(self._fail_count+self._succeed_count))) - if self._time_cost_count > 0: - f.write("[Test report] Average time: %f\r\n" % (self._total_time/self._time_cost_count)) - f.write("[Test report] Longest time: %f\r\n" % self._longest_time) - - def execute(self): - TCActionBase.TCActionBase.execute(self) - self.result_cntx.start() - - # mandatory configurable params - try: - target_ap_num = self.target_ap_num - test_count = self.test_count - except StandardError, e: - NativeLog.add_trace_critical("Error configuration for WifiJAP script, error is %s" % e) - raise StandardError("Error configuration") - - # prepare ap list - _ap_list = [["target", None]] * target_ap_num - for _ap_prop in self.ap_list: - _ap_list.append(["AP", _ap_prop]) - - # set to correct mode first - # self._utility.set_mode([1, 2]) - - for _ap in _ap_list: - # arrange ap - _ap_type = _ap[0] - _ap_prop = _ap[1] - if _ap_type == "target": - _ap_prop = self._generate_random_ap_prop() - - for i in xrange(test_count): - # step 3 : mandatory step, join AP - _join_test_method = "Normal" - time_cost = self._utility.join_ap(_join_test_method, _ap_type, _ap_prop, self.join_delay) - # log performance to performance log file - self._logging_performance(_ap_prop["ssid"], _join_test_method, time_cost) - NativeLog.add_prompt_trace("[Step] Join AP done") - - NativeLog.add_prompt_trace("[WifiJAP] One AP Done") - - # generate report and cleanup - self._generate_performance_report() - - self.result_cntx.set_result("Succeed") - - def result_check(self, port_name, data): - TCActionBase.CommonTCActionBase.result_check(self, port_name, data) - self.result_cntx.append_data(port_name, data) - - -def main(): - pass - -if __name__ == '__main__': - main() diff --git a/components/test/TestCaseScript/IOT/__init__.py b/components/test/TestCaseScript/IOT/__init__.py deleted file mode 100755 index db0afd1fc5..0000000000 --- a/components/test/TestCaseScript/IOT/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__author__ = 'Administrator' diff --git a/components/test/TestCaseScript/MeshStress/MeshSendRecv.py b/components/test/TestCaseScript/MeshStress/MeshSendRecv.py deleted file mode 100755 index bad4619a70..0000000000 --- a/components/test/TestCaseScript/MeshStress/MeshSendRecv.py +++ /dev/null @@ -1,525 +0,0 @@ -from __future__ import division -import time -import threading -import re -import random -import os -import binascii - -from TCAction import PerformanceTCBase -from NativeLog import NativeLog -from NativeLog import HTMLGenerator -from comm import MeshPort -from Utility import Encoding - -# check frequency in second -CHECK_FREQ = 0.05 -# check timeout in seconds -CHECK_TIMEOUT = 30 -# multicast group len -MULTICAST_GROUP_LEN = 2 - - -LOG_PATH = os.path.join("..", "log") - -def _convert_to_mesh_mac_format(value_in): - value_out = "" - match_list = re.findall("([0-9a-fA-F]+)", value_in) - try: - for i in range(6): - value_out += "%02X" % int(match_list[i], base=16) - pass - except StandardError, e: - NativeLog.add_exception_log(e) - raise e - return value_out - -class SendRecvTime(threading.Thread): - def __init__(self): - threading.Thread.__init__(self) - self.setDaemon(True) - self.send_time = dict() - self.recv_time = dict() - self.send_time_lock = threading.Lock() - self.recv_time_lock = threading.Lock() - - def add_send_time(self, key, timestamp): - with self.send_time_lock: - self.send_time[key] = timestamp - - def add_recv_time(self, key, timestamp): - with self.recv_time_lock: - if key in self.recv_time.keys(): - self.recv_time[key].append(timestamp) - else: - self.recv_time[key] = [timestamp] - - def calculate(self): - # add compute delay time code here - print 'send dict len:', len(self.send_time) - print 'recv dict len:', len(self.recv_time) - recv_time_keys = self.recv_time.keys() - Max_delay_time = 0.0 - Total_delay_time = 0.0 - # for i in range(len(recv_time_keys)): - # key = recv_time_keys[i] - for key in recv_time_keys: - Total_delay_time_t = 0.0 - if isinstance(self.recv_time[key], list): - for time1 in self.recv_time[key]: - if time1 - self.send_time[key] >= Max_delay_time: - Max_delay_time = time1 - self.send_time[key] - Total_delay_time_t += (time1 - self.send_time[key]) - else: - pass - else: - if self.recv_time[key] - self.send_time[key] > Max_delay_time: - Max_delay_time = self.recv_time[key] - self.send_time[key] - Total_delay_time_t += (self.recv_time[key] - self.send_time[key]) - Total_delay_time_t += (Total_delay_time_t / len(self.recv_time[key])) - Total_delay_time += Total_delay_time_t - Avg_delay_time = Total_delay_time / len(recv_time_keys) - loss_rate = (len(self.send_time.keys()) - len(self.recv_time.keys())) / len(self.send_time.keys()) - return [Max_delay_time, Avg_delay_time, loss_rate] - pass - -class EntitySendThread(threading.Thread): - def __init__(self, port, behavior, unicast_addr, send_delay, typ, device_mac_list, server_addr, send_recv_time): - threading.Thread.__init__(self) - self.setDaemon(True) - self.recv_data_cache = "" - self.packets_sent = 0 - self.port = port - self.behavior = behavior - self.typ = typ - self.unicast_addr = unicast_addr - self.node_num = len(device_mac_list) - self.device_mac_list = list(device_mac_list) - self.server_addr = server_addr - if typ != "SERVER": - self.device_mac_list.remove(port.device_mac) - self.send_delay = send_delay - self.cache_lock = threading.Lock() - self.exit_event = threading.Event() - self.send_recv_time = send_recv_time - pass - - def data_recv_callback(self, data): - with self.cache_lock: - self.recv_data_cache += data - if self.typ == "SSC": - while True: - if self.recv_data_cache is not None: - match = re.compile(".+\+MSEND1:\d+:OK", re.DOTALL) - res = match.search(self.recv_data_cache) - index = re.search("\+MSEND1:(\d+):OK", self.recv_data_cache) - if index is not None: - time1 = time.time() - index1 = int(index.group(1)) - self.send_recv_time.add_send_time(index1, time1) - #print 'send index:', index1 - process_index = res.group().split("MSEND1") - if len(process_index) > 1: - process_index_t = len(process_index[0]) + len("MSEND1") - self.recv_data_cache = self.recv_data_cache[process_index_t:] - else: - self.recv_data_cache = self.recv_data_cache[len(res.group()):] - else: - break - else: - break - pass - - - def __server_send_packet(self, dst_addr, option_list=None, group_addr=None): - ver = 0x0 - flags = 0x0 - proto = 0x0 - index = random.randint(10000, 999999999) - if group_addr is not None: - len_t = hex(len(group_addr) * 6).split("0x") - if len(group_addr) <= 2: - option_list = "070" + len_t[1] - else: - option_list = "07" + len_t[1] - group = "" - for addr in group_addr: - group += _convert_to_mesh_mac_format(addr) - option_list += group - else: - option_list = None - if self.behavior == "broadcast": - dst_addr = "00:00:00:00:00:00" - elif self.behavior == "unicast": - if self.unicast_addr == "random": - dst_addr = random.choice(self.device_mac_list) - else: - dst_addr = self.unicast_addr - elif self.behavior == "p2p": - proto = 0x2 - if self.unicast_addr == "random": - dst_addr = random.choice(self.device_mac_list) - else: - dst_addr = self.unicast_addr - packet = MeshPort.Packet(ver=ver, flags=flags, proto=proto, - dst_addr=dst_addr, src_addr=self.server_addr, option_list=option_list, data="A" * 100, index=index) - send_data = packet.dumps - try: - self.port.socket.send(send_data) - time2 = time.time() - self.send_recv_time.add_send_time(index, time2) - except StandardError, e: - NativeLog.add_exception_log(e) - return False - - def __server_do_send(self): - if self.behavior == "broadcast": - if self.__server_send_packet(dst_addr="00:00:00:00:00:00", group_addr=None) is True: - self.packets_sent += self.node_num - elif self.behavior == "multicast": - random.shuffle(self.device_mac_list) - group_addr_list = self.device_mac_list[:MULTICAST_GROUP_LEN] - if self.__server_send_packet(dst_addr="01:00:5E:00:00:00", group_addr=group_addr_list) is True: - self.packets_sent += MULTICAST_GROUP_LEN - elif self.behavior == "unicast": - if self.__server_send_packet(dst_addr=random.choice(self.device_mac_list), group_addr=None) is True: - self.packets_sent += 1 - elif self.behavior == "p2p": - if self.__server_send_packet(dst_addr=random.choice(self.device_mac_list), group_addr=None) is True: - self.packets_sent += 1 - else: - NativeLog.add_trace_critical("unsupported behavior [%s]" % self.behavior) - self.exit() - return - - def __node_send_packet(self, dst_addr, group_addr=None): - send_data = "" - ret = False - if group_addr is not None: - len_t = hex(len(group_addr) * 6).split("0x") - if len(group_addr) <= 2: - option_list = "070" + len_t[1] - else: - option_list = "07" + len_t[1] - group = "" - for addr in group_addr: - group += _convert_to_mesh_mac_format(addr) - option_list += group - dst_addr = "01:00:5E:00:00:00" - send_data = "meshsend -S -d %s -o %s -l 100\r\n" % (dst_addr, option_list) - else: - if self.behavior == "broadcast": - dst_addr = "00:00:00:00:00:00" - send_data = "meshsend -S -d %s -l 100\r\n" % dst_addr - elif self.behavior == "unicast": - if self.unicast_addr == "random": - dst_addr = random.choice(self.device_mac_list) - else: - dst_addr = self.unicast_addr - send_data = "meshsend -S -d %s -l 100\r\n" % dst_addr - elif self.behavior == "p2p": - if self.unicast_addr == "random": - dst_addr = random.choice(self.device_mac_list) - else: - dst_addr = self.unicast_addr - send_data = "meshsend -S -d %s -t 1 -l 100\r\n" % dst_addr - try: - self.port.write(send_data) - except StandardError, e: - NativeLog.add_exception_log(e) - pass - for i in range(int(CHECK_TIMEOUT / CHECK_FREQ)): - time.sleep(CHECK_FREQ) - with self.cache_lock: - if self.recv_data_cache.find("+MESHSEND:OK") != -1: - ret = True - break - elif self.recv_data_cache.find("+MESHSEND:ERROR") != -1: - break - return ret - - - def __node_do_send(self): - if self.behavior == "broadcast": - if self.__node_send_packet("00:00:00:00:00:00", group_addr=None) is True: - self.packets_sent += self.node_num - elif self.behavior == "multicast": - random.shuffle(self.device_mac_list) - group_addr_list = self.device_mac_list[:MULTICAST_GROUP_LEN] - if self.__node_send_packet("01:00:5E:00:00:00", group_addr_list) is True: - self.packets_sent += MULTICAST_GROUP_LEN - elif self.behavior == "unicast": - if self.__node_send_packet(random.choice(self.device_mac_list), group_addr=None) is True: - self.packets_sent += 1 - elif self.behavior == "p2p": - if self.__node_send_packet(random.choice(self.device_mac_list), group_addr=None) is True: - self.packets_sent += 1 - else: - NativeLog.add_trace_critical("unsupported behavior [%s]" % self.behavior) - self.exit() - return - - def get_sent_packets(self): - return self.packets_sent - - def exit(self): - self.exit_event.set() - pass - - def run(self): - while self.exit_event.isSet() is False: - if self.typ == "SSC": - self.__node_do_send() - elif self.typ == "SERVER": - self.__server_do_send() - else: - NativeLog.add_trace_critical("type [%s] is neither SSC nor SERVER" % self.typ) - break - time.sleep(self.send_delay) - - pass - - -class EntityRecvThread(threading.Thread): - def __init__(self, port, typ, send_recv_time): - threading.Thread.__init__(self) - self.setDaemon(True) - self.recv_data_cache = "" - self.packets_recv = 0 - self.port = port - self.typ = typ - self.cache_lock = threading.Lock() - self.exit_event = threading.Event() - self.send_recv_time = send_recv_time - pass - - def data_recv_callback(self, data): - # if self.typ == "SERVER": - # NativeLog.add_prompt_trace("[data_recv_callback] server recv len %d" % len(data)) - with self.cache_lock: - self.recv_data_cache += data - pass - - def __server_do_recv(self): - while True: - if self.recv_data_cache: - data_cache = self.recv_data_cache - data_cache_hex = binascii.hexlify(data_cache) - packet_len = int(data_cache_hex[2:6], 16) - if len(self.recv_data_cache) >= packet_len: - time3 = time.time() - data_catch_t = self.recv_data_cache[:packet_len] - packet = binascii.hexlify(data_catch_t) - index3 = int(packet[-8:], 16) - self.send_recv_time.add_recv_time(index3, time3) - self.recv_data_cache = self.recv_data_cache[packet_len:] - else: - break - #self.packets_recv += 1 - else: - break - - def __node_do_recv(self): - with self.cache_lock: - while True: - if self.recv_data_cache: - match = re.search("\+MESHRECV:\d+", self.recv_data_cache) - index = re.search(",(\d+),OK", self.recv_data_cache) - res = re.compile(".+,\d+,OK", re.DOTALL) - res_t = res.search(self.recv_data_cache) - if match is not None: - time4 = time.time() - if index is not None: - index4 = int(index.group(1)) - self.send_recv_time.add_recv_time(index4, time4) - if len(res_t.group()) > 1: - process_index = len(res_t.group(0)) - self.recv_data_cache = self.recv_data_cache[process_index:] - else: - process_index = len(res_t.group()) - self.recv_data_cache = self.recv_data_cache[process_index:] - else: - break - else: - break - # self.packets_recv += 1 - else: - break - pass - - def get_recv_packets(self): - return self.packets_recv - - def exit(self): - self.exit_event.set() - pass - - def run(self): - while self.exit_event.isSet() is False: - if self.typ == "SSC": - self.__node_do_recv() - elif self.typ == "SERVER": - self.__server_do_recv() - else: - NativeLog.add_trace_critical("type [%s] is neither SSC nor SERVER" % self.typ) - break - time.sleep(CHECK_FREQ) - - pass - - -class MeshSendRecv(PerformanceTCBase.PerformanceTCBase): - def __init__(self, name, test_env, cmd_set, timeout, log_path): - PerformanceTCBase.PerformanceTCBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - self.send_config = [] - self.test_time = 0 - self.loss_rate_standard = 0.8 - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy" and cmd_set[i][0] != "": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - # load node send config - for i in range(1, len(cmd_set)): - for j in range(len(cmd_set[i][1])): - if cmd_set[i][1][j] != "": - cmd_string = "self.send_config.extend([" + cmd_set[i][1][j] + "])" - exec cmd_string - node_num = self.get_parameter("node_num") - self.recv_cb = dict.fromkeys(["SSC%s" % (x + 1) for x in range(int(node_num))] + ["GSOC1"]) - self.recv_cb_lock = threading.Lock() - pass - - def register_recv_callback(self, port_name, callback): - with self.recv_cb_lock: - if self.recv_cb[port_name] is None: - self.recv_cb[port_name] = [callback] - else: - self.recv_cb[port_name].append(callback) - pass - - def process(self): - try: - test_time = self.test_time * 60 - send_config = self.send_config - loss_rate_standard = self.loss_rate_standard - node_num = self.get_parameter("node_num") - pc_ip_list = self.get_parameter("pc_ip").split(".") - port = self.get_parameter("test_tcp_port1") - send_recv_time = SendRecvTime() - except StandardError: - return - #create server_addr - server_addr = "" - for i in range(len(pc_ip_list)): - if pc_ip_list[i] in ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]: - server_addr = server_addr + "0" + pc_ip_list[i] - else: - list_t = hex(int(pc_ip_list[i])).split("0x") - server_addr += list_t[1] - port_t = hex(port).split("0x") - port_t_list = list(port_t[1]) - server_addr = server_addr + port_t_list[2] + port_t_list[3] + port_t_list[0] + port_t_list[1] - server_port = self.test_env.get_port_by_name("GSOC1") - if server_port is None: - return - - # create thread dict - thread_dict = dict.fromkeys(["SSC%s" % (x + 1) for x in range(int(node_num))] + ["GSOC1"]) - for port_name in thread_dict: - thread_dict[port_name] = dict(zip(["tx", "rx"], [None, None])) - device_mac_list = [] - # init recv thread & register port for SSC - for port_name in ["SSC%s" % (x + 1) for x in range(int(node_num))]: - port = self.test_env.get_port_by_name(port_name) - thread_dict[port_name]["rx"] = EntityRecvThread(port, "SSC", send_recv_time) - self.register_recv_callback(port_name, thread_dict[port_name]["rx"].data_recv_callback) - device_mac_list.append(port.device_mac) - - thread_dict["GSOC1"]["rx"] = EntityRecvThread(server_port, "SERVER", send_recv_time) - self.register_recv_callback("GSOC1", thread_dict["GSOC1"]["rx"].data_recv_callback) - - # config[0]: target_name; config[1]: behavior; config[2]: destination; config[3]:send_delay; - for config in send_config: - port = self.test_env.get_port_by_name(config[0]) - name = port.name - if config[2] == "GSOC1": - dst = server_addr[:2] + ":" + server_addr[2:4] + ":" + server_addr[4:6] + ":" + server_addr[6:8] + \ - ":" + server_addr[8:10] + ":" + server_addr[10:12] - elif config[2] == "random": - dst = "random" - else: - dst = self.test_env.get_port_by_name(config[2]).device_mac - if name != "GSOC1": - server_addr = None - if config[1] == "broadcast" or config[1] == "multicast": - dst = None - typ = "SSC" if isinstance(port, MeshPort.MeshPort) is False else "SERVER" - thread_dict[name]["tx"] = EntitySendThread(port, config[1], dst, config[3], typ, device_mac_list, - server_addr, send_recv_time) - self.register_recv_callback(name, thread_dict[name]["tx"].data_recv_callback) - pass - - # start all thread - for port_name in thread_dict: - if thread_dict[port_name]["rx"] is not None: - thread_dict[port_name]["rx"].start() - if thread_dict[port_name]["tx"] is not None: - thread_dict[port_name]["tx"].start() - - # wait test time - time.sleep(test_time) - # close all send thread - for port_name in thread_dict: - if thread_dict[port_name]["tx"] is not None: - thread_dict[port_name]["tx"].exit() - thread_dict[port_name]["tx"].join() - # make sure all packet received before close recv thread - time.sleep(10) - # close all recv thread - for port_name in thread_dict: - if thread_dict[port_name]["rx"] is not None: - thread_dict[port_name]["rx"].exit() - thread_dict[port_name]["rx"].join() - - [max_delay_time, avg_delay_time, loss_rate] = send_recv_time.calculate() - - NativeLog.add_trace_critical("[Mesh Send Recv Test] MAX Delay Time is %.3f" % max_delay_time) - NativeLog.add_trace_critical("[Mesh Send Recv Test] Avg Delay Time is %.3f" % avg_delay_time) - NativeLog.add_trace_critical("[Mesh Send Recv Test] loss rate is %.2f%%" % (loss_rate * 100)) - - # set succeed if loss rate higher than required - if loss_rate < loss_rate_standard: - self.set_result("Succeed") - pass - - @Encoding.encode_utf8(3) - def result_check(self, port_name, data): - if port_name in self.recv_cb: - # if port_name == "GSOC1": - # NativeLog.add_prompt_trace("[result_check] recv GSOC1 data len %s" % len(data)) - with self.recv_cb_lock: - callback_list = self.recv_cb[port_name] - if callback_list is not None: - for callback in callback_list: - callback(data) - - # do logging - timestamp = NativeLog.generate_timestamp() - with self.sync_lock: - _formatted_data = HTMLGenerator.process_one_log_item(data, self.log_index, port_name, timestamp) - self.log_index += 1 - - self.append_to_log_file(_formatted_data) - - NativeLog.add_all_tc_log(data, port_name, timestamp) - pass - - -def main(): - pass - - -if __name__ == '__main__': - main() diff --git a/components/test/TestCaseScript/MeshStress/__init__.py b/components/test/TestCaseScript/MeshStress/__init__.py deleted file mode 100755 index 6e94287c45..0000000000 --- a/components/test/TestCaseScript/MeshStress/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__all__ = ["StableCase1"] \ No newline at end of file diff --git a/components/test/TestCaseScript/SSLTest/Capability.py b/components/test/TestCaseScript/SSLTest/Capability.py deleted file mode 100755 index efdb6eeb9d..0000000000 --- a/components/test/TestCaseScript/SSLTest/Capability.py +++ /dev/null @@ -1,90 +0,0 @@ - - -class SSLCapability(object): - CAPABILITY_TYPE = ["version", "cipher_suite", "fragment_size", # for hello capability negotiation - "verify_server", "verify_client", # if support verify server/client - "key_algorithm", "key_encoding", "pem_encryption", # what kind of private it supports - "certificate_encoding", "certificate_digest", # what kind of certificate it supports - ] - SSL_TYPE = ("TargetClient", "TargetServer", "PCClient", "PCServer") - - def __init__(self, typ, **kwargs): - assert typ in self.SSL_TYPE - self.type = typ - self.capability = dict.fromkeys(self.CAPABILITY_TYPE, None) - for kw in kwargs: - self.capability[kw] = kwargs[kw] - for kw in self.capability: - assert self.capability[kw] is not None - pass - - def get(self, kw): - return self.capability[kw] - - def set(self, **kwargs): - for kw in kwargs: - self.capability[kw] = kwargs[kw] - pass - - -class TargetSSLCapability(SSLCapability): - DEFAULT_CAPABILITY = { - "version": ["SSLv23_2"], - "cipher_suite": ["TLS_RSA_WITH_AES_128_CBC_SHA", - "TLS_RSA_WITH_AES_256_CBC_SHA", - "TLS_RSA_WITH_RC4_128_SHA", - "TLS_RSA_WITH_RC4_128_MD5"], - "fragment_size": [2048, 4096, 8192], - "verify_server": True, - "verify_client": False, - "key_algorithm": ["RSA512", "RSA1024", "RSA2048", "RSA4096"], - "key_encoding": ["PEM", "DER"], - "pem_encryption": [None, "aes128", "aes256"], - "certificate_encoding": ["PEM", "DER"], - "certificate_digest": ["md5", "sha1", "sha256", "sha384", "sha512"], - } - - def __init__(self, typ, **kwargs): - assert typ == "TargetClient" or typ == "TargetServer" - capability = dict(self.DEFAULT_CAPABILITY) - for kw in kwargs: - capability[kw] = kwargs[kw] - SSLCapability.__init__(self, typ, **capability) - pass - pass - - -class PCSSLCapability(SSLCapability): - DEFAULT_CAPABILITY = { - "version": ["SSLv23", "SSLv20", "SSLv30", "TLSv10", "TLSv11", "TLSv12"], - "cipher_suite": ["TLS_RSA_WITH_AES_128_CBC_SHA", - "TLS_RSA_WITH_AES_256_CBC_SHA", - "TLS_RSA_WITH_RC4_128_SHA", - "TLS_RSA_WITH_RC4_128_MD5", - "TLS_DH_DSS_WITH_AES_128_CBC_SHA", - "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"], - "fragment_size": [16384], - "verify_server": True, - "verify_client": True, - "key_algorithm": ["RSA512", "RSA1024", "RSA2048", "RSA4096"], - "key_encoding": ["PEM"], - "pem_encryption": [None], - "certificate_encoding": ["PEM"], - "certificate_digest": ["md5", "sha1", "sha256", "sha384", "sha512"], - } - - def __init__(self, typ): - assert typ == "PCClient" or typ == "PCServer" - SSLCapability.__init__(self, typ, **self.DEFAULT_CAPABILITY) - pass - pass - - -def main(): - pc = PCSSLCapability("PCClient") - target = TargetSSLCapability("TargetClient") - pass - - -if __name__ == '__main__': - main() diff --git a/components/test/TestCaseScript/SSLTest/ConfigUtility.py b/components/test/TestCaseScript/SSLTest/ConfigUtility.py deleted file mode 100755 index f36fe44fe9..0000000000 --- a/components/test/TestCaseScript/SSLTest/ConfigUtility.py +++ /dev/null @@ -1,333 +0,0 @@ -from PKI import PKIDict, PKIItem -import Parameter - - -def multiply_2_lists(list1, list2): - def make_list(li): - if not isinstance(li, list): - li = [li] - return li - list1 = make_list(list1) - list2 = make_list(list2) - ret = [] - for a in list1: - for b in list2: - ret.append(make_list(a) + make_list(b)) - return ret - - -def list_multiply(list1, *args): - ret = list1 - for arg in args: - ret = multiply_2_lists(ret, arg) - return ret - - -def list_and(list1, list2): - ret = [] - for item in list1: - if item in list2: - ret.append(item) - return ret - - -class ComputeResult(object): - NEGOTIATION_CONFIG = ["client_version", "client_cipher_suite", "client_fragment_size", - "server_version", "server_cipher_suite", "server_fragment_size"] - CERT_KEY_CONFIG = ["verify_server", "verify_client", - "client_trust_anchor", "client_certificate", "client_key", - "server_trust_anchor", "server_certificate", "server_key"] - - TYPE_CONTEXT = "context" - TYPE_NEGOTIATION = "negotiation" - TYPE_CERT_KEY = "cert_key" - TYPE_SEND_PARAM = "send_param" - - # results - SUCCEED = 0 - CREATE_CONTEXT_FAIL = 1 - HANDSHAKE_FAIL = 2 - CERT_KEY_FAIL = 3 - - def __init__(self, client_capability, server_capability): - self.client_capability = client_capability - self.server_capability = server_capability - pass - - @staticmethod - def __check_cert(cert, capability, check_encoding=True): - ret = True - if cert.name is not None: - if check_encoding is True: - if cert.digest not in capability.get("certificate_digest") \ - or cert.key_algorithm not in capability.get("key_algorithm") \ - or cert.file_encoding not in capability.get("certificate_encoding"): - ret = False - else: - if cert.digest not in capability.get("certificate_digest") \ - or cert.key_algorithm not in capability.get("key_algorithm"): - ret = False - return ret - - @staticmethod - def __check_key(key, capability, check_encoding=True): - ret = True - if key.name is not None: - if check_encoding is True: - if key.algorithm not in capability.get("key_algorithm") \ - or key.file_encoding not in capability.get("key_encoding") \ - or key.file_encryption not in capability.get("pem_encryption"): - ret = False - else: - if key.algorithm not in capability.get("key_algorithm") \ - or key.file_encryption not in capability.get("pem_encryption"): - ret = False - return ret - - # compute result functions - def check_context(self, config): - result = self.SUCCEED - check_list = [(self.__check_cert, PKIItem.Certificate(config["client_trust_anchor"]), - self.client_capability), - (self.__check_cert, PKIItem.Certificate(config["client_certificate"]), - self.client_capability), - (self.__check_key, PKIItem.PrivateKey(config["client_key"]), - self.client_capability), - (self.__check_cert, PKIItem.Certificate(config["server_trust_anchor"]), - self.server_capability), - (self.__check_cert, PKIItem.Certificate(config["server_certificate"]), - self.server_capability), - (self.__check_key, PKIItem.PrivateKey(config["server_key"]), - self.server_capability)] - for _check in check_list: - if _check[0](_check[1], _check[2]) is False: - result = self.CREATE_CONTEXT_FAIL - break - return result - - def check_negotiation_param(self, config): - result = self.SUCCEED - # first check version - while True: - if Parameter.VERSION[config["client_version"]]\ - & Parameter.VERSION[config["server_version"]] == 0: - result = self.HANDSHAKE_FAIL - break - # check cipher suite - supported_cipher_suite = list_and(self.client_capability.get("cipher_suite"), - self.server_capability.get("cipher_suite")) - if config["client_cipher_suite"] not in supported_cipher_suite\ - or config["server_cipher_suite"] not in supported_cipher_suite\ - or config["client_cipher_suite"] != config["server_cipher_suite"]: - result = self.HANDSHAKE_FAIL - break - break - return result - - # check cert key, if it can be supported by both client and server, if it matches - def __check_cert_key_content(self, cert, key): - if self.__check_cert(cert, self.client_capability, check_encoding=False) is True\ - and self.__check_cert(cert, self.server_capability, check_encoding=False) is True \ - and self.__check_key(key, self.client_capability, check_encoding=False) is True \ - and self.__check_key(key, self.server_capability, check_encoding=False) is True \ - and key.name.find(cert.private_key) != -1: - result = True - else: - result = False - return result - - def __verify_ca(self, ca, cert, capability): - result = True - while True: - # if ca supported - if self.__check_cert(ca, capability) is False: - result = False - break - # check if ca in cert chain - try: - index = cert.cert_chain.index(ca.name) - except StandardError: - result = False - break - - # for pem cert, it contains cert chain to issuer, any cert in chain works - # der cert do not contain cert chain - # only der root cert verify L1 cert and root cert works - if cert.file_encoding == "DER": - if len(cert.cert_chain) > 2 and index != len(cert.cert_chain) - 1: - result = False - break - # check if all certs in before trust anchor supported - for cert_name in cert.cert_chain[1:index]: - _cert = PKIItem.Certificate(cert_name + ".pem") - if self.__check_cert(_cert, capability) is False: - result = False - break - break - return result - - def __check_verify_client(self, client_cert, client_key, server_ca): - result = self.__check_cert_key_content(client_cert, client_key) - if result is True: - result = self.__verify_ca(server_ca, client_cert, self.server_capability) - return result - - def __check_verify_server(self, client_ca, server_cert): - return self.__verify_ca(client_ca, server_cert, self.client_capability) - - def check_cert_key(self, config): - result = self.SUCCEED - while True: # break if when anything failed - if (config["verify_server"] is True and self.client_capability.get("verify_server") is False) \ - or (config["verify_client"] is True and - (self.server_capability.get("verify_client") is False or - self.client_capability.get("verify_client") is False)): - result = self.CERT_KEY_FAIL - break - - server_cert = PKIItem.Certificate(config["server_certificate"]) - server_key = PKIItem.PrivateKey(config["server_key"]) - server_ca = PKIItem.Certificate(config["server_trust_anchor"]) - client_cert = PKIItem.Certificate(config["client_certificate"]) - client_key = PKIItem.PrivateKey(config["client_key"]) - client_ca = PKIItem.Certificate(config["client_trust_anchor"]) - # always check server cert key - if self.__check_cert_key_content(server_cert, server_key) is False: - result = self.CERT_KEY_FAIL - break - # if require to verify server - if config["verify_server"] is True: - if self.__check_verify_server(client_ca, server_cert) is False: - result = self.CERT_KEY_FAIL - break - # if require to verify client - if config["verify_client"] is True: - if self.__check_verify_client(client_cert, client_key, server_ca) is False: - result = self.CERT_KEY_FAIL - break - break - return result - - CHECK_FUNC = { - TYPE_CONTEXT: check_context, - TYPE_NEGOTIATION: check_negotiation_param, - TYPE_CERT_KEY: check_cert_key, - } - CONFIG_KEY = { - TYPE_CONTEXT: CERT_KEY_CONFIG, - TYPE_NEGOTIATION: NEGOTIATION_CONFIG, - TYPE_CERT_KEY: CERT_KEY_CONFIG, - } - - def compute_result(self, typ, config_list): - succeed_list = [] - fail_list = [] - for config in config_list: - if self.CHECK_FUNC[typ](self, dict(zip(self.CONFIG_KEY[typ], config))) != self.SUCCEED: - fail_list.append(config) - else: - succeed_list.append(config) - return succeed_list, fail_list - pass - - -class GenerateTestConfig(ComputeResult): - TEST_CONFIG = ComputeResult.NEGOTIATION_CONFIG + \ - ComputeResult.CERT_KEY_CONFIG - - def __init__(self, client_capability, server_capability): - ComputeResult.__init__(self, client_capability, server_capability) - self.key_dict = PKIDict.PKIDict.KEY_DICT - self.cert_dict = PKIDict.PKIDict.CERT_DICT - pass - - def generate_negotiation_config(self): - _config = list_multiply(self.client_capability.get("version"), - self.client_capability.get("cipher_suite"), - self.client_capability.get("fragment_size"), - self.server_capability.get("version"), - self.server_capability.get("cipher_suite"), - self.server_capability.get("fragment_size")) - return self.compute_result(self.TYPE_NEGOTIATION, _config) - - def __choose_cert_key(self, verify_server, verify_client, - client_ca_opt, client_cert_key_opt, - server_ca_opt, server_cert_key_opt): - pass - - # CERT_KEY_CONFIG = ["verify_server", "verify_client", - # "client_trust_anchor", "client_certificate", "client_key", - # "server_trust_anchor", "server_certificate", "server_key"] - def generate_cert_key_config(self): - # first handle not verify certificate case - _config_list = [] - for cert in PKIDict.PKIDict.CERT_DICT: - for key in PKIDict.PKIDict.KEY_DICT: - _config_list.append([False, False, None, None, None, None, cert, key]) - cert_key_succeed, context_fail = self.compute_result(self.TYPE_CONTEXT, _config_list) - cert_key_succeed, cert_key_fail = self.compute_result(self.TYPE_CERT_KEY, cert_key_succeed) - key_cert_pair = [[x[6], x[7]] for x in cert_key_succeed] - # for succeed config, do server cert verify - _config_list = [] - for _config in cert_key_succeed: - for cert in PKIDict.PKIDict.CERT_DICT: - _config_list.append([True, False, cert, None, None, - None, _config[6], _config[7]]) - _cert_key_succeed, _context_fail = self.compute_result(self.TYPE_CONTEXT, _config_list) - context_fail += _context_fail - _cert_key_succeed, _cert_key_fail = self.compute_result(self.TYPE_CERT_KEY, _cert_key_succeed) - cert_key_fail += _cert_key_fail - cert_key_succeed += _cert_key_succeed - # for succeed config, do client verify - _config_list = [] - for _config in _cert_key_succeed: - for key_cert in key_cert_pair: - _config_list.append([True, True, _config[2], key_cert[0], key_cert[1], - key_cert[0], _config[6], _config[7]]) - _cert_key_succeed, _context_fail = self.compute_result(self.TYPE_CONTEXT, _config_list) - context_fail += _context_fail - _cert_key_succeed, _cert_key_fail = self.compute_result(self.TYPE_CERT_KEY, _cert_key_succeed) - cert_key_fail += _cert_key_fail - cert_key_succeed += _cert_key_succeed - # only verify client not verify server - _config_list = [] - for _config in _cert_key_succeed: - _config_list.append([False, True, None, - _config[3], _config[4], _config[5], _config[6], _config[7]]) - _cert_key_succeed, _context_fail = self.compute_result(self.TYPE_CONTEXT, _config_list) - context_fail += _context_fail - _cert_key_succeed, _cert_key_fail = self.compute_result(self.TYPE_CERT_KEY, _cert_key_succeed) - cert_key_fail += _cert_key_fail - cert_key_succeed += _cert_key_succeed - return cert_key_succeed, context_fail, cert_key_fail - - -class ConfigUtility(GenerateTestConfig): - # test config - _TEST_CONFIG_DICT_KEY = ("config", "result") - - def __init__(self, client_capability, server_capability): - GenerateTestConfig.__init__(self, client_capability, server_capability) - pass - - def get_all_test_config(self): - negotiation_succeed, negotiation_fail = self.generate_negotiation_config() - cert_key_succeed, context_fail, cert_key_fail = self.generate_cert_key_config() - succeed_config = list_multiply(negotiation_succeed, cert_key_succeed) - context_fail_config = list_multiply([negotiation_succeed[0]], context_fail) - negotiation_fail_config = list_multiply(negotiation_fail, [cert_key_succeed[0]]) - cert_key_fail_config = list_multiply([negotiation_succeed[0]], cert_key_fail) - return dict(zip(["succeed", "context_fail", "negotiation_fail", "cert_key_fail"], - [[dict(zip(self.TEST_CONFIG, x)) for x in succeed_config], - [dict(zip(self.TEST_CONFIG, x)) for x in context_fail_config], - [dict(zip(self.TEST_CONFIG, x)) for x in negotiation_fail_config], - [dict(zip(self.TEST_CONFIG, x)) for x in cert_key_fail_config]])) - pass - - -def main(): - pass - - -if __name__ == '__main__': - main() diff --git a/components/test/TestCaseScript/SSLTest/Parameter.py b/components/test/TestCaseScript/SSLTest/Parameter.py deleted file mode 100755 index 1670c5fd29..0000000000 --- a/components/test/TestCaseScript/SSLTest/Parameter.py +++ /dev/null @@ -1,56 +0,0 @@ - - -VERSION = { - "SSLv23": 0x1F, - "SSLv23_2": 0x1C, # current target ssl implementation do not support SSLv20 and TLSv12 - "SSLv20": 0x01, - "SSLv30": 0x02, - "TLSv10": 0x04, - "TLSv11": 0x08, - "TLSv12": 0x10, -} - - -CIPHER_SUITE = { - # supported algorithm - "TLS_RSA_WITH_AES_128_CBC_SHA": "AES128-SHA", - "TLS_RSA_WITH_AES_256_CBC_SHA": "AES256-SHA", - "TLS_RSA_WITH_RC4_128_SHA": "RC4-SHA", - "TLS_RSA_WITH_RC4_128_MD5": "RC4-MD5", - "TLS_DH_DSS_WITH_AES_128_CBC_SHA": "DH-DSS-AES128-SHA", - "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256": "ECDHE-RSA-AES128-GCM-SHA256", -} - - -FRAGMENT_SIZE = { - "SIZE_DEFAULT": 0, - "SIZE_512": 512, - "SIZE_1024": 1024, - "SIZE_2048": 2048, - "SIZE_4096": 4096, - "SIZE_8192": 8192, -} - - -VERIFY_OPTION = { - "NOT_VERIFY": "NOT_VERIFY", - "VERIFY": "VERIFY", -} - - -SEND_OPTION = { - "MAX_SEND_SIZE_512": 512, - "MAX_SEND_SIZE_1K": 1024, - "MAX_SEND_SIZE_2K": 2048, - "MAX_SEND_SIZE_4K": 4096, - "MAX_SEND_SIZE_8K": 8192, - "MAX_SEND_SIZE_16K": 16384, -} - - -def main(): - pass - - -if __name__ == '__main__': - main() diff --git a/components/test/TestCaseScript/SSLTest/SSLHandler.py b/components/test/TestCaseScript/SSLTest/SSLHandler.py deleted file mode 100644 index 7fe19b3cef..0000000000 --- a/components/test/TestCaseScript/SSLTest/SSLHandler.py +++ /dev/null @@ -1,498 +0,0 @@ -import socket -import ssl -import os -import re -import time -import threading - -import Parameter -from PKI import PKIDict -from PKI import PKIItem -from NativeLog import NativeLog - - -class SerialPortCheckFail(StandardError): - pass - - -class SSLHandlerFail(StandardError): - pass - - -class PCFail(StandardError): - pass - - -class TargetFail(StandardError): - pass - - -def ssl_handler_wrapper(handler_type): - if handler_type == "PC": - exception_type = PCFail - elif handler_type == "Target": - exception_type = TargetFail - else: - exception_type = None - - def _handle_func(func): - def _handle_args(*args, **kwargs): - try: - ret = func(*args, **kwargs) - except StandardError, e: - NativeLog.add_exception_log(e) - raise exception_type(str(e)) - return ret - return _handle_args - return _handle_func - - -class SerialPort(object): - def __init__(self, tc_action, port_name): - self.tc_action = tc_action - self.port_name = port_name - - def flush(self): - self.tc_action.flush_data(self.port_name) - - def write_line(self, data): - self.tc_action.serial_write_line(self.port_name, data) - - def check(self, condition, timeout=10): - if self.tc_action.check_response(self.port_name, condition, timeout) is False: - raise SerialPortCheckFail("serial port check fail, condition is %s" % condition) - - def read_data(self): - return self.tc_action.serial_read_data(self.port_name) - pass - - -class SSLHandler(object): - # ssl operation timeout is 30 seconds - TIMEOUT = 30 - - def __init__(self, typ, config, serial_port): - self.type = typ - self.config = config - self.timeout = self.TIMEOUT - self.serial_port = serial_port - self.accept_thread = None - self.data_validation = False - - def set_timeout(self, timeout): - self.timeout = timeout - - def init_context(self): - pass - - def connect(self, remote_ip, remote_port, local_ip=0, local_port=0): - pass - - def listen(self, local_port=0, local_ip=0): - pass - - def send(self, size, data): - pass - - def recv(self, length, timeout): - pass - - def set_data_validation(self, validation): - pass - - def close(self): - if self.accept_thread is not None: - self.accept_thread.exit() - self.accept_thread.join(5) - pass - - -class TargetSSLHandler(SSLHandler): - def __init__(self, typ, config, serial_port): - SSLHandler.__init__(self, typ, config, serial_port) - self.ssl_id = None - self.server_id = None - - @ssl_handler_wrapper("Target") - def init_context(self): - self.serial_port.flush() - self.serial_port.write_line("soc -T") - self.serial_port.check("+CLOSEALL") - - if self.type == "client": - version = Parameter.VERSION[self.config["client_version"]] - fragment = self.config["client_fragment_size"] - ca = self.config["client_trust_anchor"] - cert = self.config["client_certificate"] - key = self.config["client_key"] - verify_required = 0x01 if self.config["verify_server"] is True else 0x00 - context_type = 1 - else: - version = Parameter.VERSION[self.config["server_version"]] - fragment = self.config["server_fragment_size"] - ca = self.config["server_trust_anchor"] - cert = self.config["server_certificate"] - key = self.config["server_key"] - verify_required = 0x02 if self.config["verify_client"] is True else 0x00 - context_type = 2 - ssc_cmd = "ssl -I -t %u -r %u -v %u -o %u" % (context_type, fragment, version, verify_required) - - if ca is not None: - _index = PKIDict.PKIDict.CERT_DICT[ca] - ssc_cmd += " -a %d" % _index - if cert is not None: - _index = PKIDict.PKIDict.CERT_DICT[cert] - ssc_cmd += " -c %d" % _index - if key is not None: - _index = PKIDict.PKIDict.KEY_DICT[key] - ssc_cmd += " -k %d" % _index - # write command and check result - self.serial_port.flush() - self.serial_port.write_line(ssc_cmd) - self.serial_port.check(["+SSL:OK", "AND", "!+SSL:ERROR"]) - - @ssl_handler_wrapper("Target") - def connect(self, remote_ip, remote_port, local_ip=0, local_port=0): - self.serial_port.flush() - self.serial_port.write_line("soc -B -t SSL -i %s -p %s" % (local_ip, local_port)) - self.serial_port.check(["OK", "AND", "!ERROR"]) - self.serial_port.flush() - self.serial_port.write_line("soc -C -s 0 -i %s -p %s" % (remote_ip, remote_port)) - self.serial_port.check(["OK", "AND", "!ERROR"], timeout=30) - self.ssl_id = 0 - pass - - def accept_succeed(self): - self.ssl_id = 1 - - class Accept(threading.Thread): - def __init__(self, serial_port, succeed_cb): - threading.Thread.__init__(self) - self.setDaemon(True) - self.serial_port = serial_port - self.succeed_cb = succeed_cb - self.exit_flag = threading.Event() - - def run(self): - while self.exit_flag.isSet() is False: - try: - self.serial_port.check("+ACCEPT:", timeout=1) - self.succeed_cb() - break - except StandardError: - pass - - def exit(self): - self.exit_flag.set() - - @ssl_handler_wrapper("Target") - def listen(self, local_port=0, local_ip=0): - self.serial_port.flush() - self.serial_port.write_line("soc -B -t SSL -i %s -p %s" % (local_ip, local_port)) - self.serial_port.check(["OK", "AND", "!ERROR"]) - self.serial_port.flush() - self.serial_port.write_line("soc -L -s 0") - self.serial_port.check(["OK", "AND", "!ERROR"]) - self.server_id = 0 - self.accept_thread = self.Accept(self.serial_port, self.accept_succeed) - self.accept_thread.start() - pass - - @ssl_handler_wrapper("Target") - def send(self, size=10, data=None): - if data is not None: - size = len(data) - self.serial_port.flush() - self.serial_port.write_line("soc -S -s %s -l %s" % (self.ssl_id, size)) - self.serial_port.check(["OK", "AND", "!ERROR"]) - pass - - @ssl_handler_wrapper("Target") - def recv(self, length, timeout=SSLHandler.TIMEOUT): - pattern = re.compile("\+RECV:\d+,(\d+)\r\n") - data_len = 0 - data = "" - time1 = time.time() - while time.time() - time1 < timeout: - data += self.serial_port.read_data() - if self.data_validation is True: - if "+DATA_ERROR" in data: - raise SSLHandlerFail("target data validation fail") - while True: - match = pattern.search(data) - if match is None: - break - else: - data_len += int(match.group(1)) - data = data[data.find(match.group())+len(match.group()):] - if data_len >= length: - result = True - break - else: - result = False - if result is False: - raise SSLHandlerFail("Target recv fail") - - def set_data_validation(self, validation): - self.data_validation = validation - self.serial_port.flush() - self.serial_port.write_line("soc -V -s %s -o %s" % (self.ssl_id, 1 if validation is True else 0)) - self.serial_port.check(["OK", "AND", "!ERROR"]) - - @ssl_handler_wrapper("Target") - def close(self): - SSLHandler.close(self) - self.serial_port.flush() - self.serial_port.write_line("ssl -D") - self.serial_port.check(["+SSL:OK", "OR", "+SSL:ERROR"]) - self.serial_port.write_line("soc -T") - self.serial_port.check("+CLOSEALL") - pass - - pass - - -def calc_hash(index): - return (index & 0xffffffff) % 83 + (index & 0xffffffff) % 167 - - -def verify_data(data, start_index): - for i, c in enumerate(data): - if ord(c) != calc_hash(start_index + i): - NativeLog.add_trace_critical("[Data Validation Error] target sent data index %u is error." - " Sent data is %x, should be %x" - % (start_index + i, ord(c), calc_hash(start_index + i))) - return False - return True - - -def make_validation_data(length, start_index): - return bytes().join([chr(calc_hash(start_index + i)) for i in range(length)]) - - -class PCSSLHandler(SSLHandler): - PROTOCOL_MAPPING = { - "SSLv23": ssl.PROTOCOL_SSLv23, - "SSLv23_2": ssl.PROTOCOL_SSLv23, - "SSLv20": ssl.PROTOCOL_SSLv2, - "SSLv30": ssl.PROTOCOL_SSLv3, - "TLSv10": ssl.PROTOCOL_TLSv1, - "TLSv11": ssl.PROTOCOL_TLSv1_1, - "TLSv12": ssl.PROTOCOL_TLSv1_2, - } - CERT_FOLDER = os.path.join(".", "PKI", PKIDict.PKIDict.CERT_FOLDER) - KEY_FOLDER = os.path.join(".", "PKI", PKIDict.PKIDict.KEY_FOLDER) - - def __init__(self, typ, config, serial_port): - SSLHandler.__init__(self, typ, config, serial_port) - self.ssl_context = None - self.ssl = None - self.server_sock = None - self.send_index = 0 - self.recv_index = 0 - - class InitContextThread(threading.Thread): - def __init__(self, handler, version, cipher_suite, ca, cert, key, verify_required, remote_cert): - threading.Thread.__init__(self) - self.setDaemon(True) - self.handler = handler - self.version = version - self.cipher_suite = cipher_suite - self.ca = ca - self.cert = cert - self.key = key - self.verify_required = verify_required - self.remote_cert = remote_cert - pass - - @staticmethod - def handle_cert(cert_file, ca_file): - cert = PKIItem.Certificate() - cert.parse_file(cert_file) - ca = PKIItem.Certificate() - ca.parse_file(ca_file) - if cert.file_encoding == "PEM" and ca.name in cert.cert_chain: - cert_chain_t = cert.cert_chain[1:cert.cert_chain.index(ca.name)] - ret = ["%s.pem" % c for c in cert_chain_t] - else: - ret = [] - return ret - - def run(self): - try: - ssl_context = ssl.SSLContext(self.version) - # cipher suite - ssl_context.set_ciphers(self.cipher_suite) - if self.ca is not None: - ssl_context.load_verify_locations(cafile=os.path.join(self.handler.CERT_FOLDER, self.ca)) - # python ssl can't verify cert chain, don't know why - # need to load cert between cert and ca for pem (pem cert contains cert chain) - if self.remote_cert is not None: - cert_chain = self.handle_cert(self.remote_cert, self.ca) - for c in cert_chain: - NativeLog.add_trace_info("load ca chain %s" % c) - ssl_context.load_verify_locations(cafile=os.path.join(self.handler.CERT_FOLDER, c)) - if self.cert is not None: - cert = os.path.join(self.handler.CERT_FOLDER, self.cert) - key = os.path.join(self.handler.KEY_FOLDER, self.key) - ssl_context.load_cert_chain(cert, keyfile=key) - if self.verify_required is True: - ssl_context.verify_mode = ssl.CERT_REQUIRED - else: - ssl_context.verify_mode = ssl.CERT_NONE - self.handler.ssl_context = ssl_context - except StandardError, e: - NativeLog.add_exception_log(e) - pass - pass - - @ssl_handler_wrapper("PC") - def init_context(self): - if self.type == "client": - version = self.PROTOCOL_MAPPING[self.config["client_version"]] - cipher_suite = Parameter.CIPHER_SUITE[self.config["client_cipher_suite"]] - ca = self.config["client_trust_anchor"] - cert = self.config["client_certificate"] - key = self.config["client_key"] - verify_required = self.config["verify_server"] - remote_cert = self.config["server_certificate"] - else: - version = self.PROTOCOL_MAPPING[self.config["server_version"]] - cipher_suite = Parameter.CIPHER_SUITE[self.config["server_cipher_suite"]] - ca = self.config["server_trust_anchor"] - cert = self.config["server_certificate"] - key = self.config["server_key"] - verify_required = self.config["verify_client"] - remote_cert = self.config["client_certificate"] - - _init_context = self.InitContextThread(self, version, cipher_suite, ca, cert, key, verify_required, remote_cert) - _init_context.start() - _init_context.join(5) - if self.ssl_context is None: - raise StandardError("Init Context Fail") - - pass - - @ssl_handler_wrapper("PC") - def connect(self, remote_ip, remote_port, local_ip=0, local_port=0): - sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) - # reuse socket in TIME_WAIT state - sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - sock.settimeout(self.timeout) - sock.bind((local_ip, local_port)) - self.ssl = self.ssl_context.wrap_socket(sock) - self.ssl.connect((remote_ip, remote_port)) - pass - - def accept_succeed(self, ssl_new): - ssl_new.settimeout(self.timeout) - self.ssl = ssl_new - - class Accept(threading.Thread): - def __init__(self, server_sock, ssl_context, succeed_cb): - threading.Thread.__init__(self) - self.setDaemon(True) - self.server_sock = server_sock - self.ssl_context = ssl_context - self.succeed_cb = succeed_cb - self.exit_flag = threading.Event() - - def run(self): - while self.exit_flag.isSet() is False: - try: - new_socket, addr = self.server_sock.accept() - ssl_new = self.ssl_context.wrap_socket(new_socket, server_side=True) - self.succeed_cb(ssl_new) - break - except StandardError: - pass - pass - - def exit(self): - self.exit_flag.set() - - @ssl_handler_wrapper("PC") - def listen(self, local_port=0, local_ip=0): - self.server_sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) - # reuse socket in TIME_WAIT state - self.server_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - self.server_sock.settimeout(1) - self.server_sock.bind((local_ip, local_port)) - self.server_sock.listen(5) - self.accept_thread = self.Accept(self.server_sock, self.ssl_context, self.accept_succeed) - self.accept_thread.start() - pass - - @ssl_handler_wrapper("PC") - def send(self, size=10, data=None): - if data is None: - self.ssl.send(make_validation_data(size, self.send_index)) - if self.data_validation is True: - self.send_index += size - else: - self.ssl.send(data) - - @ssl_handler_wrapper("PC") - def recv(self, length, timeout=SSLHandler.TIMEOUT, data_validation=False): - time1 = time.time() - data_len = 0 - while time.time() - time1 < timeout: - data = self.ssl.read() - - if data_validation is True and len(data) > 0: - if verify_data(data, self.recv_index) is False: - raise SSLHandlerFail("PC data validation fail, index is %s" % self.recv_index) - self.recv_index += len(data) - data_len += len(data) - if data_len >= length: - result = True - break - else: - result = False - if result is False: - raise SSLHandlerFail("PC recv fail") - - def set_data_validation(self, validation): - self.data_validation = validation - - @ssl_handler_wrapper("PC") - def close(self): - SSLHandler.close(self) - if self.ssl is not None: - self.ssl.close() - self.ssl = None - if self.server_sock is not None: - self.server_sock.close() - self.server_sock = None - del self.ssl_context - - -def main(): - ssl_context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) - # cipher suite - ssl_context.set_ciphers("AES256-SHA") - ssl_context.load_cert_chain("D:\workspace\\auto_test_script\PKI\Certificate\\" - "L2CertRSA512sha1_L1CertRSA512sha1_RootCertRSA512sha1.pem", - keyfile="D:\workspace\\auto_test_script\PKI\Key\PrivateKey2RSA512.pem") - ssl_context.verify_mode = ssl.CERT_NONE - server_sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) - # reuse socket in TIME_WAIT state - server_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - server_sock.settimeout(100) - server_sock.bind(("192.168.111.5", 443)) - server_sock.listen(5) - while True: - try: - new_socket, addr = server_sock.accept() - ssl_new = ssl_context.wrap_socket(new_socket, server_side=True) - print "server connected" - break - except StandardError: - pass - - -pass - - -if __name__ == '__main__': - main() diff --git a/components/test/TestCaseScript/SSLTest/SSLHandshake.py b/components/test/TestCaseScript/SSLTest/SSLHandshake.py deleted file mode 100755 index 5eb68c3503..0000000000 --- a/components/test/TestCaseScript/SSLTest/SSLHandshake.py +++ /dev/null @@ -1,240 +0,0 @@ -import os -import random -import time -import re - -from TCAction import TCActionBase -from TCAction import PerformanceTCBase -from NativeLog import NativeLog, HTMLGenerator -from Utility import MakeFolder - -import ConfigUtility -import Capability -import SSLHandler - -LOG_FOLDER = os.path.join("AT_LOG", "TEMP") - -HEAP_SIZE_LIMIT = 30000 - - -class SSLHandshake(PerformanceTCBase.PerformanceTCBase): - - def __init__(self, name, test_env, cmd_set, timeout=15, log_path=TCActionBase.LOG_PATH): - PerformanceTCBase.PerformanceTCBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - self.client_type = None - self.server_type = None - self.client_capability = dict() - self.server_capability = dict() - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - timestamp = time.strftime("%d%H%M%S", time.localtime()) - folder = MakeFolder.make_folder(os.path.join(LOG_FOLDER, "SSLHandshake_%s" % timestamp)) - self.tested_log = os.path.join(folder, "SSLHandshakeTested.log") - self.failed_log = os.path.join(folder, "SSLHandshakeFailed.log") - self.memory_track_log = os.path.join(folder, "SSLHandshakeMemTrack.log") - self.succeed_log = os.path.join(folder, "SSLHandshakeSucceed.log") - # store test result for failed config - self.failed_log2 = os.path.join(folder, "SSLHandshakeFailed2.log") - self.succeed_log2 = os.path.join(folder, "SSLHandshakeSucceed2.log") - - self.heap_size_pattern = re.compile("\+FREEHEAP:(\d+)\r\n") - - @staticmethod - def close(client, server): - try: - client.close() - except StandardError: - pass - try: - server.close() - except StandardError: - pass - - def query_heap_size(self, scenario="idle"): - self.flush_data("SSC1") - self.serial_write_line("SSC1", "ram -H") - match = self.check_regular_expression("SSC1", self.heap_size_pattern) - if match is None: - NativeLog.add_trace_critical("No response for SSC ram command") - else: - heap_size = int(match.group(1)) - self.log_memory("[heap size][%s] %s" % (scenario, heap_size)) - if heap_size < HEAP_SIZE_LIMIT and scenario == "idle": - NativeLog.add_trace_critical("[HeapSize] %s" % heap_size) - - pass - - def prepare_handshake_test(self): - # check if connected - self.flush_data("SSC1") - self.serial_write_line("SSC1", "sta -Q") - if self.check_response("SSC1", "+JAP:CONNECTED,") is False: - ap_ssid = self.get_parameter("ap_ssid") - ap_password = self.get_parameter("ap_password") - self.serial_write_line("SSC1", "sta -C -s %s -p %s" % (ap_ssid, ap_password)) - self.check_response("SSC1", "+JAP:CONNECTED,") - self.query_heap_size() - - @staticmethod - def log_data_to_file(file_name, data): - with open(file_name, "ab+") as f: - f.write(data+"\r\n") - - def log_test_config(self, data): - # append to log - with self.sync_lock: - _formatted_data = HTMLGenerator.process_one_log_item(data) - self.append_to_log_file(_formatted_data) - self.log_data_to_file(self.tested_log, data) - - def log_memory(self, data): - self.log_data_to_file(self.memory_track_log, data) - - def log_fail(self, data, log_type="succeed"): - print data - if log_type == "succeed": - self.log_data_to_file(self.failed_log, data) - else: - self.log_data_to_file(self.failed_log2, data) - - def log_succeed(self, data, log_type="succeed"): - if log_type == "succeed": - self.log_data_to_file(self.succeed_log, data) - else: - self.log_data_to_file(self.succeed_log2, data) - - def execute(self): - TCActionBase.TCActionBase.execute(self) - # rewrite the following code - if self.client_type == "PC": - client_capability = Capability.PCSSLCapability("PCClient") - client_handler = SSLHandler.PCSSLHandler - client_ip = self.get_parameter("pc_ip") - else: - client_capability = Capability.TargetSSLCapability("TargetClient", **self.client_capability) - client_handler = SSLHandler.TargetSSLHandler - client_ip = self.get_parameter("target_ip") - if self.server_type == "PC": - server_capability = Capability.PCSSLCapability("PCServer") - server_handler = SSLHandler.PCSSLHandler - server_ip = self.get_parameter("pc_ip") - else: - server_capability = Capability.TargetSSLCapability("TargetServer", **self.server_capability) - server_handler = SSLHandler.TargetSSLHandler - server_ip = self.get_parameter("target_ip") - - serial_port = SSLHandler.SerialPort(self, "SSC1") - # generate config - config_utility = ConfigUtility.ConfigUtility(client_capability, server_capability) - config_list_dict = config_utility.get_all_test_config() - - # succeed - for config in config_list_dict["succeed"]: - self.prepare_handshake_test() - self.log_test_config("[Succeed config] %s" % config) - port = random.randint(500, 50000) - client = client_handler("client", config, serial_port) - server = server_handler("server", config, serial_port) - try: - client.init_context() - server.init_context() - server.listen(local_ip=server_ip, local_port=port) - client.connect(server_ip, port, local_ip=client_ip) - self.query_heap_size(scenario="connected") - self.log_succeed("[Succeed config] %s" % config) - except SSLHandler.TargetFail, e: - NativeLog.add_exception_log(e) - self.log_fail("[Target][%s]\r\n[Failed][Succeed config] %s" % (e, config)) - except SSLHandler.PCFail, e: - NativeLog.add_exception_log(e) - self.log_fail("[PC][%s]\r\n[Failed][Succeed config] %s" % (e, config)) - - self.close(client, server) - - # init context fail - for config in config_list_dict["context_fail"]: - self.prepare_handshake_test() - port = random.randint(500, 50000) - self.log_test_config("[Init context fail config] %s" % config) - client = client_handler("client", config, serial_port) - server = server_handler("server", config, serial_port) - try: - client.init_context() - server.init_context() - server.listen(local_ip=server_ip, local_port=port) - client.connect(server_ip, port, local_ip=client_ip) - self.log_fail("[Target]\r\n[Failed][Init context fail config] %s" % config, log_type="failed") - except StandardError, e: - NativeLog.add_exception_log(e) - self.log_succeed("[init context fail] %s" % config, log_type="failed") - self.close(client, server) - pass - - # negotiation fail - for config in config_list_dict["negotiation_fail"]: - self.prepare_handshake_test() - self.log_test_config("[negotiation_fail] %s" % config) - port = random.randint(500, 50000) - client = client_handler("client", config, serial_port) - server = server_handler("server", config, serial_port) - try: - client.init_context() - server.init_context() - server.listen(local_ip=server_ip, local_port=port) - except SSLHandler.TargetFail, e: - NativeLog.add_exception_log(e) - self.log_fail("[Target][%s]\r\n[Failed][negotiation fail config] %s" % (e, config), log_type="failed") - self.close(client, server) - continue - except SSLHandler.PCFail, e: - NativeLog.add_exception_log(e) - self.log_fail("[PC][%s]\r\n[Failed][negotiation fail config] %s" % (e, config), log_type="failed") - self.close(client, server) - continue - try: - client.connect(server_ip, port, local_ip=client_ip) - self.log_fail("[Target]\r\n[Failed][negotiation fail config] %s" % config, log_type="failed") - except StandardError, e: - NativeLog.add_exception_log(e) - self.log_succeed("[negotiation fail] %s" % config, log_type="failed") - self.close(client, server) - - # cert key fail - for config in config_list_dict["cert_key_fail"]: - self.prepare_handshake_test() - self.log_test_config("[cert_key_fail] %s" % config) - port = random.randint(500, 50000) - client = client_handler("client", config, serial_port) - server = server_handler("server", config, serial_port) - try: - client.init_context() - server.init_context() - server.listen(local_ip=server_ip, local_port=port) - except SSLHandler.TargetFail, e: - NativeLog.add_exception_log(e) - self.log_fail("[Target][%s]\r\n[Failed][cert_key fail config] %s" % (e, config), log_type="failed") - self.close(client, server) - continue - except SSLHandler.PCFail, e: - NativeLog.add_exception_log(e) - self.log_fail("[PC][%s]\r\n[Failed][cert_key fail config] %s" % (e, config), log_type="failed") - self.close(client, server) - continue - try: - client.connect(server_ip, port, local_ip=client_ip) - self.log_fail("[Target][Failed][cert_key fail config] %s" % config, log_type="failed") - except StandardError, e: - NativeLog.add_exception_log(e) - self.log_succeed("[cert_key_fail] %s" % config, log_type="failed") - self.close(client, server) - - -def main(): - pass - -if __name__ == '__main__': - main() diff --git a/components/test/TestCaseScript/SSLTest/SSLLowMem.py b/components/test/TestCaseScript/SSLTest/SSLLowMem.py deleted file mode 100644 index fdc058f902..0000000000 --- a/components/test/TestCaseScript/SSLTest/SSLLowMem.py +++ /dev/null @@ -1,140 +0,0 @@ -import os -import random -import time -import re - -from TCAction import TCActionBase -from TCAction import PerformanceTCBase -from NativeLog import NativeLog, HTMLGenerator -from Utility import MakeFolder - -import ConfigUtility -import Capability -import SSLHandler - -LOG_FOLDER = os.path.join("AT_LOG", "TEMP") - -HEAP_SIZE_LIMIT = 30000 - - -class SSLLowMem(PerformanceTCBase.PerformanceTCBase): - - def __init__(self, name, test_env, cmd_set, timeout=15, log_path=TCActionBase.LOG_PATH): - PerformanceTCBase.PerformanceTCBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - self.client_type = None - self.server_type = None - self.client_capability = dict() - self.server_capability = dict() - self.heap_usage_range = (10000, 30000) - self.test_time = 120 - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - timestamp = time.strftime("%d%H%M%S", time.localtime()) - self.heap_size_pattern = re.compile("\+FREEHEAP:(\d+)\r\n") - - @staticmethod - def close(client, server): - try: - client.close() - except StandardError: - pass - try: - server.close() - except StandardError: - pass - - def query_heap_size(self, scenario="idle"): - self.flush_data("SSC1") - self.serial_write_line("SSC1", "ram -H") - match = self.check_regular_expression("SSC1", self.heap_size_pattern) - if match is None: - NativeLog.add_trace_critical("No response for SSC ram command") - else: - heap_size = int(match.group(1)) - if heap_size < HEAP_SIZE_LIMIT and scenario == "idle": - NativeLog.add_trace_critical("[HeapSize] %s" % heap_size) - - pass - - def prepare_handshake_test(self): - # check if connected - self.flush_data("SSC1") - self.serial_write_line("SSC1", "sta -Q") - if self.check_response("SSC1", "+JAP:CONNECTED,") is False: - ap_ssid = self.get_parameter("ap_ssid") - ap_password = self.get_parameter("ap_password") - self.serial_write_line("SSC1", "sta -C -s %s -p %s" % (ap_ssid, ap_password)) - self.check_response("SSC1", "+JAP:CONNECTED,") - # random alloc memory - while True: - memory_size = random.randint(self.heap_usage_range[0], self.heap_usage_range[1]) - self.serial_write_line("SSC1", "soc -M -l %s" % memory_size) - if self.check_response("SSC1", "+SOC_BUFFER:OK", timeout=1) is True: - break - # query size - self.query_heap_size() - - @staticmethod - def log_data_to_file(file_name, data): - with open(file_name, "ab+") as f: - f.write(data+"\r\n") - - def execute(self): - TCActionBase.TCActionBase.execute(self) - # rewrite the following code - if self.client_type == "PC": - client_capability = Capability.PCSSLCapability("PCClient") - client_handler = SSLHandler.PCSSLHandler - client_ip = self.get_parameter("pc_ip") - else: - client_capability = Capability.TargetSSLCapability("TargetClient", **self.client_capability) - client_handler = SSLHandler.TargetSSLHandler - client_ip = self.get_parameter("target_ip") - if self.server_type == "PC": - server_capability = Capability.PCSSLCapability("PCServer") - server_handler = SSLHandler.PCSSLHandler - server_ip = self.get_parameter("pc_ip") - else: - server_capability = Capability.TargetSSLCapability("TargetServer", **self.server_capability) - server_handler = SSLHandler.TargetSSLHandler - server_ip = self.get_parameter("target_ip") - - test_time = self.test_time * 60 # convert test time from minutes to seconds - - serial_port = SSLHandler.SerialPort(self, "SSC1") - # generate config - config_utility = ConfigUtility.ConfigUtility(client_capability, server_capability) - config_list_dict = config_utility.get_all_test_config() - - start_time = time.time() - - # succeed - for config in config_list_dict["succeed"]: - if time.time() - start_time > test_time: - break - self.prepare_handshake_test() - port = random.randint(500, 50000) - client = client_handler("client", config, serial_port) - server = server_handler("server", config, serial_port) - try: - client.init_context() - server.init_context() - server.listen(local_ip=server_ip, local_port=port) - client.connect(server_ip, port, local_ip=client_ip) - self.query_heap_size(scenario="connected") - except SSLHandler.TargetFail, e: - NativeLog.add_exception_log(e) - except SSLHandler.PCFail, e: - NativeLog.add_exception_log(e) - self.close(client, server) - - -def main(): - pass - -if __name__ == '__main__': - main() diff --git a/components/test/TestCaseScript/SSLTest/SSLSendRecv.py b/components/test/TestCaseScript/SSLTest/SSLSendRecv.py deleted file mode 100644 index 13fe0b1529..0000000000 --- a/components/test/TestCaseScript/SSLTest/SSLSendRecv.py +++ /dev/null @@ -1,147 +0,0 @@ -import random -import time - -from TCAction import TCActionBase -from TCAction import PerformanceTCBase -from NativeLog import NativeLog -import ConfigUtility -import Capability -import SSLHandler - - -class SSLSendRecv(PerformanceTCBase.PerformanceTCBase): - - def __init__(self, name, test_env, cmd_set, timeout=15, log_path=TCActionBase.LOG_PATH): - PerformanceTCBase.PerformanceTCBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - self.target_role = "Client" - self.max_send_len = 2048 - self.test_time = 120 - self.data_validation = False - - self.target_capability = {"version": ["SSLv23"], - "cipher_suite": ["TLS_RSA_WITH_AES_256_CBC_SHA", "TLS_RSA_WITH_AES_128_CBC_SHA"], - "fragment_size": [2048], - "verify_server": False, - "verify_client": False, - "key_algorithm": ["RSA2048"], - "key_encoding": ["PEM"], - "pem_encryption": [None], - "certificate_encoding": ["PEM"], - "certificate_digest": ["sha1"], - } - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - - @staticmethod - def close(client, server): - try: - client.close() - except StandardError: - pass - try: - server.close() - except StandardError: - pass - - def cleanup(self): - self.serial_write_line("SSC1", "ssl -D") - self.check_response("SSC1", "SSL") - - def execute(self): - TCActionBase.TCActionBase.execute(self) - - target_role = self.target_role - max_send_len = self.max_send_len - test_time = self.test_time * 60 - data_validation = self.data_validation - - ssl_port = random.randint(10000, 50000) - NativeLog.add_prompt_trace("SSL port is %s" % ssl_port) - - # make sure ssl context deinit - self.serial_write_line("SSC1", "ssl -D") - self.check_response("SSC1", "SSL") - - # close all sockets and enlarge send buffer - self.serial_write_line("SSC1", "soc -T") - self.check_response("SSC1", "CLOSEALL") - - self.serial_write_line("SSC1", "soc -M -l %s" % max_send_len) - self.check_response("SSC1", "+SOC_BUFFER:OK") - - # rewrite the following code - if target_role == "Server": - client_capability = Capability.PCSSLCapability("PCClient") - client_handler = SSLHandler.PCSSLHandler - client_ip = self.get_parameter("pc_ip") - server_capability = Capability.TargetSSLCapability("TargetServer", **self.target_capability) - server_handler = SSLHandler.TargetSSLHandler - server_ip = self.get_parameter("target_ip") - elif target_role == "Client": - client_capability = Capability.TargetSSLCapability("TargetClient", **self.target_capability) - client_handler = SSLHandler.TargetSSLHandler - client_ip = self.get_parameter("target_ip") - server_capability = Capability.PCSSLCapability("PCServer") - server_handler = SSLHandler.PCSSLHandler - server_ip = self.get_parameter("pc_ip") - else: - raise StandardError("Unsupported target role %s" % target_role) - - serial_port = SSLHandler.SerialPort(self, "SSC1") - - # generate one succeed config - config_utility = ConfigUtility.ConfigUtility(client_capability, server_capability) - config_list_dict = config_utility.get_all_test_config() - - for config in config_list_dict["succeed"]: - try: - # create connection - NativeLog.add_prompt_trace(str(config)) # do print config - client = client_handler("client", config, serial_port) - server = server_handler("server", config, serial_port) - client.init_context() - server.init_context() - server.listen(local_ip=server_ip, local_port=ssl_port) - client.connect(server_ip, ssl_port, local_ip=client_ip) - except StandardError, e: - NativeLog.add_exception_log(e) - return - - # set data validation - client.set_data_validation(data_validation) - server.set_data_validation(data_validation) - - # do send recv - time_start = time.time() - while time.time() - time_start < test_time: - send_len = random.randint(1, max_send_len) - try: - client.send(size=send_len) - client.send(size=send_len) - server.recv(send_len*2) - except StandardError, e: - NativeLog.add_exception_log(e) - NativeLog.add_prompt_trace("client send / server recv fail") - break - try: - # do send twice, try to create a tcp segment with 2 records - server.send(size=send_len) - server.send(size=send_len) - client.recv(send_len*2) - except StandardError, e: - NativeLog.add_exception_log(e) - NativeLog.add_prompt_trace("server send / client recv fail") - break - else: - self.set_result("Succeed") - - -def main(): - pass - -if __name__ == '__main__': - main() diff --git a/components/test/TestCaseScript/SSLTest/__init__.py b/components/test/TestCaseScript/SSLTest/__init__.py deleted file mode 100755 index 98fe3be4a7..0000000000 --- a/components/test/TestCaseScript/SSLTest/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__all__ = ["Capability", "ConfigUtility", "Parameter", "SSLHandler", "SSLHandshake"] diff --git a/components/test/TestCaseScript/SleepMode/AutoSleep.py b/components/test/TestCaseScript/SleepMode/AutoSleep.py deleted file mode 100755 index 9db70227cf..0000000000 --- a/components/test/TestCaseScript/SleepMode/AutoSleep.py +++ /dev/null @@ -1,561 +0,0 @@ -import random -import os -import time -import string -import re -import threading - -from TCAction import TCActionBase, PerformanceTCBase -from NativeLog import NativeLog -from Utility import MakeFolder -from Utility import MultimeterUtil -from Utility import ShellCmd - -LOG_PATH = os.path.join("AT_LOG", "SLEEP") - -SLEEP_MODE_LIST = ["none_sleep", "light_sleep", "modem_sleep"] -SLEEP_MODE = dict(zip(SLEEP_MODE_LIST, range(len(SLEEP_MODE_LIST)))) - -SAMPLE_RATE_SLEEP_MODE_CHANGE = 0.002 -SAMPLE_NUM_SLEEP_MODE_CHANGE = 256 - -SAMPLE_RATE = 0.002 -SAMPLE_NUM = 512 -MAX_VALUE = 1 -Y_AXIS_LABEL = "Current (mA)" -GPIO_EDGE_DELAY = 120 # 20 ms - -NONE_SLEEP_MIN_CUR = 30 -LIGHT_SLEEP_MIN_CUR = 1.5 -MODEM_SLEEP_MIN_CUR = 20 - -GPIO_WAKE_UP = 15 -GPIO_CHIP_RESET = 14 - -SLEEP_WAKEUP_DELAY = 0.01 - - -class AutoSleep(PerformanceTCBase.PerformanceTCBase): - - def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): - PerformanceTCBase.PerformanceTCBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - self.test_mode = "mode_change" - self.test_count = 100 - self.sleep_mode = SLEEP_MODE_LIST - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - self.log_folder = MakeFolder.make_folder(os.path.join(LOG_PATH, - "AUTO_SLEEP_%s_%s" % (self.test_mode, - time.strftime("%d%H%M%S", - time.localtime())))) - self.multimeter = MultimeterUtil.MultimeterUtil(self.log_folder) - - @staticmethod - def find_min_items(item_list, count): - assert count < len(item_list) - min_items = [] - for i in range(count): - min_val = min(item_list) - min_items.append(min_val) - item_list.remove(min_val) - return min_items - - def sleep_mode_change(self, sleep_mode): - result = True - NativeLog.add_prompt_trace("[AutoSleep][ModeChange] %s start" % sleep_mode) - # choose sleep mode - sleep_mode_enum = SLEEP_MODE[sleep_mode] - # change GPIO to make sure target exit sleep mode, so it can process SSC commands - self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) - time.sleep(SLEEP_WAKEUP_DELAY) - # set sleep mode - self.serial_write_line("SSC1", "sleep -S -t %d" % sleep_mode_enum) - self.check_response("SSC1", "+SLEEP_MODE:OK") - self.check_response("SSC2", "+GPIO_SET:OK") - - NativeLog.add_prompt_trace("[AutoSleep][ModeChange] mode set") - time.sleep(6) - # measure current - current_line = self.multimeter.measure_current(sample_rate=SAMPLE_RATE_SLEEP_MODE_CHANGE, - sample_num=SAMPLE_NUM_SLEEP_MODE_CHANGE, - max_value=MAX_VALUE) - # do check measure - min_items = self.find_min_items(current_line, 10) - average_val = float(0) - for val in min_items: - average_val += val - average_val /= 10 - - NativeLog.add_prompt_trace("[AutoSleep][ModeChange] measure done, average min current %f" % average_val) - - if sleep_mode == "none_sleep": - if average_val < NONE_SLEEP_MIN_CUR: - result = False - elif sleep_mode == "light_sleep": - if average_val > LIGHT_SLEEP_MIN_CUR: - result = False - elif sleep_mode == "modem_sleep": - if average_val > MODEM_SLEEP_MIN_CUR or average_val < LIGHT_SLEEP_MIN_CUR: - result = False - if result is False: - NativeLog.add_trace_critical("[AutoSleep][ModeChange] %s failed" % sleep_mode) - self.multimeter.draw_graph(current_line, SAMPLE_RATE, "%s_fail" % sleep_mode, Y_AXIS_LABEL) - - time.sleep(5) - return result - - def sleep_current_measure(self, sleep_mode): - result = True - - NativeLog.add_prompt_trace("[AutoSleep][CurrentMeasure] %s start" % sleep_mode) - # choose sleep mode - sleep_mode_enum = SLEEP_MODE[sleep_mode] - # change GPIO to make sure target exit sleep mode, so it can process SSC commands - self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) - # set sleep mode - time.sleep(SLEEP_WAKEUP_DELAY) - self.serial_write_line("SSC1", "sleep -S -t %d" % sleep_mode_enum) - self.check_response("SSC1", "+SLEEP_MODE:OK") - self.check_response("SSC2", "+GPIO_SET:OK") - - NativeLog.add_prompt_trace("[AutoSleep][CurrentMeasure] set mode done") - time.sleep(10) - # measure current - current_line = self.multimeter.measure_current(sample_rate=SAMPLE_RATE, - sample_num=SAMPLE_NUM, - max_value=MAX_VALUE) - self.multimeter.draw_graph(current_line, SAMPLE_RATE, sleep_mode, Y_AXIS_LABEL) - NativeLog.add_prompt_trace("[AutoSleep][CurrentMeasure] measure done") - return result - - def light_sleep_wakeup(self): - result = True - NativeLog.add_prompt_trace("[AutoSleep][LightSleepWakeup] start") - - time.sleep(1) - self.serial_write_line("SSC1", "") - time.sleep(1) - # check if respond to uart - self.flush_data("SSC1") - for i in range(60): - self.serial_write("SSC1", "a") - time.sleep(0.043) - time.sleep(0.1) - respond_data = self.serial_read_data("SSC1") - if len(respond_data) >= 60: - NativeLog.add_trace_critical("[AutoSleep][light sleep wakeup] " - "Failed when recving data during sleep, %d" % len(respond_data)) - result = False - - NativeLog.add_prompt_trace("[AutoSleep][LightSleepWakeup] check on sleep mode done") - - self.serial_write_line("SSC1", "") - time.sleep(1) - - # change GPIO to make target wakeup - self.serial_write_line("SSC2", "gpio -L -p %d -t 0" % GPIO_WAKE_UP) - self.check_response("SSC2", "+GPIO_SET:OK") - - self.serial_write_line("SSC1", "") - time.sleep(1) - self.flush_data("SSC1") - for i in range(60): - self.serial_write("SSC1", "a") - time.sleep(0.043) - time.sleep(0.1) - respond_data = self.serial_read_data("SSC1") - if len(respond_data) < 60: - NativeLog.add_trace_critical("[AutoSleep][light sleep wakeup] " - "Failed when recving data during wakeup, %d" % len(respond_data)) - result = False - - NativeLog.add_prompt_trace("[AutoSleep][LightSleepWakeup] check on wakeup mode done") - self.serial_write_line("SSC1", "") - # restore GPIO level - self.serial_write_line("SSC2", "gpio -L -p %d -t 1" % GPIO_WAKE_UP) - self.check_response("SSC2", "+GPIO_SET:OK") - - self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_CHIP_RESET, GPIO_EDGE_DELAY)) - self.check_response("SSC2", "+GPIO_SET:OK") - time.sleep(2) - return result - - def sleep_exit_enter(self, sleep_mode, ssid, password): - result = True - if sleep_mode == "modem_sleep": - max_current_for_sleep = 20 - elif sleep_mode == "light_sleep": - max_current_for_sleep = 5 - else: - raise StandardError("Not supported mode %s" % sleep_mode) - - NativeLog.add_prompt_trace("[AutoSleep][EnterExitSleep] %s start" % sleep_mode) - - ap_ssid = self.get_parameter("ap_ssid") - ap_password = self.get_parameter("ap_password") - - # step A: no STA connect to SoftAP, enter modem sleep mode - self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) - time.sleep(SLEEP_WAKEUP_DELAY) - self.serial_write_line("SSC1", "op -S -o 1") - self.check_response("SSC1", "+MODE:OK") - self.check_response("SSC2", "+GPIO_SET:OK") - - self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) - time.sleep(SLEEP_WAKEUP_DELAY) - self.serial_write_line("SSC1", "sta -C -s %s -p %s" % (ap_ssid, ap_password)) - self.check_response("SSC2", "+GPIO_SET:OK") - self.check_response("SSC1", "+JAP:CONNECTED") - self.check_response("SSC1", "pm open") - - self.serial_write_line("SSC2", "sta -D") - self.check_response("SSC2", "+QAP") - - time.sleep(5) - - current_line = self.multimeter.measure_current(sample_rate=SAMPLE_RATE, - sample_num=SAMPLE_NUM, - max_value=MAX_VALUE) - min_items = self.find_min_items(current_line, 10) - average_val = float(0) - for val in min_items: - average_val += val - average_val /= 10 - if average_val > max_current_for_sleep: - NativeLog.add_trace_critical("[AutoSleep][SleepExitEnter] " - "did not enter %s sleep, %d" % (sleep_mode, average_val)) - self.multimeter.draw_graph(current_line, SAMPLE_RATE, - "%s_sleep_exit_enter_fail_A" % sleep_mode, Y_AXIS_LABEL) - result = False - - NativeLog.add_prompt_trace("[AutoSleep][EnterExitSleep] step A done") - # step B: STA connect to SoftAP, exit modem sleep mode - self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) - time.sleep(SLEEP_WAKEUP_DELAY) - self.serial_write_line("SSC1", "op -S -o 3") - self.check_response("SSC1", "+MODE:OK") - self.check_response("SSC2", "+GPIO_SET:OK") - time.sleep(1) - self.serial_write_line("SSC2", "sta -C -s %s -p %s" % (ssid, password)) - self.check_response("SSC2", "+JAP:CONNECTED") - # self.check_response("SSC1", "pm close") - time.sleep(10) - - current_line = self.multimeter.measure_current(sample_rate=SAMPLE_RATE, - sample_num=SAMPLE_NUM, - max_value=MAX_VALUE) - min_items = self.find_min_items(current_line, 10) - average_val = float(0) - for val in min_items: - average_val += val - average_val /= 10 - if average_val < 30: - NativeLog.add_trace_critical("[AutoSleep][SleepExitEnter] did not exit %s sleep" % sleep_mode) - self.multimeter.draw_graph(current_line, SAMPLE_RATE, - "%s_sleep_exit_enter_fail_B" % sleep_mode, Y_AXIS_LABEL) - result = False - - NativeLog.add_prompt_trace("[AutoSleep][EnterExitSleep] step B done") - # step C: target set to STA mode, enter modem sleep - self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) - time.sleep(SLEEP_WAKEUP_DELAY) - self.serial_write_line("SSC1", "op -S -o 1") - self.check_response("SSC1", "+MODE:OK") - - self.check_response("SSC2", "+GPIO_SET:OK") - # self.check_response("SSC1", "pm open") - time.sleep(15) - - current_line = self.multimeter.measure_current(sample_rate=SAMPLE_RATE, - sample_num=SAMPLE_NUM, - max_value=MAX_VALUE) - min_items = self.find_min_items(current_line, 10) - average_val = float(0) - for val in min_items: - average_val += val - average_val /= 10 - if average_val > max_current_for_sleep: - NativeLog.add_trace_critical("[AutoSleep][SleepExitEnter] did not enter %s sleep" % sleep_mode) - self.multimeter.draw_graph(current_line, SAMPLE_RATE, - "%s_sleep_exit_enter_fail_C" % sleep_mode, Y_AXIS_LABEL) - result = False - - NativeLog.add_prompt_trace("[AutoSleep][EnterExitSleep] step C done") - # step D: target disconnect, exit modem sleep - self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) - time.sleep(SLEEP_WAKEUP_DELAY) - self.serial_write_line("SSC1", "sta -D") - self.check_response("SSC1", "+QAP") - self.check_response("SSC2", "+GPIO_SET:OK") - # self.check_response("SSC1", "pm close") - time.sleep(5) - current_line = self.multimeter.measure_current(sample_rate=SAMPLE_RATE, - sample_num=SAMPLE_NUM, - max_value=MAX_VALUE) - min_items = self.find_min_items(current_line, 10) - average_val = float(0) - for val in min_items: - average_val += val - average_val /= 10 - if average_val < 30: - NativeLog.add_trace_critical("[AutoSleep][SleepExitEnter] did not exit %s sleep" % sleep_mode) - self.multimeter.draw_graph(current_line, SAMPLE_RATE, - "%s_sleep_exit_enter_fail_D" % sleep_mode, Y_AXIS_LABEL) - result = False - - NativeLog.add_prompt_trace("[AutoSleep][EnterExitSleep] step D done") - # step E: target connect to AP, enter modem sleep - self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) - time.sleep(SLEEP_WAKEUP_DELAY) - self.serial_write_line("SSC1", "sta -C -s %s -p %s" % (ap_ssid, ap_password)) - self.check_response("SSC2", "+GPIO_SET:OK") - self.check_response("SSC1", "+JAP:CONNECTED") - self.check_response("SSC1", "pm open") - time.sleep(3) - current_line = self.multimeter.measure_current(sample_rate=SAMPLE_RATE, - sample_num=SAMPLE_NUM, - max_value=MAX_VALUE) - min_items = self.find_min_items(current_line, 10) - average_val = float(0) - for val in min_items: - average_val += val - average_val /= 10 - if average_val > max_current_for_sleep: - NativeLog.add_trace_critical("[AutoSleep][SleepExitEnter] did not enter %s sleep" % sleep_mode) - self.multimeter.draw_graph(current_line, SAMPLE_RATE, - "%s_sleep_exit_enter_fail_E" % sleep_mode, Y_AXIS_LABEL) - result = False - - NativeLog.add_prompt_trace("[AutoSleep][EnterExitSleep] step E done") - # step F: target set to AP mode, exit modem sleep - self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) - time.sleep(SLEEP_WAKEUP_DELAY) - self.serial_write_line("SSC1", "op -S -o 2") - self.check_response("SSC1", "+MODE:OK") - self.check_response("SSC2", "+GPIO_SET:OK") - # self.check_response("SSC1", "pm close") - time.sleep(5) - - current_line = self.multimeter.measure_current(sample_rate=SAMPLE_RATE, - sample_num=SAMPLE_NUM, - max_value=MAX_VALUE) - min_items = self.find_min_items(current_line, 10) - average_val = float(0) - for val in min_items: - average_val += val - average_val /= 10 - if average_val < 30: - NativeLog.add_trace_critical("[AutoSleep][SleepExitEnter] did not exit %s sleep" % sleep_mode) - self.multimeter.draw_graph(current_line, SAMPLE_RATE, - "%s_sleep_exit_enter_fail_F" % sleep_mode, Y_AXIS_LABEL) - result = False - - NativeLog.add_prompt_trace("[AutoSleep][EnterExitSleep] step F done") - return result - - def ping_test(self, sleep_mode): - result = True - NativeLog.add_prompt_trace("[AutoSleep][PingTest] %s start" % sleep_mode) - # choose sleep mode - sleep_mode_enum = SLEEP_MODE[sleep_mode] - if sleep_mode == "modem_sleep": - max_current_for_sleep = MODEM_SLEEP_MIN_CUR - elif sleep_mode == "light_sleep": - max_current_for_sleep = LIGHT_SLEEP_MIN_CUR - else: - raise StandardError("Not supported mode %s" % sleep_mode) - - self.serial_write_line("SSC1", "op -S -o 1") - self.check_response("SSC1", "+MODE:OK") - - # set sleep mode - self.serial_write_line("SSC1", "sleep -S -t %d" % sleep_mode_enum) - self.check_response("SSC1", "+SLEEP_MODE:OK") - NativeLog.add_prompt_trace("[AutoSleep][PingTest] set mode done") - - # connect to AP - ap_ssid = self.get_parameter("ap_ssid") - ap_password = self.get_parameter("ap_password") - target_ip = self.get_parameter("target_ip") - - self.serial_write_line("SSC1", "sta -C -s %s -p %s" % (ap_ssid, ap_password)) - self.check_response("SSC1", "+JAP:CONNECTED") - - time.sleep(10) - # measure current, should be in sleep mode - current_line = self.multimeter.measure_current(sample_rate=SAMPLE_RATE, - sample_num=SAMPLE_NUM, - max_value=MAX_VALUE) - min_items = self.find_min_items(current_line, 10) - average_val = float(0) - for val in min_items: - average_val += val - average_val /= 10 - - if average_val > max_current_for_sleep: - NativeLog.add_trace_critical("[AutoSleep][PingTest] step A did not enter %s sleep, %f" - % (sleep_mode, average_val)) - self.multimeter.draw_graph(current_line, SAMPLE_RATE, - "%s_ping_test_fail_not_enter_sleep" % sleep_mode, Y_AXIS_LABEL) - result = False - else: - NativeLog.add_prompt_trace("[AutoSleep][PingTest] step A enter %s sleep, %f" - % (sleep_mode, average_val)) - - class PingThread(threading.Thread): - def __init__(self, ping_ip): - threading.Thread.__init__(self) - self.setDaemon(True) - self.target_ip = ping_ip - self.exit_event = threading.Event() - - def run(self): - while self.exit_event.isSet() is False: - ShellCmd.shell_check_output("ping %s -w 500" % self.target_ip) - time.sleep(0.1) - pass - - def exit(self): - self.exit_event.set() - - NativeLog.add_prompt_trace("[AutoSleep][PingTest] ping start") - ping_thread = PingThread(target_ip) - ping_thread.start() - time.sleep(5) - - # measure current, should not be in sleep mode - current_line = self.multimeter.measure_current(sample_rate=SAMPLE_RATE, - sample_num=SAMPLE_NUM, - max_value=MAX_VALUE) - min_items = self.find_min_items(current_line, 10) - average_val = float(0) - for val in min_items: - average_val += val - average_val /= 10 - if average_val < 30: - NativeLog.add_trace_critical("[AutoSleep][PingTest] step B did not exit %s sleep, %f" - % (sleep_mode, average_val)) - self.multimeter.draw_graph(current_line, SAMPLE_RATE, - "%s_ping_test_fail_not_exit_sleep" % sleep_mode, Y_AXIS_LABEL) - result = False - else: - NativeLog.add_prompt_trace("[AutoSleep][PingTest] step B exit %s sleep, %f" - % (sleep_mode, average_val)) - - ping_thread.exit() - ping_thread.join(20) - NativeLog.add_prompt_trace("[AutoSleep][PingTest] ping stop") - time.sleep(10) - - # measure current, should not be in sleep mode - current_line = self.multimeter.measure_current(sample_rate=SAMPLE_RATE, - sample_num=SAMPLE_NUM, - max_value=MAX_VALUE) - min_items = self.find_min_items(current_line, 10) - average_val = float(0) - for val in min_items: - average_val += val - average_val /= 10 - if average_val > max_current_for_sleep: - NativeLog.add_trace_critical("[AutoSleep][PingTest] step C did not enter %s" % sleep_mode) - self.multimeter.draw_graph(current_line, SAMPLE_RATE, - "%s_ping_test_fail_not_enter_sleep" % sleep_mode, Y_AXIS_LABEL) - result = False - else: - NativeLog.add_prompt_trace("[AutoSleep][PingTest] step C enter %s sleep" % sleep_mode) - - return result - - def cleanup(self): - self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) - time.sleep(SLEEP_WAKEUP_DELAY) - self.serial_write_line("SSC1", "sleep -S -t %d" % SLEEP_MODE["modem_sleep"]) - self.check_response("SSC1", "OK") - self.check_response("SSC2", "+GPIO_SET:OK") - - def execute(self): - TCActionBase.TCActionBase.execute(self) - - try: - test_mode = self.test_mode - test_count = self.test_count - sleep_mode = self.sleep_mode - except StandardError, e: - return - - # make sure enter modem sleep mode before start test - self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) - time.sleep(SLEEP_WAKEUP_DELAY) - self.serial_write_line("SSC1", "sleep -S -t %d" % SLEEP_MODE["modem_sleep"]) - self.check_response("SSC1", "+SLEEP_MODE:OK") - self.check_response("SSC2", "+GPIO_SET:OK") - self.check_response("SSC1", "pm open", timeout=10) - - self.serial_write_line("SSC1", "gpio -G -p %d" % GPIO_WAKE_UP) - self.check_response("SSC1", "+GPIO_GET") - self.serial_write_line("SSC1", "gpio -G -p %d" % GPIO_CHIP_RESET) - self.check_response("SSC1", "+GPIO_GET") - - # start test - if "mode_change" in test_mode: - for i in range(test_count): - result = self.sleep_mode_change(random.choice(SLEEP_MODE_LIST)) - - elif "measure_current" in test_mode: - for i in range(test_count): - for mode in sleep_mode: - result = self.sleep_current_measure(mode) - pass - elif "gpio_wakeup" in test_mode: - # change GPIO to make sure target exit sleep mode, so it can process SSC commands - self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) - time.sleep(SLEEP_WAKEUP_DELAY) - # set sleep mode - self.serial_write_line("SSC1", "sleep -S -t %d" % SLEEP_MODE["light_sleep"]) - self.check_response("SSC1", "+SLEEP_MODE:OK") - - self.check_response("SSC2", "+GPIO_SET:OK") - for i in range(test_count): - result = self.light_sleep_wakeup() - pass - elif "sleep_exit_enter" in test_mode: - ssid = "".join([random.choice(string.lowercase) for i in range(10)]) - password = "".join([random.choice(string.lowercase) for i in range(10)]) - self.serial_write_line("SSC2", "sta -D") - self.check_response("SSC2", "+QAP") - self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) - time.sleep(SLEEP_WAKEUP_DELAY) - self.serial_write_line("SSC1", "op -S -o 3") - self.check_response("SSC1", "+MODE:OK") - self.check_response("SSC2", "+GPIO_SET:OK") - self.serial_write_line("SSC1", "ap -S -s %s -p %s -t 3" % (ssid, password)) - self.check_response("SSC1", "+SAP:OK") - self.serial_write_line("SSC2", "op -S -o 1") - self.check_response("SSC2", "+MODE:OK") - - for mode in sleep_mode: - self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) - time.sleep(SLEEP_WAKEUP_DELAY) - self.serial_write_line("SSC1", "sleep -S -t %d" % SLEEP_MODE[mode]) - self.check_response("SSC1", "+SLEEP_MODE:OK") - self.check_response("SSC2", "+GPIO_SET:OK") - - for i in range(test_count): - result = self.sleep_exit_enter(mode, ssid, password) - elif "ping" in test_mode: - for mode in sleep_mode: - for i in range(test_count): - result = self.ping_test(mode) - pass - - -def main(): - pass - - -if __name__ == '__main__': - main() diff --git a/components/test/TestCaseScript/SleepMode/DeepSleep.py b/components/test/TestCaseScript/SleepMode/DeepSleep.py deleted file mode 100755 index 252ebb0758..0000000000 --- a/components/test/TestCaseScript/SleepMode/DeepSleep.py +++ /dev/null @@ -1,259 +0,0 @@ -import random -import os -import time - -from TCAction import TCActionBase, PerformanceTCBase -from Utility import MakeFolder -from Utility import MultimeterUtil -from NativeLog import NativeLog - -LOG_PATH = os.path.join("AT_LOG", "SLEEP") - -DEEP_SLEEP_OPTION_LIST = ["up_to_bin", "normal", "no_rf_calibrate", "rf_off"] -DEEP_SLEEP_OPTION = { - "up_to_bin": 0, - "normal": 1, - "no_rf_calibrate": 2, - "rf_off": 4, -} - -SAMPLE_RATE = 0.001 -SAMPLE_NUM = 512 -MAX_VALUE = 0.1 -Y_AXIS_LABEL = "Current (mA)" - - -MEASURE_FREQ = 3600 - -GPIO_WAKE_UP = 15 -GPIO_CHIP_RESET = 14 -GPIO_EDGE_DELAY = 100 # 20 ms - - -class DeepSleep(PerformanceTCBase.PerformanceTCBase): - - def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): - PerformanceTCBase.PerformanceTCBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - self.test_mode = "mode_change" - self.test_count = 100 - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - self.log_folder = MakeFolder.make_folder(os.path.join(LOG_PATH, - "DEEP_SLEEP_%s_%s" % (self.test_mode, - time.strftime("%d%H%M%S", - time.localtime())))) - self.sleep_time_log = os.path.join(self.log_folder, "deep_sleep_wakeup_time.log") - self.multimeter = MultimeterUtil.MultimeterUtil(self.log_folder) - - def deep_sleep_stable(self): - result = True - RandomTime = random.randint(1, 100) - self.serial_write_line("SSC1", "dsleep -S -t %s" % RandomTime) - if self.check_response("SSC1", "+DSLEEP:OK") is False: - result = False - if self.check_response("SSC1", "ready!!!") is False: - result = False - NativeLog.add_trace_critical("[DeepSleep][Stable] wait ready err") - else: - NativeLog.add_trace_critical("[DeepSleep][Stable] SleepTime:%d" % RandomTime) - time.sleep(1) - - RandomTime = random.randint(100000, 1000000) - self.serial_write_line("SSC1", "dsleep -S -t %s" % RandomTime) - if self.check_response("SSC1", "+DSLEEP:OK") is False: - result = False - if self.check_response("SSC1", "ready!!!") is False: - result = False - NativeLog.add_trace_critical("[DeepSleep][Stable] wait ready err") - else: - NativeLog.add_trace_critical("[DeepSleep][Stable] SleepTime:%d" % RandomTime) - time.sleep(1) - return result - - def deep_sleep_current_measure(self): - result = True - self.serial_write_line("SSC1", "") - self.serial_write_line("SSC1", "dsleep -S -t 10000000") - if self.check_response("SSC1", "+DSLEEP:OK") is False: - result = False - time.sleep(3) - # measure current - current_line = self.multimeter.measure_current(sample_rate=SAMPLE_RATE, - sample_num=SAMPLE_NUM, - max_value=MAX_VALUE) - average_current = float(0) - for current in current_line: - average_current += current - average_current /= SAMPLE_NUM - - self.multimeter.draw_graph(current_line, SAMPLE_RATE, - "deep_sleep_current", Y_AXIS_LABEL) - - if average_current > 1: - NativeLog.add_trace_critical("[DeepSleep][CurrentMeasure] average current %f > 1mA" % average_current) - else: - NativeLog.add_trace_critical("[DeepSleep][CurrentMeasure] dsleep current ok, %f" % average_current) - - if self.check_response("SSC1", "ready!!!") is False: - NativeLog.add_trace_critical("[DeepSleep][CurrentMeasure] CurrentMeasure wait ready err %f" - % average_current) - result = False - - NativeLog.add_trace_critical("[DeepSleep][CurrentMeasure] wait ready ok") - - return result - - ########################################## - # gpio wake up - ########################################## - def deep_sleep_wakeup(self): - result = True - - self.serial_write_line("SSC1", "dsleep -S -t 0") - if self.check_response("SSC1", "+DSLEEP:OK") is False: - result = False - - time.sleep(2) - - # measure current - current_line = self.multimeter.measure_current(sample_rate=SAMPLE_RATE, - sample_num=SAMPLE_NUM, - max_value=MAX_VALUE) - average_current = float(0) - for current in current_line: - average_current += current - average_current /= SAMPLE_NUM - - if average_current > 1: - NativeLog.add_trace_critical("[DeepSleep][Wakeup] average current %f > 1mA" % average_current) - self.multimeter.draw_graph(current_line, SAMPLE_RATE, - "deep_sleep_current", Y_AXIS_LABEL) - - self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_CHIP_RESET, GPIO_EDGE_DELAY)) - self.check_response("SSC2", "+GPIO_SET:OK") - if self.check_response("SSC1", "ready!!!") is False: - NativeLog.add_trace_critical("[DeepSleep][Wakeup] target did not wakeup") - result = False - else: - NativeLog.add_trace_critical("[DeepSleep][Wakeup] target wakeup") - - time.sleep(1) - return result - - ######################################### - #test one hour, Verify RTC Clock timer - ######################################### - def deep_sleep_timeout(self): - result = True - Timeout = 3600 - - start_sleep_time = time.time() - self.serial_write_line("SSC1", "") - self.serial_write_line("SSC1", "dsleep -S -t %d" % (Timeout*1000000)) - if self.check_response("SSC1", "+DSLEEP:OK") is False: - result = False - self.check_response("SSC1", "ready!!!", timeout = Timeout*2) - time_escaped = time.time() - start_sleep_time - NativeLog.add_trace_critical("[DeepSleep][timeout] desired sleep timeout is %s, actual sleep timeout is %s" % (Timeout, time_escaped)) - with open(self.sleep_time_log, "ab+") as f: - f.write("[DeepSleep] desired sleep timeout is %s, actual sleep timeout is %s" % (Timeout, time_escaped)) - return result - - ############################################ - # Capture current map, verify the process of power on - # notice: option = "up_to_bin" up to byte108 in init.bin, - ############################################ - def wake_option(self): - result = True - for option in DEEP_SLEEP_OPTION_LIST: - for i in range(8): - self.serial_write_line("SSC1", "dsleep -O -m %s" % DEEP_SLEEP_OPTION[option]) - if self.check_response("SSC1", "+DSLEEP:OK") is False: - result = False - self.serial_write_line("SSC1", "dsleep -S -t 1200000") - if self.check_response("SSC1", "+DSLEEP:OK") is False: - result = False - - # measure current - current_line = self.multimeter.measure_current(sample_rate=0.002, - sample_num=SAMPLE_NUM, - max_value=1) - self.multimeter.draw_graph(current_line, SAMPLE_RATE, - "deep_sleep_wakeup_option_%s_%d" - % (option, DEEP_SLEEP_OPTION[option]), Y_AXIS_LABEL) - - NativeLog.add_trace_critical("[DeepSleep][wake_option] target wakeup option:%d" - % DEEP_SLEEP_OPTION[option]) - time.sleep(3) - - return result - - def deep_sleep_wakeup_flash_gpio_status(self): - result = True - RandomTime = random.randint(2000000, 2000000) - self.serial_write_line("SSC1", "dsleep -S -t %s" % RandomTime) - if self.check_response("SSC1", "+DSLEEP:OK") is False: - result = False - if self.check_response("SSC1", "ready!!!") is False: - result = False - NativeLog.add_trace_critical("[DeepSleep][Stable] wait ready err") - else: - NativeLog.add_trace_critical("[DeepSleep][Stable] SleepTime:%d" % RandomTime) - - self.serial_write_line("SSC1", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) - self.check_response("SSC1", "+GPIO_SET:OK") - - time.sleep(1) - return result - - def cleanup(self): - self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_CHIP_RESET, GPIO_EDGE_DELAY)) - self.check_response("SSC2", "+GPIO_SET:OK") - - def execute(self): - TCActionBase.TCActionBase.execute(self) - self.serial_write_line("SSC2", "sta -D") - self.check_response("SSC2", "+QAP") - self.serial_write_line("SSC1", "sta -D") - self.check_response("SSC1", "+QAP") - try: - test_mode = self.test_mode - test_count = self.test_count - except StandardError, e: - return - - # self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_CHIP_RESET, GPIO_EDGE_DELAY)) - # self.check_response("SSC2", "+GPIO_SET:OK") - # time.sleep(1) - - if "stable" in test_mode: - for i in range(test_count): - # result = self.deep_sleep_wakeup_flash_gpio_status() - result = self.deep_sleep_stable() - elif "measure_current" in test_mode: - for i in range(test_count): - result = self.deep_sleep_current_measure() - elif "timeout" in test_mode: - for i in range(test_count): - result = self.deep_sleep_timeout() - elif "wakeup" in test_mode: - for i in range(test_count): - result = self.deep_sleep_wakeup() - elif "wake_option" in test_mode: - for i in range(test_count): - result = self.wake_option() - - self.set_result("Succeed") - pass - - -def main(): - pass - - -if __name__ == '__main__': - main() diff --git a/components/test/TestCaseScript/SleepMode/ForceSleep.py b/components/test/TestCaseScript/SleepMode/ForceSleep.py deleted file mode 100755 index 4938a97c2a..0000000000 --- a/components/test/TestCaseScript/SleepMode/ForceSleep.py +++ /dev/null @@ -1,254 +0,0 @@ -import random -import os -import time - -from TCAction import TCActionBase, PerformanceTCBase -from Utility import MakeFolder -from Utility import MultimeterUtil -from NativeLog import NativeLog - -LOG_PATH = os.path.join("AT_LOG", "SLEEP") - -SLEEP_MODE_LIST = ["none_sleep", "light_sleep", "modem_sleep"] -SLEEP_MODE = dict(zip(SLEEP_MODE_LIST, range(len(SLEEP_MODE_LIST)))) - -SAMPLE_RATE = 0.002 -SAMPLE_NUM = 512 -MAX_VALUE = 1 -Y_AXIS_LABEL = "Current (mA)" - -MEASURE_FREQ_HOUR = 3600 - -GPIO_WAKE_UP = 15 -GPIO_EDGE_DELAY = 120 # 20 ms -GPIO_CHIP_RESET = 14 -GPIO_CHIP_RESET_DELAY = 100 - -NONE_SLEEP_MIN_CUR = 30 -LIGHT_SLEEP_MIN_CUR = 1.5 -MODEM_SLEEP_MIN_CUR = 20 - -LIGHT_SLEEP_WAKEUP_DELAY = 0.01 - - -class ForceSleep(PerformanceTCBase.PerformanceTCBase): - - def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): - PerformanceTCBase.PerformanceTCBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - self.test_mode = "mode_change" - self.test_count = 100 - self.sleep_mode = SLEEP_MODE_LIST - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - self.log_folder = MakeFolder.make_folder(os.path.join(LOG_PATH, - "FORCE_SLEEP_%s_%s" % (self.test_mode, - time.strftime("%d%H%M%S", - time.localtime())))) - self.multimeter = MultimeterUtil.MultimeterUtil(self.log_folder) - - @staticmethod - def find_min_items(item_list, count): - assert count < len(item_list) - min_items = [] - for i in range(count): - min_val = min(item_list) - min_items.append(min_val) - item_list.remove(min_val) - return min_items - - def sleep_time_boundary_test(self): - result = True - self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) - time.sleep(LIGHT_SLEEP_WAKEUP_DELAY) - self.serial_write_line("SSC1", "op -S -o 0") - self.check_response("SSC2", "+GPIO_SET:OK") - if self.check_response("SSC1", "+MODE:OK") is False: - result = False - self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) - time.sleep(LIGHT_SLEEP_WAKEUP_DELAY) - self.serial_write_line("SSC1", "fsleep -S -t 1") - self.check_response("SSC2", "+GPIO_SET:OK") - if self.check_response("SSC1", "+FSLEEP_MODE:OK") is False: - result = False - self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) - time.sleep(LIGHT_SLEEP_WAKEUP_DELAY) - self.serial_write_line("SSC1", "fsleep -D -d 0") - self.check_response("SSC2", "+GPIO_SET:OK") - # if self.check_response("SSC1", "+FSLEEP_MODE:OK") is False: - # result = False - time.sleep(1) - current_line = self.multimeter.measure_current(sample_rate=SAMPLE_RATE, - sample_num=SAMPLE_NUM, - max_value=MAX_VALUE) - min_items = self.find_min_items(current_line, 10) - average_val = float(0) - for val in min_items: - average_val += val - average_val /= 10 - if average_val > LIGHT_SLEEP_MIN_CUR: - NativeLog.add_trace_critical("[ForceSleep][Boundary] did not enter light sleep %d" % average_val) - result = False - return result - else: - NativeLog.add_trace_critical("[ForceSleep][Boundary] enter light sleep") - - for i in range(3): - time.sleep(MEASURE_FREQ_HOUR) - for j in range(3): - time.sleep(10) - current_line = self.multimeter.measure_current(sample_rate=SAMPLE_RATE, - sample_num=SAMPLE_NUM, - max_value=MAX_VALUE) - self.multimeter.draw_graph(current_line, SAMPLE_RATE, - "light_sleep_boundary_%s_%s" % (i, j), Y_AXIS_LABEL) - pass - - self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) - self.check_response("SSC2", "+GPIO_SET:OK") - time.sleep(1) - self.serial_write_line("SSC1", "reboot") - self.check_response("SSC1", "ready!!!") - self.serial_write_line("SSC1", "fsleep -S -t 1") - if self.check_response("SSC1", "+FSLEEP_MODE:OK") is False: - result = False - self.serial_write_line("SSC1", "") - self.serial_write_line("SSC1", "fsleep -B -t 1") - if self.check_response("SSC1", "+FSLEEP_MODE:OK") is False: - result = False - time.sleep(MEASURE_FREQ_HOUR) - self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_CHIP_RESET,GPIO_CHIP_RESET_DELAY)) - return result - - def force_sleep_current_measure(self, sleep_mode): - result = True - # choose sleep mode - sleep_mode_enum = SLEEP_MODE[sleep_mode] - - self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) - time.sleep(LIGHT_SLEEP_WAKEUP_DELAY) - self.serial_write_line("SSC1", "op -S -o 0") - if self.check_response("SSC1", "+MODE:OK") is False: - result = False - self.check_response("SSC2", "+GPIO_SET:OK") - - # set sleep mode - self.serial_write_line("SSC1", "fsleep -S -t %s" % sleep_mode_enum) - if self.check_response("SSC1", "+FSLEEP_MODE:OK") is False: - result = False - self.serial_write_line("SSC1", "fsleep -D -d 0") - # if self.check_response("SSC1", "+FSLEEP_MODE:OK") is False: - # result = False - - time.sleep(3) - - for i in range(10): - time.sleep(10) - # measure current - current_line = self.multimeter.measure_current(sample_rate=SAMPLE_RATE, - sample_num=SAMPLE_NUM, - max_value=MAX_VALUE) - self.multimeter.draw_graph(current_line, SAMPLE_RATE, - "force_%s_sleep_current_%s" % (sleep_mode, i), Y_AXIS_LABEL) - NativeLog.add_trace_critical("[ForceSleep][current_measure] force_%s_%d"% (sleep_mode,i)) - - # self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP,GPIO_EDGE_DELAY)) - # self.check_response("SSC2", "+GPIO_SET:OK") - # self.serial_write_line("SSC1", "reboot") - # self.check_response("SSC1", "ready!!!") - self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_CHIP_RESET, GPIO_CHIP_RESET_DELAY)) - self.check_response("SSC2", "+GPIO_SET:OK") - if self.check_response("SSC1", "ready!!!") is False: - result = False - time.sleep(1) - return result - - def force_sleep_illegal_enter(self): - result = True - # choose sleep mode - - self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) - time.sleep(LIGHT_SLEEP_WAKEUP_DELAY) - self.serial_write_line("SSC1", "op -S -o 2") - if self.check_response("SSC1", "+MODE:OK") is False: - result = False - self.check_response("SSC2", "+GPIO_SET:OK") - - # set sleep mode - self.serial_write_line("SSC1", "fsleep -D -d 0") - if self.check_response("SSC1", "ready!!!", timeout=10) is False: - result = False - time.sleep(5) - return result - - def force_sleep_stable_test(self): - result = True - # choose sleep mode - - self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) - time.sleep(LIGHT_SLEEP_WAKEUP_DELAY) - self.serial_write_line("SSC1", "fsleep -L") - if self.check_response("SSC1", "+MODE:OK") is False: - result = False - self.check_response("SSC2", "+GPIO_SET:OK") - - time.sleep(3600) - self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_CHIP_RESET, GPIO_CHIP_RESET_DELAY)) - time.sleep(5) - return result - - def cleanup(self): - self.serial_write_line("SSC2", "gpio -E -p %d -t 0 -d %d" % (GPIO_WAKE_UP, GPIO_EDGE_DELAY)) - time.sleep(LIGHT_SLEEP_WAKEUP_DELAY) - self.serial_write_line("SSC1", "reboot") - self.check_response("SSC1", "ready!!!") - self.check_response("SSC2", "+GPIO_SET:OK") - - def execute(self): - TCActionBase.TCActionBase.execute(self) - self.serial_write_line("SSC2", "sta -D") - self.check_response("SSC2", "+QAP") - self.serial_write_line("SSC1", "sta -D") - self.check_response("SSC1", "+QAP") - try: - test_mode = self.test_mode - test_count = self.test_count - sleep_mode = self.sleep_mode - except StandardError, e: - return - - # set gpio to input on sleep target - self.serial_write_line("SSC1", "gpio -G -p %d" % GPIO_WAKE_UP) - self.check_response("SSC1", "+GPIO_GET") - self.serial_write_line("SSC1", "gpio -G -p %d" % GPIO_CHIP_RESET) - self.check_response("SSC1", "+GPIO_GET") - - if test_mode == "boundary_test": - for i in range(test_count): - result = self.sleep_time_boundary_test() - pass - elif test_mode == "measure_current": - for j in range(test_count): - for mode in sleep_mode: - result = self.force_sleep_current_measure(mode) - pass - elif test_mode == "illegal_enter": - for i in range(test_count): - result = self.force_sleep_illegal_enter() - pass - elif test_mode == "stable_test": - for i in range(test_count): - result = self.force_sleep_stable_test() - pass - pass - - -def main(): - pass - - -if __name__ == '__main__': - main() diff --git a/components/test/TestCaseScript/SleepMode/__init__.py b/components/test/TestCaseScript/SleepMode/__init__.py deleted file mode 100755 index fcd54657f3..0000000000 --- a/components/test/TestCaseScript/SleepMode/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__all__ = ["AutoSleep", "DeepSleep", "ForceSleep"] diff --git a/components/test/TestCaseScript/StableTest/StableCase1.py b/components/test/TestCaseScript/StableTest/StableCase1.py deleted file mode 100755 index 2554c1499b..0000000000 --- a/components/test/TestCaseScript/StableTest/StableCase1.py +++ /dev/null @@ -1,160 +0,0 @@ -import time -import random -import threading - -from TCAction import TCActionBase -from NativeLog import NativeLog - - -class StableCase1(TCActionBase.CommonTCActionBase): - - def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): - TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - self.exit_event = threading.Event() - self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) - pass - - def check_wifi_status(self, data): - if data.find("+JAP:DISCONNECTED") != -1: - self.exit_event.set() - NativeLog.add_trace_critical("[Wifi] Disconnected") - pass - - def execute(self): - TCActionBase.TCActionBase.execute(self) - self.result_cntx.start() - - try: - # configurable params - # target role - target_role = self.target_role - # enable tcp send/recv - tcp_enable = self.tcp_enable - # enable udp send/recv - udp_enable = self.udp_enable - # enable ping - ping_enable = self.ping_enable - # delay range - delay_range = self.delay_range - # test time in hours - test_time = self.test_time * 3600 - # configurable params - except StandardError, e: - NativeLog.add_trace_critical("Error configuration for TCPTransparent script, error is %s" % e) - raise StandardError("Error configuration") - - if target_role == "AP": - pc_ip = "" - target_ip = "" - elif target_role == "STA": - pc_ip = "" - target_ip = "" - else: - raise StandardError("target role only support AP or STA") - - # step 1, create UDP socket and TCP server - checker_stings = ["R SSC1 A :BIND:(\d+),OK"] - test_action_string = ["SSC SSC1 soc -B -t UDP -p "] - fail_string = "Fail, Fail to create UDP socket" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - checker_stings = ["R SSC1 A :BIND:(\d+),OK"] - test_action_string = ["SSC SSC1 soc -B -t TCP -p "] - fail_string = "Fail, Fail to create tcp server" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - checker_stings = ["R SSC1 RE LISTEN:(\d+),OK"] - test_action_string = ["SSC SSC1 soc -L -s "] - fail_string = "Fail, Fail to listen" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - # step 2, PC connect to 8266 tcp server, PC create UDP socket - checker_stings = ["R SOC_COM C OK"] - test_action_string = ["SOC SOC1 BIND %s" % pc_ip] - fail_string = "Fail, Fail to create udp socket on PC" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - checker_stings = ["P SSC1 A :ACCEPT:(\d+),\d+", "P SOC_COM C OK"] - test_action_string = ["SOC SOC2 CONNECT %s 0 %s" % (target_ip, pc_ip)] - fail_string = "Fail, Fail to create tcp socket on PC" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - start_time = time.time() - total_test_count = ping_fail_count = tcp_fail_count = udp_fail_count = 0 - - # step 3, start do tcp/udp/ping - while time.time() - start_time < test_time and self.exit_event.isSet() is False: - total_test_count += 1 - if ping_enable is True: - # do ping - checker_stings = ["P PC_COM RE \+PING:\d+ms"] - test_action_string = ["PING %s -n 1 -w 1000" % target_ip] - fail_string = "Fail, Fail to ping target" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - ping_fail_count += 1 - NativeLog.add_prompt_trace("[ping fail] fail/total = %s/%s" - % (ping_fail_count, total_test_count)) - pass - - data_len = random.randint(1, 1460) - - if tcp_enable is True: - # do tcp send/recv - checker_stings = ["P SSC1 SL +%s" % data_len, "P SOC2 RL %s" % data_len] - test_action_string = ["SSC SSC1 soc -S -s -l %s" % data_len, - "SOC SOC2 SEND %s" % data_len] - fail_string = "Fail, Fail to send/recv tcp" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - tcp_fail_count += 1 - NativeLog.add_prompt_trace("[tcp fail] fail/total = %s/%s" - % (tcp_fail_count, total_test_count)) - # tcp fail, break - self.exit_event.set() - pass - - if udp_enable is True: - # do udp send/recv - checker_stings = ["P SSC1 SL +%s" % data_len, "P SOC1 RL %s" % data_len] - test_action_string = ["SSC SSC1 soc -S -s " - "-i %s -p -l %s" % (pc_ip, data_len), - "SOC SOC1 SENDTO %s %s" % (data_len, target_ip)] - fail_string = "Fail, Fail to sendto/recvfrom udp" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, check_time=20) is False: - udp_fail_count += 1 - NativeLog.add_prompt_trace("[udp fail] fail/total = %s/%s" - % (udp_fail_count, total_test_count)) - pass - - # sleep - time.sleep(random.randint(delay_range[0], delay_range[1])) - pass - - # finally, execute done - if self.exit_event.isSet() is False: - self.result_cntx.set_result("Succeed") - - def result_check(self, port_name, data): - self.result_cntx.append_data(port_name, data) - if port_name != "SOC1" and port_name != "SOC2": - # socket received data do not need to be logged - TCActionBase.CommonTCActionBase.result_check(self, port_name, data) - if port_name == "SSC1": - self.check_wifi_status(data) - - -def main(): - pass - -if __name__ == '__main__': - main() diff --git a/components/test/TestCaseScript/StableTest/__init__.py b/components/test/TestCaseScript/StableTest/__init__.py deleted file mode 100755 index be905f816c..0000000000 --- a/components/test/TestCaseScript/StableTest/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__all__ = ["StableCase1"] diff --git a/components/test/TestCaseScript/TCPIPStress/ARPStress.py b/components/test/TestCaseScript/TCPIPStress/ARPStress.py deleted file mode 100755 index 38dcb8fd8b..0000000000 --- a/components/test/TestCaseScript/TCPIPStress/ARPStress.py +++ /dev/null @@ -1,121 +0,0 @@ -import time - -from NativeLog import NativeLog -from TCAction import TCActionBase -from comm.NIC import Adapter - -WARNING_COUNT = 5 - - -class ARPStress(TCActionBase.CommonTCActionBase): - - def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): - TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - self.adapter = None - self.target_mode = "STA" - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) - pass - - def cleanup(self): - self.adapter.close() - del self.adapter - - def execute(self): - TCActionBase.TCActionBase.execute(self) - self.result_cntx.start() - - try: - # configurable params - test_time = self.test_time * 60 - # test frequency min should be 0.1s, otherwise reply could be missed - test_freq = self.test_freq if self.test_freq > 0.1 else 0.1 - # test softAP or sta - target_mode = self.target_mode - # configurable params - except StandardError, e: - NativeLog.add_trace_critical("Error configuration for ARPStress script, error is %s" % e) - raise StandardError("Error configuration") - - # get parameters - if target_mode == "STA": - target_ip = self.get_parameter("target_ip") - target_mac = self.get_parameter("target_mac") - pc_mac = self.get_parameter("pc_nic_mac") - pc_nic_name = self.get_parameter("pc_nic") - elif target_mode == "SoftAP": - target_ip = self.get_parameter("target_ap_ip") - target_mac = self.get_parameter("target_ap_mac") - pc_mac = self.get_parameter("pc_wifi_nic_mac") - pc_nic_name = self.get_parameter("pc_wifi_nic") - else: - raise StandardError("Unsupported target mode: %s" % target_mode) - - time_start = time.time() - - # open device - self.adapter = Adapter.Adapter(pc_nic_name, "capture+send") - ret = self.adapter.set_filter("arp and ether src %s and ether dst %s" % (target_mac, pc_mac)) - if ret != "LIBPCAP_SUCCEED": - NativeLog.add_trace_critical("ARP Stress test error: %s" % ret) - return - - ret = self.adapter.start_capture() - if ret != "LIBPCAP_SUCCEED": - NativeLog.add_trace_critical("ARP Stress test error: %s" % ret) - return - - arp_pdu = self.adapter.create_pdu("ARP", self.adapter.create_payload(), - arp_op_code="request", arp_target_proto_addr=target_ip, - ethernet_dst_addr="ff:ff:ff:ff:ff:ff") - - data = arp_pdu.to_bytes() - - total_test_count = total_fail_count = successive_fail_count = most_successive_fail_count = 0 - - while (time.time() - time_start) < test_time: - # send arp req - ret = self.adapter.ether_send(data) - if ret != "LIBNET_SUCCEED": - NativeLog.add_prompt_trace("libnet send fail, %s" % ret) - continue - total_test_count += 1 - # wait for reply - time.sleep(test_freq) - # should get one arp reply - pdu_list = self.adapter.get_packets() - - if len(pdu_list) == 0: - # failed to get arp reply - total_fail_count += 1 - successive_fail_count += 1 - if successive_fail_count > WARNING_COUNT: - NativeLog.add_trace_critical("ARP Fail: successive fail %u times, total tested %u times" - % (successive_fail_count, total_test_count)) - else: - most_successive_fail_count = most_successive_fail_count \ - if most_successive_fail_count > successive_fail_count \ - else successive_fail_count - successive_fail_count = 0 - pass - NativeLog.add_trace_critical("ARP stress test, total %s times, failed %s times, most successive fail count %s" - % (total_test_count, total_fail_count, most_successive_fail_count)) - self.result_cntx.set_result("Succeed") - - # finally, execute done - - def result_check(self, port_name, data): - TCActionBase.CommonTCActionBase.result_check(self, port_name, data) - self.result_cntx.append_data(port_name, data) - - -def main(): - pass - -if __name__ == '__main__': - main() diff --git a/components/test/TestCaseScript/TCPIPStress/PingStress.py b/components/test/TestCaseScript/TCPIPStress/PingStress.py deleted file mode 100755 index 71ab91ce5a..0000000000 --- a/components/test/TestCaseScript/TCPIPStress/PingStress.py +++ /dev/null @@ -1,122 +0,0 @@ -import time - -from NativeLog import NativeLog -from TCAction import TCActionBase -from comm.NIC import Adapter - -WARNING_COUNT = 2 - - -class PingStress(TCActionBase.CommonTCActionBase): - - def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): - TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - self.adapter = None - self.target_mode = "STA" - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) - pass - - def cleanup(self): - self.adapter.close() - del self.adapter - - def execute(self): - TCActionBase.TCActionBase.execute(self) - self.result_cntx.start() - - try: - # configurable params - test_time = self.test_time * 60 - # ping data len - ping_len = self.ping_len - # test frequency min should be 0.1s, otherwise reply could be missed - test_freq = self.test_freq if self.test_freq > 0.1 else 0.1 - # target mode - target_mode = self.target_mode - # configurable params - except StandardError, e: - NativeLog.add_trace_critical("Error configuration for PingStress script, error is %s" % e) - raise StandardError("Error configuration") - - if target_mode == "STA": - target_ip = self.get_parameter("target_ip") - target_mac = self.get_parameter("target_mac") - pc_mac = self.get_parameter("pc_nic_mac") - pc_nic_name = self.get_parameter("pc_nic") - elif target_mode == "SoftAP": - target_ip = self.get_parameter("target_ap_ip") - target_mac = self.get_parameter("target_ap_mac") - pc_mac = self.get_parameter("pc_wifi_nic_mac") - pc_nic_name = self.get_parameter("pc_wifi_nic") - else: - raise StandardError("Unsupported target mode: %s" % target_mode) - - time_start = time.time() - # open device - self.adapter = Adapter.Adapter(pc_nic_name, "capture+send") - - ret = self.adapter.set_filter("icmp[icmpcode]=icmp-echoreply and ether src %s and ether dst %s" - % (target_mac, pc_mac)) - if ret != "LIBPCAP_SUCCEED": - NativeLog.add_trace_critical("PING Stress test error: %s" % ret) - return - - ret = self.adapter.start_capture() - if ret != "LIBPCAP_SUCCEED": - NativeLog.add_trace_critical("PING Stress test error: %s" % ret) - return - - total_test_count = total_fail_count = successive_fail_count = most_successive_fail_count = 0 - - while (time.time() - time_start) < test_time: - - ping_pdu = self.adapter.create_pdu("ICMP", self.adapter.create_payload("A" * ping_len), - icmp_type="echo-request", ipv4_protocol="ICMP", - ipv4_dst_ip=target_ip, ethernet_dst_addr=target_mac) - # send ping req - ret = self.adapter.ether_send(ping_pdu.to_bytes()) - if ret != "LIBNET_SUCCEED": - NativeLog.add_prompt_trace("libnet send fail, %s" % ret) - continue - total_test_count += 1 - # wait for reply - time.sleep(test_freq) - # should get one ping reply - pdu_list = self.adapter.get_packets() - - if len(pdu_list) == 0: - # failed to get ping reply - total_fail_count += 1 - successive_fail_count += 1 - if successive_fail_count > WARNING_COUNT: - NativeLog.add_trace_critical("Ping Fail: successive fail %u times, total tested %u times" - % (successive_fail_count, total_test_count)) - pass - else: - most_successive_fail_count = most_successive_fail_count \ - if most_successive_fail_count > successive_fail_count \ - else successive_fail_count - successive_fail_count = 0 - pass - pass - NativeLog.add_trace_critical("Ping stress test, total %s times, failed %s times, most successive fail count %s" - % (total_test_count, total_fail_count, most_successive_fail_count)) - self.result_cntx.set_result("Succeed") - # finally, execute done - - def result_check(self, port_name, data): - TCActionBase.CommonTCActionBase.result_check(self, port_name, data) - self.result_cntx.append_data(port_name, data) - - -def main(): - pass - -if __name__ == '__main__': - main() diff --git a/components/test/TestCaseScript/TCPIPStress/__init__.py b/components/test/TestCaseScript/TCPIPStress/__init__.py deleted file mode 100755 index 25ae689179..0000000000 --- a/components/test/TestCaseScript/TCPIPStress/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__all__ = ["ARPStress", "PingStress"] diff --git a/components/test/TestCaseScript/TCPStress/TCPAP4STA.py b/components/test/TestCaseScript/TCPStress/TCPAP4STA.py deleted file mode 100755 index 95be6fbe4f..0000000000 --- a/components/test/TestCaseScript/TCPStress/TCPAP4STA.py +++ /dev/null @@ -1,168 +0,0 @@ -from TCAction import TCActionBase -from NativeLog import NativeLog -import copy -import time -import random -import string - - -class TCPAP4STAResultCheckCntx(TCActionBase.ResultCheckContext): - - def __init__(self, test_action, test_env, name): - TCActionBase.ResultCheckContext.__init__(self, test_action, test_env, name) - self.failed_port = [] - pass - - def run(self): - - while True: - exit_flag = self.wait_exit_event(1) - # force exit - if exit_flag is True: - break - try: - self.lock_data() - temp_cache = copy.deepcopy(self.data_cache) - self.data_cache = [] - finally: - self.unlock_data() - - for _cache in temp_cache: - _data = _cache[1] - if _data.find("user_test_tcpclient_recon_cb") != -1 or _data.find("discon") != -1 \ - or _data.find("No heap available") != -1: - self.failed_port.append(_cache[0]) - NativeLog.add_trace_critical("TCPAP4STA failed, failed on %s" % _cache[0]) - pass - if len(self.failed_port) != 0: - # disconnect happen - break - - def get_test_results(self): - return self.failed_port - - -class TCPAP4STA(TCActionBase.CommonTCActionBase): - - def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): - TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) - pass - - def execute(self): - TCActionBase.TCActionBase.execute(self) - self.result_cntx.start() - - try: - # configurable params - send_len = self.send_len - # test count - test_count = self.test_count - # server port - server_port = self.server_port - # ap ip - ap_ip = self.ap_ip - # server echo - server_echo = self.server_echo - # station number - sta_number = self.sta_number - # pass standard - pass_standard = self.pass_standard - # send delay - send_delay = self.send_delay - # configurable params - except StandardError, e: - NativeLog.add_trace_critical("Error configuration for TCPTransparent script, error is %s" % e) - raise StandardError("Error configuration") - - # step0 reboot - checker_stings = [] - test_action_string = [] - - for i in range(sta_number+1): - checker_stings.append("P SSC%d C !!!ready!!!" % (i+1)) - test_action_string.append("SSCC SSC%d reboot" % (i+1)) - - fail_string = "Fail, Fail to reboot" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - # step1 set ap on SSC1, create server - ssid = "".join([random.choice(string.lowercase) for m in range(10)]) - password = "".join([random.choice(string.lowercase) for m in range(10)]) - checker_stings = ["R SSC1 C dhcp%20server%20start"] - test_action_string = ["SSCC SSC1 ap -S -s %s -p %s -n 10 -t 0 -m 8" % (ssid, password)] - fail_string = "Fail, Fail set ap" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - checker_stings = ["R SSC1 C server%20starts%20at%20port"] - if server_echo is True: - test_action_string = ["SSCC SSC1 tcp -S -p %s -b 1" % server_port] - else: - test_action_string = ["SSCC SSC1 tcp -S -p %s" % server_port] - fail_string = "Fail, Fail create server" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - # step 2, 4 SSC target(SSC2 - SSC5) join SSC1 soft AP - checker_stings = [] - test_action_string = [] - - for i in range(sta_number): - checker_stings.append("P SSC%d C ip C mask C gw C get%%20ip%%20of" % (i+2)) - test_action_string.append("SSCC SSC%d ap -C -s %s -p %s" % (i+2, ssid, password)) - - fail_string = "Fail, Fail to connect to server" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - start_time = time.time() - - # step 3, create client on SSC2 - SSC5 - checker_stings = [] - test_action_string = [] - - for i in range(sta_number): - checker_stings.append("P SSC%d C tcp%%20client%%20connect%%20with%%20server" % (i+2)) - test_action_string.append("SSCC SSC%d tcp -W -i %s -p %s -c %s -n 1 -l %s -d %d" - % ((i+2), ap_ip, server_port, test_count, send_len, send_delay)) - - fail_string = "Fail, Fail to connect to server" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - # switch to new result context - self.result_cntx.stop_thread() - self.result_cntx.join() - self.result_cntx = TCPAP4STAResultCheckCntx(self, self.test_env, self.tc_name) - self.result_cntx.start() - - self.result_cntx.join() - - failed_port = self.result_cntx.get_test_results() - if (time.time() - start_time) > pass_standard: - self.result_cntx.set_result("Succeed") - else: - self.result_cntx.set_result("Failed") - NativeLog.add_trace_critical("Failed port: %s" % failed_port) - - # finally, execute done - - def result_check(self, port_name, data): - TCActionBase.CommonTCActionBase.result_check(self, port_name, data) - self.result_cntx.append_data(port_name, data) - - -def main(): - pass - -if __name__ == '__main__': - main() - diff --git a/components/test/TestCaseScript/TCPStress/TCPAPNSTA.py b/components/test/TestCaseScript/TCPStress/TCPAPNSTA.py deleted file mode 100755 index 6c160a9a00..0000000000 --- a/components/test/TestCaseScript/TCPStress/TCPAPNSTA.py +++ /dev/null @@ -1,209 +0,0 @@ -from TCAction import TCActionBase -from NativeLog import NativeLog -import time -import random -import string - - -TEST_COUNT_ONE_ROUND = 500 - - -class TCPAPNSTA(TCActionBase.CommonTCActionBase): - - def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): - TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) - pass - - def execute(self): - TCActionBase.TCActionBase.execute(self) - self.result_cntx.start() - - try: - # configurable params - send_len = self.send_len - # test count - test_count = self.test_count - # server port - server_port = self.server_port - # ap ip - ap_ip = self.ap_ip - # server echo - server_echo = self.server_echo - # station number - sta_number = self.sta_number - # pass standard - pass_standard = self.pass_standard - # send delay - send_delay = self.send_delay - # configurable params - except StandardError, e: - NativeLog.add_trace_critical("Error configuration for TCPTransparent script, error is %s" % e) - raise StandardError("Error configuration") - - # step0 reboot - checker_stings = [] - test_action_string = [] - - for i in range(sta_number+1): - checker_stings.append("P SSC%d C !!!ready!!!" % (i+1)) - test_action_string.append("SSCC SSC%d reboot" % (i+1)) - - fail_string = "Fail, Fail to reboot" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - # step1 set ap on SSC1, create server - checker_stings = ["R SSC1 C +MODE:OK"] - test_action_string = ["SSCC SSC1 op -S -o 2"] - fail_string = "Fail, Fail set mode" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - ssid = "".join([random.choice(string.lowercase) for m in range(10)]) - password = "".join([random.choice(string.lowercase) for m in range(10)]) - checker_stings = ["R SSC1 C +SAP:OK"] - test_action_string = ["SSCC SSC1 ap -S -s %s -p %s -n 10 -t 0 -m 8" % (ssid, password)] - fail_string = "Fail, Fail set ap" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - checker_stings = ["R SSC1 A :BIND:(\d+),OK"] - test_action_string = ["SSCC SSC1 soc -B -t TCP -p %s" % server_port] - fail_string = "Fail, Fail create server" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - checker_stings = ["R SSC1 RE LISTEN:(\d+),OK"] - test_action_string = ["SSCC SSC1 soc -L -s "] - fail_string = "Fail, Fail create server" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - # step 2, 8 SSC target(SSC2 - SSC9) join SSC1 soft AP - checker_stings = [] - test_action_string = [] - for i in range(sta_number): - checker_stings.append("P SSC%d C +MODE:OK" % (i+2)) - test_action_string.append("SSCC SSC%d op -S -o 1" % (i+2)) - fail_string = "Fail, Fail set mode" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - checker_stings = [] - test_action_string = [] - for i in range(sta_number): - checker_stings.append("P SSC%d C +JAP:CONNECTED,%s" % (i+2, ssid)) - test_action_string.append("SSCC SSC%d ap -C -s %s -p %s" % (i+2, ssid, password)) - fail_string = "Fail, Fail to connect to server" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - start_time = time.time() - - # step 3, create client on SSC2 - SSC9 - checker_stings = [] - test_action_string = [] - for i in range(sta_number): - checker_stings.append("P SSC%d A :BIND:(\d+),OK" % (i+2, i+2)) - test_action_string.append("SSCC SSC%d soc -B -t TCP" % (i+2)) - fail_string = "Fail, Fail to connect to server" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - for i in range(sta_number): - checker_stings = ["P SSC%d RE CONNECT:(\d+),OK" % (i+2), - "P SSC1 A :ACCEPT:(\d+),.+" % (i+2)] - test_action_string = ["SSCC SSC%d soc -C -s -i %s -p %s" % - (i+2, i+2, ap_ip, server_port)] - fail_string = "Fail, Fail to connect to server" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - # step 4, do send/recv - while test_count > 0: - _tmp_count = TEST_COUNT_ONE_ROUND if test_count - TEST_COUNT_ONE_ROUND > 0 else test_count - test_count -= TEST_COUNT_ONE_ROUND - - checker_stings = [] - test_action_string = [] - for i in range(sta_number): - checker_stings.append("P SSC%d RE \+SEND:\d+,OK NC CLOSED" % (i+2)) - test_action_string.append("SSC SSC%d soc -S -s -l %d -n %d -j %d" % - (i+2, i+2, send_len, _tmp_count, send_delay)) - if server_echo is True: - test_action_string.append("SSC SSC1 soc -S -s -l %d -n %d -j %d" % - (i+2, send_len, _tmp_count, send_delay)) - checker_stings.append("P SSC1 RE \"\+SEND:%%%%s,OK\"%%%%() NC CLOSED)" % - (i+2)) - - fail_string = "Fail, Failed to send/recv data" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, - check_freq=1, check_time=300) is False: - break - pass - - if (time.time() - start_time) > pass_standard: - self.result_cntx.set_result("Succeed") - else: - checker_stings = [] - test_action_string = [] - for i in range(sta_number + 1): - checker_stings.append("P SSC%d C CLOSEALL" % (i + 1)) - test_action_string.append("SSCC SSC%d soc -T" % (i + 1)) - fail_string = "Fail, Fail to close socket" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - server_port = random.randint(20000, 30000) - checker_stings = ["R SSC1 A :BIND:(\d+),OK"] - test_action_string = ["SSCC SSC1 soc -B -t TCP -p %s" % server_port] - fail_string = "Fail, Fail to bind socket" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - checker_stings = ["R SSC1 RE LISTEN:(\d+),OK"] - test_action_string = ["SSCC SSC1 soc -L -s "] - fail_string = "Fail, Fail to listen" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - checker_stings = [] - test_action_string = [] - for i in range(sta_number): - checker_stings.append("P SSC%d A :BIND:(\d+),OK" % (i + 2, i + 2)) - test_action_string.append("SSCC SSC%d soc -B -t TCP" % (i + 2)) - fail_string = "Fail, Fail to connect to server" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - for i in range(sta_number): - checker_stings = ["P SSC%d RE CONNECT:(\d+),OK" % (i + 2), - "P SSC1 A :ACCEPT:(\d+),.+" % (i + 2)] - test_action_string = ["SSCC SSC%d soc -C -s -i %s -p %s" % - (i + 2, i + 2, ap_ip, server_port)] - fail_string = "Fail, Fail to connect to server" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - self.result_cntx.set_result("Failed") - - # finally, execute done - - def result_check(self, port_name, data): - TCActionBase.CommonTCActionBase.result_check(self, port_name, data) - self.result_cntx.append_data(port_name, data) - - -def main(): - pass - -if __name__ == '__main__': - main() - diff --git a/components/test/TestCaseScript/TCPStress/TCPConnStressTC.py b/components/test/TestCaseScript/TCPStress/TCPConnStressTC.py deleted file mode 100755 index b04ede6acb..0000000000 --- a/components/test/TestCaseScript/TCPStress/TCPConnStressTC.py +++ /dev/null @@ -1,363 +0,0 @@ -import random -import re -import sys -import threading -import time - -import TCPConnUtility -from NativeLog import NativeLog -from TCAction import TCActionBase - -reload(sys) -sys.setdefaultencoding('iso-8859-1') # # use encoding that with 1 Byte length and contain 256 chars - - -DEFAULT_MAX_CONN_ALLOWED = 5 - - -# complicated design because I want to make this script applied for all TCP connect/close test scenarios -# basic flow: try to create max connections, send/recv data if possible, close all connections -# connect: -# 1. find available (target_link_id, socket_id) list, -# notice that target_link_id maybe not correct if PC is client -# (during that time, some link may timeout and got disconnected from FIN_WAIT or other state) -# 2. choose one method from method set, try to connect -# 3. update state table: a)check result and destination state, b)find real target_link_id, c)update -# send/recv data: -# 1. find channels that are possible to send data on all connections -# 2. send data on possible channels -# disconnect: -# 1. find available connections -# 2. choose one method from disconnect set, try to disconnect -# 3. update state table (phase 1) -# async process: -# listen on AT UART port, record all "x,CONNECT" and "x,CLOSE" command -# for "x,CONNECT", append them to self.target_link_id_list, used when need to find real target_link_id -# for "x,CLOSE", update state table (phase 2), if matching connection is pending on wait state, -# close them and remove from state table -class TCPConnStressTC(TCActionBase.CommonTCActionBase): - - def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): - TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - self.__at1_buff = "" - self.max_conn_allowed = test_env.get_variable_by_name("max_conn") - self.enable_log = True - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - - # connection_state_dict: {target_link_id: [socket_id, target_state, socket_state, is_closed]} - # is_closed: found "x,CLOSE" in AT UART port - self.connection_state_dict = dict(zip(range(self.max_conn_allowed), [None] * self.max_conn_allowed)) - self.created_link_id_list = [] - - self.__available_soc_id = range(2, 2+self.max_conn_allowed) - self.__available_link_id = range(self.max_conn_allowed) - - self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) - self.utility = TCPConnUtility.TCPConnUtility(self) - self.state_lock = threading.Lock() - self.link_id_lock = threading.Lock() - self.available_id_lock = threading.Lock() - pass - - def __add_log(self, log_str): - if self.enable_log is True: - NativeLog.add_trace_info(log_str) - - def __get_created_target_link_id(self): - self.link_id_lock.acquire() - try: - link_id = self.created_link_id_list[-1] - self.created_link_id_list = [] - finally: - self.link_id_lock.release() - return link_id - pass - - def __set_created_target_link_id(self, link_id): - self.link_id_lock.acquire() - try: - self.created_link_id_list.append(link_id) - finally: - self.link_id_lock.release() - pass - - def __find_channel_list(self): - channel_list = [] # # [(socket_id, able_to_send, link_id, able_to_send), ] - self.state_lock.acquire() - try: - for link_id in self.connection_state_dict: - state = self.connection_state_dict[link_id] - if state is not None: - channel_list.append([state[0], self.utility.is_able_to_send_data(state[2]), - link_id, self.utility.is_able_to_send_data(state[1])]) - finally: - self.state_lock.release() - return channel_list - pass - - def __established_connection_list(self): - conn_list = [] # # [(socket_id, link_id), ] - self.state_lock.acquire() - try: - for link_id in self.connection_state_dict: - state = self.connection_state_dict[link_id] - if state is not None: - if self.utility.is_established_connection([state[1], state[2]]) is True: - conn_list.append([state[0], link_id]) - finally: - self.state_lock.release() - return conn_list - pass - - # find free socket_id, target_link_id pair - def __get_available_id_list(self): - self.available_id_lock.acquire() - try: - id_list = zip(self.__available_soc_id, self.__available_link_id) - finally: - self.available_id_lock.release() - return id_list - pass - - def __update_available_id_list(self, soc_id, link_id, action="ADD"): - self.available_id_lock.acquire() - try: - if action == "ADD": - self.__available_link_id.append(link_id) - self.__available_soc_id.append(soc_id) - self.__add_log("[AVAILABLE ID]soc %d link %d is available" % (soc_id, link_id)) - elif action == "REMOVE": - self.__available_link_id.remove(link_id) - self.__available_soc_id.remove(soc_id) - self.__add_log("[AVAILABLE ID]soc %d link %d is used" % (soc_id, link_id)) - finally: - self.available_id_lock.release() - - def __update_connection_state_item(self, target_link_id, socket_id=None, - target_state=None, socket_state=None, is_closed=None): - self.state_lock.acquire() - try: - state = self.connection_state_dict[target_link_id] - if state is None: - state = [None] * 4 - if socket_id is not None: - state[0] = socket_id - if target_state is not None: - state[1] = target_state - if socket_state is not None: - state[2] = socket_state - if is_closed is not None: - state[3] = is_closed - - # remove closed connections - closed = self.utility.is_closed_state(state[1]) and (state[3] is True) - if closed is True: - self.__update_available_id_list(state[0], target_link_id) - state = None - # if new connection created - if self.connection_state_dict[target_link_id] is None: - created = self.utility.is_created_state(state[1]) - if created is True: - self.__update_available_id_list(state[0], target_link_id, "REMOVE") - else: - # connection did not created, do not add them to connection state table - state = None - - # set new connection_state - self.connection_state_dict[target_link_id] = state - self.__add_log("[STATE] link id is %d, state is %s" % (target_link_id, state)) - except StandardError, e: - pass - finally: - self.state_lock.release() - pass - - # update state table: if result is false, return, if result is true: - # for connect, find real link id, update table according to destination state - # for disconnect, if target in SOC_CLOSE_STATE && catch "x,CLOSE" from AT, remove the item - def update_connection_state_table(self, conn_id, destination_state=None): - if isinstance(conn_id, list) is True or isinstance(conn_id, tuple) is True: - socket_id = conn_id[0] - try: - target_link_id = self.__get_created_target_link_id() - except IndexError: - target_link_id = conn_id[1] - self.__add_log("[STATE]fail to get link id, state is %s, %s" - % (destination_state[0], destination_state[1])) - self.__update_connection_state_item(target_link_id, socket_id, - destination_state[0], destination_state[1]) - pass - else: # # called when recv CLOSED - target_link_id = conn_id - self.__update_connection_state_item(target_link_id, is_closed=True) - pass - pass - - def process_at_data(self, data): - pos1 = 0 - pos2 = 0 - connect = re.compile("\d,CONNECT\r\n") - close = re.compile("\d,CLOSED\r\n") - connect_match = connect.findall(data) - close_match = close.findall(data) - close = re.compile("\d,CONNECT FAIL\r\n") - close_match += close.findall(data) - if len(connect_match) != 0: - pos1 = data.find(connect_match[-1]) + 9 - # append last connected link id - self.__set_created_target_link_id(int(connect_match[-1][:1])) - pass - if len(close_match) != 0: - pos2 = data.find(close_match[-1]) + 7 - # update for all closed links - for close_str in close_match: - self.update_connection_state_table(int(close_str[:1])) - pass - pos = pos1 if pos1 > pos2 else pos2 - - return data[pos:] - - def execute(self): - TCActionBase.TCActionBase.execute(self) - self.result_cntx.start() - - # configurable params - # mandatory params - try: - connect_method_set = self.connect_method_set - test_count = self.test_count - except StandardError, e: - NativeLog.add_trace_critical("Error configuration for TCPConnSingleMode script, error is %s" % e) - raise StandardError("Error configuration") - # optional params - try: - disconn_method_set = self.disconn_method_set - except StandardError: - disconn_method_set = ["D_05"] - pass - try: - delay = self.delay - except StandardError: - delay = 0 - pass - try: - check_data_len = self.check_data_len - except StandardError: - check_data_len = [0, 0] - pass - if isinstance(check_data_len, list) is False: - check_data_len = [check_data_len] * 2 - # configurable params - - # step1 use to create server on both PC and target side - checker_stings = ["SOCP SOC_COM L OK", "ATP AT1 L OK"] - test_action_string = ["SOC SOC1 LISTEN ", "ATC AT1 CIPSERVER 1 "] - fail_string = "Fail, Fail on create server" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - for tested_count in xrange(test_count): - # step2 do connect - available_id_list = self.__get_available_id_list() - - for conn_id in available_id_list: - connect_method = random.choice(connect_method_set) - # ret, destination_state = self.utility.execute_tcp_method(connect_method, conn_id) - try: - self.__add_log("[ACTION]connect method is %s, connect id is %s" - % (connect_method, conn_id)) - ret, destination_state = self.utility.execute_tcp_method(connect_method, conn_id) - except StandardError, e: - NativeLog.add_trace_critical("Error in connect, error is %s" % e) - raise StandardError("Exception happen when connect") - if ret is False: - # connect fail, should terminate TC and mark as fail - return - else: - # succeed, append to table - self.update_connection_state_table(conn_id, destination_state) - if delay != 0: - time.sleep(delay) - - # step 3 send/recv test data - # # [(socket_id, able_to_send, link_id, able_to_send)] - self.__add_log("[ACTION]SEND/RECV data") - channel_list = self.__find_channel_list() - for channel in channel_list: - _check_data_len = [0, 0] - if channel[1] is True: - _check_data_len[0] = check_data_len[0] - if channel[3] is True: - _check_data_len[1] = check_data_len[1] - ret = self.utility.send_test_data(channel[0], - channel[2], - _check_data_len) - if ret is False: - # send/recv fail, should terminate TC and mark as fail - return - if delay != 0: - time.sleep(delay) - - # step 4 close all established connections - # (socket_id, link_id) - conn_list = self.__established_connection_list() - for conn_id in conn_list: - disconn_method = random.choice(disconn_method_set) - try: - self.__add_log("[ACTION]disconnect method is %s, connect id is %s" - % (disconn_method, conn_id)) - ret, destination_state = self.utility.execute_tcp_method(disconn_method, conn_id) - except StandardError, e: - NativeLog.add_trace_critical("Error in disconnect, error is %s" % e) - raise StandardError("Exception happen when disconnect") - if ret is False: - # connect fail, should terminate TC and mark as fail - return - else: - # succeed, append to table - self.update_connection_state_table(conn_id, destination_state) - if delay != 0: - time.sleep(delay) - - # finally, execute done - self.result_cntx.set_result("Succeed") - - def result_check(self, port_name, data): - TCActionBase.CommonTCActionBase.result_check(self, port_name, data) - self.result_cntx.append_data(port_name, data) - # find "x,CONNECT" and "x,CLOSE" - if port_name.find("AT") != -1: - self.__at1_buff += data - self.__at1_buff = self.process_at_data(self.__at1_buff) - - -def main(): - at1_buff = "" - pos1 = 0 - pos2 = 0 - data = "dafgajglajdfg0,CLOSEjdalghalksdg1,CONNECT\r\n\r\n3,CONNECT4,CLOSEadfaasdf" - at1_buff += data - connect = re.compile("\d,CONNECT") - close = re.compile("\d,CLOSE") - connect_match = connect.findall(at1_buff) - close_match = close.findall(at1_buff) - if len(connect_match) != 0: - pos1 = at1_buff.find(connect_match[-1]) + 9 - pass - if len(close_match) != 0: - pos2 = at1_buff.find(close_match[-1]) + 7 - pass - pos = pos1 if pos1 > pos2 else pos2 - - at1_buff = at1_buff[pos:] - - pass - -if __name__ == '__main__': - main() - diff --git a/components/test/TestCaseScript/TCPStress/TCPConnUtility.py b/components/test/TestCaseScript/TCPStress/TCPConnUtility.py deleted file mode 100755 index 3059369010..0000000000 --- a/components/test/TestCaseScript/TCPStress/TCPConnUtility.py +++ /dev/null @@ -1,273 +0,0 @@ -from NativeLog import NativeLog - -# make sure target do not listen on this port -ERROR_PORT = 23333 - - -def unused_param(param): - return param - - -class TCPUtilError(StandardError): - pass - - -class TCPConnUtility(object): - METHOD_RESULT = {"C_01": ("ESTABLISHED", "ESTABLISHED"), # target TCP peer state, PC TCP peer state - "C_02": ("SYNC_SENT", "CLOSED"), - "C_03": ("CLOSED", "CLOSED"), - "C_04": ("SYN_RCVD", "ESTABLISHED"), - "C_05": ("ESTABLISHED", "ESTABLISHED"), - "C_06": ("CLOSED", "CLOSED"), - "C_07": ("CLOSED", "CLOSED"), - "C_08": ("CLOSED", "CLOSED"), - "D_01": ("TIME_WAIT", "CLOSED"), - "D_02": ("TIME_WAIT", "TIME_WAIT"), - "D_03": ("FIN_WAIT_2", "CLOSE_WAIT"), - "D_04": ("FIN_WAIT_1", "CLOSE_WAIT"), - "D_05": ("CLOSED", "TIME_WAIT"), - "D_06": ("CLOSED", "CLOSED"), - "D_07": ("CLOSE_WAIT", "FIN_WAIT2"), - "D_08": ("TIME_WAIT", "CLOSED"), } - - SOC_CLOSED_STATE = ("FIN_WAIT_1", "FIN_WAIT_2", "CLOSING", "TIME_WAIT", "LAST_ACK", "CLOSED") - SOC_CREATED_STATE = ("SYNC_RCVD", "SYNC_SENT", "ESTABLISHED") - SOC_SEND_DATA_STATE = ("ESTABLISHED", "CLOSE_WAIT") - SOC_ESTABLISHED_STATE = ("ESTABLISHED", ) - - def __init__(self, tc_action): - self.tc_action = tc_action - self.pc_server_port = "" - self.target_server_port = "" - self.pc_ip = "" - self.target_ip = "" - pass - - def config_parameters(self, pc_server_port=None, target_server_port=None, pc_ip=None, target_ip=None): - if pc_ip is not None: - self.pc_ip = pc_ip - if target_ip is not None: - self.target_ip = target_ip - if pc_server_port is not None: - self.pc_server_port = pc_server_port - if target_server_port is not None: - self.target_server_port = target_server_port - pass - - def __connect_c_01(self, conn_id): - checker_stings = ["SOCR SOC1 C +ACCEPT", "ATR AT1 NC CLOSE L OK"] - test_action_strings = ["ATC AT1 CIPSTART %d \"TCP\" %s %s" % - (conn_id[1], self.pc_ip, self.pc_server_port)] - fail_string = "Fail, Target failed on connect to PC server" - ret = self.tc_action.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) - if ret is False: - return ret - - checker_stings = ["SOCR SOC_COM L OK"] - test_action_strings = ["SOC SOC1 ACCEPT SOC%d" % conn_id[0]] - return self.tc_action.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) - pass - - def __connect_c_02(self, conn_id): - checker_stings = ["ATR AT1 C ERROR"] - test_action_strings = ["ATC AT1 CIPSTART %d \"TCP\" %s %s" % - (conn_id[1], self.pc_ip, ERROR_PORT)] - fail_string = "Fail, Target fail on connect to port not listened" - return self.tc_action.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) - pass - - def __connect_c_03(self, conn_id): - pass - - def __connect_c_04(self, conn_id): - pass - - def __connect_c_05(self, conn_id): - checker_stings = ["SOCP SOC_COM OK", "ATP AT1 C CONNECT"] - test_action_strings = ["SOC SOC%d CONNECT %s %s" % - (conn_id[0], self.target_server_port, self.target_ip)] - fail_string = "Fail, PC fail on connect to target server" - return self.tc_action.load_and_exe_one_step(checker_stings, test_action_strings, - fail_string, check_time=200, check_freq=0.01) - pass - - def __connect_c_06(self, conn_id): - pass - - def __connect_c_07(self, conn_id): - # no checker strings, only try to create - # while connect is a blocking function, will return till target reply RST - checker_stings = ["SOCR SOC_COM C CLOSE"] - test_action_strings = ["SOC SOC%d CONNECT %s %s" % - (conn_id[0], ERROR_PORT, self.target_ip)] - fail_string = "Fail, PC fail on connect to target server" - return self.tc_action.load_and_exe_one_step(checker_stings, test_action_strings, - fail_string, check_time=2000, check_freq=0.01) - pass - - def __connect_c_08(self, conn_id): - pass - - def __close_d_01(self, conn_id): - checker_stings = ["ATP AT1 C %d,CLOSED" % conn_id[1], "SOCP SOC_COM C CLOSE"] - test_action_strings = ["SOC SOC%d SETOPT CLOSE_OPT IMM_SEND_FIN" % conn_id[0], - "ATS AT1 AT+CIPCLOSE=%d" % conn_id[1]] - fail_string = "Fail, Fail to close socket using D_01" - return self.tc_action.load_and_exe_one_step(checker_stings, test_action_strings, - fail_string, check_time=200, check_freq=0.01) - pass - - def __close_d_02(self, conn_id): - pass - - def __close_d_03(self, conn_id): - checker_stings = [] - test_action_strings = ["SOC SOC%d SETOPT CLOSE_OPT WAIT_TO" % conn_id[0], - "ATS AT1 AT+CIPCLOSE=%d" % conn_id[1]] - fail_string = "Fail, Fail to close socket using D_01" - return self.tc_action.load_and_exe_one_step(checker_stings, test_action_strings, - fail_string, check_time=500, check_freq=0.01) - pass - - def __close_d_04(self, conn_id): - pass - - def __close_d_05(self, conn_id): - checker_stings = ["ATP AT1 C %d,CLOSED" % conn_id[1]] - test_action_strings = ["SOC SOC%d SETOPT CLOSE_OPT IMM_SEND_FIN" % conn_id[0], - "SOC SOC%d CLOSE" % conn_id[0]] - fail_string = "Fail, Fail to close socket using D_05" - return self.tc_action.load_and_exe_one_step(checker_stings, test_action_strings, - fail_string, check_time=200, check_freq=0.01) - pass - - def __close_d_06(self, conn_id): - # 1. set PC socket close option, stop calling recv; send in target - checker_stings = ["ATP AT1 C >"] - test_action_strings = ["SOC SOC%d STOPRECV" % conn_id[0], - "SOC SOC%d SETOPT CLOSE_OPT IMM_SEND_RST" % conn_id[0], - "ATS AT1 AT+CIPSEND=%d,5" % conn_id[1]] - fail_string = "Fail, Fail to close socket using D_06" - ret = self.tc_action.load_and_exe_one_step(checker_stings, test_action_strings, - fail_string, check_time=200, check_freq=0.01) - if ret is False: - return ret - - # 2. send 5 bytes to socket - checker_stings = ["ATP AT1 C OK"] - test_action_strings = ["ATSN AT1 5"] - fail_string = "Fail, Fail to close socket using D_06" - ret = self.tc_action.load_and_exe_one_step(checker_stings, test_action_strings, - fail_string, check_time=200, check_freq=0.01) - if ret is False: - return ret - - # 3. close socket - checker_stings = ["ATP AT1 OR 2 C %d,CONNECT C %d,CLOSED" % (conn_id[1], conn_id[1])] - test_action_strings = ["SOC SOC%d CLOSE" % conn_id[0]] - fail_string = "Fail, Fail to close socket using D_06" - return self.tc_action.load_and_exe_one_step(checker_stings, test_action_strings, - fail_string, check_time=200, check_freq=0.01) - pass - - def __close_d_07(self, conn_id): - pass - - def __close_d_08(self, conn_id): - pass - - def send_test_data(self, socket_id, target_link_id, check_data_len): - # check_data_len[0] for socket data len, check_data_len[1] for target link data len - fail_string = "Fail, Fail on send and recv data" - - ret = True - - for i in range(1): - if check_data_len[1] != 0: - checker_stings = ["ATP AT1 C >"] - test_action_strings = ["ATS AT1 AT+CIPSEND=%d,%d" % (target_link_id, check_data_len[1])] - if self.tc_action.load_and_exe_one_step(checker_stings, test_action_strings, - fail_string, check_time=20) is False: - NativeLog.add_trace_critical("Fail on target send command for link %d" % target_link_id) - ret = False - break - checker_stings = ["SOCP SOC%d RL %d" % (socket_id, check_data_len[1]), "ATP AT1 C OK"] - test_action_strings = ["ATSN AT1 %d" % check_data_len[1]] - if self.tc_action.load_and_exe_one_step(checker_stings, test_action_strings, - fail_string, check_time=20) is False: - NativeLog.add_trace_critical("Fail on target send for link %d, send or recv error" % target_link_id) - ret = False - break - - if check_data_len[0] != 0: - checker_stings = ["ATP AT1 DL %d+%d" % (target_link_id, check_data_len[0])] - test_action_strings = ["SOC SOC%d SEND %d" % (socket_id, check_data_len[0])] - - if self.tc_action.load_and_exe_one_step(checker_stings, test_action_strings, - fail_string, check_time=20) is False: - NativeLog.add_trace_critical("Fail to receive PC SOC%d sent data" % socket_id) - ret = False - break - - # return ret - # for now do not validate data - return True - - TCP_ACTION_DICT = {"C_01": __connect_c_01, - "C_02": __connect_c_02, - "C_03": __connect_c_03, - "C_04": __connect_c_04, - "C_05": __connect_c_05, - "C_06": __connect_c_06, - "C_07": __connect_c_07, - "C_08": __connect_c_08, - "D_01": __close_d_01, - "D_02": __close_d_02, - "D_03": __close_d_03, - "D_04": __close_d_04, - "D_05": __close_d_05, - "D_06": __close_d_06, - "D_07": __close_d_07, - "D_08": __close_d_08, - } - - def get_method_destination_state(self, method): - return self.METHOD_RESULT[method] - - def execute_tcp_method(self, method, conn_id): - if method in self.METHOD_RESULT: - return self.TCP_ACTION_DICT[method](self, conn_id), self.get_method_destination_state(method) - else: - raise TCPUtilError("Not TCP connection method") - pass - - def is_created_state(self, state): - if state in self.SOC_CREATED_STATE: - return True - else: - return False - - def is_closed_state(self, state): - if state in self.SOC_CLOSED_STATE: - return True - else: - return False - - def is_able_to_send_data(self, state): - if state in self.SOC_SEND_DATA_STATE: - return True - else: - return False - - def is_established_connection(self, state): - if state[0] in self.SOC_ESTABLISHED_STATE and state[1] in self.SOC_ESTABLISHED_STATE: - return True - else: - return False - - -def main(): - pass - -if __name__ == '__main__': - main() diff --git a/components/test/TestCaseScript/TCPStress/TCPConnection.py b/components/test/TestCaseScript/TCPStress/TCPConnection.py deleted file mode 100755 index 8b481c7df8..0000000000 --- a/components/test/TestCaseScript/TCPStress/TCPConnection.py +++ /dev/null @@ -1,321 +0,0 @@ -import random -import re -import socket -import threading -import time - -import TCPConnectionUtility -from NativeLog import NativeLog -from TCAction import PerformanceTCBase - -DELAY_RANGE = [10, 3000] -CONNECTION_STRUCTURE = ("Connection handler", "PC socket", "Target socket id", - "Target port", "PC port", "PC state", "Target state") - - -class CheckerBase(threading.Thread): - - CHECK_ITEM = ("CONDITION", "NOTIFIER", "ID", "DATA") - SLEEP_TIME = 0.1 # sleep 100ms between each check action - - def __init__(self): - threading.Thread.__init__(self) - self.setDaemon(True) - self.exit_event = threading.Event() - self.sync_lock = threading.Lock() - self.check_item_list = [] - self.check_item_id = 0 - - def run(self): - while self.exit_event.isSet() is False: - self.process() - pass - - def process(self): - pass - - def add_check_item(self, condition, notifier): - with self.sync_lock: - check_item_id = self.check_item_id - self.check_item_id += 1 - self.check_item_list.append(dict(zip(self.CHECK_ITEM, (condition, notifier, check_item_id, str())))) - return check_item_id - - def remove_check_item(self, check_item_id): - ret = None - with self.sync_lock: - check_items = filter(lambda x: x["ID"] == check_item_id, self.check_item_list) - if len(check_items) > 0: - self.check_item_list.remove(check_items[0]) - ret = check_items[0]["DATA"] - return ret - - def exit(self): - self.exit_event.set() - pass - - -# check on serial port -class SerialPortChecker(CheckerBase): - def __init__(self, serial_reader): - CheckerBase.__init__(self) - self.serial_reader = serial_reader - pass - - # check condition for serial is compiled regular expression pattern - @staticmethod - def do_check(check_item, data): - match = check_item["CONDITION"].search(data) - if match is not None: - pos = data.find(match.group()) + len(match.group()) - # notify user - check_item["NOTIFIER"]("serial", match) - else: - pos = -1 - return pos - - def process(self): - # do check - with self.sync_lock: - # read data - new_data = self.serial_reader() - # NativeLog.add_trace_info("[debug][read data] %s" % new_data) - # do check each item - for check_item in self.check_item_list: - # NativeLog.add_trace_info("[debug][read data][ID][%s]" % check_item["ID"]) - check_item["DATA"] += new_data - self.do_check(check_item, check_item["DATA"]) - time.sleep(self.SLEEP_TIME) - - -# handle PC TCP server accept and notify user -class TCPServerChecker(CheckerBase): - def __init__(self, server_sock): - CheckerBase.__init__(self) - self.server_sock = server_sock - server_sock.settimeout(self.SLEEP_TIME) - self.accepted_socket_list = [] - - # check condition for tcp accepted sock is tcp source port - @staticmethod - def do_check(check_item, data): - for sock_addr_pair in data: - addr = sock_addr_pair[1] - if addr[1] == check_item["CONDITION"]: - # same port, so this is the socket that matched, notify and remove it from list - check_item["NOTIFIER"]("tcp", sock_addr_pair[0]) - data.remove(sock_addr_pair) - - def process(self): - # do accept - try: - client_sock, addr = self.server_sock.accept() - self.accepted_socket_list.append((client_sock, addr)) - except socket.error: - pass - # do check - with self.sync_lock: - check_item_list = self.check_item_list - for check_item in check_item_list: - self.do_check(check_item, self.accepted_socket_list) - pass - - -# this thread handles one tcp connection. -class ConnectionHandler(threading.Thread): - CHECK_FREQ = CheckerBase.SLEEP_TIME/2 - - def __init__(self, utility, serial_checker, tcp_checker, connect_method, disconnect_method): - threading.Thread.__init__(self) - self.setDaemon(True) - self.utility = utility - self.connect_method = connect_method - self.disconnect_method = disconnect_method - self.exit_event = threading.Event() - # following members are used in communication with checker threads - self.serial_checker = serial_checker - self.tcp_checker = tcp_checker - self.serial_notify_event = threading.Event() - self.tcp_notify_event = threading.Event() - self.serial_result = None - self.tcp_result = None - self.serial_check_item_id = None - self.tcp_check_item_id = None - self.data_cache = None - pass - - def new_connection_structure(self): - connection = dict.fromkeys(CONNECTION_STRUCTURE, None) - connection["Connection handler"] = self - return connection - - def run(self): - while self.exit_event.isSet() is False: - connection = self.new_connection_structure() - # do connect - connect_method_choice = random.choice(self.connect_method) - self.utility.execute_tcp_method(connect_method_choice, connection) - # check if established - if self.utility.is_established_state(connection) is True: - time.sleep(float(random.randint(DELAY_RANGE[0], DELAY_RANGE[1]))/1000) - # do disconnect if established - disconnect_method_choice = random.choice(self.disconnect_method) - self.utility.execute_tcp_method(disconnect_method_choice, connection) - # make sure target socket closed - self.utility.close_connection(connection) - time.sleep(float(random.randint(DELAY_RANGE[0], DELAY_RANGE[1]))/1000) - pass - - # serial_condition: re string - # tcp_condition: target local port - def add_checkers(self, serial_condition=None, tcp_condition=None): - # cleanup - self.serial_result = None - self.tcp_result = None - self.serial_notify_event.clear() - self.tcp_notify_event.clear() - # serial_checker - if serial_condition is not None: - pattern = re.compile(serial_condition) - self.serial_check_item_id = self.serial_checker.add_check_item(pattern, self.notifier) - else: - # set event so that serial check always pass - self.serial_notify_event.set() - if tcp_condition is not None: - self.tcp_check_item_id = self.tcp_checker.add_check_item(tcp_condition, self.notifier) - else: - # set event so that tcp check always pass - self.tcp_notify_event.set() - # NativeLog.add_trace_info("[Debug] add check item %s, connection is %s" % (self.serial_check_item_id, self)) - pass - - def get_checker_results(self, timeout=5): - time1 = time.time() - while time.time() - time1 < timeout: - # if one type of checker is not set, its event will be set in add_checkers - if self.serial_notify_event.isSet() is True and self.tcp_notify_event.isSet() is True: - break - time.sleep(self.CHECK_FREQ) - # do cleanup - # NativeLog.add_trace_info("[Debug] remove check item %s, connection is %s" % (self.serial_check_item_id, self)) - self.data_cache = self.serial_checker.remove_check_item(self.serial_check_item_id) - self.tcp_checker.remove_check_item(self.tcp_check_item_id) - # self.serial_check_item_id = None - # self.tcp_check_item_id = None - return self.serial_result, self.tcp_result - - def notifier(self, typ, result): - if typ == "serial": - self.serial_notify_event.set() - self.serial_result = result - elif typ == "tcp": - self.tcp_notify_event.set() - self.tcp_result = result - - def exit(self): - self.exit_event.set() - pass - - -class TCPConnection(PerformanceTCBase.PerformanceTCBase): - def __init__(self, name, test_env, cmd_set, timeout=120, log_path=None): - PerformanceTCBase.PerformanceTCBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - self.max_connection = 5 - self.execute_time = 120 # execute time default 120 minutes - self.pc_ip = "pc_ip" - self.target_ip = "target_ip" - self.connect_method = ["C_01"] - self.disconnect_method = ["D_05"] - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - - self.error_event = threading.Event() - self.serial_lock = threading.Lock() - pass - - def serial_reader(self): - return self.serial_read_data("SSC1") - - def send_ssc_command(self, data): - with self.serial_lock: - time.sleep(0.05) - self.serial_write_line("SSC1", data) - - def error_detected(self): - self.error_event.set() - - def process(self): - # parameters - max_connection = self.max_connection - execute_time = self.execute_time * 60 - pc_ip = self.get_parameter(self.pc_ip) - target_ip = self.get_parameter(self.target_ip) - connect_method = self.connect_method - disconnect_method = self.disconnect_method - server_port = random.randint(30000, 50000) - - # step 1, create TCP server on target and PC - # create TCP server on target - self.serial_write_line("SSC1", "soc -B -t TCP -p %s" % server_port) - match = self.check_regular_expression("SSC1", re.compile("BIND:(\d+),OK")) - if match is None: - NativeLog.add_prompt_trace("Failed to create TCP server on target") - return - target_sock_id = match.group(1) - - self.serial_write_line("SSC1", "soc -L -s %s" % target_sock_id) - if self.check_response("SSC1", "+LISTEN:%s,OK" % target_sock_id) is False: - NativeLog.add_prompt_trace("Failed to create TCP server on target") - return - - # create TCP server on PC - try: - server_sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) - server_sock.bind((pc_ip, server_port)) - server_sock.listen(5) - except StandardError: - NativeLog.add_prompt_trace("Failed to create TCP server on PC") - return - - # step 2, create checker - serial_port_checker = SerialPortChecker(self.serial_reader) - tcp_server_checker = TCPServerChecker(server_sock) - serial_port_checker.start() - tcp_server_checker.start() - - # step 3, create 5 thread and do connection - utility = TCPConnectionUtility.Utility(self, server_port, server_port, pc_ip, target_ip) - work_thread = [] - for i in range(max_connection): - t = ConnectionHandler(utility, serial_port_checker, tcp_server_checker, - connect_method, disconnect_method) - work_thread.append(t) - t.start() - - # step 4, wait and exit - self.error_event.wait(execute_time) - # close all threads - for t in work_thread: - t.exit() - t.join() - serial_port_checker.exit() - tcp_server_checker.exit() - serial_port_checker.join() - tcp_server_checker.join() - - if self.error_event.isSet() is False: - # no error detected - self.set_result("Succeed") - pass - - -def main(): - pass - - -if __name__ == '__main__': - main() diff --git a/components/test/TestCaseScript/TCPStress/TCPConnectionUtility.py b/components/test/TestCaseScript/TCPStress/TCPConnectionUtility.py deleted file mode 100755 index f28218af0b..0000000000 --- a/components/test/TestCaseScript/TCPStress/TCPConnectionUtility.py +++ /dev/null @@ -1,251 +0,0 @@ -import random -import socket -import threading - -from NativeLog import NativeLog - -# from NativeLog import NativeLog - -# make sure target do not listen on this port -ERROR_PORT = 62685 - - -class Utility(object): - METHOD_RESULT = {"C_01": ("ESTABLISHED", "ESTABLISHED"), # target TCP peer state, PC TCP peer state - "C_02": ("SYNC_SENT", "CLOSED"), - "C_03": ("CLOSED", "CLOSED"), - "C_04": ("SYN_RCVD", "ESTABLISHED"), - "C_05": ("ESTABLISHED", "ESTABLISHED"), - "C_06": ("CLOSED", "CLOSED"), - "C_07": ("CLOSED", "CLOSED"), - "C_08": ("CLOSED", "CLOSED"), - "D_01": ("TIME_WAIT", "CLOSED"), - "D_02": ("TIME_WAIT", "TIME_WAIT"), - "D_03": ("FIN_WAIT_2", "CLOSE_WAIT"), - "D_04": ("FIN_WAIT_1", "CLOSE_WAIT"), - "D_05": ("CLOSED", "TIME_WAIT"), - "D_06": ("CLOSED", "CLOSED"), - "D_07": ("CLOSE_WAIT", "FIN_WAIT2"), - "D_08": ("TIME_WAIT", "CLOSED"), } - - SOC_CLOSED_STATE = ("FIN_WAIT_1", "FIN_WAIT_2", "CLOSING", "TIME_WAIT", "LAST_ACK", "CLOSED") - SOC_CREATED_STATE = ("SYNC_RCVD", "ESTABLISHED") - SOC_SEND_DATA_STATE = ("ESTABLISHED", "CLOSE_WAIT") - SOC_ESTABLISHED_STATE = ("ESTABLISHED", ) - - def __init__(self, tc_action, pc_server_port, target_server_port, pc_ip, target_ip): - self.tc_action = tc_action - self.pc_server_port = pc_server_port - self.target_server_port = target_server_port - self.pc_ip = pc_ip - self.target_ip = target_ip - self.pc_close_wait_socket_list = [] - self.sync_lock = threading.Lock() - pass - - # create a tcp socket, return True or False - def __create_tcp_socket(self, connection): - connection_handler = connection["Connection handler"] - connection["Target port"] = random.randint(10000, 60000) - connection_handler.add_checkers("BIND:(\d+),OK,%s,%s" - % (self.target_ip, connection["Target port"])) - self.tc_action.send_ssc_command("soc -B -t TCP -i %s -p %s" % (self.target_ip, connection["Target port"])) - serial_result, tcp_result = connection_handler.get_checker_results() - if serial_result is not None: - connection["Target socket id"] = serial_result.group(1) - return True - else: - return False - - # target do connect, return True or False - def __target_do_connect(self, connection, dest_ip, dest_port, timeout=20): - connection_handler = connection["Connection handler"] - connection_handler.add_checkers("CONNECT:%s,OK" % connection["Target socket id"], - connection["Target port"]) - self.tc_action.send_ssc_command("soc -C -s %s -i %s -p %s" - % (connection["Target socket id"], dest_ip, dest_port)) - serial_result, tcp_result = connection_handler.get_checker_results(timeout) - if serial_result is not None and tcp_result is not None: - connection["PC socket"] = tcp_result - return True - else: - return False - pass - - # pc do connect, return True or False - def __pc_do_connect(self, connection, dest_ip, dest_port, timeout=20): - connection_handler = connection["Connection handler"] - sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) - while True: - connection["PC port"] = random.randint(10000, 60000) - try: - sock.bind((self.pc_ip, connection["PC port"])) - break - except socket.error, e: - if e.errno == 10048: # socket port reuse - continue - sock.settimeout(timeout) - connection["PC socket"] = sock - connection_handler.add_checkers("ACCEPT:(\d+),\d+,%s,%s" - % (self.pc_ip, connection["PC port"])) - try: - sock.connect((dest_ip, dest_port)) - except socket.error: - pass - serial_result, tcp_result = connection_handler.get_checker_results() - if serial_result is not None: - connection["Target socket id"] = serial_result.group(1) - return True - else: - return False - pass - - def connect_c_01(self, connection): - if self.__create_tcp_socket(connection) is True: - return self.__target_do_connect(connection, self.pc_ip, self.pc_server_port) - else: - return False - - def connect_c_02(self, connection): - if self.__create_tcp_socket(connection) is True: - return not self.__target_do_connect(connection, self.pc_ip, ERROR_PORT, timeout=5) - else: - return False - - def connect_c_03(self, connection): - return False - - def connect_c_04(self, connection): - return False - - def connect_c_05(self, connection): - return self.__pc_do_connect(connection, self.target_ip, self.target_server_port) - - def connect_c_06(self, connection): - return False - - def connect_c_07(self, connection): - return not self.__pc_do_connect(connection, self.target_ip, ERROR_PORT) - - def connect_c_08(self, connection): - return False - - def __target_socket_close(self, connection): - connection_handler = connection["Connection handler"] - if connection["Target socket id"] is not None: - connection_handler.add_checkers("CLOSE:%s" % connection["Target socket id"]) - self.tc_action.send_ssc_command("soc -T -s %s" % connection["Target socket id"]) - serial_result, tcp_result = connection_handler.get_checker_results() - connection["Target socket id"] = None - else: - serial_result = None - return True if serial_result is not None else False - - @staticmethod - def __pc_socket_close(connection): - connection_handler = connection["Connection handler"] - if connection["PC socket"] is not None: - connection_handler.add_checkers("CLOSED:%s" % connection["Target socket id"]) - connection["PC socket"].close() - serial_result, tcp_result = connection_handler.get_checker_results() - connection["PC socket"] = None - else: - serial_result = None - return True if serial_result is not None else False - - def close_d_01(self, connection): - connection["PC socket"] = None - return self.__target_socket_close(connection) - - def close_d_02(self, connection): - pass - - def close_d_03(self, connection): - with self.sync_lock: - self.pc_close_wait_socket_list.append(connection["PC socket"]) - return self.__target_socket_close(connection) - pass - - def close_d_04(self, connection): - pass - - def close_d_05(self, connection): - return self.__pc_socket_close(connection) - - def close_d_06(self, connection): - # target send data to PC, PC don't recv and close socket - connection_handler = connection["Connection handler"] - connection_handler.add_checkers("SEND:%s,OK" % connection["Target socket id"]) - self.tc_action.send_ssc_command("soc -S -s %s -l 100" % connection["Target socket id"]) - serial_result, tcp_result = connection_handler.get_checker_results() - if serial_result is None: - return False - return self.__pc_socket_close(connection) - - def close_d_07(self, connection): - # PC shutdown WR - result = False - try: - connection["PC socket"].shutdown(socket.SHUT_WR) - result = True - except StandardError: - pass - return result - - def close_d_08(self, connection): - pass - - def close_connection(self, connection): - self.__target_socket_close(connection) - pass - - TCP_ACTION_DICT = {"C_01": connect_c_01, - "C_02": connect_c_02, - "C_03": connect_c_03, - "C_04": connect_c_04, - "C_05": connect_c_05, - "C_06": connect_c_06, - "C_07": connect_c_07, - "C_08": connect_c_08, - "D_01": close_d_01, - "D_02": close_d_02, - "D_03": close_d_03, - "D_04": close_d_04, - "D_05": close_d_05, - "D_06": close_d_06, - "D_07": close_d_07, - "D_08": close_d_08, - } - - def get_method_destination_state(self, method): - return self.METHOD_RESULT[method] - - def execute_tcp_method(self, method, connection): - if method in self.METHOD_RESULT: - result = self.TCP_ACTION_DICT[method](self, connection) - if result is True: - state = self.get_method_destination_state(method) - connection["Target state"] = state[0] - connection["PC state"] = state[1] - else: - NativeLog.add_prompt_trace("[TCPConnection] tcp method %s fail, connection is %s" - % (method, connection)) - NativeLog.add_trace_info("[TCPConnection][data cache][check item %s] %s" - % (connection["Connection handler"].serial_check_item_id, - connection["Connection handler"].data_cache)) - else: - raise StandardError("Not TCP connection method") - return result - - def is_established_state(self, connection): - return True if connection["Target state"] in self.SOC_CREATED_STATE else False - - def is_closed_state(self, connection): - return True if connection["Target state"] in self.SOC_CLOSED_STATE else False - - -def main(): - pass - -if __name__ == '__main__': - main() diff --git a/components/test/TestCaseScript/TCPStress/TCPDataValidation.py b/components/test/TestCaseScript/TCPStress/TCPDataValidation.py deleted file mode 100755 index b056af38fa..0000000000 --- a/components/test/TestCaseScript/TCPStress/TCPDataValidation.py +++ /dev/null @@ -1,244 +0,0 @@ -import os -import random -import threading -import socket -import time -import re - -from TCAction import TCActionBase -from TCAction import PerformanceTCBase -from NativeLog import NativeLog - - -LOG_FOLDER = os.path.join("AT_LOG", "Performance", "Throughput") - - -AP_PROP_KEY = ("ssid", "password", "apc") - - -def calc_hash(index): - return (index & 0xffffffff) % 83 + (index & 0xffffffff) % 167 - - -def verify_data(data, start_index): - for i, c in enumerate(data): - if ord(c) != calc_hash(start_index + i): - NativeLog.add_trace_critical("[Data Validation Error] target sent data index %u is error." - " Sent data is %x, should be %x" - % (start_index + i, ord(c), calc_hash(start_index + i))) - return False - return True - - -def make_validation_data(length, start_index): - return bytes().join([chr(calc_hash(start_index + i)) for i in range(length)]) - - -class SendThread(threading.Thread): - def __init__(self, sock, send_len): - threading.Thread.__init__(self) - self.setDaemon(True) - self.sock = sock - self.send_len = send_len - self.exit_event = threading.Event() - pass - - def exit(self): - self.exit_event.set() - - def run(self): - index = 0 - while self.exit_event.isSet() is False: - data = make_validation_data(self.send_len, index) - try: - self.sock.send(data) - index += self.send_len - except StandardError: - # pass but not exit thread - time.sleep(1) - continue - pass - - -class RecvThread(threading.Thread): - def __init__(self, sock): - threading.Thread.__init__(self) - self.setDaemon(True) - self.sock = sock - self.exit_event = threading.Event() - - def exit(self): - self.exit_event.set() - - def run(self): - index = 0 - while self.exit_event.isSet() is False: - if self.sock is not None: - try: - data = self.sock.recv(8*1024) - except StandardError, e: - NativeLog.add_exception_log(e) - NativeLog.add_trace_critical("recv error, connection closed") - break - if verify_data(data, index) is not True: - break - index += len(data) - else: - time.sleep(1) - pass - - -class ValidationThread(threading.Thread): - def __init__(self, tc_action): - threading.Thread.__init__(self) - self.setDaemon(True) - self.tc_action = tc_action - self.exit_event = threading.Event() - - def exit(self): - self.exit_event.set() - - def run(self): - while self.exit_event.isSet() is False: - if self.tc_action.check_response("SSC1", "DATA_ERROR", 5) is True: - NativeLog.add_trace_critical("[Data Validation Error] target recv data error") - break - pass - - -class TCPDataValidation(PerformanceTCBase.PerformanceTCBase): - - def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): - PerformanceTCBase.PerformanceTCBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - self.send_len = 1460 - self.tx_enable = True - self.rx_enable = True - self.conn_num = 1 - self.test_time = 300 - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - pass - - def execute(self): - TCActionBase.TCActionBase.execute(self) - - try: - # configurable params - send_len = self.send_len - tx_enable = self.tx_enable - rx_enable = self.rx_enable - conn_num = self.conn_num - test_time = self.test_time * 60 # convert minutes to seconds - # configurable params - except StandardError, e: - NativeLog.add_trace_critical("Error configuration for TCPThroughput script, error is %s" % e) - raise StandardError("Error configuration") - - # init throughput result data - test_item = "" - if tx_enable is True: - test_item += "Tx" - if rx_enable is True: - test_item += "Rx" - if test_item == "": - raise StandardError("no throughput test item") - - pc_ip = self.get_parameter("pc_ip") - tcp_port = random.randint(10000, 50000) - - # disable recv print during throughput test - self.serial_write_line("SSC1", "soc -R -o 0") - if self.check_response("SSC1", "+RECVPRINT", 2) is False: - NativeLog.add_trace_critical("Fail, Fail to disable recv print") - - # create server - server_sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) - server_sock.bind((pc_ip, tcp_port)) - server_sock.settimeout(5) - server_sock.listen(5) - - sock_id_list = [] - send_thread_list = [] - recv_thread_list = [] - - # step 4 create tcp connection - for i in range(conn_num): - self.serial_write_line("SSC1", "soc -B -t TCP") - match = self.check_regular_expression("SSC1", re.compile("\+BIND:(\d+),OK"), 2) - if match is None: - NativeLog.add_trace_critical("Fail, Fail to bind") - return - else: - sock_id_list.append(int(match.group(1))) - - self.serial_write_line("SSC1", "soc -V -s %s -o 3" % sock_id_list[-1]) - if self.check_regular_expression("SSC1", re.compile("\+DATA_VALIDATION:\d+,OK"), 2) is None: - NativeLog.add_trace_critical("Fail, Failed to enable validation") - return - - self.serial_write_line("SSC1", "soc -C -s %s -i %s -p %s" % (sock_id_list[-1], pc_ip, tcp_port)) - try: - sock, addr = server_sock.accept() - except socket.error, e: - NativeLog.add_trace_critical("%s" % e) - raise e - - if self.check_regular_expression("SSC1", re.compile("\+CONNECT:\d+,OK"), 5) is None: - NativeLog.add_trace_critical("Fail, Failed to connect") - return - - sock.settimeout(10) - - send_thread_list.append(SendThread(sock if rx_enable is True else None, send_len)) - recv_thread_list.append(RecvThread(sock if tx_enable is True else None)) - recv_thread_list[-1].start() - - # step 5 do test - validation_thread = ValidationThread(self) - validation_thread.start() - - for send_thread in send_thread_list: - send_thread.start() - - if tx_enable is True: - # do send from target - for sock_id in sock_id_list: - self.serial_write_line("SSC1", "soc -S -s %s -l %s -n 10000000" % (sock_id, send_len)) - - time1 = time.time() - exit_flag = False - - while time.time() - time1 < test_time and exit_flag is False: - for i in sock_id_list: - send_thread_list[i].join(0.5) - recv_thread_list[i].join(0.5) - validation_thread.join(0.5) - if send_thread_list[i].isAlive() is False \ - or recv_thread_list[i].isAlive() is False \ - or validation_thread.isAlive() is False: - NativeLog.add_trace_critical("validation error found") - exit_flag = True - break - else: - self.set_result("Succeed") - - # exit all thread - for i in sock_id_list: - send_thread_list[i].exit() - recv_thread_list[i].exit() - send_thread_list[i].join() - send_thread_list[i].join() - - validation_thread.exit() - validation_thread.join() - - -def main(): - pass - -if __name__ == '__main__': - main() diff --git a/components/test/TestCaseScript/TCPStress/TCPRandomSend.py b/components/test/TestCaseScript/TCPStress/TCPRandomSend.py deleted file mode 100755 index 5a07a2d965..0000000000 --- a/components/test/TestCaseScript/TCPStress/TCPRandomSend.py +++ /dev/null @@ -1,103 +0,0 @@ -import os -import time -import random -import threading -import socket -from TCAction import TCActionBase -from NativeLog import NativeLog -from NativeLog import ThroughputResult - - -class TCPRandomSend(TCActionBase.CommonTCActionBase): - - def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): - TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - self.send_len_config = range(1460) - self.delay_config = [0, 0.01, 0.1, 0.5, 1] - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) - pass - - def execute(self): - TCActionBase.TCActionBase.execute(self) - self.result_cntx.start() - - try: - # configurable params - send_len_config = self.send_len_config - delay_config = self.delay_config - send_count = self.send_count - test_time = self.test_time * 60 - # configurable params - except StandardError, e: - NativeLog.add_trace_critical("Error configuration for TCPThroughput script, error is %s" % e) - raise StandardError("Error configuration") - - # disable recv print during random send test - checker_stings = ["R SSC1 C +RECVPRINT"] - test_action_string = ["SSC SSC1 soc -R -o 0"] - fail_string = "Fail, Fail to disable recv print" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - pc_ip = self.test_env.get_variable_by_name("pc_ip")[1] - tcp_port = random.randint(50000, 60000) - - # step 0 create tcp connection - - server_sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) - server_sock.bind((pc_ip, tcp_port)) - server_sock.settimeout(1) - server_sock.listen(5) - - checker_stings = ["R SSC1 A :\+BIND:(\d+),OK"] - test_action_string = ["SSC SSC1 soc -B -t TCP"] - fail_string = "Fail, Fail bind" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - checker_stings = ["P SSC1 RE \+CONNECT:\d+,OK"] - test_action_string = ["SSC SSC1 soc -C -s -i %s -p %s" % (pc_ip, tcp_port)] - fail_string = "Fail, Fail to connect" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - sock, addr = server_sock.accept() - sock.settimeout(10) - # set no delay so that tcp segment will be send as soon as send called - sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) - - # step 1 start send - start_time = time.time() - while time.time() - start_time < test_time: - for delay in delay_config: - for i in xrange(send_count): - send_len = random.choice(send_len_config) - data = "A" * (send_len+1) - try: - sock.send(data) - except socket.error, e: - NativeLog.add_exception_log(e) - return - pass - time.sleep(delay) - - self.result_cntx.set_result("Succeed") - - # finally, execute done - - def result_check(self, port_name, data): - TCActionBase.CommonTCActionBase.result_check(self, port_name, data) - self.result_cntx.append_data(port_name, data) - - -def main(): - pass - -if __name__ == '__main__': - main() diff --git a/components/test/TestCaseScript/TCPStress/TCPSendRecv.py b/components/test/TestCaseScript/TCPStress/TCPSendRecv.py deleted file mode 100755 index e14d7f04d4..0000000000 --- a/components/test/TestCaseScript/TCPStress/TCPSendRecv.py +++ /dev/null @@ -1,143 +0,0 @@ -from TCAction import TCActionBase -from NativeLog import NativeLog -import time -import random -import string - -TEST_COUNT_ONE_ROUND = 1000 - - -class TCPSendRecv(TCActionBase.CommonTCActionBase): - - def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): - TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) - pass - - def cleanup(self): - # step 0 turn on recv print - checker_stings = ["R SSC1 C +RECVPRINT:1"] - test_action_string = ["SSC SSC1 soc -R -o 1"] - fail_string = "Fail, Fail to turn on recv print" - self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) - pass - - def execute(self): - TCActionBase.TCActionBase.execute(self) - self.result_cntx.start() - - try: - # configurable params - send_len = self.send_len - test_time = self.test_time * 60 - duplex = self.duplex - conn_num = self.conn_num - send_delay = self.send_delay - # configurable params - except StandardError, e: - NativeLog.add_trace_critical("Error configuration for TCPSendRecv script, error is %s" % e) - raise StandardError("Error configuration") - - ssid = "".join([random.choice(string.lowercase) for m in range(10)]) - password = "".join([random.choice(string.lowercase) for m in range(10)]) - - # step 0 set ap - checker_stings = ["R SSC1 C +SAP:OK"] - test_action_string = ["SSC SSC1 ap -S -s %s -p %s -t 3" % (ssid, password)] - fail_string = "Fail, Fail to set ap" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - # step 1 connect to ap and turn off recv print - checker_stings = ["R SSC2 C +JAP:CONNECTED"] - test_action_string = ["SSC SSC2 sta -C -s %s -p %s" % (ssid, password)] - fail_string = "Fail, Fail to connect to server" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, check_time=200) is False: - return - - checker_stings = ["P SSC1 C +RECVPRINT:0", "P SSC2 C +RECVPRINT:0"] - test_action_string = ["SSC SSC1 soc -R -o 0", "SSC SSC2 soc -R -o 0"] - fail_string = "Fail, Fail to turn off recv print" - self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, check_time=200) is False: - return - - # step 2 create server on AP - checker_stings = ["R SSC1 A :\+BIND:(\d+),OK"] - test_action_string = ["SSC SSC1 soc -B -t TCP -p "] - fail_string = "Fail, Fail to create server" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - checker_stings = ["R SSC1 A :\+LISTEN:(\d+),OK"] - test_action_string = ["SSC SSC1 soc -L -s "] - fail_string = "Fail, Fail to create server" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - # step 3 create conn_num tcp connections - for i in range(conn_num): - checker_stings = ["R SSC2 A :\+BIND:(\d+),OK" % i] - test_action_string = ["SSC SSC2 soc -B -t TCP"] - fail_string = "Fail, Fail to bind" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - checker_stings = ["P SSC1 A :\+ACCEPT:(\d+),\d+" % i, - "P SSC2 RE \+CONNECT:\d+,OK"] - test_action_string = ["SSC SSC2 soc -C -s -i -p " % i] - fail_string = "Fail, Fail to connect" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - start_time = time.time() - # step 4, do send/recv - while time.time()-start_time < test_time: - - checker_stings = ["P SSC1 NC ERROR NC CLOSE"] - for i in range(conn_num): - test_action_string = ["SSC SSC2 soc -S -s -l %d -n %d -j %d" % - (i, send_len, TEST_COUNT_ONE_ROUND, send_delay)] - checker_stings.append("P SSC2 RE \"\+SEND:%%%%s,OK\"%%%%() NC ERROR NC CLOSE" % i) - - if duplex is True: - checker_stings.append("P SSC1 RE \"\+SEND:%%%%s,OK\"%%%%()" % i) - test_action_string.append("SSC SSC1 soc -S -s -l %d -n %d -j %d" % - (i, send_len, TEST_COUNT_ONE_ROUND, send_delay)) - - fail_string = "Fail, Failed on send command" - if self.load_and_exe_one_step([], test_action_string, fail_string) is False: - break - # if self.load_and_exe_one_step([], ["SSC SSC1 ram -H", "SSC SSC2 ram -H"], fail_string) is False: - # break - # time.sleep(0.1) - - fail_string = "Fail, Failed to send/recv data" - if self.load_and_exe_one_step(checker_stings, ["DELAY 0.1"], fail_string, - check_freq=1, check_time=300) is False: - break - pass - - NativeLog.add_prompt_trace("time escape: %s" % (time.time() - start_time)) - self.result_cntx.set_result("Succeed") - - # finally, execute done - - def result_check(self, port_name, data): - TCActionBase.CommonTCActionBase.result_check(self, port_name, data) - self.result_cntx.append_data(port_name, data) - - -def main(): - pass - -if __name__ == '__main__': - main() - - diff --git a/components/test/TestCaseScript/TCPStress/TCPSoftAPSTASendRecv.py b/components/test/TestCaseScript/TCPStress/TCPSoftAPSTASendRecv.py deleted file mode 100644 index de31bacc11..0000000000 --- a/components/test/TestCaseScript/TCPStress/TCPSoftAPSTASendRecv.py +++ /dev/null @@ -1,318 +0,0 @@ -from TCAction import TCActionBase -from NativeLog import NativeLog -import time -import random -import string - -TEST_COUNT_ONE_ROUND = 500 - - -class TCPSoftAPSTASendRecv(TCActionBase.CommonTCActionBase): - def __init__(self, name, test_env, cmd_set, timeout=45, log_path=TCActionBase.LOG_PATH): - TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) - pass - - def execute(self): - TCActionBase.TCActionBase.execute(self) - self.result_cntx.start() - - try: - # configurable params - send_len = self.send_len - # test count - test_count = self.test_count - # server port - server_port = self.server_port - server_port_t = self.server_port_2 - # ap ip - # ap_ip = self.ap_ip - # server echo - server_echo = self.server_echo - # station number - sta_number = self.sta_number - # pass standard - pass_standard = self.pass_standard - # send delay - send_delay = self.send_delay - # configurable params - except StandardError, e: - NativeLog.add_trace_critical("Error configuration for TCPTransparent script, error is %s" % e) - raise StandardError("Error configuration") - - # step0 reboot - checker_stings = [] - test_action_string = [] - - for i in range(sta_number + 2): - checker_stings.append("P SSC%d C !!!ready!!!" % (i + 1)) - test_action_string.append("SSCC SSC%d reboot" % (i + 1)) - - fail_string = "Fail, Fail to reboot" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - # step1, set ap/STA mode on all target - for i in range(sta_number + 2): - checker_stings = ["R SSC%d C +MODE:OK" % (i + 1)] - test_action_string = ["SSCC SSC%d op -S -o 3" % (i + 1)] - fail_string = "Fail, Fail to set mode on SSC%d" % (i + 1) - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - # set different getway for SSC1 softAP - checker_stings = ["R SSC1 C +DHCP:AP,OK"] - test_action_string = ["SSCC SSC1 dhcp -E -o 2"] - fail_string = "Fail, SSC1 Fail to disable DHCP" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - checker_stings = ["R SSC1 C +IP:OK"] - test_action_string = ["SSCC SSC1 ip -S -o 2 -i 192.168.6.1"] - fail_string = "Fail, SSC1 Fail to set IP" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - checker_stings = ["R SSC1 C +DHCP:AP,OK"] - test_action_string = ["SSCC SSC1 dhcp -S -o 2"] - fail_string = "Fail, SSC1 Fail to enable DHCP" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - # set different getway for SSC2 softAP - checker_stings = ["R SSC2 C +DHCP:AP,OK"] - test_action_string = ["SSCC SSC2 dhcp -E -o 2"] - fail_string = "Fail, SSC2 Fail to disable DHCP" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - checker_stings = ["R SSC2 C +IP:OK"] - test_action_string = ["SSCC SSC2 ip -S -o 2 -i 192.168.5.1"] - fail_string = "Fail, SSC2 Fail to set IP" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - checker_stings = ["R SSC2 C +DHCP:AP,OK"] - test_action_string = ["SSCC SSC2 dhcp -S -o 2"] - fail_string = "Fail, SSC2 Fail to enable DHCP" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - # step2, set ssid/password on SSC1 - ssid = "".join([random.choice(string.lowercase) for m in range(10)]) - password = "".join([random.choice(string.lowercase) for m in range(10)]) - checker_stings = ["R SSC1 C +SAP:OK"] - test_action_string = ["SSCC SSC1 ap -S -s %s -p %s -n 10 -t 0 -m 8" % (ssid, password)] - fail_string = "Fail, Fail to set ssid/password on SSC1" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - # step3, set ssid/password on SSC2 - ssid_1 = "".join([random.choice(string.lowercase) for m in range(10)]) - password_1 = "".join([random.choice(string.lowercase) for m in range(10)]) - checker_stings = ["R SSC2 C +SAP:OK"] - test_action_string = ["SSCC SSC2 ap -S -s %s -p %s -n 10 -t 0 -m 8" % (ssid_1, password_1)] - fail_string = "Fail, Fail to set ap ssid/password on SSC2" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - # step4, SSC2 join SSC1(soft AP) - checker_stings = [] - test_action_string = [] - checker_stings.append("P SSC2 C +JAP:CONNECTED,%s" % ssid) - test_action_string.append("SSCC SSC2 ap -C -s %s -p %s" % (ssid, password)) - fail_string = "Fail, Fail to connect to SSC1 SoftAP" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - # step5, create server on SSC1 - checker_stings = ["R SSC1 A :BIND:(\d+),OK"] - test_action_string = ["SSCC SSC1 soc -B -t TCP -p %s" % server_port] - fail_string = "Fail, Fail to create server on SSC1 while binding" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - checker_stings = ["R SSC1 RE LISTEN:(\d+),OK"] - test_action_string = ["SSCC SSC1 soc -L -s "] - fail_string = "Fail, Fail to create server on SSC1 while listening" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - # step6, create client on SSC2 - checker_stings = [] - test_action_string = [] - checker_stings.append("P SSC2 A :BIND:(\d+),OK") - test_action_string.append("SSCC SSC2 soc -B -t TCP") - fail_string = "Fail, SSC2 Fail to connect to server while binding" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - checker_stings = ["P SSC2 RE CONNECT:(\d+),OK", "P SSC1 A :ACCEPT:(\d+),.+"] - test_action_string = ["SSCC SSC2 soc -C -s -i %s -p %s" % ("192.168.6.1", server_port)] - fail_string = "Fail, SSC2 Fail to connect to server while connecting" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - # step7, SSC3 - SSC5 join SSC2 - checker_stings = [] - test_action_string = [] - for i in range(sta_number): - checker_stings.append("P SSC%d C +JAP:CONNECTED,%s" % (i + 3, ssid_1)) - test_action_string.append("SSCC SSC%d ap -C -s %s -p %s" % (i + 3, ssid_1, password_1)) - fail_string = "Fail, SSC%d Fail to connect to SSC2" % (i + 3) - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, check_time=450) is False: - return - - # step8, create server on SSC2 - checker_stings = ["R SSC2 A :BIND:(\d+),OK"] - test_action_string = ["SSCC SSC2 soc -B -t TCP -p %s -i 192.168.5.1" % server_port_t] - fail_string = "Fail, Fail to create server one SSC2 while binding" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - checker_stings = ["R SSC2 RE LISTEN:(\d+),OK"] - test_action_string = ["SSCC SSC2 soc -L -s "] - fail_string = "Fail, Fail to create server one SSC2 while listening" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - # step9, create client on SSC3 - SSC5 - checker_stings = [] - test_action_string = [] - for i in range(sta_number): - checker_stings.append("P SSC%d A :BIND:(\d+),OK" % (i + 3, i + 3)) - test_action_string.append("SSCC SSC%d soc -B -t TCP" % (i + 3)) - fail_string = "Fail, Fail to connect to SSC2 server while binding" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - for i in range(sta_number): - checker_stings = ["P SSC%d RE CONNECT:(\d+),OK" % (i + 3), - "P SSC2 A :ACCEPT:(\d+),.+" % (i + 3)] - test_action_string = ["SSCC SSC%d soc -C -s -i %s -p %s" % - (i + 3, i + 3, "192.168.5.1", server_port_t)] - fail_string = "Fail, Fail to connect to SSC2 server while connecting" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - start_time = time.time() - # step 10, do send/recv - while test_count > 0: - _tmp_count = TEST_COUNT_ONE_ROUND if test_count - TEST_COUNT_ONE_ROUND > 0 else test_count - test_count -= TEST_COUNT_ONE_ROUND - - checker_stings = [] - test_action_string = [] - if server_echo is True: - test_action_string.append("SSC SSC1 soc -S -s -l %d -n %d -j %d" % - (send_len, _tmp_count, send_delay)) - checker_stings.append("P SSC1 RE \+SEND:\d+,OK NC CLOSED") - test_action_string.append("SSC SSC2 soc -S -s -l %d -n %d -j %d" % - (send_len, _tmp_count, send_delay)) - checker_stings.append("P SSC2 RE \+SEND:\d+,OK NC CLOSED") - - for i in range(sta_number): - checker_stings.append("P SSC%d RE \+SEND:\d+,OK NC CLOSED" % (i + 3)) - test_action_string.append("SSC SSC%d soc -S -s -l %d -n %d -j %d" % - (i + 3, i + 3, send_len, _tmp_count, send_delay)) - for i in range(sta_number): - test_action_string.append("SSC SSC2 soc -S -s -l %d -n %d -j %d" % - (i + 3, send_len, _tmp_count, send_delay)) - checker_stings.append("P SSC2 RE \+SEND:\d+,OK NC CLOSED") - - fail_string = "Fail, Failed to send/recv data" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, - check_freq=1, check_time=300) is False: - break - pass - - if (time.time() - start_time) > pass_standard: - self.result_cntx.set_result("Succeed") - else: - checker_stings = [] - test_action_string = [] - for i in range(sta_number + 2): - checker_stings.append("P SSC%d C CLOSEALL" % (i + 1)) - test_action_string.append("SSCC SSC%d soc -T" % (i + 1)) - fail_string = "Fail, Fail to close socket" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - # re-set server on SSC1 - server_port = random.randint(20000, 30000) - checker_stings = ["R SSC1 A :BIND:(\d+),OK"] - test_action_string = ["SSCC SSC1 soc -B -t TCP -p %s" % server_port] - fail_string = "Fail, Fail to bind socket" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - checker_stings = ["R SSC1 RE LISTEN:(\d+),OK"] - test_action_string = ["SSCC SSC1 soc -L -s "] - fail_string = "Fail, Fail to listen" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - # SSC2 connnect SSC1 - checker_stings = [] - test_action_string = [] - checker_stings.append("P SSC2 A :BIND:(\d+),OK") - test_action_string.append("SSCC SSC2 soc -B -t TCP") - fail_string = "Fail, SSC2 Fail to bind sock" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - checker_stings = ["P SSC2 RE CONNECT:(\d+),OK", "P SSC1 A :ACCEPT:(\d+),.+"] - test_action_string = ["SSCC SSC2 soc -C -s -i %s -p %s" % ("192.168.6.1", server_port)] - fail_string = "Fail, SSC2 Fail to connect to SSC1 server" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - #create server on SSC2 - checker_stings = [] - test_action_string = [] - checker_stings.append("P SSC2 A :BIND:(\d+),OK") - test_action_string.append("SSCC SSC2 soc -B -t TCP -p %s -i 192.168.5.1" % server_port_t) - fail_string = "Fail, SSC2 Fail to bind" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - checker_stings = ["R SSC2 RE LISTEN:(\d+),OK"] - test_action_string = ["SSCC SSC2 soc -L -s "] - fail_string = "Fail, SSC2 Fail to listen" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - #create client on SSC3-SSC5 - checker_stings = [] - test_action_string = [] - for i in range(sta_number): - checker_stings.append("P SSC%d A :BIND:(\d+),OK" % (i + 3, i + 3)) - test_action_string.append("SSCC SSC%d soc -B -t TCP" % (i + 3)) - fail_string = "Fail, Fail to connect to SSC2 server while binding" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - for i in range(sta_number): - checker_stings = ["P SSC%d RE CONNECT:(\d+),OK" % (i + 3), - "P SSC2 A :ACCEPT:(\d+),.+" % (i + 3)] - test_action_string = ["SSCC SSC%d soc -C -s -i %s -p %s" % - (i + 3, i + 3, "192.168.5.1", server_port_t)] - fail_string = "Fail, Fail to connect to server" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - self.result_cntx.set_result("Failed") - - # finally, execute done - - def result_check(self, port_name, data): - TCActionBase.CommonTCActionBase.result_check(self, port_name, data) - self.result_cntx.append_data(port_name, data) - - -def main(): - pass - - -if __name__ == '__main__': - main() diff --git a/components/test/TestCaseScript/TCPStress/TCPThroughput.py b/components/test/TestCaseScript/TCPStress/TCPThroughput.py deleted file mode 100755 index 0c40603e37..0000000000 --- a/components/test/TestCaseScript/TCPStress/TCPThroughput.py +++ /dev/null @@ -1,315 +0,0 @@ -import os -import time -import random -import threading -import socket - -from TCAction import TCActionBase -from NativeLog import NativeLog -from NativeLog import ThroughputResult -from Utility import RSSICalibrator -from Utility import MakeFolder - - -LOG_FOLDER = os.path.join("AT_LOG", "Performance", "Throughput") - - -AP_PROP_KEY = ("ssid", "password", "apc") - - -class SendThread(threading.Thread): - def __init__(self, sock, send_len): - threading.Thread.__init__(self) - self.setDaemon(True) - self.sock = sock - self.send_len = send_len - self.exit_event = threading.Event() - self.calc_event = threading.Event() - self.bytes_sent = 0 - pass - - def start_calc(self): - self.calc_event.set() - - def stop_calc(self): - self.calc_event.clear() - self.exit_event.set() - - def run(self): - data = "A" * self.send_len - if self.sock is None: - return - while True: - if self.exit_event.isSet() is True: - break - try: - self.sock.send(data) - except StandardError: - break - if self.calc_event.isSet() is True: - self.bytes_sent += self.send_len - - def get_bytes_sent(self): - return self.bytes_sent - pass - - -class RecvThread(threading.Thread): - def __init__(self, sock): - threading.Thread.__init__(self) - self.setDaemon(True) - self.sock = sock - self.exit_event = threading.Event() - self.calc_event = threading.Event() - self.bytes_recv = 0 - - def start_calc(self): - self.calc_event.set() - - def stop_calc(self): - self.calc_event.clear() - self.exit_event.set() - - def run(self): - if self.sock is None: - return - while True: - if self.exit_event.isSet() is True: - break - try: - data = self.sock.recv(8*1024) - except StandardError: - break - if self.calc_event.isSet() is True: - self.bytes_recv += len(data) - - def get_bytes_recv(self): - return self.bytes_recv - pass - - -class TCPThroughput(TCActionBase.CommonTCActionBase): - - def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): - TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - self.att_test_list = range(60) - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - # read AP list - self.ap_list = [] - for i in range(1, len(cmd_set)): - for j in range(len(cmd_set[i][1])): - if cmd_set[i][1][j] != "": - cmd_string = "self.ap_list.append(dict(zip(AP_PROP_KEY, " + cmd_set[i][1][j] + ")))" - exec cmd_string - self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) - pass - - def execute(self): - TCActionBase.TCActionBase.execute(self) - self.result_cntx.start() - - try: - # configurable params - ap_list = self.ap_list - send_len = self.send_len - att_test_list = self.att_test_list - tx_enable = self.tx_enable - rx_enable = self.rx_enable - measure_period = self.measure_period - # configurable params - except StandardError, e: - NativeLog.add_trace_critical("Error configuration for TCPThroughput script, error is %s" % e) - raise StandardError("Error configuration") - - # find local ip and generate local port - local_ip_list = socket.gethostbyname_ex(socket.gethostname())[2] - for local_ip in local_ip_list: - if local_ip.find("192.168.1.") != -1: - pc_ip = local_ip - break - else: - raise StandardError("Can't find local IP.") - - tcp_port = random.randint(40000, 50000) - - # init throughput result data - test_item = "" - if tx_enable is True: - test_item += "Tx" - if rx_enable is True: - test_item += "Rx" - if test_item == "": - raise StandardError("no throughput test item") - - folder_path = MakeFolder.make_folder(LOG_FOLDER) - file_name = os.path.join(folder_path, - "TCPThroughput_%s_%s" % (test_item, time.strftime("%d%H%M%S", time.localtime()))) - - result = ThroughputResult.ThroughputResult(file_name, standard_required=True) - - # restart before executing throughput - checker_stings = ["R SSC1 C !!!ready!!!"] - test_action_string = ["SSC SSC1 reboot"] - fail_string = "Fail, Fail to reboot" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - # disable recv print during throughput test - checker_stings = ["R SSC1 C +RECVPRINT"] - test_action_string = ["SSC SSC1 soc -R -o 0"] - fail_string = "Fail, Fail to disable recv print" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - for ap_prop in ap_list: - if ap_prop["password"] == "": - # set a default string for open ap - ap_prop["password"] = "1" - - # switch off all outlet, switch on AP outlet - outlet_config_dict = dict.fromkeys(range(1, 9), "OFF") - outlet_config_dict[ap_prop["apc"]] = "ON" - apc_cmd = "APC " - for outlet in outlet_config_dict: - apc_cmd += " %s %s" % (outlet_config_dict[outlet], outlet) - checker_stings = ["P PC_COM L OK"] - fail_string = "Fail, Fail to switch apc" - if self.load_and_exe_one_step(checker_stings, [apc_cmd], fail_string) is False: - return - - # wait AP ready - time.sleep(20) - - # create server - server_sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) - server_sock.bind((pc_ip, tcp_port)) - server_sock.settimeout(5) - server_sock.listen(5) - - if tx_enable is True: - result.add_test_item(ap_prop["ssid"] + "_tx") - if rx_enable is True: - result.add_test_item(ap_prop["ssid"] + "_rx") - - # create RSSI Calibrator - calibrator = RSSICalibrator.Calibrator() - - for att_value in att_test_list: - # step 0 set att value - checker_stings = ["R PC_COM L OK"] - test_action_string = ["ATT %s" % att_value] - fail_string = "Fail, Fail to set att value" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - continue - # step 1 connect to AP - checker_stings = ["R SSC1 C +JAP:CONNECTED"] - test_action_string = ["SSC SSC1 sta -C -s %s -p %s" % (ap_prop["ssid"], ap_prop["password"])] - fail_string = "Fail, Fail to JAP" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, - check_freq=1, check_time=30) is False: - continue - # step 2 get AP RSSI - checker_stings = ["R SSC1 A :\+SCAN:%s,[:\d\w]+,\d+,\d+,([-\d]+)" % ap_prop["ssid"]] - test_action_string = ["SSC SSC1 sta -S -s %s" % ap_prop["ssid"]] - fail_string = "Fail, Fail to scan" - rssi = scan_count = 0 - for i in range(3): - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - continue - rssi += int(self.test_env.get_variable_by_name("rssi")[1]) - scan_count += 1 - - rssi = calibrator.calibrate_rssi(float(rssi)/scan_count if scan_count > 0 else 0, att_value) - - # step 3 close all connections - checker_stings = ["R SSC1 C +CLOSEALL"] - test_action_string = ["SSC SSC1 soc -T"] - fail_string = "Fail, Fail to create server" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - continue - - # step 4 create tcp connection - - checker_stings = ["R SSC1 A :\+BIND:(\d+),OK"] - test_action_string = ["SSC SSC1 soc -B -t TCP"] - fail_string = "Fail, Fail bind" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - continue - - checker_stings = ["P SSC1 RE \+CONNECT:\d+,OK"] - test_action_string = ["SSC SSC1 soc -C -s -i %s -p %s" % (pc_ip, tcp_port)] - fail_string = "Fail, Fail to connect" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - continue - - try: - sock, addr = server_sock.accept() - except socket.error, e: - NativeLog.add_trace_critical("%s" % e) - continue - sock.settimeout(measure_period) - - # step 5 do throughput test - send_thread = SendThread(sock if rx_enable is True else None, send_len) - send_thread.start() - - recv_thread = RecvThread(sock if tx_enable is True else None) - recv_thread.start() - - if tx_enable is True: - # do send from target - test_action_string = ["SSC SSC1 soc -S -s -l %s -n 10000000" % send_len] - fail_string = "Fail, Fail to send" - if self.load_and_exe_one_step([], test_action_string, fail_string) is False: - pass - - # start throughput calculate - send_thread.start_calc() - recv_thread.start_calc() - - # sleep for measure period - time.sleep(measure_period) - - # stop throughput calculate - send_thread.stop_calc() - recv_thread.stop_calc() - - send_thread.join() - recv_thread.join() - - sock.close() - - # output throughput result - # in Mbps - if send_thread.get_bytes_sent() > 0: - result.log_throughput(ap_prop["ssid"] + "_rx", rssi, att_value, - float(send_thread.get_bytes_sent() * 8) / (measure_period * 1000000)) - - if recv_thread.get_bytes_recv() > 0: - result.log_throughput(ap_prop["ssid"] + "_tx", rssi, att_value, - float(recv_thread.get_bytes_recv() * 8) / (measure_period * 1000000)) - - result.output_to_file() - pass - - server_sock.close() - - self.result_cntx.set_result("Succeed") - - # finally, execute done - - def result_check(self, port_name, data): - TCActionBase.CommonTCActionBase.result_check(self, port_name, data) - self.result_cntx.append_data(port_name, data) - - -def main(): - pass - -if __name__ == '__main__': - main() diff --git a/components/test/TestCaseScript/TCPStress/__init__.py b/components/test/TestCaseScript/TCPStress/__init__.py deleted file mode 100755 index 049c1b961f..0000000000 --- a/components/test/TestCaseScript/TCPStress/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__all__ = ["TCPConnUtility", "TCPConnSingleMode", "TCPConnMixedMode"] \ No newline at end of file diff --git a/components/test/TestCaseScript/UDPStress/UDPSendRecv.py b/components/test/TestCaseScript/UDPStress/UDPSendRecv.py deleted file mode 100755 index 3a528c6ba7..0000000000 --- a/components/test/TestCaseScript/UDPStress/UDPSendRecv.py +++ /dev/null @@ -1,130 +0,0 @@ -from TCAction import TCActionBase -from NativeLog import NativeLog -import time -import random -import string - -TEST_COUNT_ONE_ROUND = 1000 - - -class UDPSendRecv(TCActionBase.CommonTCActionBase): - - def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): - TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) - pass - - def cleanup(self): - # step 0 turn on recv print - checker_stings = ["R SSC1 C +RECVPRINT:1"] - test_action_string = ["SSC SSC1 soc -R -o 1"] - fail_string = "Fail, Fail to turn on recv print" - self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) - pass - - def execute(self): - TCActionBase.TCActionBase.execute(self) - self.result_cntx.start() - - try: - # configurable params - send_len = self.send_len - test_time = self.test_time * 60 - duplex = self.duplex - conn_num = self.conn_num - send_delay = self.send_delay - # configurable params - except StandardError, e: - NativeLog.add_trace_critical("Error configuration for UDPSendRecv script, error is %s" % e) - raise StandardError("Error configuration") - - ssid = "".join([random.choice(string.lowercase) for m in range(10)]) - password = "".join([random.choice(string.lowercase) for m in range(10)]) - - # step 0 set ap - checker_stings = ["R SSC1 C +SAP:OK"] - test_action_string = ["SSC SSC1 ap -S -s %s -p %s -t 3" % (ssid, password)] - fail_string = "Fail, Fail to set ap" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - # step 1 connect to ap and turn off recv print - checker_stings = ["R SSC2 C +JAP:CONNECTED"] - test_action_string = ["SSC SSC2 sta -C -s %s -p %s" % (ssid, password)] - fail_string = "Fail, Fail to connect to server" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, check_time=200) is False: - return - - checker_stings = ["R SSC2 A :\+STAIP:(\d+\.\d+\.\d+\.\d+)\r"] - test_action_string = ["SSC SSC2 ip -Q -o 1"] - fail_string = "Fail, Fail to connect to server" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, check_time=200) is False: - return - - checker_stings = ["P SSC1 C +RECVPRINT:0", "P SSC2 C +RECVPRINT:0"] - test_action_string = ["SSC SSC1 soc -R -o 0", "SSC SSC2 soc -R -o 0"] - fail_string = "Fail, Fail to turn off recv print" - self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, check_time=200) is False: - return - - # step 2 create conn_num udp socket - for i in range(1, conn_num+1): - checker_stings = ["R SSC1 A :\+BIND:(\d+),OK" % i, - "R SSC2 A :\+BIND:(\d+),OK" % i] - test_action_string = ["SSC SSC1 soc -B -t UDP -p " % i, - "SSC SSC2 soc -B -t UDP -p " % i] - fail_string = "Fail, Fail to create socket" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - start_time = time.time() - # step 3, do send/recv - while time.time()-start_time < test_time: - - checker_stings = ["P SSC1 NC ERROR NC CLOSE"] - for i in range(1, conn_num+1): - test_action_string = ["SSC SSC2 soc -S -s -l %d -n %d -j %d " - "-i -p " % - (i, send_len, TEST_COUNT_ONE_ROUND, send_delay, i)] - checker_stings.append("P SSC2 RE \"\+SEND:%%%%s,OK\"%%%%() NC ERROR NC CLOSE" % i) - if duplex is True: - test_action_string.append("SSC SSC1 soc -S -s -l %d -n %d -j %d" - " -i -p " % - (i, send_len, TEST_COUNT_ONE_ROUND, send_delay, i)) - checker_stings.append("P SSC1 RE \"\+SEND:%%%%s,OK\"%%%%()" % i) - - fail_string = "Fail, Failed on send command" - if self.load_and_exe_one_step([], test_action_string, fail_string) is False: - break - time.sleep(1) - - fail_string = "Fail, Failed to send/recv data" - if self.load_and_exe_one_step(checker_stings, ["DELAY 0.1"], fail_string, - check_freq=1, check_time=300) is False: - break - pass - - NativeLog.add_prompt_trace("time escape: %s" % (time.time() - start_time)) - self.result_cntx.set_result("Succeed") - - # finally, execute done - - def result_check(self, port_name, data): - TCActionBase.CommonTCActionBase.result_check(self, port_name, data) - self.result_cntx.append_data(port_name, data) - - -def main(): - pass - -if __name__ == '__main__': - main() - - diff --git a/components/test/TestCaseScript/UDPStress/UDPThroughput.py b/components/test/TestCaseScript/UDPStress/UDPThroughput.py deleted file mode 100755 index dac7c2206b..0000000000 --- a/components/test/TestCaseScript/UDPStress/UDPThroughput.py +++ /dev/null @@ -1,305 +0,0 @@ -import os -import time -import random -import threading -import socket - -from TCAction import TCActionBase -from NativeLog import NativeLog -from NativeLog import ThroughputResult -from Utility import RSSICalibrator -from Utility import MakeFolder - - -LOG_FOLDER = os.path.join("AT_LOG", "Performance", "Throughput") - - -AP_PROP_KEY = ("ssid", "password", "apc") - - -class SendThread(threading.Thread): - def __init__(self, sock, send_len, target_addr): - threading.Thread.__init__(self) - self.setDaemon(True) - self.sock = sock - self.send_len = send_len - self.target_addr = target_addr - self.exit_event = threading.Event() - pass - - def exit(self): - self.exit_event.set() - - def run(self): - data = "A" * self.send_len - if self.sock is None: - return - while True: - if self.exit_event.isSet() is True: - break - try: - self.sock.sendto(data, self.target_addr) - except StandardError: - break - pass - - -class RecvThread(threading.Thread): - def __init__(self, sock): - threading.Thread.__init__(self) - self.setDaemon(True) - self.sock = sock - self.exit_event = threading.Event() - self.calc_event = threading.Event() - self.bytes_recv = 0 - - def start_calc(self): - self.calc_event.set() - - def stop_calc(self): - self.calc_event.clear() - self.exit_event.set() - - def run(self): - if self.sock is None: - return - while True: - if self.exit_event.isSet() is True: - break - try: - data, addr = self.sock.recvfrom(65535) - except StandardError: - break - if self.calc_event.isSet() is True: - self.bytes_recv += len(data) - - def get_bytes_recv(self): - return self.bytes_recv - pass - - -class UDPThroughput(TCActionBase.CommonTCActionBase): - - def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): - TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - self.att_test_list = range(60) - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - # read AP list - self.ap_list = [] - for i in range(1, len(cmd_set)): - for j in range(len(cmd_set[i][1])): - if cmd_set[i][1][j] != "": - cmd_string = "self.ap_list.append(dict(zip(AP_PROP_KEY, " + cmd_set[i][1][j] + ")))" - exec cmd_string - self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) - pass - - def execute(self): - TCActionBase.TCActionBase.execute(self) - self.result_cntx.start() - - try: - # configurable params - ap_list = self.ap_list - send_len = self.send_len - att_test_list = self.att_test_list - tx_enable = self.tx_enable - rx_enable = self.rx_enable - measure_period = self.measure_period - # configurable params - except StandardError, e: - NativeLog.add_trace_critical("Error configuration for TCPThroughput script, error is %s" % e) - raise StandardError("Error configuration") - - # find local ip and generate local port - local_ip_list = socket.gethostbyname_ex(socket.gethostname())[2] - for local_ip in local_ip_list: - if local_ip.find("192.168.1.") != -1: - pc_ip = local_ip - break - else: - raise StandardError("Can't find local IP.") - - udp_port = random.randint(40000, 50000) - - # init throughput result data - test_item = "" - if tx_enable is True: - test_item += "Tx" - if rx_enable is True: - test_item += "Rx" - if test_item == "": - raise StandardError("no throughput test item") - - folder_path = MakeFolder.make_folder(LOG_FOLDER) - file_name = os.path.join(folder_path, - "UDPThroughput_%s_%s" % (test_item, time.strftime("%d%H%M%S", time.localtime()))) - - result = ThroughputResult.ThroughputResult(file_name) - - # restart before executing throughput - checker_stings = ["R SSC1 C !!!ready!!!"] - test_action_string = ["SSC SSC1 reboot"] - fail_string = "Fail, Fail to reboot" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - # disable recv print during throughput test - checker_stings = ["R SSC1 C +RECVPRINT"] - test_action_string = ["SSC SSC1 soc -R -o 0"] - fail_string = "Fail, Fail to disable recv print" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - return - - for ap_prop in ap_list: - if ap_prop["password"] == "": - # set a default string for open ap - ap_prop["password"] = "1" - - # switch off all outlet, switch on AP outlet - outlet_config_dict = dict.fromkeys(range(1, 9), "OFF") - outlet_config_dict[ap_prop["apc"]] = "ON" - apc_cmd = "APC " - for outlet in outlet_config_dict: - apc_cmd += " %s %s" % (outlet_config_dict[outlet], outlet) - checker_stings = ["P PC_COM L OK"] - fail_string = "Fail, Fail to switch apc" - if self.load_and_exe_one_step(checker_stings, [apc_cmd], fail_string) is False: - return - - # wait AP ready - time.sleep(20) - - # create server - udp_sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM) - udp_sock.bind((pc_ip, udp_port)) - udp_sock.settimeout(1) - - if tx_enable is True: - result.add_test_item(ap_prop["ssid"] + "_tx") - if rx_enable is True: - result.add_test_item(ap_prop["ssid"] + "_rx") - - # create RSSI Calibrator - calibrator = RSSICalibrator.Calibrator() - - for att_value in att_test_list: - # step 0 set att value - checker_stings = ["R PC_COM L OK"] - test_action_string = ["ATT %s" % att_value] - fail_string = "Fail, Fail to set att value" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - continue - # step 1 connect to AP - checker_stings = ["R SSC1 C +JAP:CONNECTED"] - test_action_string = ["SSC SSC1 sta -C -s %s -p %s" % (ap_prop["ssid"], ap_prop["password"])] - fail_string = "Fail, Fail to JAP" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, - check_freq=1, check_time=30) is False: - continue - checker_stings = ["R SSC1 A :STAIP:(\d+\.\d+\.\d+\.\d+)"] - test_action_string = ["SSC SSC1 ip -Q"] - fail_string = "Fail, Fail to get ip" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, - check_freq=1, check_time=30) is False: - continue - target_ip = self.get_parameter("target_ip") - # step 2 get AP RSSI - checker_stings = ["R SSC1 A :\+SCAN:%s,[:\d\w]+,\d+,\d+,([-\d]+)\r" % ap_prop["ssid"]] - test_action_string = ["SSC SSC1 sta -S -s %s" % ap_prop["ssid"]] - fail_string = "Fail, Fail to scan" - rssi = scan_count = 0 - for i in range(3): - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - continue - rssi += int(self.test_env.get_variable_by_name("rssi")[1]) - scan_count += 1 - - rssi = calibrator.calibrate_rssi(float(rssi)/scan_count if scan_count > 0 else 0, att_value) - - # step 3 close all connections - checker_stings = ["R SSC1 C +CLOSEALL"] - test_action_string = ["SSC SSC1 soc -T"] - fail_string = "Fail, Fail to create server" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - continue - - # step 4 create UDP socket - checker_stings = ["R SSC1 A :\+BIND:(\d+),OK"] - test_action_string = ["SSC SSC1 soc -B -t UDP -i %s -p %s" % (target_ip, udp_port)] - fail_string = "Fail, Fail bind" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - continue - - # step 5 do throughput test - send_thread = SendThread(udp_sock if rx_enable is True else None, - send_len, (target_ip, udp_port)) - send_thread.start() - - recv_thread = RecvThread(udp_sock if tx_enable is True else None) - recv_thread.start() - - if tx_enable is True: - # do send from target - test_action_string = ["SSC SSC1 soc -S -s -l %s -n 10000000 -i %s -p %s" - % (send_len, pc_ip, udp_port)] - fail_string = "Fail, Fail to send" - if self.load_and_exe_one_step([], test_action_string, fail_string) is False: - pass - - # start throughput calculate - recv_thread.start_calc() - - # sleep for measure period - time.sleep(measure_period) - - # stop throughput calculate - recv_thread.stop_calc() - send_thread.exit() - - send_thread.join() - recv_thread.join() - - # output throughput result - # in Mbps - if rx_enable is True: - # get received data len from PC - self.load_and_exe_one_step(["R SSC1 A :RECVLEN:(\d+)"], - ["SSC SSC1 soc -Q -s -o 1"], - "Fail, Fail to get recv data len") - try: - rx_data_len = int(self.get_parameter("recv_len")) - except StandardError: - rx_data_len = 0 - - result.log_throughput(ap_prop["ssid"] + "_rx", rssi, att_value, - float(rx_data_len * 8) / (measure_period * 1000000)) - - if recv_thread.get_bytes_recv() > 0: - result.log_throughput(ap_prop["ssid"] + "_tx", rssi, att_value, - float(recv_thread.get_bytes_recv() * 8) / (measure_period * 1000000)) - - result.output_to_file() - pass - - udp_sock.close() - - self.result_cntx.set_result("Succeed") - - # finally, execute done - - def result_check(self, port_name, data): - TCActionBase.CommonTCActionBase.result_check(self, port_name, data) - self.result_cntx.append_data(port_name, data) - - -def main(): - pass - -if __name__ == '__main__': - main() diff --git a/components/test/TestCaseScript/UDPStress/__init__.py b/components/test/TestCaseScript/UDPStress/__init__.py deleted file mode 100755 index d29ee405a4..0000000000 --- a/components/test/TestCaseScript/UDPStress/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__all__ = ["UDPSendRecv", ] diff --git a/components/test/TestCaseScript/WiFiStress/SoftAPNSTA.py b/components/test/TestCaseScript/WiFiStress/SoftAPNSTA.py deleted file mode 100755 index 70a1169f20..0000000000 --- a/components/test/TestCaseScript/WiFiStress/SoftAPNSTA.py +++ /dev/null @@ -1,178 +0,0 @@ -import random -import time -import string -import threading - -from TCAction import TCActionBase -from NativeLog import NativeLog -from TCAction import PerformanceTCBase -from Utility import Encoding - - -class STAJAPThread(threading.Thread): - def __init__(self, test_action, port_name, ssid, password, delay1, delay2, change_mac): - threading.Thread.__init__(self) - self.setDaemon(True) - self.test_action = test_action - self.port_name = port_name - self.ssid = ssid - self.password = password - self.delay1 = delay1 - self.delay2 = delay2 - self.change_mac = change_mac - self.exit_flag = threading.Event() - pass - - def exit(self): - self.exit_flag.set() - pass - - def run(self): - total_test_count = 0 - fail_count = 0 - while self.exit_flag.isSet() is False: - # change mac - if self.change_mac is True: - mac = Encoding.generate_random_mac() - self.test_action.serial_write_line(self.port_name, "mac -S -o 1 -m %s" % mac) - self.test_action.check_response(self.port_name, "+MAC:STA,OK") - - time.sleep(1) - - # JAP - total_test_count += 1 - # flush current port data - self.test_action.flush_data(self.port_name) - self.test_action.serial_write_line(self.port_name, "sta -C -s %s -p %s" % (self.ssid, self.password)) - if self.test_action.check_response(self.port_name, "+JAP:CONNECTED", 45) is False: - fail_count += 1 - NativeLog.add_trace_critical("[%s] Failed to JAP, Failed/Total : %d/%d" - % (self.port_name, fail_count, total_test_count)) - continue - time.sleep(random.randint(self.delay1[0], self.delay1[1])) - - # QAP - self.test_action.serial_write_line(self.port_name, "sta -D") - if self.test_action.check_response(self.port_name, "+QAP:OK", 5) is False: - NativeLog.add_trace_critical("[%s] Failed to QAP" % self.port_name) - time.sleep(random.randint(self.delay2[0], self.delay2[1])) - - # make sure quit AP - self.test_action.serial_write_line(self.port_name, "sta -D") - pass - pass - - -class SoftAPNSTA(PerformanceTCBase.PerformanceTCBase): - - def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): - PerformanceTCBase.PerformanceTCBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - self.sta_num = 0 - self.max_sta = 4 - self.test_time = 60 - self.delay1 = [5, 30] - self.delay2 = [5, 10] - self.change_mac = True - self.channel = 11 - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy" and cmd_set[i][0] != "": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - pass - - def process(self): - # configurable parameters - try: - sta_num = self.sta_num - max_sta = self.max_sta - test_time = self.test_time - # delay between JAP succeed and QAP - delay1 = self.delay1 - # delay between QAP and JAP - delay2 = self.delay2 - # if change mac each time before JAP - change_mac = self.change_mac - # channel - channel = self.channel - except StandardError, e: - raise StandardError("miss mandatory parameters") - - # step 0, set op mode and enable dhcp - self.serial_write_line("SSC1", "op -S -o 2") - if self.check_response("SSC1", "+MODE:OK", 2) is False: - NativeLog.add_trace_critical("Failed to set ap mode") - return - self.serial_write_line("SSC1", "dhcp -E -o 2") - if self.check_response("SSC1", "+DHCP:AP,OK", 2) is False: - NativeLog.add_trace_critical("Failed to enable ap dhcp") - return - self.serial_write_line("SSC1", "dhcp -L -s 192.168.4.2 -e 192.168.4.100 -t 1") - if self.check_response("SSC1", "+DHCP:LEASE,OK", 2) is False: - NativeLog.add_trace_critical("Failed to enable ap dhcp") - return - self.serial_write_line("SSC1", "dhcp -S -o 2") - if self.check_response("SSC1", "+DHCP:AP,OK", 2) is False: - NativeLog.add_trace_critical("Failed to enable ap dhcp") - return - - for i in range(sta_num): - self.serial_write_line("SSC%d" % (i+2), "op -S -o 1") - if self.check_response("SSC%d" % (i+2), "+MODE:OK", 2) is False: - NativeLog.add_trace_critical("Failed to set sta mode") - return - self.serial_write_line("SSC%d" % (i+2), "dhcp -S -o 1") - if self.check_response("SSC%d" % (i+2), "+DHCP:STA,OK", 2) is False: - NativeLog.add_trace_critical("Failed to enable sta dhcp") - - # step 1, set ap config and load - ap_ssid = "".join([random.choice(string.uppercase) for m in range(15)]) - ap_password = "".join([random.choice(string.lowercase) for m in range(15)]) - - self.serial_write_line("SSC1", "ap -S -s %s -p %s -t 3 -m %s -n %s" - % (ap_ssid, ap_password, max_sta, channel)) - if self.check_response("SSC1", "+SAP:OK", 2) is False: - NativeLog.add_trace_critical("Failed to set AP") - return - - # step 2, start thread to let STA JAP - sta_thread_list = [] - for i in range(sta_num): - sta_thread_list.append(STAJAPThread(self, "SSC%d" % (i+2), - ap_ssid, ap_password, delay1, delay2, change_mac)) - for sta_thread in sta_thread_list: - sta_thread.start() - - # step 3, sleep for test time - for i in range(test_time): - self.flush_data("SSC1") - time.sleep(60) - - # step 4, close all thread, will disconnect when exit thread - for sta_thread in sta_thread_list: - sta_thread.exit() - for sta_thread in sta_thread_list: - sta_thread.join() - # wait and make sure disconnect done - time.sleep(1) - - # step 5, join AP and check - sta_num_temp = max_sta if sta_num > max_sta else sta_num - - for i in range(sta_num_temp): - self.serial_write_line("SSC%d" % (i+2), "sta -C -s %s -p %s" % (ap_ssid, ap_password)) - if self.check_response("SSC%d" % (i+2), "+JAP:CONNECTED", 45) is False: - self.set_result("Fail") - break - pass - else: - self.set_result("Succeed") - - -def main(): - pass - -if __name__ == '__main__': - main() - diff --git a/components/test/TestCaseScript/WiFiStress/WifiConnUtility.py b/components/test/TestCaseScript/WiFiStress/WifiConnUtility.py deleted file mode 100755 index 24702bfc8d..0000000000 --- a/components/test/TestCaseScript/WiFiStress/WifiConnUtility.py +++ /dev/null @@ -1,240 +0,0 @@ -from NativeLog import NativeLog -import time -import random - - -ERROR_AP_PROP = {"ssid": "123456789012345678901234567890", - "ssid_len": 30, - "pwd": "12345678901234567890", - "pwd_len": 20, - "channel": 10, - "enc": 3, - "apc": 9, # invalid apc count - } - - -class WifiConnUtilError(StandardError): - pass - - -class WifiConnUtility(object): - - def __init__(self, tc_action): - self.tc_action = tc_action - self.target_type = tc_action.target_type - pass - - def set_mode(self, mode): - ret = True - fail_string = "set mode fail" - cmd = [] - checker_stings = [] - for i in range(2): - if self.target_type[0] == "SSC": - cmd.append("SSCC SSC%d op -S -o %d" % (i+1, mode[i])) - checker_stings.append("SSCP SSC%d C +MODE:OK" % (i+1)) - pass - else: - cmd.append("ATC AT%d CWMODE %d" % (i+1, mode[i])) - checker_stings.append("ATP AT%d L OK" % (i+1)) - pass - if self.tc_action.load_and_exe_one_step(checker_stings, cmd, - fail_string, check_time=50) is False: - NativeLog.add_trace_critical("Failed to set mode") - ret = False - return ret - pass - - def _apc_switch(self, outlet_list, action_list): - checker_stings = ["R PC_COM C OK"] - switch_cmd = "APC " - fail_string = "Error when switching APC" - ret = True - - for [_outlet, _action] in zip(action_list, outlet_list): - switch_cmd += " %s %d" % (_action, _outlet) - - if self.tc_action.load_and_exe_one_step(checker_stings, [switch_cmd], - fail_string, check_time=50) is False: - NativeLog.add_trace_critical("Error when switching APC") - ret = False - return ret - pass - - def _set_target_ap(self, ap_prop): - ret = True - fail_string = "set target ap fail, %s, %s" % (ap_prop["ssid"], ap_prop["pwd"]) - if self.target_type[1] == "SSC": - if ap_prop["pwd"] == "": - cmd = ["SSCC SSC2 ap -S -s %s -t %d" % (ap_prop["ssid"], - ap_prop["enc"]) - ] - else: - cmd = ["SSCC SSC2 ap -S -s %s -p %s -t %d" % (ap_prop["ssid"], - ap_prop["pwd"], - ap_prop["enc"]) - ] - checker_stings = ["SSCP SSC2 C +SAP:OK"] - pass - else: - cmd = ["ATC AT2 CWSAP \"%s\" \"%s\" %d %d" % (ap_prop["ssid"], - ap_prop["pwd"], - ap_prop["channel"], - ap_prop["enc"]) - ] - checker_stings = ["ATR AT2 L OK"] - pass - if self.tc_action.load_and_exe_one_step(checker_stings, cmd, - fail_string, check_time=50) is False: - NativeLog.add_trace_critical("set target ap fail") - ret = False - return ret - pass - - def setup_ap(self, ap_type, ap_prop): - if ap_type == "target": - ret = self._set_target_ap(ap_prop) - pass - else: - ret = self._apc_switch(["ON"], [ap_prop["apc"]]) - # delay for 5 seconds, wait AP ready - time.sleep(5) - pass - return ret - - def do_scan(self, ap_prop): - fail_string = "Scan fail" - ret = True - # do not check if the set AP can be scanned - if self.target_type[1] == "SSC": - cmd = ["SSCC SSC1 sta -S"] - checker_stings = ["SSCR SSC1 C +SCANDONE"] - pass - else: - cmd = ["ATS AT1 AT+CWLAP"] - checker_stings = ["ATR AT1 L OK"] - pass - if self.tc_action.load_and_exe_one_step(checker_stings, cmd, - fail_string, check_time=100) is False: - NativeLog.add_trace_critical("Scan fail") - ret = False - return ret - pass - - def _switch_off_target_ap(self, delay): - time.sleep(delay) - self._set_target_ap(ERROR_AP_PROP) - pass - - def _switch_on_target_ap(self, ap_prop, delay): - time.sleep(delay) - self._set_target_ap(ap_prop) - pass - - def _switch_off_ap(self, ap_type, ap_prop, delay_range): - delay = random.randint(delay_range[0]*10, delay_range[1]*10)/10 - if ap_type == "target": - self._switch_off_target_ap(delay) - else: - delay -= 1.5 - time.sleep(delay if delay > 0 else 0) - self._apc_switch(["OFF"], [ap_prop["apc"]]) - pass - - def _switch_on_ap(self, ap_type, ap_prop, delay_range): - delay = random.randint(delay_range[0]*10, delay_range[1]*10)/10 - if ap_type == "target": - self._switch_on_target_ap(ap_prop, delay) - else: - delay -= 1.5 - time.sleep(delay if delay > 0 else 0) - self._apc_switch(["ON"], [ap_prop["apc"]]) - pass - - def _join_ap(self, ap_prop, test_method): - fail_string = "join target ap fail, %s, %s" % (ap_prop["ssid"], ap_prop["pwd"]) - if self.target_type[1] == "SSC": - cmd = ["SSCC SSC1 ap -C -s %s -p %s" % (ap_prop["ssid"], - ap_prop["pwd"],) - ] - checker_stings = ["SSCR SSC1 C +JAP:CONNECTED"] - pass - else: - cmd = ["ATC AT1 CWJAP \"%s\" \"%s\"" % (ap_prop["ssid"], - ap_prop["pwd"]) - ] - checker_stings = ["ATR AT1 NC ERROR NC FAIL L OK"] - pass - if test_method == "Normal": - ret = self.tc_action.load_and_exe_one_step(checker_stings, cmd, - fail_string, check_freq=0.1, check_time=350) - if ret is not False: - ret *= 0.1 - else: - ret = self.tc_action.load_and_exe_one_step([], cmd, fail_string) - return ret - pass - - def _check_join_ap_result(self, ap_prop): - ret = False - fail_string = "join ap fail, %s, %s" % (ap_prop["ssid"], ap_prop["pwd"]) - - if self.target_type[1] == "SSC": - checker_stings = ["SSCR SSC1 C +JAP:CONNECTED"] - ret = self.tc_action.load_and_exe_one_step(checker_stings, ["DELAY 0"], - fail_string, check_freq=1, check_time=120) - pass - else: - cmd = ["ATS AT1 AT+CWJAP?"] - checker_stings = ["ATR AT1 NC busy NC No%20AP C +CWJAP"] - for i in range(3): - ret = self.tc_action.load_and_exe_one_step(checker_stings, cmd, - fail_string, check_freq=1, check_time=2) - if ret is not False: - break - time.sleep(15) - - return ret - pass - - def join_ap(self, join_test_method, ap_type, ap_prop, delay): - - if join_test_method == "WRONG_PROP": - _prop = ERROR_AP_PROP - else: - _prop = ap_prop - - ret = self._join_ap(_prop, join_test_method) - - if join_test_method == "OFF_ON": - self._switch_off_ap(ap_type, ap_prop, delay[0]) - self._switch_on_ap(ap_type, ap_prop, delay[1]) - ret = self._check_join_ap_result(_prop) - pass - elif join_test_method == "OFF": - self._switch_off_ap(ap_type, ap_prop, delay[0]) - time.sleep(25) - pass - - return ret - pass - - def do_reconnect(self, reconnect_test_method, ap_type, ap_prop, delay): - ret = True - if reconnect_test_method == "OFF_ON": - self._switch_off_ap(ap_type, ap_prop, delay[0]) - self._switch_on_ap(ap_type, ap_prop, delay[1]) - ret = self._check_join_ap_result(ap_prop) - pass - elif reconnect_test_method == "OFF": - self._switch_off_ap(ap_type, ap_prop, delay[0]) - pass - return ret - pass - - -def main(): - pass - -if __name__ == '__main__': - main() diff --git a/components/test/TestCaseScript/WiFiStress/WifiJAP.py b/components/test/TestCaseScript/WiFiStress/WifiJAP.py deleted file mode 100755 index 20dd28041e..0000000000 --- a/components/test/TestCaseScript/WiFiStress/WifiJAP.py +++ /dev/null @@ -1,218 +0,0 @@ -import os -import random -import time - -import WifiConnUtility -from NativeLog import NativeLog -from TCAction import TCActionBase -from Utility import Encoding -from Utility import MakeFolder - -STEPS = {"SCAN1": 0x01, "JAP": 0x02, "SCAN2": 0x04, "RECONNECT": 0x08} - -AP_PROP = ("ssid", "ssid_len", "pwd", - "pwd_len", "channel", "enc", "apc") - -JAP_TEST_METHOD = ("Normal", "OFF_ON", "OFF", "WRONG_PROP") - -RECONNECT_TEST_METHOD = ("OFF_ON", "OFF") - -LOG_FOLDER = os.path.join("AT_LOG", "Performance", "JAP") - - -SSID_LEN_RANGE = (1, 32) # in bytes -ENC_TYPE = (0, 2, 3, 4) # do not support WEP for 8266 soft AP -PWD_RANGE = {0: [0, 0], - 1: [5, 5], - 2: [8, 63], - 3: [8, 63], - 4: [8, 63], - } - - -class WifiJAP(TCActionBase.CommonTCActionBase): - - def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): - TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - # default value for optional configurable params - self.pwd_len = [8, 64] - self.step_config = [0x03, 0x01, 0x02, 0x0B, 0x0F] - self.join_test_method = ["Normal"] - self.join_delay = [[1.5, 5], [1.5, 5]] - self.reconnect_test_method = ["OFF_ON"] - self.reconnect_delay = [[1.5, 5], [1.5, 6]] - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy" and cmd_set[i][0] != "": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - # read AP list - self.ap_list = [] - for i in range(1, len(cmd_set)): - for j in range(len(cmd_set[i][1])): - if cmd_set[i][1][j] != "": - cmd_string = "self.ap_list.append(dict(zip(AP_PROP, " + cmd_set[i][1][j] + ")))" - exec cmd_string - - folder_path = MakeFolder.make_folder(LOG_FOLDER) - file_name = "JAP_log_%s.log" % (time.strftime("%m%d%H%M%S", time.localtime())) - self._performance_log_file = os.path.join(folder_path, file_name) - - # test statistics - self._succeed_count = self._fail_count = self._time_cost_count = 0 - self._total_time = self._longest_time = 0 - - self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) - # get target type "SSC" or "AT" - self.target_type = ["SSC" if test_env.get_port_by_name("AT1") is None else "AT"] - self.target_type.append("SSC" if test_env.get_port_by_name("AT2") is None else "AT") - self._utility = WifiConnUtility.WifiConnUtility(self) - pass - - def _generate_random_ap_prop(self): - ap_prop = dict.fromkeys(AP_PROP) - # generate target ap_value - ap_prop["ssid_len"] = random.randint(SSID_LEN_RANGE[0], SSID_LEN_RANGE[1]) - ap_prop["channel"] = random.choice(range(1, 14)) - ap_prop["enc"] = random.choice(ENC_TYPE) - ap_prop["pwd_len"] = random.randint(PWD_RANGE[ap_prop["enc"]][0], PWD_RANGE[ap_prop["enc"]][1]) - # generate string - if self.target_type[0] == self.target_type[1] == "AT": - ap_prop["ssid"] = Encoding.generate_random_utf8_str(ap_prop["ssid_len"]) - ap_prop["pwd"] = Encoding.generate_random_utf8_str(ap_prop["pwd_len"]) - # NativeLog.add_trace_info("ssid hex is : %x" % ap_prop["ssid"]) - # NativeLog.add_trace_info("pwd hex is : %x" % ap_prop["pwd"]) - else: - ap_prop["ssid"] = Encoding.generate_random_printable_str(ap_prop["ssid_len"]) - ap_prop["pwd"] = Encoding.generate_random_printable_str(ap_prop["pwd_len"]) - - return ap_prop - - def _logging_performance(self, ssid, join_method="Normal", time_cost=0): - # log performance to performance log file - with open(self._performance_log_file, "ab+") as f: - # log time and ssid - f.write("\r\n[%s]:\r\n[AP name] %s\r\n" % - (time.strftime("%m-%d %H:%M:%S", time.localtime()), ssid)) - if join_method == "Normal" or join_method == "OFF_ON": - if time_cost is not False: - self._succeed_count += 1 - if join_method == "Normal": - f.write("[Succeed][%f]\r\n" % time_cost) - self._longest_time = (time_cost > self._longest_time and - [time_cost] or [self._longest_time])[0] - self._time_cost_count += 1 - self._total_time += time_cost - else: - f.write("[Succeed][%s]\r\n" % join_method) - else: - self._fail_count += 1 - f.write("[Fail][%s]\r\n" % join_method) - pass - - def _logging_fail_step(self, ssid, step): - with open(self._performance_log_file, "ab+") as f: - f.write("\r\n[%s]:\r\n[AP name] %s\r\n" % - (time.strftime("%m-%d %H:%M:%S", time.localtime()), ssid)) - f.write("[Fail][%s]\r\n" % step) - pass - - def _generate_performance_report(self): - with open(self._performance_log_file, "ab+") as f: - f.write("[Test report] Succeed: %d\r\n" % self._succeed_count) - f.write("[Test report] Failed: %d\r\n" % self._fail_count) - if self._succeed_count > 0 or self._fail_count > 0: - f.write("[Test report] Pass Rate: %f\r\n" % - (self._succeed_count/(self._fail_count+self._succeed_count))) - if self._time_cost_count > 0: - f.write("[Test report] Average time: %f\r\n" % (self._total_time/self._time_cost_count)) - f.write("[Test report] Longest time: %f\r\n" % self._longest_time) - - def execute(self): - TCActionBase.TCActionBase.execute(self) - self.result_cntx.start() - - # mandatory configurable params - try: - target_ap_num = self.target_ap_num - test_count = self.test_count - except StandardError, e: - NativeLog.add_trace_critical("Error configuration for WifiJAP script, error is %s" % e) - raise StandardError("Error configuration") - - # prepare ap list - _ap_list = [["target", None]] * target_ap_num - for _ap_prop in self.ap_list: - _ap_list.append(["AP", _ap_prop]) - - # set to correct mode first - self._utility.set_mode([1, 2]) - - for i in xrange(test_count): - _ap = random.choice(_ap_list) - # arrange ap - _ap_type = _ap[0] - _ap_prop = _ap[1] - if _ap_type == "target": - _ap_prop = self._generate_random_ap_prop() - pass - - # step 1 : mandatory step, set up AP - if self._utility.setup_ap(_ap_type, _ap_prop) is False: - self._logging_fail_step(_ap_prop["ssid"], "Set AP") - NativeLog.add_prompt_trace("[Step1] setup AP Fail") - continue - step_config = random.choice(self.step_config) - NativeLog.add_prompt_trace("[Step1] setup AP succeed") - - # step 2 : optional step, do scan before connect - if step_config & STEPS["SCAN1"] != 0: # check option - if self._utility.do_scan(_ap_prop) is False: - self._logging_fail_step(_ap_prop["ssid"], "Scan before JAP") - NativeLog.add_prompt_trace("[Step2] Scan Done") - - # step 3 : mandatory step, join AP - if step_config & STEPS["JAP"] != 0: # check option - _join_test_method = random.choice(self.join_test_method) - time_cost = self._utility.join_ap(_join_test_method, _ap_type, _ap_prop, self.join_delay) - # log performance to performance log file - self._logging_performance(_ap_prop["ssid"], _join_test_method, time_cost) - if time_cost is False: - # do scan once to check if AP exist - self._utility.do_scan(_ap_prop) - continue - NativeLog.add_prompt_trace("[Step3] Join AP done") - - # step 4 : optional step, scan after join AP - if step_config & STEPS["SCAN2"] != 0: # check option - if self._utility.do_scan(_ap_prop) is False: - self._logging_fail_step(_ap_prop["ssid"], "Scan after JAP") - NativeLog.add_prompt_trace("[Step4] Scan done") - - # step 5 : optional step, reconnect test - if step_config & STEPS["RECONNECT"] != 0: # check option - _reconnect_test_method = random.choice(self.reconnect_test_method) - if self._utility.do_reconnect(_reconnect_test_method, - _ap_type, _ap_prop, self.reconnect_delay) is False: - self._logging_fail_step(_ap_prop["ssid"], "Reconnect") - - NativeLog.add_prompt_trace("[Step5] Reconnect done") - # continue to next loop - NativeLog.add_prompt_trace("[WifiJAP] Test count %d done" % i) - - # generate report and cleanup - self._generate_performance_report() - - self.result_cntx.set_result("Succeed") - - def result_check(self, port_name, data): - TCActionBase.CommonTCActionBase.result_check(self, port_name, data) - self.result_cntx.append_data(port_name, data) - - -def main(): - pass - -if __name__ == '__main__': - main() diff --git a/components/test/TestCaseScript/WiFiStress/WifiJAPAtt.py b/components/test/TestCaseScript/WiFiStress/WifiJAPAtt.py deleted file mode 100755 index 2c2eadc79d..0000000000 --- a/components/test/TestCaseScript/WiFiStress/WifiJAPAtt.py +++ /dev/null @@ -1,173 +0,0 @@ -import os -import time -from TCAction import TCActionBase -from NativeLog import NativeLog -from Utility import RSSICalibrator -from Utility import MakeFolder - -MAX_RSSI = 0 -MIN_RSSI = -110 -MAX_ATT = 60 -LOG_FOLDER = os.path.join("AT_LOG", "Performance", "JAP") -AP_PROP_KEY = ("ssid", "password", "apc") - - -class Performance(object): - def __init__(self): - self.succeed_rssi = dict.fromkeys(range(MIN_RSSI, MAX_RSSI), 0) - self.failed_rssi = dict.fromkeys(range(MIN_RSSI, MAX_RSSI), 0) - self.failed_att = dict.fromkeys(range(MAX_ATT), 0) - pass - - def log_performance(self, result, att, rssi): - if result == "Succeed": - self.succeed_rssi[rssi] += 1 - else: - if rssi == 0: - self.failed_att[att] += 1 - else: - self.failed_rssi[rssi] += 1 - pass - - def __str__(self): - data = "Succeed:\r\n" - for rssi in self.succeed_rssi: - if self.succeed_rssi[rssi] > 0: - data += "\tRSSI%4d: %2d times\r\n" % (rssi, self.succeed_rssi[rssi]) - - data += "Failed during scan:\r\n" - for att in self.failed_att: - if self.failed_att[att] > 0: - data += "\tATT%3d: %2d times\r\n" % (att, self.failed_att[att]) - - data += "Failed during JAP:\r\n" - for rssi in self.failed_rssi: - if self.failed_rssi[rssi] > 0: - data += "\tRSSI%4d: %2d times\r\n" % (rssi, self.failed_rssi[rssi]) - - return data - pass - - -class WifiJAPAtt(TCActionBase.CommonTCActionBase): - - def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): - TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - self.att_test_list = range(60) - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - # read AP list - self.ap_list = [] - for i in range(1, len(cmd_set)): - for j in range(len(cmd_set[i][1])): - if cmd_set[i][1][j] != "": - cmd_string = "self.ap_list.append(dict(zip(AP_PROP_KEY, " + cmd_set[i][1][j] + ")))" - exec cmd_string - - self.performance = dict([(ap_prop["ssid"], Performance()) for ap_prop in self.ap_list]) - # create log file - folder_path = MakeFolder.make_folder(LOG_FOLDER) - self.performance_log = os.path.join(folder_path, - "JAP_Att_%s.log" % time.strftime("%d%H%M%S", time.localtime())) - - self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) - pass - - def log_performance(self, att, rssi, ssid, result): - NativeLog.add_prompt_trace("[%s][ssid %s] [att %s] [rssi %s]" % (result, ssid, att, rssi)) - data = "" - self.performance[ssid].log_performance(result, att, rssi) - for _ssid in self.performance: - data += "[ssid] %s\r\n%s\r\n" % (_ssid, self.performance[_ssid]) - with open(self.performance_log, "wb+") as f: - f.write(data) - pass - - def execute(self): - TCActionBase.TCActionBase.execute(self) - self.result_cntx.start() - - try: - # configurable params - ap_list = self.ap_list - att_test_list = self.att_test_list - test_count = self.test_count - # configurable params - except StandardError, e: - NativeLog.add_trace_critical("Error configuration for JAPAtt script, error is %s" % e) - raise StandardError("Error configuration") - - for x in xrange(test_count): - for ap_prop in ap_list: - if ap_prop["password"] == "": - # set a default string for open ap - ap_prop["password"] = "1" - - # switch off all outlet, switch on AP outlet - outlet_config_dict = dict.fromkeys(range(1, 9), "OFF") - outlet_config_dict[ap_prop["apc"]] = "ON" - apc_cmd = "APC " - for outlet in outlet_config_dict: - apc_cmd += " %s %s" % (outlet_config_dict[outlet], outlet) - checker_stings = ["P PC_COM L OK"] - fail_string = "Fail, Fail to switch apc" - if self.load_and_exe_one_step(checker_stings, [apc_cmd], fail_string) is False: - return - - # wait AP ready - time.sleep(20) - - # create RSSI Calibrator - calibrator = RSSICalibrator.Calibrator() - - for att_value in att_test_list: - # step 0 set att value - checker_stings = ["R PC_COM L OK"] - test_action_string = ["ATT %s" % att_value] - fail_string = "Fail, Fail to set att value" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: - continue - - # step 1 get AP RSSI - checker_stings = ["R SSC1 A :\+SCAN:%s,[:\d\w]+,\d+,\d+,([-\d]+)" % ap_prop["ssid"]] - test_action_string = ["SSC SSC1 sta -S -s %s" % ap_prop["ssid"]] - fail_string = "Fail, Fail to scan" - rssi = scan_count = 0 - for i in range(3): - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, - check_freq=1, check_time=5) is False: - self.log_performance(att_value, 0, ap_prop["ssid"], "Failed to measure RSSI") - continue - rssi += int(self.test_env.get_variable_by_name("rssi")[1]) - scan_count += 1 - - rssi = calibrator.calibrate_rssi(float(rssi)/scan_count if scan_count > 0 else 0, att_value) - - # step 2 connect to AP - checker_stings = ["R SSC1 C +JAP:CONNECTED"] - test_action_string = ["SSC SSC1 sta -C -s %s -p %s" % (ap_prop["ssid"], ap_prop["password"])] - fail_string = "Fail, Fail to JAP" - if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, - check_freq=1, check_time=45) is False: - self.log_performance(att_value, rssi, ap_prop["ssid"], "Failed to JAP") - continue - - self.log_performance(att_value, rssi, ap_prop["ssid"], "Succeed") - - # finally, execute done - self.result_cntx.set_result("Succeed") - - def result_check(self, port_name, data): - TCActionBase.CommonTCActionBase.result_check(self, port_name, data) - self.result_cntx.append_data(port_name, data) - - -def main(): - pass - -if __name__ == '__main__': - main() diff --git a/components/test/TestCaseScript/WiFiStress/WifiSmartConfig.py b/components/test/TestCaseScript/WiFiStress/WifiSmartConfig.py deleted file mode 100755 index 3a95a920fb..0000000000 --- a/components/test/TestCaseScript/WiFiStress/WifiSmartConfig.py +++ /dev/null @@ -1,273 +0,0 @@ -import random -import os -import time -import copy - -from TCAction import TCActionBase -from NativeLog import NativeLog -from Utility import Encoding -from Utility import MakeFolder - -AP_PROP = ("ssid", "ssid_len", "pwd", - "pwd_len", "channel", "enc", "apc") - -SMART_TYPE = ("esp-touch", "airkiss") - -TEST_METHOD = ("ssid_broadcast", "ssid_hidden") - -HT = ("ht20", "ht40") - -TEST_STAT = ("total count", "fail count", "total time", "longest time") - -_TEST_STAT_INIT_DICT = {"total count": 0, - "fail count": 0, - "total time": 0, - "longest time": 0, - } - -LOG_FOLDER = os.path.join("AT_LOG", "Performance", "SmartConfig") - - -SSID_LEN_RANGE = (1, 32) # in bytes -ENC_TYPE = (0, 2, 3, 4) # do not support WEP for 8266 soft AP -PWD_RANGE = {0: [0, 0], - 1: [5, 5], - 2: [8, 32], - 3: [8, 32], - 4: [8, 32], - } - - -class WifiSmartConfig(TCActionBase.CommonTCActionBase): - - def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): - TCActionBase.CommonTCActionBase.__init__(self, name, test_env, cmd_set=cmd_set, - timeout=timeout, log_path=log_path) - # default value for optional configurable params - self.test_method = ["ssid_hidden", "ssid_broadcast"] - self.bssid = "ff:ff:ff:ff:ff:ff" - self.ht_ap = dict(zip(HT, [("", ""), - ("", "")])) - self.ap_channel = {"ht20": 1, "ht40": 1} - self.delay_time = 3 # default 3s, wait for scan done - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy" and cmd_set[i][0] != "": - cmd_string = "self." + cmd_set[i][0] - exec cmd_string - - folder_path = MakeFolder.make_folder(LOG_FOLDER) - file_name = "SmartConfig_log_%s.log" % (time.strftime("%m%d%H%M%S", time.localtime())) - self._performance_log_file = os.path.join(folder_path, file_name) - - # type - self.target_type = ["SSC" if test_env.get_port_by_name("AT1") is None else "AT"] - self.target_type.append("SSC" if test_env.get_port_by_name("AT2") is None else "AT") - - # test statistics - # better ways to create? - _test_stat = dict.fromkeys(TEST_STAT, 0) - _test_method = dict.fromkeys(TEST_METHOD) - _test_ht = dict.fromkeys(HT) - self.test_stat = dict.fromkeys(SMART_TYPE) - for i in SMART_TYPE: - self.test_stat[i] = copy.deepcopy(_test_ht) - for j in HT: - self.test_stat[i][j] = copy.deepcopy(_test_method) - for k in TEST_METHOD: - self.test_stat[i][j][k] = copy.deepcopy(_test_stat) - - self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) - pass - - def _generate_random_ap_prop(self, ht_type): - ap_prop = dict.fromkeys(AP_PROP) - # generate target ap_value - ap_prop["ssid_len"] = random.randint(SSID_LEN_RANGE[0], SSID_LEN_RANGE[1]) - ap_prop["channel"] = self.ap_channel[ht_type] - ap_prop["enc"] = random.choice(ENC_TYPE) - ap_prop["pwd_len"] = random.randint(PWD_RANGE[ap_prop["enc"]][0], PWD_RANGE[ap_prop["enc"]][1]) - ap_prop["ssid"] = Encoding.generate_random_printable_str(ap_prop["ssid_len"]) - ap_prop["pwd"] = Encoding.generate_random_printable_str(ap_prop["pwd_len"]) - - return ap_prop - - def _logging_performance(self, time_cost, ssid, password, smart_type, test_method, ht_type): - # update test statistics - stat = self.test_stat[smart_type][ht_type][test_method] - stat["total count"] += 1 - # log performance to performance log file - with open(self._performance_log_file, "ab+") as f: - # log time and ssid - if time_cost is not False: - time_tmp = float(time_cost)/10 - f.write("\r\n[%s]:\r\n[Succeed] [%.2f]\r\n" % - (time.strftime("%m-%d %H:%M:%S", time.localtime()), time_tmp)) - stat["total time"] += time_tmp - stat["longest time"] = time_tmp if time_tmp > stat["longest time"] else stat["longest time"] - else: - f.write("\r\n[%s]:\r\n[Fail]\r\n" % - time.strftime("%m-%d %H:%M:%S", time.localtime())) - stat["fail count"] += 1 - - f.write("[%s] [%s] [%s]\r\n" % - (smart_type, test_method, ht_type)) - f.write("[ssid] %s \r\n[password] %s\r\n" % - (ssid, password)) - pass - - def _generate_performance_report(self): - with open(self._performance_log_file, "ab+") as f: - for i in SMART_TYPE: - for j in HT: - for k in TEST_METHOD: - stat = self.test_stat[i][j][k] - f.write("\r\n[Test report] [%s] [%s] [%s]\r\n" % (i, j, k)) - if stat["total count"] > 0: - f.write("[Total]: %d\r\n" % stat["total count"]) - f.write("[Failed]: %d\r\n" % stat["fail count"]) - f.write("[Fail ratio]: %.2f%%\r\n" % - (float(stat["fail count"])/stat["total count"] * 100)) - f.write("[Longest time cost]: %.2f\r\n" % stat["longest time"]) - if (stat["total count"] - stat["fail count"]) > 0: - f.write("[Average time cost]: %.2f\r\n" % - (stat["total time"]/(stat["total count"]-stat["fail count"]))) - - @staticmethod - def cmd_exception_catcher(e): - raise e - pass - - def execute(self): - TCActionBase.TCActionBase.execute(self) - self.result_cntx.start() - - # mandatory configurable params - try: - test_count = self.test_count - delay_time = self.delay_time - except StandardError, e: - NativeLog.add_trace_critical("Error configuration for WifiJAP script, error is %s" % e) - raise StandardError("Error configuration") - - # step 0 : set AT1 mode - fail_string = "Fail to restore init condition" - if self.target_type[0] == "AT": - cmd = ["ATS AT1 AT+CWMODE=1"] - checker_stings = ["R AT1 L OK"] - else: - cmd = ["SSC SSC1 op -S -o 1"] - checker_stings = ["R SSC1 C +MODE:OK"] - if self.target_type[1] == "AT": - cmd.append("ATS AT2 AT+CWMODE=2") - checker_stings.append("R AT2 L OK") - else: - cmd.append("SSC SSC2 op -S -o 2") - checker_stings.append("R SSC2 C +MODE:OK") - - if self.load_and_exe_one_step(checker_stings, cmd, - fail_string, check_time=150) is False: - NativeLog.add_trace_critical(fail_string) - return - - for i in xrange(test_count): - _method = random.choice(self.test_method) - _ht = random.choice(self.ht) - _ap_prop = self._generate_random_ap_prop(_ht) - _smart_type = random.choice(self.smart_type) - _ht_ap = self.ht_ap[_ht] - is_hidden = 0 if _method == "ssid_broadcast" else 1 - # get ip and - - # step 1 : restore init condition - fail_string = "Fail to restore init condition" - if self.target_type[0] == "AT": - cmd = ["ATS AT1 AT+CWSTOPSMART", "WIFI CONN %s %s " % (_ht_ap[0], _ht_ap[1])] - checker_stings = ["P AT1 L OK", "P PC_COM L OK"] - else: - cmd = ["SSC SSC1 smart -E", "WIFI CONN %s %s " % (_ht_ap[0], _ht_ap[1])] - checker_stings = ["P SSC1 C +SC:OK", "P PC_COM L OK"] - - if self.load_and_exe_one_step(checker_stings, cmd, - fail_string, check_time=200) is False: - NativeLog.add_trace_critical(fail_string) - continue - NativeLog.add_prompt_trace("Step1 Done") - - # step 2 : test method is ssid_broadcast, then set AP on target 2 - if _method == "ssid_broadcast": - fail_string = "Fail to set AP" - if self.target_type[1] == "AT": - cmd = ["ATS AT2 AT+CWSAP=\"%s\",\"%s\",%d,%d" % (_ap_prop["ssid"], _ap_prop["pwd"], - _ap_prop["channel"], _ap_prop["enc"])] - checker_stings = ["R AT2 L OK"] - else: - cmd = ["SSC SSC2 ap -S -s %s -p %s -n %d -t %d" % (_ap_prop["ssid"], _ap_prop["pwd"], - _ap_prop["channel"], _ap_prop["enc"])] - checker_stings = ["R SSC2 C +SAP:OK"] - - if self.load_and_exe_one_step(checker_stings, cmd, - fail_string, check_time=50) is False: - NativeLog.add_trace_critical(fail_string) - continue - NativeLog.add_prompt_trace("Step2 Done") - - # step 3 : start SMART - fail_string = "Fail to start smart config" - if self.target_type[0] == "AT": - cmd = ["ATS AT1 AT+CWSTARTSMART"] - checker_stings = ["R AT1 L OK"] - else: - cmd = ["SSC SSC1 smart -S -a 0"] - checker_stings = ["R SSC1 C +SC:OK"] - - if self.load_and_exe_one_step(checker_stings, cmd, - fail_string, check_time=50) is False: - NativeLog.add_trace_critical(fail_string) - continue - # sleep for delay_time seconds to wait scan done or simulate delay config situation - time.sleep(delay_time) - NativeLog.add_prompt_trace("Step3 Done") - - # step 4 : do smart config - fail_string = "Fail in smart config" - cmd = ["SMART %s %s %s %s %d" - % (_smart_type, _ap_prop["ssid"], _ap_prop["pwd"], self.bssid, is_hidden)] - if self.target_type[0] == "AT": - checker_stings = ["P AT1 C Smart%20get%20wifi%20info", - "P LOG1 C %s C %s" % (_ap_prop["ssid"], _ap_prop["pwd"])] - else: - checker_stings = ["P SSC1 C %s C %s" % (_ap_prop["ssid"], _ap_prop["pwd"])] - - try: - time_cost = self.load_and_exe_one_step(checker_stings, cmd, - fail_string, check_time=400, - cmd_exception_catcher=self.cmd_exception_catcher) - except StandardError: - NativeLog.add_prompt_trace("Exception occurred during executing cmd") - continue - pass - self._logging_performance(time_cost, _ap_prop["ssid"], _ap_prop["pwd"], - _smart_type, _method, _ht) - if time_cost is False: - NativeLog.add_prompt_trace(fail_string) - continue - - # continue to next loop - NativeLog.add_prompt_trace("[WifiSmartConfig] Test count %d done" % i) - - # generate report and cleanup - self._generate_performance_report() - - self.result_cntx.set_result("Succeed") - - def result_check(self, port_name, data): - TCActionBase.CommonTCActionBase.result_check(self, port_name, data) - self.result_cntx.append_data(port_name, data) - - -def main(): - pass - -if __name__ == '__main__': - main() diff --git a/components/test/TestCaseScript/WiFiStress/__init__.py b/components/test/TestCaseScript/WiFiStress/__init__.py deleted file mode 100755 index 7960a3ce80..0000000000 --- a/components/test/TestCaseScript/WiFiStress/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__all__ = ["WifiJAP", ] \ No newline at end of file diff --git a/components/test/TestCaseScript/__init__.py b/components/test/TestCaseScript/__init__.py deleted file mode 100755 index 0cc319da70..0000000000 --- a/components/test/TestCaseScript/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -__all__ = ['ATFunc', "ATStress", "IOT", "MeshStress", "StableTest", "TCPIPStress" - "TCPStress", "UDPStress", "WiFiStress"] From e9199a0320c1930274757d3f6759f7851dc8b81c Mon Sep 17 00:00:00 2001 From: Yinling Date: Wed, 12 Oct 2016 11:44:54 +0800 Subject: [PATCH 080/343] should set TEST_CASE_FILE_PATH before CONFIG_FILE use it --- .gitlab-ci.yml | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 42dc78e9ee..8b7b25dd91 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -223,8 +223,8 @@ IT_Function_SYS_01: - ESP32_IDF - SSC_T1_1 before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_SYS_01.yml - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_SYS_01.yml IT_Function_WIFI_01: <<: *test_template @@ -233,8 +233,8 @@ IT_Function_WIFI_01: - SSC_T1_1 - SSC_T2_1 before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_01.yml - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_01.yml IT_Function_WIFI_02: <<: *test_template @@ -243,8 +243,8 @@ IT_Function_WIFI_02: - SSC_T1_1 - SSC_T2_1 before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_02.yml - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_02.yml IT_Function_TCPIP_01: <<: *test_template @@ -253,8 +253,8 @@ IT_Function_TCPIP_01: - SSC_T1_1 - SSC_T2_1 before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_01.yml - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_01.yml IT_Function_TCPIP_02: <<: *test_template @@ -263,8 +263,8 @@ IT_Function_TCPIP_02: - SSC_T1_1 - SSC_T2_1 before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_02.yml - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_02.yml IT_Function_TCPIP_03: <<: *test_template @@ -273,8 +273,8 @@ IT_Function_TCPIP_03: - SSC_T1_1 - SSC_T2_1 before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_03.yml - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_03.yml IT_Function_TCPIP_04: <<: *test_template @@ -283,8 +283,8 @@ IT_Function_TCPIP_04: - SSC_T1_1 - SSC_T2_1 before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_04.yml - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_04.yml IT_Function_TCPIP_05: <<: *test_template @@ -293,8 +293,8 @@ IT_Function_TCPIP_05: - SSC_T1_1 - SSC_T2_1 before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_05.yml - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_05.yml IT_Function_TCPIP_06: <<: *test_template_night @@ -302,8 +302,8 @@ IT_Function_TCPIP_06: - ESP32_IDF - SSC_T1_1 before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_06.yml - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_06.yml IT_Function_WIFI_03: <<: *test_template @@ -311,8 +311,8 @@ IT_Function_WIFI_03: - ESP32_IDF - SSC_T3_PhyMode before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_03.yml - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_03.yml IT_Function_WIFI_04: <<: *test_template @@ -320,8 +320,8 @@ IT_Function_WIFI_04: - ESP32_IDF - SSC_T1_APC before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_04.yml - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_04.yml IT_Function_WIFI_05: <<: *test_template @@ -329,8 +329,8 @@ IT_Function_WIFI_05: - ESP32_IDF - SSC_T1_WEP before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_05.yml - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_05.yml IT_Function_WIFI_06: <<: *test_template @@ -338,8 +338,8 @@ IT_Function_WIFI_06: - ESP32_IDF - SSC_T2_PhyMode before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_06.yml - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_06.yml IT_Function_TCPIP_07: <<: *test_template @@ -349,8 +349,8 @@ IT_Function_TCPIP_07: - SSC_T1_2 - SSC_T2_1 before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_07.yml - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_07.yml IT_Function_TCPIP_08: <<: *test_template @@ -358,8 +358,8 @@ IT_Function_TCPIP_08: - ESP32_IDF - SSC_T1_1 before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_08.yml - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_08.yml IT_Function_TCPIP_09: <<: *test_template @@ -367,8 +367,8 @@ IT_Function_TCPIP_09: - ESP32_IDF - SSC_T1_1 before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_09.yml - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_09.yml IT_Function_TCPIP_10: <<: *test_template @@ -378,8 +378,8 @@ IT_Function_TCPIP_10: - SSC_T1_2 - SSC_T2_1 before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_10.yml - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_10.yml IT_Function_TCPIP_11: <<: *test_template @@ -387,8 +387,8 @@ IT_Function_TCPIP_11: - ESP32_IDF - SSC_T1_1 before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_11.yml - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_11.yml IT_Function_TCPIP_12: <<: *test_template @@ -397,5 +397,5 @@ IT_Function_TCPIP_12: - SSC_T1_1 - SSC_T1_2 before_script: - - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_12.yml - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_12.yml From 5e0a9bfcf20a7da71fbb2c13f4133d29da15363a Mon Sep 17 00:00:00 2001 From: Yinling Date: Wed, 12 Oct 2016 11:48:24 +0800 Subject: [PATCH 081/343] remove debug command "ls" in test report job --- .gitlab-ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8b7b25dd91..dd4049358a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -123,7 +123,6 @@ test_report: - $REPORT_PATH expire_in: 6 mos script: - - ls $LOG_PATH # clone test bench - git clone $GITLAB_SSH_SERVER/yinling/auto_test_script.git - cd auto_test_script From 89097d5f113bc670de96380bb686fe709c8e068d Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Wed, 12 Oct 2016 17:46:15 +0800 Subject: [PATCH 082/343] Add xCoreID arg to prvInitialiseNewTask code; initialize pvThreadLocalStoragePointersDelCallback array to NULL --- components/freertos/tasks.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/components/freertos/tasks.c b/components/freertos/tasks.c index 7fb40e771e..b938418424 100644 --- a/components/freertos/tasks.c +++ b/components/freertos/tasks.c @@ -601,7 +601,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask, TCB_t *pxNewTCB, - const MemoryRegion_t * const xRegions ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const MemoryRegion_t * const xRegions, const BaseType_t xCoreID) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ /* * Called after a new task has been created and initialised to place the task @@ -637,7 +637,6 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB, TaskFunction_t pxTaskCode function - use them. */ pxNewTCB = ( TCB_t * ) pxTaskBuffer; /*lint !e740 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */ pxNewTCB->pxStack = ( StackType_t * ) puxStackBuffer; - pxNewTCB->xCoreID = xCoreID; #if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) { @@ -647,7 +646,7 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB, TaskFunction_t pxTaskCode } #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ - prvInitialiseNewTask( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, &xReturn, pxNewTCB, NULL ); + prvInitialiseNewTask( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, &xReturn, pxNewTCB, NULL, xCoreID ); prvAddNewTaskToReadyList( pxNewTCB, pxTaskCode, xCoreID ); } else @@ -693,7 +692,8 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB, TaskFunction_t pxTaskCode pxTaskDefinition->pvParameters, pxTaskDefinition->uxPriority, pxCreatedTask, pxNewTCB, - pxTaskDefinition->xRegions ); + pxTaskDefinition->xRegions, + tskNO_AFFINITY ); prvAddNewTaskToReadyList( pxNewTCB, pxTaskDefinition->pvTaskCode, tskNO_AFFINITY ); xReturn = pdPASS; @@ -785,7 +785,7 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB, TaskFunction_t pxTaskCode } #endif /* configSUPPORT_STATIC_ALLOCATION */ - prvInitialiseNewTask( pxTaskCode, pcName, ( uint32_t ) usStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB, NULL ); + prvInitialiseNewTask( pxTaskCode, pcName, ( uint32_t ) usStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB, NULL, tskNO_AFFINITY ); prvAddNewTaskToReadyList( pxNewTCB, pxTaskCode, xCoreID ); xReturn = pdPASS; } @@ -807,7 +807,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask, TCB_t *pxNewTCB, - const MemoryRegion_t * const xRegions ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const MemoryRegion_t * const xRegions, const BaseType_t xCoreID ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ { StackType_t *pxTopOfStack; UBaseType_t x; @@ -893,6 +893,7 @@ UBaseType_t x; } pxNewTCB->uxPriority = uxPriority; + pxNewTCB->xCoreID = xCoreID; #if ( configUSE_MUTEXES == 1 ) { pxNewTCB->uxBasePriority = uxPriority; @@ -945,6 +946,9 @@ UBaseType_t x; for( x = 0; x < ( UBaseType_t ) configNUM_THREAD_LOCAL_STORAGE_POINTERS; x++ ) { pxNewTCB->pvThreadLocalStoragePointers[ x ] = NULL; + #if ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS == 1) + pxNewTCB->pvThreadLocalStoragePointersDelCallback[ x ] = NULL; + #endif } } #endif From 03bd5b6d220c86da983736dbffac4d52e66ed502 Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Wed, 12 Oct 2016 18:17:58 +0800 Subject: [PATCH 083/343] Fix offset of coreid in tasktcb --- components/freertos/xtensa_vectors.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/freertos/xtensa_vectors.S b/components/freertos/xtensa_vectors.S index f0d874a59c..0e83cb0850 100644 --- a/components/freertos/xtensa_vectors.S +++ b/components/freertos/xtensa_vectors.S @@ -96,7 +96,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Define for workaround: pin no-cpu-affinity tasks to a cpu when fpu is used. Please change this when the tcb structure is changed */ -#define TASKTCB_XCOREID_OFFSET (0x3C+configMAX_TASK_NAME_LEN+3)&~3 +#define TASKTCB_XCOREID_OFFSET (0x38+configMAX_TASK_NAME_LEN+3)&~3 .extern pxCurrentTCB /* Enable stack backtrace across exception/interrupt - see below */ From 20b508e62ed1606c5e515b30902bc3ea106074bd Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 13 Oct 2016 11:01:30 +1100 Subject: [PATCH 084/343] build system tests: Verify bootloader doesn't build any files outside build/bootloader & config See TW7505. Looks like bug was fixed via prior refactors, but adding the test ensures it will stay fixed. --- make/test_build_system.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/make/test_build_system.sh b/make/test_build_system.sh index 5be1504e3d..86be1f82ec 100755 --- a/make/test_build_system.sh +++ b/make/test_build_system.sh @@ -80,6 +80,13 @@ function run_tests() failure "Files weren't cleaned: ${ALL_BUILD_FILES}" fi + print_status "Bootloader build shouldn't leave build output anywhere else" + rm -rf --preserve-root ${BUILD} + make bootloader + # find wizardry: find any file not named sdkconfig.h that + # isn't in the "bootloader" or "config" directories + find ${BUILD} -type d \( -name bootloader -o -name config \) -prune , -type f ! -name sdkconfig.h || failure "Bootloader built files outside the bootloader or config directories" + print_status "Can still clean build if all text files are CRLFs" make clean find . -exec unix2dos {} \; # CRLFify template dir From 72712c00a760bd43620d3619c4f19157f33e2783 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 14 Oct 2016 21:24:58 +0800 Subject: [PATCH 085/343] freertos: forward task affinity argument to prvInitializeNewTask --- components/freertos/tasks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/freertos/tasks.c b/components/freertos/tasks.c index b938418424..0e2bf6e8e1 100644 --- a/components/freertos/tasks.c +++ b/components/freertos/tasks.c @@ -785,7 +785,7 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB, TaskFunction_t pxTaskCode } #endif /* configSUPPORT_STATIC_ALLOCATION */ - prvInitialiseNewTask( pxTaskCode, pcName, ( uint32_t ) usStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB, NULL, tskNO_AFFINITY ); + prvInitialiseNewTask( pxTaskCode, pcName, ( uint32_t ) usStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB, NULL, xCoreID ); prvAddNewTaskToReadyList( pxNewTCB, pxTaskCode, xCoreID ); xReturn = pdPASS; } From 4370794d07847c3253fe305c0cd4a30882b9c777 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 14 Oct 2016 21:52:43 +0800 Subject: [PATCH 086/343] wifi libraries: update to match new FreeRTOS header files --- components/esp32/lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp32/lib b/components/esp32/lib index a1e5f8b953..9c71f406de 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit a1e5f8b953c7934677ba7a6ed0a6dd2da0e6bd0f +Subproject commit 9c71f406de7be4774e1049b247c11a1983e6dfaa From 0aab006bb799242bad310cd9745678fd099577ff Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Mon, 17 Oct 2016 12:18:17 +0800 Subject: [PATCH 087/343] Add Trax-support to esp-idf --- components/esp32/Kconfig | 14 +++- components/esp32/cpu_start.c | 14 ++++ components/esp32/heap_alloc_caps.c | 4 + components/freertos/tasks.c | 5 +- components/xtensa-debug-module/component.mk | 5 ++ components/xtensa-debug-module/eri.c | 19 +++++ components/xtensa-debug-module/include/eri.h | 31 ++++++++ components/xtensa-debug-module/include/trax.h | 62 +++++++++++++++ .../include/xtensa-debug-module.h | 75 +++++++++++++++++++ components/xtensa-debug-module/trax.c | 64 ++++++++++++++++ 10 files changed, 289 insertions(+), 4 deletions(-) create mode 100755 components/xtensa-debug-module/component.mk create mode 100644 components/xtensa-debug-module/eri.c create mode 100644 components/xtensa-debug-module/include/eri.h create mode 100644 components/xtensa-debug-module/include/trax.h create mode 100644 components/xtensa-debug-module/include/xtensa-debug-module.h create mode 100644 components/xtensa-debug-module/trax.c diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig index 535df23eb5..4aacd937ab 100644 --- a/components/esp32/Kconfig +++ b/components/esp32/Kconfig @@ -63,10 +63,22 @@ config MEMMAP_TRACEMEM of memory that can't be used for general purposes anymore. Disable this if you do not know what this is. +config MEMMAP_TRACEMEM_TWOBANKS + bool "Reserve memory for tracing both pro as well as app cpu execution" + default "n" + depends on MEMMAP_TRACEMEM && MEMMAP_SMP + help + The ESP32 contains a feature which allows you to trace the execution path the processor + has taken through the program. This is stored in a chunk of 32K (16K for single-processor) + of memory that can't be used for general purposes anymore. Disable this if you do not know + what this is. + + # Memory to reverse for trace, used in linker script config TRACEMEM_RESERVE_DRAM hex - default 0x8000 if MEMMAP_TRACEMEM + default 0x8000 if MEMMAP_TRACEMEM && MEMMAP_TRACEMEM_TWOBANKS + default 0x4000 if MEMMAP_TRACEMEM && !MEMMAP_TRACEMEM_TWOBANKS default 0x0 config MEMMAP_SPISRAM diff --git a/components/esp32/cpu_start.c b/components/esp32/cpu_start.c index 7b2ccdc609..5c7a411c8e 100644 --- a/components/esp32/cpu_start.c +++ b/components/esp32/cpu_start.c @@ -43,6 +43,8 @@ #include "esp_ipc.h" #include "esp_log.h" +#include "trax.h" + void start_cpu0(void) __attribute__((weak, alias("start_cpu0_default"))); void start_cpu0_default(void) IRAM_ATTR; #if !CONFIG_FREERTOS_UNICORE @@ -131,6 +133,15 @@ void IRAM_ATTR call_start_cpu1() void start_cpu0_default(void) { +//Enable trace memory and immediately start trace. +#if CONFIG_MEMMAP_TRACEMEM +#if CONFIG_MEMMAP_TRACEMEM_TWOBANKS + trax_enable(TRAX_ENA_PRO_APP); +#else + trax_enable(TRAX_ENA_PRO); +#endif + trax_start_trace(TRAX_DOWNCOUNT_WORDS); +#endif esp_set_cpu_freq(); // set CPU frequency configured in menuconfig uart_div_modify(0, (APB_CLK_FREQ << 4) / 115200); ets_setup_syscalls(); @@ -147,6 +158,9 @@ void start_cpu0_default(void) #if !CONFIG_FREERTOS_UNICORE void start_cpu1_default(void) { +#if CONFIG_MEMMAP_TRACEMEM_TWOBANKS + trax_start_trace(TRAX_DOWNCOUNT_WORDS); +#endif // Wait for FreeRTOS initialization to finish on PRO CPU while (port_xSchedulerRunning[0] == 0) { ; diff --git a/components/esp32/heap_alloc_caps.c b/components/esp32/heap_alloc_caps.c index 46b1125ccb..04e2dc8c83 100644 --- a/components/esp32/heap_alloc_caps.c +++ b/components/esp32/heap_alloc_caps.c @@ -186,7 +186,11 @@ void heap_alloc_caps_init() { #endif #if CONFIG_MEMMAP_TRACEMEM +#if CONFIG_MEMMAP_TRACEMEM_TWOBANKS disable_mem_region((void*)0x3fff8000, (void*)0x40000000); //knock out trace mem region +#else + disable_mem_region((void*)0x3fff8000, (void*)0x3fffc000); //knock out trace mem region +#endif #endif #if 0 diff --git a/components/freertos/tasks.c b/components/freertos/tasks.c index 3cde3bf136..95e7811dde 100644 --- a/components/freertos/tasks.c +++ b/components/freertos/tasks.c @@ -3755,9 +3755,8 @@ In fact, nothing below this line has/is. /* Gotcha (which seems to be deliberate in FreeRTOS, according to http://www.freertos.org/FreeRTOS_Support_Forum_Archive/December_2012/freertos_PIC32_Bug_-_vTaskEnterCritical_6400806.html -) is that calling vTaskEnterCritical followed by vTaskExitCritical will leave the interrupts DISABLED! Re-enabling the -scheduler will re-enable the interrupts instead. */ - +) is that calling vTaskEnterCritical followed by vTaskExitCritical will leave the interrupts DISABLED when the scheduler +is not running. Re-enabling the scheduler will re-enable the interrupts instead. */ #if ( portCRITICAL_NESTING_IN_TCB == 1 ) diff --git a/components/xtensa-debug-module/component.mk b/components/xtensa-debug-module/component.mk new file mode 100755 index 0000000000..a57ae0b12b --- /dev/null +++ b/components/xtensa-debug-module/component.mk @@ -0,0 +1,5 @@ +# +# Component Makefile +# + +include $(IDF_PATH)/make/component_common.mk diff --git a/components/xtensa-debug-module/eri.c b/components/xtensa-debug-module/eri.c new file mode 100644 index 0000000000..e2c7e41eb3 --- /dev/null +++ b/components/xtensa-debug-module/eri.c @@ -0,0 +1,19 @@ +#include +#include "eri.h" + +uint32_t eri_read(int addr) { + uint32_t ret; + asm( + "RER %0,%1" + :"=r"(ret):"r"(addr) + ); + return ret; +} + +void eri_write(int addr, uint32_t data) { + asm volatile ( + "WER %0,%1" + ::"r"(data),"r"(addr) + ); +} + diff --git a/components/xtensa-debug-module/include/eri.h b/components/xtensa-debug-module/include/eri.h new file mode 100644 index 0000000000..33e4dd0918 --- /dev/null +++ b/components/xtensa-debug-module/include/eri.h @@ -0,0 +1,31 @@ +#ifndef ERI_H +#define ERI_H + +#include + +/* + The ERI is a bus internal to each Xtensa core. It connects, amongst others, to the debug interface, where it + allows reading/writing the same registers as available over JTAG. +*/ + + +/** + * @brief Perform an ERI read + * @param addr : ERI register to read from + * + * @return Value read + */ +uint32_t eri_read(int addr); + + +/** + * @brief Perform an ERI write + * @param addr : ERI register to write to + * @param data : Value to write + * + * @return Value read + */ +void eri_write(int addr, uint32_t data); + + +#endif \ No newline at end of file diff --git a/components/xtensa-debug-module/include/trax.h b/components/xtensa-debug-module/include/trax.h new file mode 100644 index 0000000000..c1b3608eb8 --- /dev/null +++ b/components/xtensa-debug-module/include/trax.h @@ -0,0 +1,62 @@ +#include "soc/dport_reg.h" +#include "sdkconfig.h" +#include "esp_err.h" +#include "eri.h" +#include "xtensa-debug-module.h" + + +typedef enum { + TRAX_DOWNCOUNT_WORDS, + TRAX_DOWNCOUNT_INSTRUCTIONS +} trax_downcount_unit_t; + +typedef enum { + TRAX_ENA_NONE = 0, + TRAX_ENA_PRO, + TRAX_ENA_APP, + TRAX_ENA_PRO_APP, + TRAX_ENA_PRO_APP_SWAP +} trax_ena_select_t; + + +/** + * @brief Enable the trax memory blocks to be used as Trax memory. + * + * @param pro_cpu_enable : true if Trax needs to be enabled for the pro CPU + * @param app_cpu_enable : true if Trax needs to be enabled for the pro CPU + * @param swap_regions : Normally, the pro CPU writes to Trax mem block 0 while + * the app cpu writes to block 1. Setting this to true + * inverts this. + * + * @return esp_err_t. Fails with ESP_ERR_NO_MEM if Trax enable is requested for 2 CPUs + * but memmap only has room for 1, or if Trax memmap is disabled + * entirely. + */ +int trax_enable(trax_ena_select_t ena); + +/** + * @brief Start a Trax trace on the current CPU + * + * @param units_until_stop : Set the units of the delay that gets passed to + * trax_trigger_traceend_after_delay. One of TRAX_DOWNCOUNT_WORDS + * or TRAX_DOWNCOUNT_INSTRUCTIONS. + * + * @return esp_err_t. Fails with ESP_ERR_NO_MEM if Trax is disabled. + */ +int trax_start_trace(trax_downcount_unit_t units_until_stop); + + +/** + * @brief Trigger a Trax trace stop after the indicated delay. If this is called + * before and the previous delay hasn't ended yet, this will overwrite + * that delay with the new value. The delay will always start at the time + * the function is called. + * + * @param delay : The delay to stop the trace in, in the unit indicated to + * trax_start_trace. Note: the trace memory has 4K words available. + * + * @return esp_err_t + */ +int trax_trigger_traceend_after_delay(int delay); + + diff --git a/components/xtensa-debug-module/include/xtensa-debug-module.h b/components/xtensa-debug-module/include/xtensa-debug-module.h new file mode 100644 index 0000000000..61b2182531 --- /dev/null +++ b/components/xtensa-debug-module/include/xtensa-debug-module.h @@ -0,0 +1,75 @@ +#ifndef XTENSA_DEBUG_MODULE_H +#define XTENSA_DEBUG_MODULE_H + +/* +ERI registers / OCD offsets and field definitions +*/ + +#define ERI_DEBUG_OFFSET 0x100000 + +#define ERI_TRAX_OFFSET (ERI_DEBUG_OFFSET+0) +#define ERI_PERFMON_OFFSET (ERI_DEBUG_OFFSET+0x1000) +#define ERI_OCDREG_OFFSET (ERI_DEBUG_OFFSET+0x2000) +#define ERI_MISCDBG_OFFSET (ERI_DEBUG_OFFSET+0x3000) +#define ERI_CORESIGHT_OFFSET (ERI_DEBUG_OFFSET+0x3F00) + +#define ERI_TRAX_TRAXID (ERI_TRAX_OFFSET+0x00) +#define ERI_TRAX_TRAXCTRL (ERI_TRAX_OFFSET+0x04) +#define ERI_TRAX_TRAXSTAT (ERI_TRAX_OFFSET+0x08) +#define ERI_TRAX_TRAXDATA (ERI_TRAX_OFFSET+0x0C) +#define ERI_TRAX_TRAXADDR (ERI_TRAX_OFFSET+0x10) +#define ERI_TRAX_TRIGGERPC (ERI_TRAX_OFFSET+0x14) +#define ERI_TRAX_PCMATCHCTRL (ERI_TRAX_OFFSET+0x18) +#define ERI_TRAX_DELAYCNT (ERI_TRAX_OFFSET+0x1C) +#define ERI_TRAX_MEMADDRSTART (ERI_TRAX_OFFSET+0x20) +#define ERI_TRAX_MEMADDREND (ERI_TRAX_OFFSET+0x24) + +#define TRAXCTRL_TREN (1<<0) //Trace enable. Tracing starts on 0->1 +#define TRAXCTRL_TRSTP (1<<1) //Trace Stop. Make 1 to stop trace. +#define TRAXCTRL_PCMEN (1<<2) //PC match enable +#define TRAXCTRL_PTIEN (1<<4) //Processor-trigger enable +#define TRAXCTRL_CTIEN (1<<5) //Cross-trigger enable +#define TRAXCTRL_TMEN (1<<7) //Tracemem Enable. Always set. +#define TRAXCTRL_CNTU (1<<9) //Post-stop-trigger countdown units; selects when DelayCount-- happens. + //0 - every 32-bit word written to tracemem, 1 - every cpu instruction +#define TRAXCTRL_TSEN (1<<11) //Undocumented/deprecated? +#define TRAXCTRL_SMPER_SHIFT 12 //Send sync every 2^(9-smper) messages. 7=reserved, 0=no sync msg +#define TRAXCTRL_SMPER_MASK 0x7 //Synchronization message period +#define TRAXCTRL_PTOWT (1<<16) //Processor Trigger Out (OCD halt) enabled when stop triggered +#define TRAXCTRL_PTOWS (1<<17) //Processor Trigger Out (OCD halt) enabled when trace stop completes +#define TRAXCTRL_CTOWT (1<<20) //Cross-trigger Out enabled when stop triggered +#define TRAXCTRL_CTOWS (1<<21) //Cross-trigger Out enabled when trace stop completes +#define TRAXCTRL_ITCTO (1<<22) //Integration mode: cross-trigger output +#define TRAXCTRL_ITCTIA (1<<23) //Integration mode: cross-trigger ack +#define TRAXCTRL_ITATV (1<<24) //replaces ATID when in integration mode: ATVALID output +#define TRAXCTRL_ATID_MASK 0x7F //ARB source ID +#define TRAXCTRL_ATID_SHIFT 24 +#define TRAXCTRL_ATEN (1<<31) //ATB interface enable + +#define TRAXSTAT_TRACT (1<<0) //Trace active flag. +#define TRAXSTAT_TRIG (1<<1) //Trace stop trigger. Clears on TREN 1->0 +#define TRAXSTAT_PCMTG (1<<2) //Stop trigger caused by PC match. Clears on TREN 1->0 +#define TRAXSTAT_PJTR (1<<3) //JTAG transaction result. 1=err in preceding jtag transaction. +#define TRAXSTAT_PTITG (1<<4) //Stop trigger caused by Processor Trigger Input. Clears on TREN 1->0 +#define TRAXSTAT_CTITG (1<<5) //Stop trigger caused by Cross-Trigger Input. Clears on TREN 1->0 +#define TRAXSTAT_MEMSZ_SHIFT 8 //Traceram size inducator. Usable trace ram is 2^MEMSZ bytes. +#define TRAXSTAT_MEMSZ_MASK 0x1F +#define TRAXSTAT_PTO (1<<16) //Processor Trigger Output: current value +#define TRAXSTAT_CTO (1<<17) //Cross-Trigger Output: current value +#define TRAXSTAT_ITCTOA (1<<22) //Cross-Trigger Out Ack: current value +#define TRAXSTAT_ITCTI (1<<23) //Cross-Trigger Input: current value +#define TRAXSTAT_ITATR (1<<24) //ATREADY Input: current value + +#define TRAXADDR_TADDR_SHIFT 0 //Trax memory address, in 32-bit words. +#define TRAXADDR_TADDR_MASK 0x1FFFFF //Actually is only as big as the trace buffer size max addr. +#define TRAXADDR_TWRAP_SHIFT 21 //Amount of times TADDR has overflown +#define TRAXADDR_TWRAP_MASK 0x3FF +#define TRAXADDR_TWSAT (1<<31) //1 if TWRAP has overflown, clear by disabling tren. + +#define PCMATCHCTRL_PCML_SHIFT 0 //Amount of lower bits to ignore in pc trigger register +#define PCMATCHCTRL_PCML_MASK 0x1F +#define PCMATCHCTRL_PCMS (1<<31) //PC Match Sense, 0 - match when procs PC is in-range, 1 - match when + //out-of-range + + +#endif \ No newline at end of file diff --git a/components/xtensa-debug-module/trax.c b/components/xtensa-debug-module/trax.c new file mode 100644 index 0000000000..18c260a97f --- /dev/null +++ b/components/xtensa-debug-module/trax.c @@ -0,0 +1,64 @@ +#include +#include "soc/dport_reg.h" +#include "sdkconfig.h" +#include "esp_err.h" +#include "eri.h" +#include "xtensa-debug-module.h" +#include "trax.h" +#include "esp_log.h" + +#define TRACEMEM_MUX_PROBLK0_APPBLK1 0 +#define TRACEMEM_MUX_BLK0_ONLY 1 +#define TRACEMEM_MUX_BLK1_ONLY 2 +#define TRACEMEM_MUX_PROBLK1_APPBLK0 3 + +static const char* TAG = "log"; + +int trax_enable(trax_ena_select_t which) { +#if !CONFIG_MEMMAP_TRACEMEM + return ESP_ERR_NO_MEM; +#endif +#if !CONFIG_MEMMAP_TRACEMEM_TWOBANKS + if (which == TRAX_ENA_PRO_APP || which == TRAX_ENA_PRO_APP_SWAP) return ESP_ERR_NO_MEM; +#endif + if (which == TRAX_ENA_PRO_APP || which == TRAX_ENA_PRO_APP_SWAP) { + WRITE_PERI_REG(DPORT_TRACEMEM_MUX_MODE_REG, (which == TRAX_ENA_PRO_APP_SWAP)?TRACEMEM_MUX_PROBLK1_APPBLK0:TRACEMEM_MUX_PROBLK0_APPBLK1); + } else { + WRITE_PERI_REG(DPORT_TRACEMEM_MUX_MODE_REG, TRACEMEM_MUX_BLK0_ONLY); + } + WRITE_PERI_REG(DPORT_PRO_TRACEMEM_ENA_REG, (which == TRAX_ENA_PRO_APP || which == TRAX_ENA_PRO_APP_SWAP || which == TRAX_ENA_PRO)); + WRITE_PERI_REG(DPORT_APP_TRACEMEM_ENA_REG, (which == TRAX_ENA_PRO_APP || which == TRAX_ENA_PRO_APP_SWAP || which == TRAX_ENA_APP)); + return ESP_OK; +} + + +int trax_start_trace(trax_downcount_unit_t units_until_stop) { +#if !CONFIG_MEMMAP_TRACEMEM + return ESP_ERR_NO_MEM; +#endif + uint32_t v; + if (eri_read(ERI_TRAX_TRAXSTAT)&TRAXSTAT_TRACT) { + ESP_LOGI(TAG, "Stopping active trace first."); + //Trace is active. Stop trace. + eri_write(ERI_TRAX_DELAYCNT, 0); + eri_write(ERI_TRAX_TRAXCTRL, eri_read(ERI_TRAX_TRAXCTRL)|TRAXCTRL_TRSTP); + //ToDo: This will probably trigger a trace done interrupt. ToDo: Fix, but how? -JD + eri_write(ERI_TRAX_TRAXCTRL, 0); + } + eri_write(ERI_TRAX_PCMATCHCTRL, 31); //do not stop at any pc match + v=TRAXCTRL_TREN | TRAXCTRL_TMEN | TRAXCTRL_PTOWS | (1< Date: Mon, 17 Oct 2016 12:38:17 +0800 Subject: [PATCH 088/343] build system: add menuconfig choice for optimization level, reorganize C*FLAGS This change adds two options (Debug/Release) for optimization level. Debug enables -O0, release enables -Os and adds -DNDEBUG (which removes all assert() statements). Debugging symbols are kept in both cases, although we may add an option to strip output file if necessary. Also we used to define all common compiler flags in CPPFLAGS, and then appended them to CFLAGS/CXXFLAGS. It makes it impossible to add preprocessor macros to CPPFLAGS at component level (one has to use CFLAGS/CXXFLAGS instead). Some third party libraries are not compatible with this approach. Changed to the more common way of using these variables. --- Kconfig | 11 +++++++++++ components/log/log.c | 2 +- make/component_common.mk | 10 +++++----- make/project.mk | 35 ++++++++++++++++++++++++++++------- 4 files changed, 45 insertions(+), 13 deletions(-) diff --git a/Kconfig b/Kconfig index 11ea099de2..936181a9cb 100644 --- a/Kconfig +++ b/Kconfig @@ -23,6 +23,17 @@ endmenu source "$COMPONENT_KCONFIGS_PROJBUILD" +choice OPTIMIZATION_LEVEL + prompt "Optimization level" + default OPTIMIZATION_LEVEL_DEBUG + help + This option sets compiler optimization level. +config OPTIMIZATION_LEVEL_DEBUG + bool "Debug" +config OPTIMIZATION_LEVEL_RELEASE + bool "Release" +endchoice + menu "Component config" source "$COMPONENT_KCONFIGS" endmenu diff --git a/components/log/log.c b/components/log/log.c index aae12a7735..a2b41d7e62 100644 --- a/components/log/log.c +++ b/components/log/log.c @@ -284,7 +284,7 @@ static inline void heap_swap(int i, int j) } #endif //BOOTLOADER_BUILD -inline IRAM_ATTR uint32_t esp_log_early_timestamp() +IRAM_ATTR uint32_t esp_log_early_timestamp() { return xthal_get_ccount() / (CPU_CLK_FREQ_ROM / 1000); } diff --git a/make/component_common.mk b/make/component_common.mk index ebad525a76..bf2eace019 100644 --- a/make/component_common.mk +++ b/make/component_common.mk @@ -91,15 +91,15 @@ define GenerateCompileTargets # $(1) - directory containing source files, relative to $(COMPONENT_PATH) $(1)/%.o: $$(COMPONENT_PATH)/$(1)/%.c | $(1) $$(summary) CC $$@ - $$(Q) $$(CC) $$(CFLAGS) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@ + $$(Q) $$(CC) $$(CFLAGS) $(CPPFLAGS) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@ $(1)/%.o: $$(COMPONENT_PATH)/$(1)/%.cpp | $(1) - $$(summary) CC $$@ - $$(Q) $$(CXX) $$(CXXFLAGS) $$(addprefix -I,$$(COMPONENT_INCLUDES)) $$(addprefix -I,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@ + $$(summary) CXX $$@ + $$(Q) $$(CXX) $$(CXXFLAGS) $(CPPFLAGS) $$(addprefix -I,$$(COMPONENT_INCLUDES)) $$(addprefix -I,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@ $(1)/%.o: $$(COMPONENT_PATH)/$(1)/%.S | $(1) - $$(summary) CC $$@ - $$(Q) $$(CC) $$(CFLAGS) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@ + $$(summary) AS $$@ + $$(Q) $$(CC) $$(CFLAGS) $(CPPFLAGS) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@ # CWD is build dir, create the build subdirectory if it doesn't exist $(1): diff --git a/make/project.mk b/make/project.mk index d91165cfd7..49c3499467 100644 --- a/make/project.mk +++ b/make/project.mk @@ -157,15 +157,36 @@ LDFLAGS ?= -nostdlib \ # If you need your component to add CFLAGS/etc globally for all source # files, set CFLAGS += in your component's Makefile.projbuild -# CPPFLAGS used by an compile pass that uses the C preprocessor -CPPFLAGS = -DESP_PLATFORM -Og -g3 -Wpointer-arith -Werror -Wno-error=unused-function -Wno-error=unused-but-set-variable \ - -Wno-error=unused-variable -Wall -ffunction-sections -fdata-sections -mlongcalls -nostdlib -MMD -MP +# CPPFLAGS used by C preprocessor +CPPFLAGS = -DESP_PLATFORM -# C flags use by C only -CFLAGS = $(CPPFLAGS) -std=gnu99 -g3 -fstrict-volatile-bitfields +# Warnings-related flags relevant both for C and C++ +COMMON_WARNING_FLAGS = -Wall -Werror \ + -Wno-error=unused-function \ + -Wno-error=unused-but-set-variable \ + -Wno-error=unused-variable -# CXXFLAGS uses by C++ only -CXXFLAGS = $(CPPFLAGS) -Og -std=gnu++11 -g3 -fno-exceptions -fstrict-volatile-bitfields -fno-rtti +# Flags which control code generation and dependency generation, both for C and C++ +COMMON_FLAGS = \ + -ffunction-sections -fdata-sections \ + -fstrict-volatile-bitfields \ + -mlongcalls \ + -nostdlib \ + -MMD -MP + +# Optimization flags are set based on menuconfig choice +ifneq ("$(CONFIG_OPTIMIZATION_LEVEL_RELEASE)","") +OPTMIZATION_FLAGS = -Os +CPPFLAGS += -DNDEBUG +else +OPTMIZATION_FLAGS = -O0 +endif + +# List of flags to pass to C compiler +CFLAGS = -ggdb -std=gnu99 $(strip $(OPTMIZATION_FLAGS) $(COMMON_FLAGS) $(COMMON_WARNING_FLAGS)) + +# List of flags to pass to C++ compiler +CXXFLAGS = -ggdb -std=gnu++11 -fno-exceptions -fno-rtti $(strip $(OPTMIZATION_FLAGS) $(COMMON_FLAGS) $(COMMON_WARNING_FLAGS)) export CFLAGS CPPFLAGS CXXFLAGS From 1cd572c7b982cd876d2f16958c1b2d75cf5f0ea5 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Mon, 17 Oct 2016 12:45:42 +0800 Subject: [PATCH 089/343] Add test for compiling in release mode, fix warnings and errors which appeared --- .gitlab-ci.yml | 6 ++++++ components/nghttp/library/nghttp2_session.c | 2 +- components/nvs_flash/src/nvs_page.cpp | 2 +- components/nvs_flash/src/nvs_pagemanager.cpp | 4 +++- components/nvs_flash/src/nvs_storage.cpp | 3 +-- 5 files changed, 12 insertions(+), 5 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index dd4049358a..aff9bea8d1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -37,6 +37,12 @@ build_template_app: # branch - git checkout ${CI_BUILD_REF_NAME} || echo "Using esp-idf-template default branch..." - make defconfig + # Test debug build (default) + - make all V=1 + # Now test release build + - make clean + - sed -i.bak -e's/CONFIG_OPTIMIZATION_LEVEL_DEBUG\=y/CONFIG_OPTIMIZATION_LEVEL_RELEASE=y/' sdkconfig + - make defconfig - make all V=1 diff --git a/components/nghttp/library/nghttp2_session.c b/components/nghttp/library/nghttp2_session.c index f93cd1729b..0100dd32c4 100644 --- a/components/nghttp/library/nghttp2_session.c +++ b/components/nghttp/library/nghttp2_session.c @@ -7177,7 +7177,7 @@ uint32_t nghttp2_session_get_remote_settings(nghttp2_session *session, return session->remote_settings.max_header_list_size; } - assert(0); + abort(); } static int nghttp2_session_upgrade_internal(nghttp2_session *session, diff --git a/components/nvs_flash/src/nvs_page.cpp b/components/nvs_flash/src/nvs_page.cpp index 4f6a198c61..f4fc5430cd 100644 --- a/components/nvs_flash/src/nvs_page.cpp +++ b/components/nvs_flash/src/nvs_page.cpp @@ -769,7 +769,7 @@ void Page::invalidateCache() void Page::debugDump() const { - printf("state=%x addr=%x seq=%d\nfirstUsed=%d nextFree=%d used=%d erased=%d\n", mState, mBaseAddress, mSeqNumber, static_cast(mFirstUsedEntry), static_cast(mNextFreeEntry), mUsedEntryCount, mErasedEntryCount); + printf("state=%x addr=%x seq=%d\nfirstUsed=%d nextFree=%d used=%d erased=%d\n", (int) mState, mBaseAddress, mSeqNumber, static_cast(mFirstUsedEntry), static_cast(mNextFreeEntry), mUsedEntryCount, mErasedEntryCount); size_t skip = 0; for (size_t i = 0; i < ENTRY_COUNT; ++i) { printf("%3d: ", static_cast(i)); diff --git a/components/nvs_flash/src/nvs_pagemanager.cpp b/components/nvs_flash/src/nvs_pagemanager.cpp index 790ab7e19f..f4d02a7d40 100644 --- a/components/nvs_flash/src/nvs_pagemanager.cpp +++ b/components/nvs_flash/src/nvs_pagemanager.cpp @@ -49,7 +49,7 @@ esp_err_t PageManager::load(uint32_t baseSector, uint32_t sectorCount) return activatePage(); } else { uint32_t lastSeqNo; - assert(mPageList.back().getSeqNumber(lastSeqNo) == ESP_OK); + ESP_ERROR_CHECK( mPageList.back().getSeqNumber(lastSeqNo) ); mSeqNumber = lastSeqNo + 1; } @@ -142,7 +142,9 @@ esp_err_t PageManager::requestNewPage() Page* newPage = &mPageList.back(); Page* erasedPage = maxErasedItemsPageIt; +#ifndef NDEBUG size_t usedEntries = erasedPage->getUsedEntryCount(); +#endif err = erasedPage->markFreeing(); if (err != ESP_OK) { return err; diff --git a/components/nvs_flash/src/nvs_storage.cpp b/components/nvs_flash/src/nvs_storage.cpp index 4a217ebe18..eb90cac5bc 100644 --- a/components/nvs_flash/src/nvs_storage.cpp +++ b/components/nvs_flash/src/nvs_storage.cpp @@ -123,8 +123,7 @@ esp_err_t Storage::writeItem(uint8_t nsIndex, ItemType datatype, const char* key if (findPage) { if (findPage->state() == Page::PageState::UNINITIALIZED || findPage->state() == Page::PageState::INVALID) { - auto err = findItem(nsIndex, datatype, key, findPage, item); - assert(err == ESP_OK); + ESP_ERROR_CHECK( findItem(nsIndex, datatype, key, findPage, item) ); } err = findPage->eraseItem(nsIndex, datatype, key); if (err == ESP_ERR_FLASH_OP_FAIL) { From 34fa6a60a9812b4a91ac16535ad5ee86d5755a22 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Mon, 17 Oct 2016 13:47:13 +0800 Subject: [PATCH 090/343] build system: fix typo, move -ggdb to OPTIMIZATION_FLAGS --- make/project.mk | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/make/project.mk b/make/project.mk index 49c3499467..9088eda85d 100644 --- a/make/project.mk +++ b/make/project.mk @@ -176,17 +176,20 @@ COMMON_FLAGS = \ # Optimization flags are set based on menuconfig choice ifneq ("$(CONFIG_OPTIMIZATION_LEVEL_RELEASE)","") -OPTMIZATION_FLAGS = -Os +OPTIMIZATION_FLAGS = -Os CPPFLAGS += -DNDEBUG else -OPTMIZATION_FLAGS = -O0 +OPTIMIZATION_FLAGS = -O0 endif +# Enable generation of debugging symbols +OPTIMIZATION_FLAGS += -ggdb + # List of flags to pass to C compiler -CFLAGS = -ggdb -std=gnu99 $(strip $(OPTMIZATION_FLAGS) $(COMMON_FLAGS) $(COMMON_WARNING_FLAGS)) +CFLAGS = -std=gnu99 $(strip $(OPTIMIZATION_FLAGS) $(COMMON_FLAGS) $(COMMON_WARNING_FLAGS)) # List of flags to pass to C++ compiler -CXXFLAGS = -ggdb -std=gnu++11 -fno-exceptions -fno-rtti $(strip $(OPTMIZATION_FLAGS) $(COMMON_FLAGS) $(COMMON_WARNING_FLAGS)) +CXXFLAGS = -std=gnu++11 -fno-exceptions -fno-rtti $(strip $(OPTIMIZATION_FLAGS) $(COMMON_FLAGS) $(COMMON_WARNING_FLAGS)) export CFLAGS CPPFLAGS CXXFLAGS From eaace9846af25f95dbfe06fff7c309748a3b651b Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Mon, 17 Oct 2016 14:12:16 +0800 Subject: [PATCH 091/343] smartconfig: update to match new FreeRTOS header files --- components/esp32/lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp32/lib b/components/esp32/lib index 9c71f406de..aac7d416a7 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit 9c71f406de7be4774e1049b247c11a1983e6dfaa +Subproject commit aac7d416a702215f2501a6237caf034ec7e8e80a From 28d83e766a64b52b3e5a1ed6e64aa6fe6797c667 Mon Sep 17 00:00:00 2001 From: Yinling Date: Mon, 17 Oct 2016 17:03:54 +0800 Subject: [PATCH 092/343] fix bug that deploy when test failed: test report will be a single stage. The result of test report will be calculated from the result of all test jobs in test stage. So it will only deploy when all test job passed. --- .gitlab-ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index dd4049358a..5718cc542d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,6 +1,7 @@ stages: - build - test + - test_report - deploy before_script: @@ -106,13 +107,12 @@ test_build_system: - ./make/test_build_system.sh test_report: - stage: deploy + stage: test_report only: - master - triggers tags: - test_report - allow_failure: true variables: LOG_PATH: "$CI_PROJECT_DIR/$CI_BUILD_REF" TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/components/idf_test" @@ -121,7 +121,7 @@ test_report: when: always paths: - $REPORT_PATH - expire_in: 6 mos + expire_in: 12 mos script: # clone test bench - git clone $GITLAB_SSH_SERVER/yinling/auto_test_script.git From 0403d43b194f5c7c77dd246aece7d936d6985fce Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Mon, 17 Oct 2016 18:09:15 +0800 Subject: [PATCH 093/343] Optimize xPortGetCoreID to 2-instruction inline assembly. --- components/freertos/include/freertos/portable.h | 3 +-- .../freertos/include/freertos/xtensa_context.h | 7 +------ components/freertos/panic.c | 1 - components/freertos/portasm.S | 12 ------------ 4 files changed, 2 insertions(+), 21 deletions(-) diff --git a/components/freertos/include/freertos/portable.h b/components/freertos/include/freertos/portable.h index 4030ca0c03..58e6903664 100644 --- a/components/freertos/include/freertos/portable.h +++ b/components/freertos/include/freertos/portable.h @@ -192,8 +192,7 @@ void vPortEndScheduler( void ) PRIVILEGED_FUNCTION; #endif /* Multi-core: get current core ID */ -int xPortGetCoreID( void ); - +#define xPortGetCoreID() __extension__({int id; asm volatile("rsr.prid %0; extui %0,%0,13,1":"=r"(id)); id;}) #ifdef __cplusplus } diff --git a/components/freertos/include/freertos/xtensa_context.h b/components/freertos/include/freertos/xtensa_context.h index 3167c84726..b748a0d1a7 100644 --- a/components/freertos/include/freertos/xtensa_context.h +++ b/components/freertos/include/freertos/xtensa_context.h @@ -322,12 +322,7 @@ STRUCT_END(XtSolFrame) #ifdef __ASSEMBLER__ .macro getcoreid reg rsr.prid \reg - bbci \reg,1,1f - movi \reg,1 - j 2f -1: - movi \reg,0 -2: + extui \reg,\reg,13,1 .endm #endif diff --git a/components/freertos/panic.c b/components/freertos/panic.c index 9400867356..6a87679d13 100644 --- a/components/freertos/panic.c +++ b/components/freertos/panic.c @@ -76,7 +76,6 @@ inline static void panicPutHex(int a) { } inline static void panicPutDec(int a) { } #endif -int xPortGetCoreID(); void __attribute__((weak)) vApplicationStackOverflowHook( TaskHandle_t xTask, signed char *pcTaskName ) { panicPutStr("***ERROR*** A stack overflow in task "); diff --git a/components/freertos/portasm.S b/components/freertos/portasm.S index 65406b0b06..3a45b19a32 100644 --- a/components/freertos/portasm.S +++ b/components/freertos/portasm.S @@ -51,18 +51,6 @@ port_switch_flag: .text - - -/* C function to get proc ID.*/ - .global xPortGetCoreID - .type xPortGetCoreID,@function - .align 4 -xPortGetCoreID: - ENTRY(16) - getcoreid a2 - RET(16) - - /* ******************************************************************************* * _frxt_setup_switch From c03549e1170f76871a5f66cbc709371e38dbf9d2 Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Mon, 17 Oct 2016 18:30:13 +0800 Subject: [PATCH 094/343] Make uxPortCompareSet into a macro. 25uS -> 24uS --- components/freertos/port.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/components/freertos/port.c b/components/freertos/port.c index 6117a2804e..f42cba936c 100644 --- a/components/freertos/port.c +++ b/components/freertos/port.c @@ -263,17 +263,14 @@ void vPortAssertIfInISR() * *bitwise inverse* of the old mem if the mem wasn't written. This doesn't seem to happen on the * ESP32, though. (Would show up directly if it did because the magic wouldn't match.) */ -uint32_t uxPortCompareSet(volatile uint32_t *mux, uint32_t compare, uint32_t set) -{ - __asm__ __volatile__ ( - "WSR %2,SCOMPARE1 \n" //initialize SCOMPARE1 - "ISYNC \n" //wait sync - "S32C1I %0, %1, 0 \n" //store id into the lock, if the lock is the same as comparel. Otherwise, no write-access - :"=r"(set) \ - :"r"(mux), "r"(compare), "0"(set) \ - ); - return set; -} +#define uxPortCompareSet(mux, compare, set) \ + __asm__ __volatile__( \ + "WSR %2,SCOMPARE1 \n" \ + "ISYNC \n" \ + "S32C1I %0, %1, 0 \n" \ + :"=r"(*set) \ + :"r"(mux), "r"(compare), "0"(*set) \ + ); \ /* * For kernel use: Initialize a per-CPU mux. Mux will be initialized unlocked. @@ -310,7 +307,8 @@ void vPortCPUAcquireMutex(portMUX_TYPE *mux) { irqStatus=portENTER_CRITICAL_NESTED(); do { //Lock mux if it's currently unlocked - res=uxPortCompareSet(&mux->mux, portMUX_FREE_VAL, (xPortGetCoreID()<mux, portMUX_FREE_VAL, &res); //If it wasn't free and we're the owner of the lock, we are locking recursively. if ( (res != portMUX_FREE_VAL) && (((res&portMUX_VAL_MASK)>>portMUX_VAL_SHIFT) == xPortGetCoreID()) ) { //Mux was already locked by us. Just bump the recurse count by one. @@ -362,7 +360,8 @@ portBASE_TYPE vPortCPUReleaseMutex(portMUX_TYPE *mux) { if ( (mux->mux & portMUX_MAGIC_MASK) != portMUX_MAGIC_VAL ) ets_printf("ERROR: vPortCPUReleaseMutex: mux %p is uninitialized (0x%X)!\n", mux, mux->mux); #endif //Unlock mux if it's currently locked with a recurse count of 0 - res=uxPortCompareSet(&mux->mux, (xPortGetCoreID()<mux, (xPortGetCoreID()< Date: Mon, 17 Oct 2016 18:49:19 +0800 Subject: [PATCH 095/343] Detect success before errors in vPortCPUReleaseMutex. Shaves off another half uS. --- components/freertos/port.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/components/freertos/port.c b/components/freertos/port.c index f42cba936c..ef72b1cb5e 100644 --- a/components/freertos/port.c +++ b/components/freertos/port.c @@ -363,27 +363,30 @@ portBASE_TYPE vPortCPUReleaseMutex(portMUX_TYPE *mux) { res=portMUX_FREE_VAL; uxPortCompareSet(&mux->mux, (xPortGetCoreID()<>portMUX_VAL_SHIFT) == xPortGetCoreID() ) { + //Lock is valid, we can return safely. Just need to check if it's a recursive lock; if so we need to decrease the refcount. + if ( ((res&portMUX_CNT_MASK)>>portMUX_CNT_SHIFT)!=0) { + //We locked this, but the reccount isn't zero. Decrease refcount and continue. + recCnt=(res&portMUX_CNT_MASK)>>portMUX_CNT_SHIFT; + recCnt--; +#ifdef CONFIG_FREERTOS_PORTMUX_DEBUG_RECURSIVE + ets_printf("Recursive unlock: recCnt=%d last locked %s line %d, curr %s line %d\n", recCnt, lastLockedFn, lastLockedLine, fnName, line); +#endif + mux->mux=portMUX_MAGIC_VAL|(recCnt<>portMUX_VAL_SHIFT) != xPortGetCoreID() ) { + } else { #ifdef CONFIG_FREERTOS_PORTMUX_DEBUG ets_printf("ERROR: vPortCPUReleaseMutex: mux %p wasn't locked by this core (%d) but by core %d (ret=%x, mux=%x).\n", mux, xPortGetCoreID(), ((res&portMUX_VAL_MASK)>>portMUX_VAL_SHIFT), res, mux->mux); ets_printf("Last non-recursive lock %s line %d\n", lastLockedFn, lastLockedLine); ets_printf("Called by %s line %d\n", fnName, line); #endif ret=pdFALSE; - } else if ( ((res&portMUX_CNT_MASK)>>portMUX_CNT_SHIFT)!=0) { - //We locked this, but the reccount isn't zero. Decrease refcount and continue. - recCnt=(res&portMUX_CNT_MASK)>>portMUX_CNT_SHIFT; - recCnt--; -#ifdef CONFIG_FREERTOS_PORTMUX_DEBUG_RECURSIVE - ets_printf("Recursive unlock: recCnt=%d last locked %s line %d, curr %s line %d\n", recCnt, lastLockedFn, lastLockedLine, fnName, line); -#endif - mux->mux=portMUX_MAGIC_VAL|(recCnt< Date: Tue, 18 Oct 2016 10:51:08 +0800 Subject: [PATCH 096/343] Some more optimizations, mostly in involuntary task switches. Doesn not really help here, but might in other cases. --- components/freertos/portasm.S | 48 +++++++++++----------------- components/freertos/xtensa_vectors.S | 7 ++-- 2 files changed, 21 insertions(+), 34 deletions(-) diff --git a/components/freertos/portasm.S b/components/freertos/portasm.S index 3a45b19a32..ad65a103ed 100644 --- a/components/freertos/portasm.S +++ b/components/freertos/portasm.S @@ -69,9 +69,8 @@ _frxt_setup_switch: ENTRY(16) getcoreid a3 - slli a3, a3, 2 movi a2, port_switch_flag - add a2, a2, a3 + addx4 a2, a3, a2 movi a3, 1 s32i a3, a2, 0 @@ -116,12 +115,11 @@ _frxt_int_enter: Manage nesting directly rather than call the generic IntEnter() (in windowed ABI we can't call a C function here anyway because PS.EXCM is still set). */ - getcoreid a3 - slli a4, a3, 2 /* a4 = cpuid * 4 */ + getcoreid a4 movi a2, port_xSchedulerRunning - add a2, a2, a4 + addx4 a2, a4, a2 movi a3, port_interruptNesting - add a3, a3, a4 + addx4 a3, a4, a3 l32i a2, a2, 0 /* a2 = port_xSchedulerRunning */ beqz a2, 1f /* scheduler not running, no tasks */ l32i a2, a3, 0 /* a2 = port_interruptNesting */ @@ -130,14 +128,13 @@ _frxt_int_enter: bnei a2, 1, .Lnested /* !=0 before incr, so nested */ movi a2, pxCurrentTCB - add a2, a2, a4 + addx4 a2, a4, a2 l32i a2, a2, 0 /* a2 = current TCB */ beqz a2, 1f s32i a1, a2, TOPOFSTACK_OFFS /* pxCurrentTCB->pxTopOfStack = SP */ movi a1, port_IntStackTop /* a1 = top of intr stack */ movi a2, configISR_STACK_SIZE - getcoreid a3 - mull a2, a3, a2 + mull a2, a4, a2 add a1, a1, a2 /* for current proc */ .Lnested: @@ -165,12 +162,11 @@ _frxt_int_enter: .align 4 _frxt_int_exit: - getcoreid a3 - slli a4, a3, 2 /* a4 is core * 4 */ + getcoreid a4 movi a2, port_xSchedulerRunning - add a2, a2, a4 + addx4 a2, a4, a2 movi a3, port_interruptNesting - add a3, a3, a4 + addx4 a3, a4, a3 rsil a0, XCHAL_EXCM_LEVEL /* lock out interrupts */ l32i a2, a2, 0 /* a2 = port_xSchedulerRunning */ beqz a2, .Lnoswitch /* scheduler not running, no tasks */ @@ -180,13 +176,13 @@ _frxt_int_exit: bnez a2, .Lnesting /* !=0 after decr so still nested */ movi a2, pxCurrentTCB - add a2, a2, a4 + addx4 a2, a4, a2 l32i a2, a2, 0 /* a2 = current TCB */ beqz a2, 1f /* no task ? go to dispatcher */ l32i a1, a2, TOPOFSTACK_OFFS /* SP = pxCurrentTCB->pxTopOfStack */ movi a2, port_switch_flag /* address of switch flag */ - add a2, a2, a4 /* point to flag for this cpu */ + addx4 a2, a4, a2 /* point to flag for this cpu */ l32i a3, a2, 0 /* a3 = port_switch_flag */ beqz a3, .Lnoswitch /* flag = 0 means no switch reqd */ movi a3, 0 @@ -392,14 +388,12 @@ _frxt_dispatch: call0 vTaskSwitchContext // Get next TCB to resume movi a2, pxCurrentTCB getcoreid a3 - slli a3, a3, 2 - add a2, a2, a3 + addx4 a2, a3, a2 #else call4 vTaskSwitchContext // Get next TCB to resume movi a2, pxCurrentTCB getcoreid a3 - slli a3, a3, 2 - add a2, a2, a3 + addx4 a2, a3, a2 #endif l32i a3, a2, 0 l32i sp, a3, TOPOFSTACK_OFFS /* SP = next_TCB->pxTopOfStack; */ @@ -439,8 +433,7 @@ _frxt_dispatch: /* Restore CPENABLE from task's co-processor save area. */ movi a3, pxCurrentTCB /* cp_state = */ getcoreid a2 - slli a2, a2, 2 - add a3, a2, a3 + addx4 a3, a2, a3 l32i a3, a3, 0 l32i a2, a3, CP_TOPOFSTACK_OFFS /* StackType_t *pxStack; */ l16ui a3, a2, XT_CPENABLE /* CPENABLE = cp_state->cpenable; */ @@ -529,8 +522,7 @@ vPortYield: movi a2, pxCurrentTCB getcoreid a3 - slli a3, a3, 2 - add a2, a2, a3 + addx4 a2, a3, a2 l32i a2, a2, 0 /* a2 = pxCurrentTCB */ movi a3, 0 s32i a3, sp, XT_SOL_EXIT /* 0 to flag as solicited frame */ @@ -581,8 +573,7 @@ vPortYieldFromInt: /* Save CPENABLE in task's co-processor save area, and clear CPENABLE. */ movi a3, pxCurrentTCB /* cp_state = */ getcoreid a2 - slli a2, a2, 2 - add a3, a2, a3 + addx4 a3, a2, a3 l32i a3, a3, 0 l32i a2, a3, CP_TOPOFSTACK_OFFS @@ -625,18 +616,17 @@ _frxt_task_coproc_state: /* We can use a3 as a scratchpad, the instances of code calling XT_RTOS_CP_STATE don't seem to need it saved. */ getcoreid a3 - slli a3, a3, 2 /* a3=coreid*4 */ movi a15, port_xSchedulerRunning /* if (port_xSchedulerRunning */ - add a15, a15, a3 + addx4 a15, a3,a15 l32i a15, a15, 0 beqz a15, 1f movi a15, port_interruptNesting /* && port_interruptNesting == 0 */ - add a15, a15, a3 + addx4 a15, a3, a15 l32i a15, a15, 0 bnez a15, 1f movi a15, pxCurrentTCB - add a15, a3, a15 + addx4 a15, a3, a15 l32i a15, a15, 0 /* && pxCurrentTCB != 0) { */ diff --git a/components/freertos/xtensa_vectors.S b/components/freertos/xtensa_vectors.S index f0d874a59c..7c2fc29607 100644 --- a/components/freertos/xtensa_vectors.S +++ b/components/freertos/xtensa_vectors.S @@ -904,16 +904,13 @@ _xt_coproc_exc: core we're running on now. */ movi a2, pxCurrentTCB getcoreid a3 - slli a3, a3, 2 - add a2, a2, a3 + addx4 a2, a3, a2 l32i a2, a2, 0 /* a2 = start of pxCurrentTCB[cpuid] */ addi a2, a2, TASKTCB_XCOREID_OFFSET /* offset to xCoreID in tcb struct */ - getcoreid a3 s32i a3, a2, 0 /* store current cpuid */ /* Grab correct xt_coproc_owner_sa for this core */ - getcoreid a2 - movi a3, XCHAL_CP_MAX << 2 + movi a2, XCHAL_CP_MAX << 2 mull a2, a2, a3 movi a3, _xt_coproc_owner_sa /* a3 = base of owner array */ add a3, a3, a2 From 340a722715c0710ee1058db88cf5c359f15b88c3 Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Tue, 18 Oct 2016 11:50:19 +0800 Subject: [PATCH 097/343] Warn user if trax is disabled in menuconfig but functions are called anyway. --- components/xtensa-debug-module/trax.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/components/xtensa-debug-module/trax.c b/components/xtensa-debug-module/trax.c index 18c260a97f..d216a3df9a 100644 --- a/components/xtensa-debug-module/trax.c +++ b/components/xtensa-debug-module/trax.c @@ -12,10 +12,12 @@ #define TRACEMEM_MUX_BLK1_ONLY 2 #define TRACEMEM_MUX_PROBLK1_APPBLK0 3 -static const char* TAG = "log"; +static const char* TAG = "trax"; -int trax_enable(trax_ena_select_t which) { +int trax_enable(trax_ena_select_t which) +{ #if !CONFIG_MEMMAP_TRACEMEM + ESP_LOGE(TAG, "Trax_enable called, but trax is disabled in menuconfig!"); return ESP_ERR_NO_MEM; #endif #if !CONFIG_MEMMAP_TRACEMEM_TWOBANKS @@ -32,8 +34,10 @@ int trax_enable(trax_ena_select_t which) { } -int trax_start_trace(trax_downcount_unit_t units_until_stop) { +int trax_start_trace(trax_downcount_unit_t units_until_stop) +{ #if !CONFIG_MEMMAP_TRACEMEM + ESP_LOGE(TAG, "Trax_start_trace called, but trax is disabled in menuconfig!"); return ESP_ERR_NO_MEM; #endif uint32_t v; @@ -54,8 +58,10 @@ int trax_start_trace(trax_downcount_unit_t units_until_stop) { } -int trax_trigger_traceend_after_delay(int delay) { +int trax_trigger_traceend_after_delay(int delay) +{ #if !CONFIG_MEMMAP_TRACEMEM + ESP_LOGE(TAG, "Trax_trigger_traceend_after_delay called, but trax is disabled in menuconfig!"); return ESP_ERR_NO_MEM; #endif eri_write(ERI_TRAX_DELAYCNT, delay); From 746ad41d890f8e2e60b5ace63a7910b7c60b89e6 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 18 Oct 2016 15:35:17 +1100 Subject: [PATCH 098/343] Build tests: Use & document clean_build_dir --- make/test_build_system.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/make/test_build_system.sh b/make/test_build_system.sh index a6de14987b..7c8cbc1f1e 100755 --- a/make/test_build_system.sh +++ b/make/test_build_system.sh @@ -21,7 +21,8 @@ # * The function "take_build_snapshot" can be paired with the functions "assert_rebuilt" and "assert_not_rebuilt" to compare file timestamps and verify if they were rebuilt or not since the snapshot was taken. # # To add a new test case, add it to the end of the run_tests function. Note that not all test cases do comprehensive cleanup -# (although very invasive ones like appending CRLFs to all files take a copy of the esp-idf tree.) +# (although very invasive ones like appending CRLFs to all files take a copy of the esp-idf tree), however the clean_build_dir +# function can be used to force-delete all files from the build output directory. # Set up some variables # @@ -92,7 +93,7 @@ function run_tests() fi print_status "Bootloader build shouldn't leave build output anywhere else" - rm -rf --preserve-root ${BUILD} + clean_build_dir make bootloader # find wizardry: find any file not named sdkconfig.h that # isn't in the "bootloader" or "config" directories From da706111965e471e9d0425e1b853aa63cc4e64d3 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 13 Oct 2016 11:46:51 +1100 Subject: [PATCH 099/343] Deep sleep: Any source named rtc_wake_stub* is linked as RTC wake stub code Also move esp_deepsleep.h documentation out to docs/deep-sleep-stub.rst --- components/esp32/cpu_start.c | 8 +++ components/esp32/deepsleep.c | 3 +- components/esp32/include/esp_attr.h | 9 ++- components/esp32/include/esp_deepsleep.h | 36 +--------- components/esp32/include/esp_system.h | 1 + components/esp32/ld/esp32.common.ld | 44 ++++++++---- docs/deep-sleep-stub.rst | 87 ++++++++++++++++++++++++ 7 files changed, 134 insertions(+), 54 deletions(-) create mode 100644 docs/deep-sleep-stub.rst diff --git a/components/esp32/cpu_start.c b/components/esp32/cpu_start.c index 7b2ccdc609..35f2efd477 100644 --- a/components/esp32/cpu_start.c +++ b/components/esp32/cpu_start.c @@ -19,6 +19,7 @@ #include "rom/ets_sys.h" #include "rom/uart.h" +#include "rom/rtc.h" #include "soc/cpu.h" #include "soc/dport_reg.h" @@ -59,6 +60,8 @@ extern void app_main(void); extern int _bss_start; extern int _bss_end; +extern int _rtc_bss_start; +extern int _rtc_bss_end; extern int _init_start; extern void (*__init_array_start)(void); extern void (*__init_array_end)(void); @@ -89,6 +92,11 @@ void IRAM_ATTR call_start_cpu0() memset(&_bss_start, 0, (&_bss_end - &_bss_start) * sizeof(_bss_start)); + /* Unless waking from deep sleep (implying RTC memory is intact), clear RTC bss */ + if (rtc_get_reset_reason(0) != DEEPSLEEP_RESET) { + memset(&_rtc_bss_start, 0, (&_rtc_bss_end - &_rtc_bss_start) * sizeof(_rtc_bss_start)); + } + // Initialize heap allocator heap_alloc_caps_init(); diff --git a/components/esp32/deepsleep.c b/components/esp32/deepsleep.c index 61268bce6b..742ff8cf40 100644 --- a/components/esp32/deepsleep.c +++ b/components/esp32/deepsleep.c @@ -40,8 +40,7 @@ void esp_set_deep_sleep_wake_stub(esp_deep_sleep_wake_stub_fn_t new_stub) } void RTC_IRAM_ATTR esp_default_wake_deep_sleep(void) { - // - //mmu_init(0); + /* Clear MMU for CPU 0 */ REG_SET_BIT(DPORT_PRO_CACHE_CTRL1_REG, DPORT_PRO_CACHE_MMU_IA_CLR); REG_CLR_BIT(DPORT_PRO_CACHE_CTRL1_REG, DPORT_PRO_CACHE_MMU_IA_CLR); } diff --git a/components/esp32/include/esp_attr.h b/components/esp32/include/esp_attr.h index 156d2957f9..78aa3bd190 100644 --- a/components/esp32/include/esp_attr.h +++ b/components/esp32/include/esp_attr.h @@ -20,22 +20,21 @@ //and all variables in shared RAM. These macros can be used to redirect //particular functions/variables to other memory regions. -// Forces code into IRAM instead of flash +// Forces code into IRAM instead of flash. #define IRAM_ATTR __attribute__((section(".iram1"))) // Forces data into DRAM instead of flash #define DRAM_ATTR __attribute__((section(".dram1"))) -// Forces code into RTC fast memory +// Forces code into RTC fast memory. See "docs/deep-sleep-stub.rst" #define RTC_IRAM_ATTR __attribute__((section(".rtc.text"))) -// Forces data into RTC slow memory +// Forces data into RTC slow memory. See "docs/deep-sleep-stub.rst" // Any variable marked with this attribute will keep its value // during a deep sleep / wake cycle. #define RTC_DATA_ATTR __attribute__((section(".rtc.data"))) -// Forces read-only data into RTC slow memory -// Makes constant data available to RTC wake stubs (see esp_deepsleep.h) +// Forces read-only data into RTC slow memory. See "docs/deep-sleep-stub.rst" #define RTC_RODATA_ATTR __attribute__((section(".rtc.rodata"))) #endif /* __ESP_ATTR_H__ */ diff --git a/components/esp32/include/esp_deepsleep.h b/components/esp32/include/esp_deepsleep.h index 3683a8eeab..59b3129185 100644 --- a/components/esp32/include/esp_deepsleep.h +++ b/components/esp32/include/esp_deepsleep.h @@ -54,37 +54,7 @@ void system_deep_sleep(uint64_t time_in_us); * to run code immediately when the chip wakes from * sleep. * - * For example: - * @code - * void RTC_IRAM_ATTR esp_wake_deep_sleep(void) { - * esp_default_wake_deep_sleep(); - * // Add additional functionality here - * } - * - * (Implementing this function is not required for normal operation, - * in the usual case your app will start normally when waking from - * deep sleep.) - * - * esp_wake_deep_sleep() functionality is limited: - * - * - Runs immediately on wake, so most of the SoC is freshly reset - - * flash is unmapped and hardware is otherwise uninitialised. - * - * - Can only call functions implemented in ROM, or marked RTC_IRAM_ATTR. - * - * - Static variables marked RTC_DATA_ATTR will have initial values on - * cold boot, and maintain these values between sleep/wake cycles. - * - * - Read-only data should be marked RTC_RODATA_ATTR. Strings must be - * declared as variables also using RTC_RODATA_ATTR, like this: - * RTC_RODATA_ATTR const char message[] = "Hello from very early boot!\n"; - * - * - Any other static memory will not be initialised (either to zero, - * or to any predefined value). - * - * - * - If you implement your own stub, the first call the stub makes - should be to esp_default_wake_deep_sleep(). + * See docs/deep-sleep-stub.rst for details. */ void esp_wake_deep_sleep(void); @@ -115,9 +85,7 @@ esp_deep_sleep_wake_stub_fn_t esp_get_deep_sleep_wake_stub(void); /* The default esp-idf-provided esp_wake_deep_sleep() stub. - If you replace esp_wake_deep_sleep() in your program, or use - esp_set_deep_sleep_wake_stub(), then it is recommended you call - esp_default_wake_deep_sleep() as the first function in your stub. + See docs/deep-sleep-stub.rst for details. */ void esp_default_wake_deep_sleep(void); diff --git a/components/esp32/include/esp_system.h b/components/esp32/include/esp_system.h index 84133366d7..8c6564c55b 100644 --- a/components/esp32/include/esp_system.h +++ b/components/esp32/include/esp_system.h @@ -16,6 +16,7 @@ #define __ESP_SYSTEM_H__ #include +#include #include "esp_err.h" #include "esp_deepsleep.h" diff --git a/components/esp32/ld/esp32.common.ld b/components/esp32/ld/esp32.common.ld index a3c6367840..991259a5e2 100644 --- a/components/esp32/ld/esp32.common.ld +++ b/components/esp32/ld/esp32.common.ld @@ -3,8 +3,38 @@ ENTRY(call_start_cpu0); SECTIONS { + /* RTC fast memory holds RTC wake stub code, + including from any source file named rtc_wake_stub*.c + */ + .rtc.text : + { + . = ALIGN(4); + *(.rtc.literal .rtc.text) + *rtc_wake_stub*.o(.literal .text .literal.* .text.*) + } >rtc_iram_seg + + /* RTC slow memory holds RTC wake stub + data/rodata, including from any source file + named rtc_wake_stub*.c + */ + .rtc.data : + { + *(.rtc.data) + *(.rtc.rodata) + *rtc_wake_stub*.o(.data .rodata .data.* .rodata.* .bss .bss.*) + } > rtc_slow_seg + + /* RTC bss, from any source file named rtc_wake_stub*.c */ + .rtc.bss (NOLOAD) : + { + _rtc_bss_start = ABSOLUTE(.); + *rtc_wake_stub*.o(.bss .bss.*) + *rtc_wake_stub*.o(COMMON) + _rtc_bss_end = ABSOLUTE(.); + } > rtc_slow_seg + /* Send .iram0 code to iram */ - .iram0.vectors : + .iram0.vectors : { /* Vectors go to IRAM */ _init_start = ABSOLUTE(.); @@ -153,16 +183,4 @@ SECTIONS _text_end = ABSOLUTE(.); _etext = .; } >iram0_2_seg - - .rtc.text : - { - . = ALIGN(4); - *(.rtc.literal .rtc.text) - } >rtc_iram_seg - - .rtc.data : - { - *(.rtc.data) - *(.rtc.rodata) - } > rtc_slow_seg } diff --git a/docs/deep-sleep-stub.rst b/docs/deep-sleep-stub.rst new file mode 100644 index 0000000000..983f8bbf26 --- /dev/null +++ b/docs/deep-sleep-stub.rst @@ -0,0 +1,87 @@ +Deep Sleep Wake Stubs +--------------------- + +ESP32 supports running a "deep sleep wake stub" when coming out of deep sleep. This function runs immediately as soon as the chip wakes up - before any normal initialisation, bootloader, or ESP-IDF code has run. After the wake stub runs, the SoC can go back to sleep or continue to start ESP-IDF normally. + +Deep sleep wake stub code is loaded into "RTC Fast Memory" and any data which it uses must also be loaded into RTC memory. RTC memory regions hold their contents during deep sleep. + +Rules for Wake Stubs +==================== + +Wake stub code must be carefully written: + +* As the SoC has freshly woken from sleep, most of the peripherals are in reset states. The SPI flash is unmapped. + +* The wake stub code can only call functions implemented in ROM or loaded into RTC Fast Memory (see below.) + +* The wake stub code can only access data loaded in RTC memory. All other RAM will be unintiailised and have random contents. The wake stub can use other RAM for temporary storage, but the contents will be overwritten when the SoC goes back to sleep or starts ESP-IDF. + +* RTC memory must include any read-only data (.rodata) used by the stub. + +* Data in RTC memory is initialised whenever the SoC restarts, except when waking from deep sleep. When waking from deep sleep, the values which were present before going to sleep are kept. + +* Wake stub code is a part of the main esp-idf app. During normal running of esp-idf, functions can call the wake stub functions or access RTC memory. It is as if these were regular parts of the app. + +Implementing A Stub +=================== + +The wake stub in esp-idf is called ``esp_wake_deep_sleep()``. This function runs whenever the SoC wakes from deep sleep. There is a default version of this function provided in esp-idf, but the default function is weak-linked so if your app contains a function named ``esp_wake_deep_sleep()` then this will override the default. + +If supplying a custom wake stub, the first thing it does should be to call ``esp_default_wake_deep_sleep()``. + +It is not necessary to implement ``esp_wake_deep_sleep()`` in your app in order to use deep sleep. It is only necessary if you want to have special behaviour immediately on wake. + +If you want to swap between different deep sleep stubs at runtime, it is also possible to do this by calling the ``esp_set_deep_sleep_wake_stub()`` function. This is not necessary if you only use the default ``esp_wake_deep_sleep()`` function. + +All of these functions are declared in the ``esp_deepsleep.h`` header under components/esp32. + +Loading Code Into RTC Memory +============================ + +Wake stub code must be resident in RTC Fast Memory. This can be done in one of two ways. + +The first way is to use the ``RTC_IRAM_ATTR`` attribute to place a function into RTC memory:: + + void RTC_IRAM_ATTR esp_wake_deep_sleep(void) { + esp_default_wake_deep_sleep(); + // Add additional functionality here + } + +The second way is to place the function into any source file whose name starts with ``rtc_wake_stub``. Files names ``rtc_wake_stub*`` have their contents automatically put into RTC memory by the linker. + +The first way is simpler for very short and simple code, or for source files where you want to mix "normal" and "RTC" code. The second way is simpler when you want to write longer pieces of code for RTC memory. + + +Loading Data Into RTC Memory +============================ + +Data used by stub code must be resident in RTC Slow Memory. This memory is also used by the ULP. + +Specifying this data can be done in one of two ways: + +The first way is to use the ``RTC_DATA_ATTR`` and ``RTC_RODATA_ATTR`` to specify any data (writeable or read-only, respectivley) which should be loaded into RTC slow memory:: + + RTC_DATA_ATTR int wake_count; + + void RTC_IRAM_ATTR esp_wake_deep_sleep(void) { + esp_default_wake_deep_sleep(); + static RTC_RODATA_ATTR const char fmt_str[] = "Wake count %d\n"; + ets_printf(fmt_str, wake_count++); + } + +Unfortunately, any string constants used in this way must be declared as arrays and marked with RTC_RODATA_ATTR, as shown in the example above. + +The second way is to place the data into any source file whose name starts with ``rtc_wake_stub``. + +For example, the equivalent example in ``rtc_wake_stub_counter.c``:: + + int wake_count; + + void RTC_IRAM_ATTR esp_wake_deep_sleep(void) { + esp_default_wake_deep_sleep(); + ets_printf("Wake count %d\n", wake_count++); + } + +The second way is a better option if you need to use strings, or write other more complex code. + + From 3f521c4afae7ac1e1145ce6b7fa5f15211bb6ec7 Mon Sep 17 00:00:00 2001 From: Yinling Date: Wed, 19 Oct 2016 15:11:38 +0800 Subject: [PATCH 100/343] update KnowIssues: 1. unsupported cases by "phy" command 2. DHCP server behavior different from ESP8266 3. TCP failed cases causes by unstable TCP behavior 4. UDP failed cases by poor UDP performance --- .../idf_test/integration_test/KnownIssues | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/components/idf_test/integration_test/KnownIssues b/components/idf_test/integration_test/KnownIssues index 08bc48f185..0c48a811e2 100644 --- a/components/idf_test/integration_test/KnownIssues +++ b/components/idf_test/integration_test/KnownIssues @@ -23,6 +23,24 @@ TCPIP_IGMP_0204 ^TCPIP_IGMP_0203 ^TCPIP_IGMP_0204 +# don't support PHY mode command +WIFI_SCAN_0201 +WIFI_SCAN_0302 +WIFI_PHY_0401 +WIFI_PHY_0402 +WIFI_PHY_0403 +WIFI_PHY_0404 +WIFI_PHY_0405 +WIFI_PHY_0407 +WIFI_PHY_0406 +WIFI_PHY_0408 +WIFI_PHY_0501 +WIFI_PHY_0502 +WIFI_PHY_0503 +WIFI_PHY_0504 +WIFI_PHY_0505 +WIFI_PHY_0506 + # BUG # auth change event @@ -46,6 +64,10 @@ TCPIP_DHCP_0207 ^TCPIP_DHCP_0207 TCPIP_DHCP_0208 ^TCPIP_DHCP_0208 +TCPIP_DHCP_0205 +^TCPIP_DHCP_0205 +TCPIP_DHCP_0209 +^TCPIP_DHCP_0209 # TCP issue TCPIP_TCP_0402 @@ -54,6 +76,9 @@ TCPIP_TCP_0402 TCPIP_TCP_0210 ^TCPIP_TCP_0210 TCPIP_TCP_0103 +^TCPIP_TCP_0103 +TCPIP_TCP_0112 +^TCPIP_TCP_0112 # UDP issue @@ -61,6 +86,8 @@ TCPIP_UDP_0103 ^TCPIP_UDP_0103 TCPIP_UDP_0110 ^TCPIP_UDP_0110 +TCPIP_UDP_0305 +^TCPIP_UDP_0305 From de7b2f5a09b3852cc92465af24f4f243bab9f5ee Mon Sep 17 00:00:00 2001 From: Yinling Date: Wed, 19 Oct 2016 15:16:47 +0800 Subject: [PATCH 101/343] fix following test case bugs: 1. (^)TCPIP_DHCP_0101, (^)TCPIP_DHCP_0301: IDF set IP 0.0.0.0 may return error, don't check the result of setting IP to 0.0.0.0; 2. rename (^)TCPIP_DHCP_0102 to (^)TCPIP_DHCP_0212 as it's a DHCP server test case; 3. (^)TCPIP_TCP_0204,(^)TCPIP_TCP_0210,(^)TCPIP_UDP_0201,(^)TCPIP_UDP_0202: recv thread can't be deleted, change case to not create recv thread when create socket ; 4. (^)TCPIP_TCP_0206,(^)TCPIP_TCP_0212: query TCP server status format changed. 5. WIFI_SCAN_0301: check command error and test environment not correct 6. WIFI_SCAN_0302, WIFI_SCAN_0303, WIFI_SCAN_0304: test environment not correct --- .../idf_test/integration_test/TestCaseAll.yml | 369 +++++++----------- 1 file changed, 143 insertions(+), 226 deletions(-) diff --git a/components/idf_test/integration_test/TestCaseAll.yml b/components/idf_test/integration_test/TestCaseAll.yml index 0835c146bd..a7f63a185b 100644 --- a/components/idf_test/integration_test/TestCaseAll.yml +++ b/components/idf_test/integration_test/TestCaseAll.yml @@ -87,7 +87,7 @@ test cases: - - SSC SSC1 dhcp -E -o 1 - ['R SSC1 C +DHCP:STA,OK'] - - SSC SSC1 ip -S -i 0.0.0.0 - - ['R SSC1 C +IP:OK'] + - [R SSC1 C +IP] - - SSC SSC1 sta -C -s -p - [''] - - DELAY 20 @@ -121,54 +121,7 @@ test cases: 1 SSC target connect with PC by UART.' test point 1: basic function test point 2: DHCP client function test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: TCPIP_DHCP_0102 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -p -t - - ['R SSC1 C +SAP:OK'] - - - SSC SSC1 dhcp -E -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC2 sta -C -s -p - - [''] - - - DELAY 20 - - [P PC_COM C +DELAYDONE, 'P SSC2 NC +JAP:CONNECTED'] - - - SSC SSC1 dhcp -S -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - comment: '' - execution time: 0.0 - expected result: "1.target1 set AP OK \n2.target1 关闭DHCP OK\n3.target2 jap target\ - \ 1,FAIL \n4.target1 打开DHCP OK\n5.target2 jap target 1,ok" - initial condition: T2_1 - initial condition description (auto): target 1 as SoftAP, target 2 as STA, will - autogen a TC with initial condition T2_2 - level: Integration - module: TCPIP - steps: "1.target1 set AP OK \n2.target1 关闭DHCP OK\n3.target2 jap target 1,FAIL \n\ - 4.target1 打开DHCP OK\n5.target2 jap target 1,ok" - sub module: DHCP - summary: dhcp server function test - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: DHCP client function test - version: v1 (2016-8-15) + version: v2 (2016-10-19) - CI ready: 'Yes' ID: TCPIP_DHCP_0103 SDK: '8266_NonOS @@ -967,6 +920,53 @@ test cases: test point 1: basic function test point 2: DHCP server function test version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_DHCP_0212 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC2 sta -C -s -p + - [''] + - - DELAY 20 + - [P PC_COM C +DELAYDONE, 'P SSC2 NC +JAP:CONNECTED'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: "1.target1 set AP OK \n2.target1 关闭DHCP OK\n3.target2 jap target\ + \ 1,FAIL \n4.target1 打开DHCP OK\n5.target2 jap target 1,ok" + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA, will + autogen a TC with initial condition T2_2 + level: Integration + module: TCPIP + steps: "1.target1 set AP OK \n2.target1 关闭DHCP OK\n3.target2 jap target 1,FAIL \n\ + 4.target1 打开DHCP OK\n5.target2 jap target 1,ok" + sub module: DHCP + summary: dhcp server function test + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v2 (2016-10-19) - CI ready: 'Yes' ID: TCPIP_DHCP_0301 SDK: '8266_NonOS @@ -987,7 +987,7 @@ test cases: - - SSC SSC1 sta -C -s -p - ['R SSC1 C +JAP:CONNECTED'] - - SSC SSC1 ip -S -i 0.0.0.0 -o 1 - - ['R SSC1 C +IP:OK'] + - [R SSC1 C +IP] - - SSC SSC1 sta -C -s -p - [''] - - DELAY 10 @@ -1027,7 +1027,7 @@ test cases: 1 SSC target connect with PC by UART.' test point 1: interaction test point 2: static IP and DHCP interaction test - version: v1 (2016-8-15) + version: v2 (2016-10-19) - CI ready: 'Yes' ID: TCPIP_DHCP_0302 SDK: '8266_NonOS @@ -3189,14 +3189,12 @@ test cases: - '' - - SOC SOC1 LISTEN - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP + - - SSC SSC1 soc -B -t TCP -w 0 - ['R SSC1 A :BIND:(\d+),OK'] - - SSC SSC1 soc -C -s -i -p - ['R SSC1 RE CONNECT:\d+,OK'] - - SOC SOC1 ACCEPT SOC2 - [R SOC_COM L OK] - - - SSC SSC1 soc -W -s -o 0 - - ['R SSC1 RE WORKTHREAD:\d+,OK'] - - SOC SOC2 SEND 146000 - [P SOC_COM R *] - - SSC SSC1 soc -W -s -o 1 @@ -3246,7 +3244,7 @@ test cases: 1 SSC target connect with PC by UART.' test point 1: basic function test point 2: use TCP SAP (socket/espconn API) in different state - version: v1 (2016-8-15) + version: v2 (2016-10-19) - CI ready: 'Yes' ID: TCPIP_TCP_0206 SDK: '8266_NonOS @@ -3280,7 +3278,7 @@ test cases: - ['R SSC1 A :ACCEPT:(\d+),\d+,.+,\d+'] - - SSC SSC1 soc -I - ['P SSC1 RE "SOCINFO:%%s,2,%%s,\d+,%%s,%%d"%%(,,,)', - 'P SSC1 RE "SOCINFO:%%s,2,.+,\d+,.+,\d+"%%()', 'P SSC1 RE "SOCINFO:%%s,82,.+,%%d,.+,\d+"%%(,)', + 'P SSC1 RE "SOCINFO:%%s,2,.+,\d+,.+,\d+"%%()', 'P SSC1 RE "SOCINFO:%%s,82,.+,%%d"%%(,)', 'P SSC1 RE "SOCINFO:%%s,2,%%s,%%d,%%s,\d+"%%(,,,)'] comment: '' execution time: 0.0 @@ -3531,14 +3529,12 @@ test cases: - '' - - SOC SOC1 LISTEN - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP + - - SSC SSC1 soc -B -t TCP -w 0 - ['R SSC1 A :BIND:(\d+),OK'] - - SSC SSC1 soc -C -s -i -p - ['R SSC1 RE CONNECT:\d+,OK'] - - SOC SOC1 ACCEPT SOC2 - [R SOC_COM L OK] - - - SSC SSC1 soc -W -s -o 0 - - ['R SSC1 RE WORKTHREAD:\d+,OK'] - - SOC SOC2 SEND 146000 - [P SOC_COM R *] - - SSC SSC1 soc -W -s -o 1 @@ -3586,7 +3582,7 @@ test cases: 1 SSC target connect with PC by UART.' test point 1: basic function test point 2: use TCP SAP (socket/espconn API) in different state - version: v1 (2016-8-15) + version: v2 (2016-10-19) - CI ready: 'Yes' ID: TCPIP_TCP_0212 SDK: '8266_NonOS @@ -3620,7 +3616,7 @@ test cases: - ['R SSC1 A :ACCEPT:(\d+),\d+,.+,\d+'] - - SSC SSC1 soc -I - ['P SSC1 RE "SOCINFO:%%s,2,%%s,\d+,%%s,%%d"%%(,,,)', - 'P SSC1 RE "SOCINFO:%%s,2,.+,\d+,.+,\d+"%%()', 'P SSC1 RE "SOCINFO:%%s,82,.+,%%d,.+,\d+"%%(,)', + 'P SSC1 RE "SOCINFO:%%s,2,.+,\d+,.+,\d+"%%()', 'P SSC1 RE "SOCINFO:%%s,82,.+,%%d"%%(,)', 'P SSC1 RE "SOCINFO:%%s,2,%%s,%%d,%%s,\d+"%%(,,,)'] comment: '' execution time: 0.0 @@ -5119,10 +5115,8 @@ test cases: - '' - - SOC SOC1 BIND - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t UDP -p + - - SSC SSC1 soc -B -t UDP -p -w 0 - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -W -s -o 0 - - ['R SSC1 RE WORKTHREAD:\d+,OK'] - - SOC SOC1 SENDTO 1472 - [''] - - SOC SOC1 SENDTO 1472 @@ -5180,7 +5174,7 @@ test cases: 1 SSC target connect with PC by UART.' test point 1: abnormal/special use test point 2: use UDP SAP (socket/espconn API) in different state - version: v1 (2016-8-15) + version: v2 (2016-10-19) - CI ready: 'Yes' ID: TCPIP_UDP_0202 SDK: '8266_NonOS @@ -5198,8 +5192,8 @@ test cases: - [R SOC_COM L OK] - - SSC SSC1 soc -B -t UDP -p - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -W -s -o 0 - - ['R SSC1 RE WORKTHREAD:\d+,OK'] + - - SOC SOC1 SENDTO 1472 + - [''] - - SOC SOC1 SENDTO 1472 - [''] - - SOC SOC1 SENDTO 1472 @@ -5257,7 +5251,7 @@ test cases: 1 SSC target connect with PC by UART.' test point 1: abnormal/special use test point 2: use UDP SAP (socket/espconn API) in different state - version: v1 (2016-8-15) + version: v2 (2016-10-19) - CI ready: 'Yes' ID: TCPIP_UDP_0301 SDK: '8266_NonOS @@ -7915,7 +7909,7 @@ test cases: - - SSC SSC1 sta -S - [''] - - SSC SSC1 sta -S - - [P SSC1 C +SCANFAIL, 'P SSC1 P +SCAN:', R SSC1 C +SCANDONE] + - [P SSC1 C +SCANFAIL, 'P SSC1 C +SCAN:', R SSC1 C +SCANDONE] comment: '' execution time: 0.0 expected result: '1. second scan failed @@ -7931,14 +7925,12 @@ test cases: 2. do scan before scan finished' sub module: WIFI Scan summary: reject scan request before scan finished - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. - PC has one WiFi NIC support capture wlan packet using libpcap. + PC has 1 WiFi NIC. - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' + 1 SSC target connect with PC by UART.' test point 1: interaction test point 2: Scan interact with other WiFi operation version: v1 (2015-8-15) @@ -7987,14 +7979,12 @@ test cases: 3. target 2 scan in AP channel in 11b.g,n,ht40 mode' sub module: WIFI Scan summary: scan in congest channel - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. - PC has one WiFi NIC support capture wlan packet using libpcap. + PC has 1 WiFi NIC. - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' + 2 SSC target connect with PC by UART.' test point 1: interaction test point 2: Scan interact with other WiFi operation version: v1 (2015-8-15) @@ -8022,8 +8012,9 @@ test cases: expected result: '2. scan succeed, JAP succeed 5. JAP succeed, scan succeed' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + initial condition: STAM1 + initial condition description (auto): sta mode, quit AP, DHCP on, will autogen a + TC with initial condition STAAP1 level: Integration module: WIFI MAC steps: '1. target 1 STA join AP @@ -8037,14 +8028,12 @@ test cases: 5. target 1 JAP before scan succeed' sub module: WIFI Scan summary: scan during JAP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. - PC has one WiFi NIC support capture wlan packet using libpcap. + PC has 1 WiFi NIC. - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' + 1 SSC target connect with PC by UART.' test point 1: interaction test point 2: Scan interact with other WiFi operation version: v1 (2015-8-15) @@ -8087,14 +8076,12 @@ test cases: 5. target 2 STA JAP before target 1 STA scan succeed' sub module: WIFI Scan summary: scan during ext STA join SoftAP - test environment: SSC_T2_PhyMode - test environment description (auto): '2 SSC target connect with PC by UART. + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. - PC has one WiFi NIC support capture wlan packet using libpcap. + PC has 1 WiFi NIC. - Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40. - - Put 4 APs near SSC targets.' + 2 SSC target connect with PC by UART.' test point 1: interaction test point 2: Scan interact with other WiFi operation version: v1 (2015-8-15) @@ -8114,7 +8101,7 @@ test cases: - - SSC SSC1 dhcp -E -o 1 - ['R SSC1 C +DHCP:STA,OK'] - - SSC SSC1 ip -S -i 0.0.0.0 - - ['R SSC1 C +IP:OK'] + - [R SSC1 C +IP] - - SSC SSC1 sta -C -s -p - [''] - - DELAY 20 @@ -8148,53 +8135,7 @@ test cases: 1 SSC target connect with PC by UART.' test point 1: basic function test point 2: DHCP client function test - version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^TCPIP_DHCP_0102 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 ap -S -s -p -t - - ['R SSC1 C +SAP:OK'] - - - SSC SSC1 dhcp -E -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC2 sta -C -s -p - - [''] - - - DELAY 20 - - [P PC_COM C +DELAYDONE, 'P SSC2 NC +JAP:CONNECTED'] - - - SSC SSC1 dhcp -S -o 2 - - ['R SSC1 C +DHCP:AP,OK'] - - - SSC SSC2 sta -C -s -p - - ['R SSC2 C +JAP:CONNECTED'] - comment: '' - execution time: 0.0 - expected result: "1.target1 set AP OK \n2.target1 关闭DHCP OK\n3.target2 jap target\ - \ 1,FAIL \n4.target1 打开DHCP OK\n5.target2 jap target 1,ok" - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - level: Integration - module: TCPIP - steps: "1.target1 set AP OK \n2.target1 关闭DHCP OK\n3.target2 jap target 1,FAIL \n\ - 4.target1 打开DHCP OK\n5.target2 jap target 1,ok" - sub module: DHCP - summary: dhcp server function test - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: DHCP client function test - version: v1 (2016-8-15) + version: v2 (2016-10-19) - CI ready: 'Yes' ID: ^TCPIP_DHCP_0103 SDK: '8266_NonOS @@ -8982,6 +8923,52 @@ test cases: test point 1: basic function test point 2: DHCP server function test version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: ^TCPIP_DHCP_0212 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + allow fail: '' + auto test: 'Yes' + category: Function + cmd set: + - '' + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] + - - SSC SSC1 dhcp -E -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC2 sta -C -s -p + - [''] + - - DELAY 20 + - [P PC_COM C +DELAYDONE, 'P SSC2 NC +JAP:CONNECTED'] + - - SSC SSC1 dhcp -S -o 2 + - ['R SSC1 C +DHCP:AP,OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 C +JAP:CONNECTED'] + comment: '' + execution time: 0.0 + expected result: "1.target1 set AP OK \n2.target1 关闭DHCP OK\n3.target2 jap target\ + \ 1,FAIL \n4.target1 打开DHCP OK\n5.target2 jap target 1,ok" + initial condition: T2_2 + initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) + level: Integration + module: TCPIP + steps: "1.target1 set AP OK \n2.target1 关闭DHCP OK\n3.target2 jap target 1,FAIL \n\ + 4.target1 打开DHCP OK\n5.target2 jap target 1,ok" + sub module: DHCP + summary: dhcp server function test + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: basic function + test point 2: DHCP server function test + version: v2 (2016-10-19) - CI ready: 'Yes' ID: ^TCPIP_DHCP_0301 SDK: '8266_NonOS @@ -9002,7 +8989,7 @@ test cases: - - SSC SSC1 sta -C -s -p - ['R SSC1 C +JAP:CONNECTED'] - - SSC SSC1 ip -S -i 0.0.0.0 -o 1 - - ['R SSC1 C +IP:OK'] + - [R SSC1 C +IP] - - SSC SSC1 sta -C -s -p - [''] - - DELAY 10 @@ -9042,7 +9029,7 @@ test cases: 1 SSC target connect with PC by UART.' test point 1: interaction test point 2: static IP and DHCP interaction test - version: v1 (2016-8-15) + version: v2 (2016-10-19) - CI ready: 'Yes' ID: ^TCPIP_DHCP_0302 SDK: '8266_NonOS @@ -11199,14 +11186,12 @@ test cases: - '' - - SOC SOC1 LISTEN - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP + - - SSC SSC1 soc -B -t TCP -w 0 - ['R SSC1 A :BIND:(\d+),OK'] - - SSC SSC1 soc -C -s -i -p - ['R SSC1 RE CONNECT:\d+,OK'] - - SOC SOC1 ACCEPT SOC2 - [R SOC_COM L OK] - - - SSC SSC1 soc -W -s -o 0 - - ['R SSC1 RE WORKTHREAD:\d+,OK'] - - SOC SOC2 SEND 146000 - [P SOC_COM R *] - - SSC SSC1 soc -W -s -o 1 @@ -11254,7 +11239,7 @@ test cases: 1 SSC target connect with PC by UART.' test point 1: basic function test point 2: use TCP SAP (socket/espconn API) in different state - version: v1 (2016-8-15) + version: v2 (2016-10-19) - CI ready: 'Yes' ID: ^TCPIP_TCP_0206 SDK: '8266_NonOS @@ -11288,7 +11273,7 @@ test cases: - ['R SSC1 A :ACCEPT:(\d+),\d+,.+,\d+'] - - SSC SSC1 soc -I - ['P SSC1 RE "SOCINFO:%%s,2,%%s,\d+,%%s,%%d"%%(,,,)', - 'P SSC1 RE "SOCINFO:%%s,2,.+,\d+,.+,\d+"%%()', 'P SSC1 RE "SOCINFO:%%s,82,.+,%%d,.+,\d+"%%(,)', + 'P SSC1 RE "SOCINFO:%%s,2,.+,\d+,.+,\d+"%%()', 'P SSC1 RE "SOCINFO:%%s,82,.+,%%d"%%(,)', 'P SSC1 RE "SOCINFO:%%s,2,%%s,%%d,%%s,\d+"%%(,,,)'] comment: '' execution time: 0.0 @@ -11539,14 +11524,12 @@ test cases: - '' - - SOC SOC1 LISTEN - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t TCP + - - SSC SSC1 soc -B -t TCP -w 0 - ['R SSC1 A :BIND:(\d+),OK'] - - SSC SSC1 soc -C -s -i -p - ['R SSC1 RE CONNECT:\d+,OK'] - - SOC SOC1 ACCEPT SOC2 - [R SOC_COM L OK] - - - SSC SSC1 soc -W -s -o 0 - - ['R SSC1 RE WORKTHREAD:\d+,OK'] - - SOC SOC2 SEND 146000 - [P SOC_COM R *] - - SSC SSC1 soc -W -s -o 1 @@ -11592,7 +11575,7 @@ test cases: 1 SSC target connect with PC by UART.' test point 1: basic function test point 2: use TCP SAP (socket/espconn API) in different state - version: v1 (2016-8-15) + version: v2 (2016-10-19) - CI ready: 'Yes' ID: ^TCPIP_TCP_0212 SDK: '8266_NonOS @@ -11626,7 +11609,7 @@ test cases: - ['R SSC1 A :ACCEPT:(\d+),\d+,.+,\d+'] - - SSC SSC1 soc -I - ['P SSC1 RE "SOCINFO:%%s,2,%%s,\d+,%%s,%%d"%%(,,,)', - 'P SSC1 RE "SOCINFO:%%s,2,.+,\d+,.+,\d+"%%()', 'P SSC1 RE "SOCINFO:%%s,82,.+,%%d,.+,\d+"%%(,)', + 'P SSC1 RE "SOCINFO:%%s,2,.+,\d+,.+,\d+"%%()', 'P SSC1 RE "SOCINFO:%%s,82,.+,%%d"%%(,)', 'P SSC1 RE "SOCINFO:%%s,2,%%s,%%d,%%s,\d+"%%(,,,)'] comment: '' execution time: 0.0 @@ -12981,10 +12964,8 @@ test cases: - '' - - SOC SOC1 BIND - [R SOC_COM L OK] - - - SSC SSC1 soc -B -t UDP -p + - - SSC SSC1 soc -B -t UDP -p -w 0 - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -W -s -o 0 - - ['R SSC1 RE WORKTHREAD:\d+,OK'] - - SOC SOC1 SENDTO 1472 - [''] - - SOC SOC1 SENDTO 1472 @@ -13042,7 +13023,7 @@ test cases: 1 SSC target connect with PC by UART.' test point 1: abnormal/special use test point 2: use UDP SAP (socket/espconn API) in different state - version: v1 (2016-8-15) + version: v2 (2016-10-19) - CI ready: 'Yes' ID: ^TCPIP_UDP_0202 SDK: '8266_NonOS @@ -13060,8 +13041,8 @@ test cases: - [R SOC_COM L OK] - - SSC SSC1 soc -B -t UDP -p - ['R SSC1 A :BIND:(\d+),OK'] - - - SSC SSC1 soc -W -s -o 0 - - ['R SSC1 RE WORKTHREAD:\d+,OK'] + - - SOC SOC1 SENDTO 1472 + - [''] - - SOC SOC1 SENDTO 1472 - [''] - - SOC SOC1 SENDTO 1472 @@ -13119,7 +13100,7 @@ test cases: 1 SSC target connect with PC by UART.' test point 1: abnormal/special use test point 2: use UDP SAP (socket/espconn API) in different state - version: v1 (2016-8-15) + version: v2 (2016-10-19) - CI ready: 'Yes' ID: ^TCPIP_UDP_0301 SDK: '8266_NonOS @@ -14652,67 +14633,3 @@ test cases: test point 1: basic function test point 2: scan with different config version: v1 (2016-8-15) -- CI ready: 'Yes' - ID: ^WIFI_SCAN_0105 - SDK: '8266_NonOS - - 8266_RTOS - - ESP32_IDF' - Test App: SSC - allow fail: '' - auto test: 'Yes' - category: Function - cmd set: - - '' - - - SSC SSC1 sta -D - - ['R SSC1 C +QAP:'] - - - SSC SSC1 ap -S -s -p 123456789 -t 3 -h 0 -n 11 - - ['R SSC1 C +SAP:OK'] - - - SSC SSC2 sta -S -s -b -n 11 - - [R SSC2 P C +SCANDONE] - - - SSC SSC2 sta -S -s -b -n 11 - - [R SSC2 NP C +SCANDONE] - - - SSC SSC2 sta -S -s -b ff:ff:ff:ff:ff:11 -n 11 - - [R SSC2 P , R SSC2 NP C +SCANDONE] - - - SSC SSC2 sta -S -s -b -n 10 - - [R SSC2 P , R SSC2 NP C +SCANDONE] - comment: '' - execution time: 0.0 - expected result: '1.target1 QAP - - 2. target1 set AP,set ssid broad cast,set channel 11 - - 3.target2 上查询到 - - 4.target2 上查询不到 - - 5.target2 上查询不到 - - 6.target2 上查询不到' - initial condition: T2_2 - initial condition description (auto): target 1 as AP+STA, target 2 as AP+STA (autogen) - level: Integration - module: WIFI MAC - steps: '1.target1 QAP - - 2. target1 set AP,set ssid broad cast,set channel 11 - - 3.target2 上查询到 - - 4.target2 上查询不到 - - 5.target2 上查询不到 - - 6.target2 上查询不到' - sub module: WIFI Scan - summary: scan with several configs - test environment: SSC_T2_1 - test environment description (auto): 'PC has 1 wired NIC connected to AP. - - PC has 1 WiFi NIC. - - 2 SSC target connect with PC by UART.' - test point 1: basic function - test point 2: scan with different config - version: v1 (2016-8-15) From c2b63a614ee110759ffc211f2fd571fa4c50fdf0 Mon Sep 17 00:00:00 2001 From: Yinling Date: Wed, 19 Oct 2016 15:22:13 +0800 Subject: [PATCH 102/343] sync test env from auto_test_script (add SSC_T5_IOT1) --- components/idf_test/integration_test/TestEnvAll.yml | 4 ++++ components/idf_test/uint_test/TestEnvAll.yml | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/components/idf_test/integration_test/TestEnvAll.yml b/components/idf_test/integration_test/TestEnvAll.yml index afa6cb812a..2e59961d97 100644 --- a/components/idf_test/integration_test/TestEnvAll.yml +++ b/components/idf_test/integration_test/TestEnvAll.yml @@ -229,6 +229,10 @@ test environment: Put 4 APs near SSC targets.', test script: EnvBase} - {PC OS: '', Special: N, Target Count: 5.0, script path: EnvBase.py, tag: SSC_T5_1, test environment detail: 5 SSC target connect with PC by UART., test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 5.0, script path: EnvBase.py, tag: SSC_T5_IOT1, + test environment detail: '5 SSC targets connect with PC by UART. + + some Android smart phone are placed near SSC targets.', test script: EnvBase} - {PC OS: '', Special: N, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T6_1, test environment detail: 'PC has 1 wired NIC connected to AP. diff --git a/components/idf_test/uint_test/TestEnvAll.yml b/components/idf_test/uint_test/TestEnvAll.yml index afa6cb812a..2e59961d97 100644 --- a/components/idf_test/uint_test/TestEnvAll.yml +++ b/components/idf_test/uint_test/TestEnvAll.yml @@ -229,6 +229,10 @@ test environment: Put 4 APs near SSC targets.', test script: EnvBase} - {PC OS: '', Special: N, Target Count: 5.0, script path: EnvBase.py, tag: SSC_T5_1, test environment detail: 5 SSC target connect with PC by UART., test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 5.0, script path: EnvBase.py, tag: SSC_T5_IOT1, + test environment detail: '5 SSC targets connect with PC by UART. + + some Android smart phone are placed near SSC targets.', test script: EnvBase} - {PC OS: '', Special: N, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T6_1, test environment detail: 'PC has 1 wired NIC connected to AP. From 0324373cd1c89570dc3b454410d124504df8e10f Mon Sep 17 00:00:00 2001 From: Yinling Date: Wed, 19 Oct 2016 15:23:07 +0800 Subject: [PATCH 103/343] update auto generated CI job config --- .../integration_test/CIConfigs/IT_Function_TCPIP_02.yml | 8 ++++---- .../integration_test/CIConfigs/IT_Function_TCPIP_03.yml | 2 +- .../integration_test/CIConfigs/IT_Function_TCPIP_04.yml | 2 +- .../integration_test/CIConfigs/IT_Function_WIFI_01.yml | 8 ++++---- .../integration_test/CIConfigs/IT_Function_WIFI_02.yml | 6 +++--- .../integration_test/CIConfigs/IT_Function_WIFI_06.yml | 5 ++--- 6 files changed, 15 insertions(+), 16 deletions(-) diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_02.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_02.yml index 61adea9821..73618e0d70 100644 --- a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_02.yml +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_02.yml @@ -4,7 +4,7 @@ Filter: - Add: ID: [TCPIP_IGMP_0203, ^TCPIP_TCP_0403, ^TCPIP_TCP_0408, TCPIP_UDP_0201, TCPIP_UDP_0202, ^TCPIP_DHCP_0301, ^TCPIP_TCP_0101, ^TCPIP_TCP_0103, ^TCPIP_TCP_0105, ^TCPIP_TCP_0104, - ^TCPIP_TCP_0107, ^TCPIP_TCP_0106, ^TCPIP_DHCP_0210, ^TCPIP_DHCP_0211, ^TCPIP_TCP_0404, - TCPIP_TCP_0212, TCPIP_TCP_0210, ^TCPIP_TCP_0406, ^TCPIP_TCP_0407, ^TCPIP_TCP_0401, - ^TCPIP_TCP_0210, ^TCPIP_TCP_0212, TCPIP_DHCP_0211, TCPIP_DHCP_0210, TCPIP_DHCP_0101, - TCPIP_DHCP_0103, TCPIP_DHCP_0102, TCPIP_DHCP_0206, TCPIP_DHCP_0207, ^TCPIP_IP_0102] + ^TCPIP_TCP_0107, ^TCPIP_TCP_0106, ^TCPIP_DHCP_0210, ^TCPIP_DHCP_0211, ^TCPIP_DHCP_0212, + ^TCPIP_TCP_0404, TCPIP_TCP_0212, TCPIP_TCP_0210, ^TCPIP_TCP_0406, ^TCPIP_TCP_0407, + ^TCPIP_TCP_0401, ^TCPIP_TCP_0210, ^TCPIP_TCP_0212, TCPIP_DHCP_0211, TCPIP_DHCP_0210, + TCPIP_DHCP_0212, TCPIP_DHCP_0101, TCPIP_DHCP_0103, TCPIP_DHCP_0206, TCPIP_DHCP_0207] diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_03.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_03.yml index 9d64630e9c..b326ed721c 100644 --- a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_03.yml +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_03.yml @@ -2,7 +2,7 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC2, SSC1] Filter: - Add: - ID: [^TCPIP_UDP_0105, ^TCPIP_UDP_0107, ^TCPIP_UDP_0106, ^TCPIP_UDP_0101, TCPIP_TCP_0203, + ID: [^TCPIP_IP_0102, ^TCPIP_UDP_0105, ^TCPIP_UDP_0107, ^TCPIP_UDP_0106, ^TCPIP_UDP_0101, TCPIP_TCP_0202, ^TCPIP_UDP_0108, ^TCPIP_IGMP_0201, ^TCPIP_IGMP_0203, ^TCPIP_IGMP_0202, ^TCPIP_IGMP_0103, TCPIP_UDP_0114, TCPIP_UDP_0113, TCPIP_UDP_0112, TCPIP_DHCP_0205, TCPIP_DHCP_0202, TCPIP_DHCP_0203, ^TCPIP_TCP_0102, TCPIP_TCP_0106, TCPIP_TCP_0107, diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_04.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_04.yml index 6be01f698c..314de4a7e0 100644 --- a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_04.yml +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_04.yml @@ -5,6 +5,6 @@ Filter: ID: [^TCPIP_TCP_0110, ^TCPIP_TCP_0111, TCPIP_DHCP_0209, ^TCPIP_DHCP_0209, ^TCPIP_DHCP_0207, ^TCPIP_DHCP_0206, ^TCPIP_DHCP_0205, ^TCPIP_DHCP_0204, ^TCPIP_DHCP_0203, ^TCPIP_DHCP_0202, ^TCPIP_DHCP_0201, TCPIP_TCP_0204, TCPIP_TCP_0207, TCPIP_TCP_0206, TCPIP_TCP_0201, - ^TCPIP_DHCP_0101, ^TCPIP_DHCP_0102, ^TCPIP_DHCP_0103, ^TCPIP_DHCP_0208, TCPIP_TCP_0208, + ^TCPIP_DHCP_0101, TCPIP_TCP_0203, ^TCPIP_DHCP_0103, ^TCPIP_DHCP_0208, TCPIP_TCP_0208, ^TCPIP_TCP_0202, ^TCPIP_TCP_0203, TCPIP_DHCP_0204, ^TCPIP_TCP_0201, ^TCPIP_TCP_0206, ^TCPIP_TCP_0207, ^TCPIP_TCP_0204, TCPIP_DHCP_0201, ^TCPIP_TCP_0208, TCPIP_DHCP_0208] diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_01.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_01.yml index c22bc59bd8..9f8424f6d2 100644 --- a/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_01.yml +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_01.yml @@ -4,7 +4,7 @@ Filter: - Add: ID: [^WIFI_CONN_0601, ^WIFI_ADDR_0101, WIFI_SCAN_0103, WIFI_SCAN_0102, WIFI_SCAN_0101, WIFI_SCAN_0105, WIFI_SCAN_0104, ^WIFI_CONN_0103, WIFI_CONN_0201, WIFI_CONN_0904, - ^WIFI_SCAN_0102, ^WIFI_SCAN_0103, ^WIFI_SCAN_0104, ^WIFI_SCAN_0105, WIFI_CONN_0401, - WIFI_ADDR_0101, WIFI_ADDR_0102, WIFI_CONN_0301, ^WIFI_CONN_0801, ^WIFI_CONN_0301, - WIFI_CONN_0501, WIFI_CONN_0502, ^WIFI_CONN_0401, WIFI_MODE_0101, WIFI_MODE_0103, - WIFI_MODE_0102, ^WIFI_CONN_0904, ^WIFI_CONN_0901, WIFI_CONN_0601, ^WIFI_CONN_0201] + ^WIFI_SCAN_0102, ^WIFI_SCAN_0103, ^WIFI_SCAN_0104, WIFI_CONN_0401, WIFI_ADDR_0101, + WIFI_ADDR_0102, WIFI_CONN_0301, WIFI_SCAN_0301, WIFI_SCAN_0303, ^WIFI_CONN_0801, + WIFI_SCAN_0304, ^WIFI_CONN_0301, WIFI_CONN_0501, WIFI_CONN_0502, ^WIFI_CONN_0401, + WIFI_MODE_0101, WIFI_MODE_0103, WIFI_MODE_0102, ^WIFI_CONN_0904, ^WIFI_CONN_0901] diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_02.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_02.yml index 049054dbac..74e6ca612d 100644 --- a/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_02.yml +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_02.yml @@ -2,6 +2,6 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC2, SSC1] Filter: - Add: - ID: [^WIFI_ADDR_0102, WIFI_CONN_0901, WIFI_CONN_0801, ^WIFI_CONN_0104, WIFI_CONN_0104, - WIFI_CONN_0101, WIFI_CONN_0102, WIFI_CONN_0103, ^WIFI_SCAN_0101, ^WIFI_CONN_0101, - ^WIFI_CONN_0502, ^WIFI_CONN_0501] + ID: [WIFI_SCAN_0302, WIFI_CONN_0601, ^WIFI_CONN_0201, ^WIFI_ADDR_0102, WIFI_CONN_0901, + WIFI_CONN_0801, ^WIFI_CONN_0104, WIFI_CONN_0104, WIFI_CONN_0101, WIFI_CONN_0102, + WIFI_CONN_0103, ^WIFI_SCAN_0101, ^WIFI_CONN_0101, ^WIFI_CONN_0502, ^WIFI_CONN_0501] diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_06.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_06.yml index 9d639f9121..dd42815a91 100644 --- a/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_06.yml +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_06.yml @@ -2,6 +2,5 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC2, SSC1] Filter: - Add: - ID: [WIFI_SCAN_0301, WIFI_SCAN_0303, WIFI_SCAN_0304, WIFI_SCAN_0302, WIFI_SCAN_0201, - WIFI_PHY_0403, WIFI_PHY_0402, WIFI_PHY_0401, WIFI_PHY_0407, WIFI_PHY_0406, WIFI_PHY_0405, - WIFI_PHY_0404, WIFI_PHY_0408] + ID: [WIFI_SCAN_0201, WIFI_PHY_0403, WIFI_PHY_0402, WIFI_PHY_0401, WIFI_PHY_0407, + WIFI_PHY_0406, WIFI_PHY_0405, WIFI_PHY_0404, WIFI_PHY_0408] From 6eaf595a0e7e66ecebd64ab153e3651e657d5c5b Mon Sep 17 00:00:00 2001 From: Yinling Date: Wed, 19 Oct 2016 18:00:27 +0800 Subject: [PATCH 104/343] change test WAN server URL: form iot.espressif.cn to factory.espressif.cn --- .../idf_test/integration_test/TestCaseAll.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/components/idf_test/integration_test/TestCaseAll.yml b/components/idf_test/integration_test/TestCaseAll.yml index a7f63a185b..315682c3f0 100644 --- a/components/idf_test/integration_test/TestCaseAll.yml +++ b/components/idf_test/integration_test/TestCaseAll.yml @@ -1143,7 +1143,7 @@ test cases: category: Function cmd set: - '' - - - SSC SSC1 soc -H -d iot.espressif.cn + - - SSC SSC1 soc -H -d factory.espressif.cn - ['R SSC1 A :\+HOSTIP:OK,(.+)\r\n'] - - SSC SSC1 soc -B -t TCP - ['R SSC1 A :\+BIND:(\d+),OK'] @@ -1178,7 +1178,7 @@ test cases: 1 SSC target connect with PC by UART.' test point 1: basic function test point 2: DNS function test - version: v1 (2016-8-15) + version: v2 (2016-10-19) - CI ready: 'Yes' ID: TCPIP_DNS_0103 SDK: '8266_NonOS @@ -1192,7 +1192,7 @@ test cases: category: Function cmd set: - '' - - - SSC SSC1 soc -H -d iot.espressif.cn + - - SSC SSC1 soc -H -d factory.espressif.cn - ['R SSC1 A :\+HOSTIP:OK,(.+)\r\n'] - - SSC SSC1 soc -B -t UDP - ['R SSC1 A :\+BIND:(\d+),OK'] @@ -1223,7 +1223,7 @@ test cases: 1 SSC target connect with PC by UART.' test point 1: basic function test point 2: DNS function test - version: v1 (2016-8-15) + version: v2 (2016-10-19) - CI ready: 'Yes' ID: TCPIP_ICMP_0101 SDK: '8266_NonOS @@ -9144,7 +9144,7 @@ test cases: category: Function cmd set: - '' - - - SSC SSC1 soc -H -d iot.espressif.cn + - - SSC SSC1 soc -H -d factory.espressif.cn - ['R SSC1 A :\+HOSTIP:OK,(.+)\r\n'] - - SSC SSC1 soc -B -t TCP - ['R SSC1 A :\+BIND:(\d+),OK'] @@ -9179,7 +9179,7 @@ test cases: 1 SSC target connect with PC by UART.' test point 1: basic function test point 2: DNS function test - version: v1 (2016-8-15) + version: v2 (2016-10-19) - CI ready: 'Yes' ID: ^TCPIP_DNS_0103 SDK: '8266_NonOS @@ -9193,7 +9193,7 @@ test cases: category: Function cmd set: - '' - - - SSC SSC1 soc -H -d iot.espressif.cn + - - SSC SSC1 soc -H -d factory.espressif.cn - ['R SSC1 A :\+HOSTIP:OK,(.+)\r\n'] - - SSC SSC1 soc -B -t UDP - ['R SSC1 A :\+BIND:(\d+),OK'] @@ -9224,7 +9224,7 @@ test cases: 1 SSC target connect with PC by UART.' test point 1: basic function test point 2: DNS function test - version: v1 (2016-8-15) + version: v2 (2016-10-19) - CI ready: 'Yes' ID: ^TCPIP_ICMP_0101 SDK: '8266_NonOS From 18ebc6411e811393edcfbbb24e1d9ae9c936f5f0 Mon Sep 17 00:00:00 2001 From: Yinling Date: Wed, 19 Oct 2016 18:03:43 +0800 Subject: [PATCH 105/343] fix bug for WIFI_SCAN_0304: need to set AP config first --- components/idf_test/integration_test/TestCaseAll.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/idf_test/integration_test/TestCaseAll.yml b/components/idf_test/integration_test/TestCaseAll.yml index 315682c3f0..a98b89b403 100644 --- a/components/idf_test/integration_test/TestCaseAll.yml +++ b/components/idf_test/integration_test/TestCaseAll.yml @@ -8046,6 +8046,8 @@ test cases: category: Function cmd set: - '' + - - SSC SSC1 ap -S -s -p -t + - ['R SSC1 C +SAP:OK'] - - SSC SSC2 sta -C -s -p - ['R SSC2 C +JAP:OK'] - - SSC SSC1 sta -S From c350972eacc85ae1ead7d71ffe8dc26b057b5b15 Mon Sep 17 00:00:00 2001 From: Yinling Date: Wed, 19 Oct 2016 20:22:43 +0800 Subject: [PATCH 106/343] update following know issues: 1. ^WIFI_CONN_0801: auth change event not correct 2. WIFI_SCAN_0303: scan interact with JAP not correct 3. ^WIFI_SCAN_0103,^WIFI_SCAN_0105: no scan done event 4. ^TCPIP_UDP_0304,TCPIP_UDP_0104: UDP poor performance --- components/idf_test/integration_test/KnownIssues | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/components/idf_test/integration_test/KnownIssues b/components/idf_test/integration_test/KnownIssues index 0c48a811e2..5e81430408 100644 --- a/components/idf_test/integration_test/KnownIssues +++ b/components/idf_test/integration_test/KnownIssues @@ -45,6 +45,7 @@ WIFI_PHY_0506 # auth change event WIFI_CONN_0801 +^WIFI_CONN_0801 # disconnect reason WIFI_CONN_0904 @@ -56,6 +57,11 @@ WIFI_CONN_0901 WIFI_CONN_0104 ^WIFI_CONN_0104 +# Wifi scan issue +WIFI_SCAN_0303 +^WIFI_SCAN_0103 +^WIFI_SCAN_0105 + # DHCP issues ^TCPIP_DHCP_0301 TCPIP_DHCP_0301 @@ -88,6 +94,8 @@ TCPIP_UDP_0110 ^TCPIP_UDP_0110 TCPIP_UDP_0305 ^TCPIP_UDP_0305 +^TCPIP_UDP_0304 +TCPIP_UDP_0104 From 2d393f05300b6050788561ba1dada185c27917f8 Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Thu, 20 Oct 2016 11:23:59 +0800 Subject: [PATCH 107/343] Change inline assembly bits from macros to inline functions --- .../freertos/include/freertos/portable.h | 9 ++++++++- .../freertos/include/freertos/portmacro.h | 20 +++++++++++++++++++ components/freertos/port.c | 19 ------------------ 3 files changed, 28 insertions(+), 20 deletions(-) diff --git a/components/freertos/include/freertos/portable.h b/components/freertos/include/freertos/portable.h index 58e6903664..a3d39bd5a2 100644 --- a/components/freertos/include/freertos/portable.h +++ b/components/freertos/include/freertos/portable.h @@ -192,7 +192,14 @@ void vPortEndScheduler( void ) PRIVILEGED_FUNCTION; #endif /* Multi-core: get current core ID */ -#define xPortGetCoreID() __extension__({int id; asm volatile("rsr.prid %0; extui %0,%0,13,1":"=r"(id)); id;}) +inline uint32_t xPortGetCoreID() { + int id; + asm volatile( + "rsr.prid %0\n" + " extui %0,%0,13,1" + :"=r"(id)); + return id; +} #ifdef __cplusplus } diff --git a/components/freertos/include/freertos/portmacro.h b/components/freertos/include/freertos/portmacro.h index ab83b0e05a..5e2386d721 100644 --- a/components/freertos/include/freertos/portmacro.h +++ b/components/freertos/include/freertos/portmacro.h @@ -225,6 +225,26 @@ static inline unsigned portENTER_CRITICAL_NESTED() { unsigned state = XTOS_SET_I #define portCLEAR_INTERRUPT_MASK_FROM_ISR(state) portEXIT_CRITICAL_NESTED(state) +/* + * Wrapper for the Xtensa compare-and-set instruction. This subroutine will atomically compare + * *mux to compare, and if it's the same, will set *mux to set. It will return the old value + * of *addr in *set. + * + * Warning: From the ISA docs: in some (unspecified) cases, the s32c1i instruction may return the + * *bitwise inverse* of the old mem if the mem wasn't written. This doesn't seem to happen on the + * ESP32, though. (Would show up directly if it did because the magic wouldn't match.) + */ +inline void uxPortCompareSet(volatile uint32_t *addr, uint32_t compare, uint32_t *set) { + __asm__ __volatile__( + "WSR %2,SCOMPARE1 \n" + "ISYNC \n" + "S32C1I %0, %1, 0 \n" + :"=r"(*set) + :"r"(addr), "r"(compare), "0"(*set) + ); +} + + /*-----------------------------------------------------------*/ /* Architecture specifics. */ diff --git a/components/freertos/port.c b/components/freertos/port.c index ef72b1cb5e..a982db7d42 100644 --- a/components/freertos/port.c +++ b/components/freertos/port.c @@ -253,25 +253,6 @@ void vPortAssertIfInISR() configASSERT(port_interruptNesting[xPortGetCoreID()]==0) } - -/* - * Wrapper for the Xtensa compare-and-set instruction. This subroutine will atomically compare - * *mux to compare, and if it's the same, will set *mux to set. It will return the old value - * of *addr. - * - * Warning: From the ISA docs: in some (unspecified) cases, the s32c1i instruction may return the - * *bitwise inverse* of the old mem if the mem wasn't written. This doesn't seem to happen on the - * ESP32, though. (Would show up directly if it did because the magic wouldn't match.) - */ -#define uxPortCompareSet(mux, compare, set) \ - __asm__ __volatile__( \ - "WSR %2,SCOMPARE1 \n" \ - "ISYNC \n" \ - "S32C1I %0, %1, 0 \n" \ - :"=r"(*set) \ - :"r"(mux), "r"(compare), "0"(*set) \ - ); \ - /* * For kernel use: Initialize a per-CPU mux. Mux will be initialized unlocked. */ From 5e8849d03206b83f19532d38c6eabffeacd9b573 Mon Sep 17 00:00:00 2001 From: Yinling Date: Thu, 20 Oct 2016 11:28:06 +0800 Subject: [PATCH 108/343] modify TCPIP_DHCP_0211: delay 30s to make sure STA got enough time to disconnect and reconnect. --- components/idf_test/integration_test/TestCaseAll.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/idf_test/integration_test/TestCaseAll.yml b/components/idf_test/integration_test/TestCaseAll.yml index a98b89b403..3b2242787c 100644 --- a/components/idf_test/integration_test/TestCaseAll.yml +++ b/components/idf_test/integration_test/TestCaseAll.yml @@ -880,7 +880,7 @@ test cases: - ['R SSC1 C +DHCP:AP,OK'] - - SSC SSC2 sta -C -s -p - ['R SSC2 C +JAP:CONNECTED'] - - - DELAY 10 + - - DELAY 30 - [''] - - SSC SSC1 ap -L - [R SSC1 C 192.168.4.2 C 192.168.4.3 P P ] @@ -8886,7 +8886,7 @@ test cases: - ['R SSC1 C +DHCP:AP,OK'] - - SSC SSC2 sta -C -s -p - ['R SSC2 C +JAP:CONNECTED'] - - - DELAY 10 + - - DELAY 30 - [''] - - SSC SSC1 ap -L - [R SSC1 C 192.168.4.2 C 192.168.4.3 P P ] From 39a06319e245b7b4bd9ec5f8dbfe12d00a1c7940 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Thu, 20 Oct 2016 16:10:51 +0800 Subject: [PATCH 109/343] build system: use -Og instead of -O0 for debug builds, expand help text in menuconfig --- Kconfig | 5 ++++- make/project.mk | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Kconfig b/Kconfig index 936181a9cb..97da1f01f5 100644 --- a/Kconfig +++ b/Kconfig @@ -27,7 +27,10 @@ choice OPTIMIZATION_LEVEL prompt "Optimization level" default OPTIMIZATION_LEVEL_DEBUG help - This option sets compiler optimization level. + This option sets optimization level. + For "Release" setting, -Os flag is added to CFLAGS, + and -DNDEBUG flag is added to CPPFLAGS. + For "Debug" setting, -Og flag is added to CFLAGS. config OPTIMIZATION_LEVEL_DEBUG bool "Debug" config OPTIMIZATION_LEVEL_RELEASE diff --git a/make/project.mk b/make/project.mk index 9088eda85d..b646dfc419 100644 --- a/make/project.mk +++ b/make/project.mk @@ -179,7 +179,7 @@ ifneq ("$(CONFIG_OPTIMIZATION_LEVEL_RELEASE)","") OPTIMIZATION_FLAGS = -Os CPPFLAGS += -DNDEBUG else -OPTIMIZATION_FLAGS = -O0 +OPTIMIZATION_FLAGS = -Og endif # Enable generation of debugging symbols From d3d8c0453516e9a2c6b8a340086eef63e7ee0cbe Mon Sep 17 00:00:00 2001 From: Yinling Date: Thu, 20 Oct 2016 16:43:04 +0800 Subject: [PATCH 110/343] add known issue exception when setting mac address: WIFI_ADDR_0101,^WIFI_ADDR_0101 --- components/idf_test/integration_test/KnownIssues | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/components/idf_test/integration_test/KnownIssues b/components/idf_test/integration_test/KnownIssues index 5e81430408..85b5b2f218 100644 --- a/components/idf_test/integration_test/KnownIssues +++ b/components/idf_test/integration_test/KnownIssues @@ -62,6 +62,10 @@ WIFI_SCAN_0303 ^WIFI_SCAN_0103 ^WIFI_SCAN_0105 +# set mac address may lead to exception +WIFI_ADDR_0101 +^WIFI_ADDR_0101 + # DHCP issues ^TCPIP_DHCP_0301 TCPIP_DHCP_0301 From dfe0dcaed477023443bda6fa2319132b1f5bf20f Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Thu, 20 Oct 2016 17:17:54 +0800 Subject: [PATCH 111/343] build system: fix setting C**FLAGS from project makefile --- Kconfig | 10 ++++++++-- make/project.mk | 28 +++++++++++++++++++++------- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/Kconfig b/Kconfig index 97da1f01f5..deb0cea839 100644 --- a/Kconfig +++ b/Kconfig @@ -28,9 +28,15 @@ choice OPTIMIZATION_LEVEL default OPTIMIZATION_LEVEL_DEBUG help This option sets optimization level. - For "Release" setting, -Os flag is added to CFLAGS, + + - for "Release" setting, -Os flag is added to CFLAGS, and -DNDEBUG flag is added to CPPFLAGS. - For "Debug" setting, -Og flag is added to CFLAGS. + + - for "Debug" setting, -Og flag is added to CFLAGS. + + To override any of these settings, set CFLAGS and/or CPPFLAGS + in project makefile, before including $(IDF_PATH)/make/project.mk. + config OPTIMIZATION_LEVEL_DEBUG bool "Debug" config OPTIMIZATION_LEVEL_RELEASE diff --git a/make/project.mk b/make/project.mk index b646dfc419..887086fd47 100644 --- a/make/project.mk +++ b/make/project.mk @@ -149,16 +149,16 @@ LDFLAGS ?= -nostdlib \ -Wl,-EL # Set default CPPFLAGS, CFLAGS, CXXFLAGS -# # These are exported so that components can use them when compiling. -# # If you need your component to add CFLAGS/etc for it's own source compilation only, set CFLAGS += in your component's Makefile. -# # If you need your component to add CFLAGS/etc globally for all source -# files, set CFLAGS += in your component's Makefile.projbuild +# files, set CFLAGS += in your component's Makefile.projbuild +# If you need to set CFLAGS/CPPFLAGS/CXXFLAGS at project level, set them in application Makefile +# before including project.mk. Default flags will be added before the ones provided in application Makefile. # CPPFLAGS used by C preprocessor -CPPFLAGS = -DESP_PLATFORM +# If any flags are defined in application Makefile, add them at the end. +CPPFLAGS := -DESP_PLATFORM $(CPPFLAGS) # Warnings-related flags relevant both for C and C++ COMMON_WARNING_FLAGS = -Wall -Werror \ @@ -186,10 +186,24 @@ endif OPTIMIZATION_FLAGS += -ggdb # List of flags to pass to C compiler -CFLAGS = -std=gnu99 $(strip $(OPTIMIZATION_FLAGS) $(COMMON_FLAGS) $(COMMON_WARNING_FLAGS)) +# If any flags are defined in application Makefile, add them at the end. +CFLAGS := $(strip \ + -std=gnu99 \ + $(OPTIMIZATION_FLAGS) \ + $(COMMON_FLAGS) \ + $(COMMON_WARNING_FLAGS) \ + $(CFLAGS)) # List of flags to pass to C++ compiler -CXXFLAGS = -std=gnu++11 -fno-exceptions -fno-rtti $(strip $(OPTIMIZATION_FLAGS) $(COMMON_FLAGS) $(COMMON_WARNING_FLAGS)) +# If any flags are defined in application Makefile, add them at the end. +CXXFLAGS := $(strip \ + -std=gnu++11 \ + -fno-exceptions \ + -fno-rtti \ + $(OPTIMIZATION_FLAGS) \ + $(COMMON_FLAGS) \ + $(COMMON_WARNING_FLAGS) \ + $(CXXFLAGS)) export CFLAGS CPPFLAGS CXXFLAGS From 6b8504005920535764a51d8ec4e9a392e3fcb178 Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Thu, 20 Oct 2016 20:11:13 +0800 Subject: [PATCH 112/343] Also export HOSTCC etc for components --- make/project.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/make/project.mk b/make/project.mk index 2b2eff3f5e..d822d6a21d 100644 --- a/make/project.mk +++ b/make/project.mk @@ -176,6 +176,7 @@ HOSTCC := $(CC) HOSTLD := $(LD) HOSTAR := $(AR) HOSTOBJCOPY := $(OBJCOPY) +export HOSTCC HOSTLD HOSTAR HOSTOBJCOPY #Set target compiler. Defaults to whatever the user has #configured as prefix + yer olde gcc commands From feca308f1f13f5191a510064fc1a6c00a6235da2 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Fri, 21 Oct 2016 10:44:05 +1100 Subject: [PATCH 113/343] rom/spi_flash.h: Remove first parameter of SPI_read_status_high() Corrects the prototype to match the one compiled into ROM. --- components/esp32/include/rom/spi_flash.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/esp32/include/rom/spi_flash.h b/components/esp32/include/rom/spi_flash.h index ba8eebc2ce..d182b51ca0 100644 --- a/components/esp32/include/rom/spi_flash.h +++ b/components/esp32/include/rom/spi_flash.h @@ -218,7 +218,7 @@ void SelectSpiFunction(uint32_t ishspi); void spi_flash_attach(uint32_t ishspi, bool legacy); /** - * @brief SPI Read Flash status register. We use CMD 0x05. + * @brief SPI Read Flash status register. We use CMD 0x05 (RDSR). * Please do not call this function in SDK. * * @param SpiFlashChip *spi : The information for Flash, which is exported from ld file. @@ -232,7 +232,7 @@ void spi_flash_attach(uint32_t ishspi, bool legacy); SpiFlashOpResult SPI_read_status(SpiFlashChip *spi, uint32_t *status); /** - * @brief SPI Read Flash status register high 16 bit. We use CMD 0x35. + * @brief SPI Read Flash status register bits 8-15. We use CMD 0x35 (RDSR2). * Please do not call this function in SDK. * * @param SpiFlashChip *spi : The information for Flash, which is exported from ld file. @@ -243,7 +243,7 @@ SpiFlashOpResult SPI_read_status(SpiFlashChip *spi, uint32_t *status); * SPI_FLASH_RESULT_ERR : read error. * SPI_FLASH_RESULT_TIMEOUT : read timeout. */ -SpiFlashOpResult SPI_read_status_high(SpiFlashChip *spi, uint32_t *status); +SpiFlashOpResult SPI_read_status_high(uint32_t *status); /** * @brief Write status to Falsh status register. From 7104284e31aff45949bd087a7a278ca58751eef6 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Fri, 21 Oct 2016 15:26:11 +1100 Subject: [PATCH 114/343] Bump esptool version Incorporates fix for locked flash #50 --- components/esptool_py/esptool | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esptool_py/esptool b/components/esptool_py/esptool index 197ba605fe..5c6962e894 160000 --- a/components/esptool_py/esptool +++ b/components/esptool_py/esptool @@ -1 +1 @@ -Subproject commit 197ba605fe0c05e16bf4c5ec07b726adc8d86abc +Subproject commit 5c6962e894e0a118c9a4b5760876433493449260 From 42827ff8693e229bd541c295651f3ef96aa6012d Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 18 Oct 2016 19:03:59 +0800 Subject: [PATCH 115/343] bootloader, menuconfig: add flash size setting support --- .../bootloader/src/main/bootloader_config.h | 2 +- .../bootloader/src/main/bootloader_start.c | 37 ++++++++++++++++++- components/esp32/include/rom/spi_flash.h | 6 +++ components/esp32/ld/esp32.rom.ld | 1 + components/esptool_py/Kconfig.projbuild | 27 ++++++++++++++ components/esptool_py/Makefile.projbuild | 7 +++- 6 files changed, 75 insertions(+), 5 deletions(-) diff --git a/components/bootloader/src/main/bootloader_config.h b/components/bootloader/src/main/bootloader_config.h index 709ff41b16..f99a1c94e5 100644 --- a/components/bootloader/src/main/bootloader_config.h +++ b/components/bootloader/src/main/bootloader_config.h @@ -51,7 +51,7 @@ enum { SPI_SPEED_20M, SPI_SPEED_80M = 0xF }; -/*suppport flash size in esp32 */ +/*supported flash sizes*/ enum { SPI_SIZE_1MB = 0, SPI_SIZE_2MB, diff --git a/components/bootloader/src/main/bootloader_start.c b/components/bootloader/src/main/bootloader_start.c index a61ea77d59..e87f579f42 100644 --- a/components/bootloader/src/main/bootloader_start.c +++ b/components/bootloader/src/main/bootloader_start.c @@ -58,6 +58,7 @@ void IRAM_ATTR set_cache_and_start_app(uint32_t drom_addr, uint32_t irom_load_addr, uint32_t irom_size, uint32_t entry_addr); +static void update_flash_config(struct flash_hdr* pfhdr); void IRAM_ATTR call_start_cpu0() @@ -258,7 +259,7 @@ void bootloader_main() memset(&bs, 0, sizeof(bs)); ESP_LOGI(TAG, "compile time " __TIME__ ); - /* close watch dog here */ + /* disable watch dog here */ REG_CLR_BIT( RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_FLASHBOOT_MOD_EN ); REG_CLR_BIT( TIMG_WDTCONFIG0_REG(0), TIMG_WDT_FLASHBOOT_MOD_EN ); SPIUnlock(); @@ -269,6 +270,8 @@ void bootloader_main() print_flash_info(&fhdr); + update_flash_config(&fhdr); + if (!load_partition_table(&bs, PARTITION_ADD)) { ESP_LOGE(TAG, "load partition table error!"); return; @@ -364,7 +367,7 @@ void unpack_load_app(const partition_pos_t* partition) uint32_t irom_size = 0; /* Reload the RTC memory sections whenever a non-deepsleep reset - is occuring */ + is occurring */ bool load_rtc_memory = rtc_get_reset_reason(0) != DEEPSLEEP_RESET; ESP_LOGD(TAG, "bin_header: %u %u %u %u %08x", image_header.magic, @@ -482,6 +485,36 @@ void IRAM_ATTR set_cache_and_start_app( (*entry)(); } +static void update_flash_config(struct flash_hdr* pfhdr) +{ + uint32_t size; + switch(pfhdr->spi_size) { + case SPI_SIZE_1MB: + size = 1; + break; + case SPI_SIZE_2MB: + size = 2; + break; + case SPI_SIZE_4MB: + size = 4; + break; + case SPI_SIZE_8MB: + size = 8; + break; + case SPI_SIZE_16MB: + size = 16; + break; + default: + size = 2; + } + Cache_Read_Disable( 0 ); + // Set flash chip size + SPIParamCfg(g_rom_flashchip.deviceId, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff); + // TODO: set mode + // TODO: set frequency + Cache_Flush(0); + Cache_Read_Enable( 0 ); +} void print_flash_info(struct flash_hdr* pfhdr) { diff --git a/components/esp32/include/rom/spi_flash.h b/components/esp32/include/rom/spi_flash.h index d182b51ca0..1f14c6617a 100644 --- a/components/esp32/include/rom/spi_flash.h +++ b/components/esp32/include/rom/spi_flash.h @@ -503,6 +503,12 @@ void SPI_Write_Encrypt_Disable(void); */ SpiFlashOpResult SPI_Encrypt_Write(uint32_t flash_addr, uint32_t *data, uint32_t len); + +/** @brief Global SpiFlashChip structure used by ROM functions + * + */ +extern SpiFlashChip g_rom_flashchip; + /** * @} */ diff --git a/components/esp32/ld/esp32.rom.ld b/components/esp32/ld/esp32.rom.ld index cc14d3258a..0fa28397ee 100644 --- a/components/esp32/ld/esp32.rom.ld +++ b/components/esp32/ld/esp32.rom.ld @@ -286,6 +286,7 @@ PROVIDE ( _global_impure_ptr = 0x3ffae0b0 ); PROVIDE ( gmtime = 0x40059848 ); PROVIDE ( gmtime_r = 0x40059868 ); PROVIDE ( g_phyFuns_instance = 0x3ffae0c4 ); +PROVIDE ( g_rom_flashchip = 0x3ffae270 ); PROVIDE ( gpio_init = 0x40009c20 ); PROVIDE ( gpio_input_get = 0x40009b88 ); PROVIDE ( gpio_input_get_high = 0x40009b9c ); diff --git a/components/esptool_py/Kconfig.projbuild b/components/esptool_py/Kconfig.projbuild index 3da802296a..8bab51225e 100644 --- a/components/esptool_py/Kconfig.projbuild +++ b/components/esptool_py/Kconfig.projbuild @@ -94,4 +94,31 @@ config ESPTOOLPY_FLASHFREQ default "26m" if ESPTOOLPY_FLASHFREQ_26M default "20m" if ESPTOOLPY_FLASHFREQ_20M + +choice ESPTOOLPY_FLASHSIZE + prompt "Flash size" + default ESPTOOLPY_FLASHSIZE_2MB + help + SPI flash size, in megabytes + +config ESPTOOLPY_FLASHSIZE_1MB + bool "1 MB" +config ESPTOOLPY_FLASHSIZE_2MB + bool "2 MB" +config ESPTOOLPY_FLASHSIZE_4MB + bool "4 MB" +config ESPTOOLPY_FLASHSIZE_8MB + bool "8 MB" +config ESPTOOLPY_FLASHSIZE_16MB + bool "16 MB" +endchoice + +config ESPTOOLPY_FLASHSIZE + string + default "1MB" if ESPTOOLPY_FLASHSIZE_1MB + default "2MB" if ESPTOOLPY_FLASHSIZE_2MB + default "4MB" if ESPTOOLPY_FLASHSIZE_4MB + default "8MB" if ESPTOOLPY_FLASHSIZE_8MB + default "16MB" if ESPTOOLPY_FLASHSIZE_16MB + endmenu diff --git a/components/esptool_py/Makefile.projbuild b/components/esptool_py/Makefile.projbuild index 4d0dd1b3e5..69c01e1e7f 100644 --- a/components/esptool_py/Makefile.projbuild +++ b/components/esptool_py/Makefile.projbuild @@ -4,6 +4,7 @@ ESPPORT ?= $(CONFIG_ESPTOOLPY_PORT) ESPBAUD ?= $(CONFIG_ESPTOOLPY_BAUD) ESPFLASHMODE ?= $(CONFIG_ESPTOOLPY_FLASHMODE) ESPFLASHFREQ ?= $(CONFIG_ESPTOOLPY_FLASHFREQ) +ESPFLASHSIZE ?= $(CONFIG_ESPTOOLPY_FLASHSIZE) PYTHON ?= $(call dequote,$(CONFIG_PYTHON)) @@ -15,13 +16,15 @@ ESPTOOLPY_SRC := $(COMPONENT_PATH)/esptool/esptool.py ESPTOOLPY := $(PYTHON) $(ESPTOOLPY_SRC) --chip esp32 ESPTOOLPY_SERIAL := $(ESPTOOLPY) --port $(ESPPORT) --baud $(ESPBAUD) +ESPTOOL_FLASH_OPTIONS := --flash_mode $(ESPFLASHMODE) --flash_freq $(ESPFLASHFREQ) --flash_size $(ESPFLASHSIZE) + # the no-stub argument is temporary until esptool.py fully supports compressed uploads -ESPTOOLPY_WRITE_FLASH=$(ESPTOOLPY_SERIAL) write_flash $(if $(CONFIG_ESPTOOLPY_COMPRESSED),-z) --flash_mode $(ESPFLASHMODE) --flash_freq $(ESPFLASHFREQ) +ESPTOOLPY_WRITE_FLASH=$(ESPTOOLPY_SERIAL) write_flash $(if $(CONFIG_ESPTOOLPY_COMPRESSED),-z) $(ESPTOOL_FLASH_OPTIONS) ESPTOOL_ALL_FLASH_ARGS += $(CONFIG_APP_OFFSET) $(APP_BIN) $(APP_BIN): $(APP_ELF) $(ESPTOOLPY_SRC) - $(Q) $(ESPTOOLPY) elf2image --flash_mode $(ESPFLASHMODE) --flash_freq $(ESPFLASHFREQ) -o $@ $< + $(Q) $(ESPTOOLPY) elf2image $(ESPTOOL_FLASH_OPTIONS) -o $@ $< flash: all_binaries $(ESPTOOLPY_SRC) @echo "Flashing binaries to serial port $(ESPPORT) (app at offset $(CONFIG_APP_OFFSET))..." From 8e8caca2e2dc0bdad5966e59026e2f58975c8621 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Fri, 21 Oct 2016 16:02:06 +1100 Subject: [PATCH 116/343] Replace ROM SPIUnlock function with a version that can't lock flash Avoid bug where a bad status read is copied back to flash and can set lock bits. --- components/esp32/ld/esp32.rom.ld | 2 +- components/spi_flash/spi_flash_rom_patch.c | 72 ++++++++++++++++++++++ 2 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 components/spi_flash/spi_flash_rom_patch.c diff --git a/components/esp32/ld/esp32.rom.ld b/components/esp32/ld/esp32.rom.ld index 0fa28397ee..4b0c1c17eb 100644 --- a/components/esp32/ld/esp32.rom.ld +++ b/components/esp32/ld/esp32.rom.ld @@ -1598,7 +1598,7 @@ PROVIDE ( SPI_read_status = 0x4006226c ); PROVIDE ( SPI_read_status_high = 0x40062448 ); PROVIDE ( SPIUnlock = 0x400628b0 ); PROVIDE ( SPI_user_command_read = 0x400621b0 ); -PROVIDE ( spi_w25q16 = 0x3ffae270 ); +PROVIDE ( SPI_flashchip_data = 0x3ffae270 ); PROVIDE ( SPIWrite = 0x40062d50 ); /* This is static function, but can be used, not generated by script*/ PROVIDE ( SPI_write_enable = 0x40062320 ); diff --git a/components/spi_flash/spi_flash_rom_patch.c b/components/spi_flash/spi_flash_rom_patch.c new file mode 100644 index 0000000000..7e23beaea2 --- /dev/null +++ b/components/spi_flash/spi_flash_rom_patch.c @@ -0,0 +1,72 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include "rom/spi_flash.h" +#include "soc/spi_reg.h" + +static const uint32_t STATUS_QIE_BIT = (1 << 9); /* Quad Enable */ + +#define SPI_IDX 1 +#define OTH_IDX 0 + +extern SpiFlashChip SPI_flashchip_data; + +static void IRAM_ATTR Wait_SPI_Idle(void) +{ + /* Wait for SPI state machine to be idle */ + while((REG_READ(SPI_EXT2_REG(SPI_IDX)) & SPI_ST)) { + } + while(REG_READ(SPI_EXT2_REG(OTH_IDX)) & SPI_ST) { + } +} + +/* Modified version of SPIUnlock() that replaces version in ROM. + + This works around a bug where SPIUnlock sometimes reads the wrong + high status byte (RDSR2 result) and then copies it back to the + flash status, which can cause the CMP bit or Status Register + Protect bit to become set. + + Like other ROM SPI functions, this function is not designed to be + called directly from an RTOS environment without taking precautions + about interrupts, CPU coordination, flash mapping. However some of + the functions in esp_spi_flash.c call it. + */ +SpiFlashOpResult IRAM_ATTR SPIUnlock(void) +{ + uint32_t status; + + Wait_SPI_Idle(); + + if (SPI_read_status_high(&status) != SPI_FLASH_RESULT_OK) { + return SPI_FLASH_RESULT_ERR; + } + + /* Clear all bits except QIE, if it is set. + (This is different from ROM SPIUnlock, which keeps all bits as-is.) + */ + status &= STATUS_QIE_BIT; + + Wait_SPI_Idle(); + REG_WRITE(SPI_CMD_REG(SPI_IDX), SPI_FLASH_WREN); + while(REG_READ(SPI_CMD_REG(SPI_IDX)) != 0) { + } + Wait_SPI_Idle(); + + SET_PERI_REG_MASK(SPI_CTRL_REG(SPI_IDX), SPI_WRSR_2B); + if (SPI_write_status(&SPI_flashchip_data, status) != SPI_FLASH_RESULT_OK) { + return SPI_FLASH_RESULT_ERR; + } + + return SPI_FLASH_RESULT_OK; +} From f37e70ebd60a3b807a09299006ba94c3f32f65dc Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Fri, 21 Oct 2016 17:44:34 +1100 Subject: [PATCH 117/343] Bootloader: Export IS_BOOTLOADER_BUILD during make process --- components/bootloader/Makefile.projbuild | 2 +- components/bootloader/src/Makefile | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/components/bootloader/Makefile.projbuild b/components/bootloader/Makefile.projbuild index 91be3a6d6e..50c95f9fec 100644 --- a/components/bootloader/Makefile.projbuild +++ b/components/bootloader/Makefile.projbuild @@ -8,7 +8,7 @@ # basically runs Make in the src/ directory but it needs to zero some variables # the ESP-IDF project.mk makefile exports first, to not let them interfere. # -ifeq ("$(IS_BOOTLOADER_BUILD)","") +ifndef IS_BOOTLOADER_BUILD BOOTLOADER_COMPONENT_PATH := $(COMPONENT_PATH) BOOTLOADER_BUILD_DIR=$(abspath $(BUILD_DIR_BASE)/bootloader) diff --git a/components/bootloader/src/Makefile b/components/bootloader/src/Makefile index f30e314a5f..ddf664d446 100644 --- a/components/bootloader/src/Makefile +++ b/components/bootloader/src/Makefile @@ -10,6 +10,7 @@ COMPONENTS := esptool_py bootloader log # # IS_BOOTLOADER_BUILD tells the component Makefile.projbuild to be a no-op IS_BOOTLOADER_BUILD := 1 +export IS_BOOTLOADER_BUILD #We cannot include the esp32 component directly but we need its includes. #This is fixed by adding CFLAGS from Makefile.projbuild From 1413ec3ff0ba9409bbb9f839be644be25543f20f Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Fri, 21 Oct 2016 17:08:05 +1100 Subject: [PATCH 118/343] Remove SPIUnlock from linker script symbols Add a comment about why it was removed and where it went. --- components/bootloader/src/Makefile | 2 +- components/esp32/ld/esp32.rom.ld | 3 ++- components/spi_flash/component.mk | 5 +++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/components/bootloader/src/Makefile b/components/bootloader/src/Makefile index ddf664d446..add9c15d61 100644 --- a/components/bootloader/src/Makefile +++ b/components/bootloader/src/Makefile @@ -4,7 +4,7 @@ # PROJECT_NAME := bootloader -COMPONENTS := esptool_py bootloader log +COMPONENTS := esptool_py bootloader log spi_flash # The bootloader pseudo-component is also included in this build, for its Kconfig.projbuild to be included. # diff --git a/components/esp32/ld/esp32.rom.ld b/components/esp32/ld/esp32.rom.ld index 4b0c1c17eb..5266a679be 100644 --- a/components/esp32/ld/esp32.rom.ld +++ b/components/esp32/ld/esp32.rom.ld @@ -1585,6 +1585,8 @@ PROVIDE ( SPIEraseBlock = 0x40062c4c ); PROVIDE ( SPIEraseChip = 0x40062c14 ); PROVIDE ( SPIEraseSector = 0x40062ccc ); PROVIDE ( spi_flash_attach = 0x40062a6c ); +/* NB: SPIUnlock @ 0x400628b0 has been replaced with an updated + version in the "spi_flash" component */ PROVIDE ( SPILock = 0x400628f0 ); PROVIDE ( SPIMasterReadModeCnfig = 0x40062b64 ); PROVIDE ( spi_modes = 0x3ff99270 ); @@ -1596,7 +1598,6 @@ PROVIDE ( SPIReadModeCnfig = 0x40062944 ); PROVIDE ( SPI_read_status = 0x4006226c ); /* This is static function, but can be used, not generated by script*/ PROVIDE ( SPI_read_status_high = 0x40062448 ); -PROVIDE ( SPIUnlock = 0x400628b0 ); PROVIDE ( SPI_user_command_read = 0x400621b0 ); PROVIDE ( SPI_flashchip_data = 0x3ffae270 ); PROVIDE ( SPIWrite = 0x40062d50 ); diff --git a/components/spi_flash/component.mk b/components/spi_flash/component.mk index ef497a7ecb..459da06419 100755 --- a/components/spi_flash/component.mk +++ b/components/spi_flash/component.mk @@ -1,3 +1,8 @@ COMPONENT_ADD_INCLUDEDIRS := include +ifdef IS_BOOTLOADER_BUILD +# Bootloader needs updated SPIUnlock from this file +COMPONENT_OBJS := spi_flash_rom_patch.o +endif + include $(IDF_PATH)/make/component_common.mk From 53146799a003439e3594c3c1957306889af76aad Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Fri, 21 Oct 2016 17:59:57 +0800 Subject: [PATCH 119/343] Initial addition of wdt and brownout code --- components/esp32/Kconfig | 113 +++++++++++++ components/esp32/brownout.c | 37 ++++ components/esp32/cpu_start.c | 12 ++ components/esp32/include/esp_brownout.h | 6 + components/esp32/include/esp_int_wdt.h | 6 + components/esp32/include/esp_task_wdt.h | 8 + components/esp32/int_wdt.c | 82 +++++++++ components/esp32/task_wdt.c | 158 ++++++++++++++++++ .../include/freertos/FreeRTOSConfig.h | 4 +- 9 files changed, 424 insertions(+), 2 deletions(-) create mode 100644 components/esp32/brownout.c create mode 100644 components/esp32/include/esp_brownout.h create mode 100644 components/esp32/include/esp_int_wdt.h create mode 100644 components/esp32/include/esp_task_wdt.h create mode 100644 components/esp32/int_wdt.c create mode 100644 components/esp32/task_wdt.c diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig index 535df23eb5..c40d7930d0 100644 --- a/components/esp32/Kconfig +++ b/components/esp32/Kconfig @@ -140,4 +140,117 @@ config ULP_COPROC_RESERVE_MEM default 0 depends on !ULP_COPROC_ENABLED +menu "Watchdogs & brown-out detection" + +config INT_WDT + bool "Interrupt watchdog" + default y + help + This watchdog timer can detect if the FreeRTOS tick interrupt has not been called for a certain time, + either because a task turned off interrupts and did not turn them on for a long time, or because an + interrupt handler did not return. It will try to invoke the panic handler first and failing that + reset the SoC. + +config INT_WDT_TIMEOUT_MS_MIN + default (2000/CONFIG_FREERTOS_HZ) + +config INT_WDT_TIMEOUT_MS + int "Interrupt watchdog timeout (ms)" + depends on INT_WDT + default 100 + range INT_WDT_TIMEOUT_MS_MIN 10000 + help + The timeout of the watchdog, in miliseconds. + +config TASK_WDT + bool "Task watchdog" + default y + help + This watchdog timer can be used to make sure individual tasks are still running. + +config TASK_WDT_PANIC + bool "Invoke panic handler when Task Watchdog is triggered" + depends on TASK_WDT + default n + help + Normally, the Task Watchdog will only print out a warning if it detects it has not + been fed. If this is enabled, it will invoke the panic handler instead, which + can then halt or reboot the chip. + +config TASK_WDT_TIMEOUT_S + int "Task watchdog timeout (seconds)" + depends on TASK_WDT + range 1 60 + default 5 + help + Timeout for the task WDT, in seconds. + +config TASK_WDT_CHECK_IDLE_TASK + bool "Task watchdog watches idle tasks" + depends on TASK_WDT + default y + help + With this turned on, the task WDT can detect if the idle task is not called within the task + watchdog timeout period. The idle task not being called usually is a symptom of another + task hoarding the CPU. It is also a bad thing because FreeRTOS household tasks depend on the + idle task getting some runtime every now and then. + +config BROWNOUT_DET + bool "Hardware brownout detect & reset" + default y + help + The ESP32 has a built-in brownout detector which can detect if the voltage is lower than + a specific value. If this happens, it will reset the chip in order to prevent unintended + behaviour. + +choice BROWNOUT_DET_LVL_SEL + prompt "Brownout voltage level" + depends on BROWNOUT_DET + default BROWNOUT_DET_LVL_SEL_25 + help + The brownout detector will reset the chip when the supply voltage is below this level. + +config BROWNOUT_DET_LVL_SEL_0 + bool "2.1V" +config BROWNOUT_DET_LVL_SEL_1 + bool "2.2V" +config BROWNOUT_DET_LVL_SEL_2 + bool "2.3V" +config BROWNOUT_DET_LVL_SEL_3 + bool "2.4V" +config BROWNOUT_DET_LVL_SEL_4 + bool "2.5V" +config BROWNOUT_DET_LVL_SEL_5 + bool "2.6V" +config BROWNOUT_DET_LVL_SEL_6 + bool "2.7V" +config BROWNOUT_DET_LVL_SEL_7 + bool "2.8V" +endchoice + +config BROWNOUT_DET_LVL + int + default 0 if BROWNOUT_DET_LVL_SEL_0 + default 1 if BROWNOUT_DET_LVL_SEL_1 + default 2 if BROWNOUT_DET_LVL_SEL_2 + default 3 if BROWNOUT_DET_LVL_SEL_3 + default 4 if BROWNOUT_DET_LVL_SEL_4 + default 5 if BROWNOUT_DET_LVL_SEL_5 + default 6 if BROWNOUT_DET_LVL_SEL_6 + default 7 if BROWNOUT_DET_LVL_SEL_7 + + +config BROWNOUT_DET_RESETDELAY + int "Brownout reset delay (in uS)" + depends on BROWNOUT_DET + range 0 6820 + default 1000 + help + The brownout detector can reset the chip after a certain delay, in order to make sure e.g. a voltage dip has entirely passed + before trying to restart the chip. You can set the delay here. + +endmenu + + + endmenu diff --git a/components/esp32/brownout.c b/components/esp32/brownout.c new file mode 100644 index 0000000000..173d63a0c1 --- /dev/null +++ b/components/esp32/brownout.c @@ -0,0 +1,37 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +#include +#include +#include +#include +#include "sdkconfig.h" +#include "soc/soc.h" +#include "soc/rtc_cntl_reg.h" + + +void esp_brownout_init() { +// WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, +// RTC_CNTL_BROWN_OUT_ENA | (CONFIG_BROWNOUT_DET_LVL << RTC_CNTL_DBROWN_OUT_THRES_S) | +// RTC_CNTL_BROWN_OUT_RST_ENA | (((CONFIG_BROWNOUT_DET_RESETDELAY*150)/1000) << RTC_CNTL_BROWN_OUT_RST_WAIT_S) | +// RTC_CNTL_BROWN_OUT_PD_RF_ENA|RTC_CNTL_BROWN_OUT_CLOSE_FLASH_ENA); + + + WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, + RTC_CNTL_BROWN_OUT_ENA | (4 << RTC_CNTL_DBROWN_OUT_THRES_S) | + RTC_CNTL_BROWN_OUT_RST_ENA | (0x3FF << RTC_CNTL_BROWN_OUT_RST_WAIT_S) | + RTC_CNTL_BROWN_OUT_PD_RF_ENA | RTC_CNTL_BROWN_OUT_CLOSE_FLASH_ENA); + +} \ No newline at end of file diff --git a/components/esp32/cpu_start.c b/components/esp32/cpu_start.c index 7b2ccdc609..6a482c539c 100644 --- a/components/esp32/cpu_start.c +++ b/components/esp32/cpu_start.c @@ -43,6 +43,8 @@ #include "esp_ipc.h" #include "esp_log.h" +#include "esp_brownout.h" + void start_cpu0(void) __attribute__((weak, alias("start_cpu0_default"))); void start_cpu0_default(void) IRAM_ATTR; #if !CONFIG_FREERTOS_UNICORE @@ -137,6 +139,16 @@ void start_cpu0_default(void) do_global_ctors(); esp_ipc_init(); spi_flash_init(); +#if CONFIG_BROWNOUT_DET + esp_brownout_init(); +#endif +#if CONFIG_INT_WDT + int_wdt_init() +#endif +#if CONFIG_TASK_WDT + task_wdt_init() +#endif + xTaskCreatePinnedToCore(&main_task, "main", ESP_TASK_MAIN_STACK, NULL, ESP_TASK_MAIN_PRIO, NULL, 0); diff --git a/components/esp32/include/esp_brownout.h b/components/esp32/include/esp_brownout.h new file mode 100644 index 0000000000..acce05e0db --- /dev/null +++ b/components/esp32/include/esp_brownout.h @@ -0,0 +1,6 @@ +#ifndef BROWNOUT_H +#define BROWNOUT_H + +void esp_brownout_init(); + +#endif \ No newline at end of file diff --git a/components/esp32/include/esp_int_wdt.h b/components/esp32/include/esp_int_wdt.h new file mode 100644 index 0000000000..81404e3053 --- /dev/null +++ b/components/esp32/include/esp_int_wdt.h @@ -0,0 +1,6 @@ +#ifndef INT_WDT_H +#define INT_WDT_H + +void int_wdt_init(); + +#endif \ No newline at end of file diff --git a/components/esp32/include/esp_task_wdt.h b/components/esp32/include/esp_task_wdt.h new file mode 100644 index 0000000000..9163e6907a --- /dev/null +++ b/components/esp32/include/esp_task_wdt.h @@ -0,0 +1,8 @@ +#ifndef TASK_WDT_H +#define TASK_WDT_H + +void task_wdt_feed(); +void task_wdt_delete(); +void task_wdt_init(); + +#endif \ No newline at end of file diff --git a/components/esp32/int_wdt.c b/components/esp32/int_wdt.c new file mode 100644 index 0000000000..392ed6b6a1 --- /dev/null +++ b/components/esp32/int_wdt.c @@ -0,0 +1,82 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +/* +This routine enables a watchdog to catch instances of processes disabling +interrupts for too long, or code within interrupt handlers taking too long. +It does this by setting up a watchdog which gets fed from the FreeRTOS +task switch interrupt. When this watchdog times out, initially it will call +a high-level interrupt routine that will panic FreeRTOS in order to allow +for forensic examination of the state of the CPU. When this interrupt +handler is not called and the watchdog times out a second time, it will +reset the SoC. + +This uses the TIMERG1 WDT. +*/ + +#include "sdkconfig.h" +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include +#include "esp_err.h" +#include "esp_intr.h" +#include "soc/timer_group_struct.h" + +#include "esp_int_wdt.h" + +#if CONFIG_INT_WDT + + +#define WDT_INT_NUM 24 + + +#define WDT_WRITE_KEY 0x50D83AA1 + +static void esp_int_wdt_isr(void *arg) { + abort(); +} + + +void int_wdt_init() { + TIMERG1.wdt_wprotect=WDT_WRITE_KEY; + TIMERG1.wdt_config0.sys_reset_length=7; //3.2uS + TIMERG1.wdt_config0.cpu_reset_length=7; //3.2uS + TIMERG1.wdt_config0.level_int_en=1; + TIMERG1.wdt_config0.stg0=1; //1st stage timeout: interrupt + TIMERG1.wdt_config0.stg1=3; //2nd stage timeout: reset system + TIMERG1.wdt_config1.clk_prescale=80*500; //Prescaler: wdt counts in ticks of 0.5mS + TIMERG1.wdt_config2=CONFIG_INT_WDT_TIMEOUT_MS*2; //Set timeout before interrupt + TIMERG1.wdt_config3=CONFIG_INT_WDT_TIMEOUT_MS*4; //Set timeout before reset + TIMERG1.wdt_config0.en=1; + TIMERG1.wdt_feed=1; + TIMERG1.wdt_wprotect=0; + ESP_INTR_DISABLE(WDT_INT_NUM); + intr_matrix_set(xPortGetCoreID(), ETS_TG1_WDT_LEVEL_INTR_SOURCE, WDT_INT_NUM); + xt_set_interrupt_handler(WDT_INT_NUM, int_wdt_isr, NULL); + ESP_INTR_ENABLE(WDT_INT_NUM); +} + + + +void vApplicationTickHook(void) { + TIMERG1.wdt_wprotect=WDT_WRITE_KEY; + TIMERG1.wdt_feed=1; + TIMERG1.wdt_wprotect=0; +} + +#endif \ No newline at end of file diff --git a/components/esp32/task_wdt.c b/components/esp32/task_wdt.c new file mode 100644 index 0000000000..7ae3dfb2e8 --- /dev/null +++ b/components/esp32/task_wdt.c @@ -0,0 +1,158 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +/* +This routine enables a more general-purpose task watchdog: tasks can individually +feed the watchdog and the watchdog will bark if one or more tasks haven't fed the +watchdog within the specified time. Optionally, the idle tasks can also configured +to feed the watchdog in a similar fashion, to detect CPU starvation. + +This uses the TIMERG0 WDT. +*/ + +#include +#include +#include +#include +#include +#include "sdkconfig.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include +#include "esp_err.h" +#include "esp_intr.h" +#include "soc/timer_group_struct.h" +#include "esp_log.h" + +#include "esp_task_wdt.h" + +#if CONFIG_TASK_WDT + +static const char* TAG = "task_wdt"; + + +typedef struct wdt_task_t wdt_task_t; +struct wdt_task_t { + TaskHandle_t task_handle; + bool fed_watchdog; + wdt_task_t *next; +}; + + +static wdt_task_t *wdt_task_list=NULL; + +#define WDT_INT_NUM 24 + + +#define WDT_WRITE_KEY 0x50D83AA1 + +static void task_wdt_isr(void *arg) { + abort(); +} + + +void task_wdt_feed() { + wdt_task_t *wdttask=wdt_task_list; + bool found_task=false, do_feed_wdt=true; + TaskHandle_t handle=xTaskGetCurrentTaskHandle(); + //Walk the linked list of wdt tasks to find this one, as well as see if we need to feed + //the real watchdog timer. + while (wdttask!=NULL) { + //See if we are at the current task. + if (wdttask->task_handle == handle) { + wdttask->fed_watchdog=true; + found_task=true; + } + //If even one task in the list doesn't have the do_feed_wdt var set, we do not feed the watchdog. + if (!wdttask->fed_watchdog) do_feed_wdt=false; + //Next entry. + wdttask=wdttask->next; + } + + if (!found_task) { + //This is the first time the task calls the task_wdt_feed function. Create a new entry for it in + //the linked list. + wdt_task_t *newtask=malloc(sizeof(wdt_task_t)); + memset(newtask, 0, sizeof(wdt_task_t)); + newtask->task_handle=handle; + newtask->fed_watchdog=true; + if (wdt_task_list == NULL) { + wdt_task_list=newtask; + } else { + wdttask=wdt_task_list; + while (!(wdttask->next == NULL)) wdttask=wdttask->next; + wdttask->next=wdttask; + } + } + if (do_feed_wdt) { + //All tasks have checked in; time to feed the hw watchdog. + TIMERG0.wdt_wprotect=WDT_WRITE_KEY; + TIMERG0.wdt_feed=1; + TIMERG0.wdt_wprotect=0; + } +} + +void task_wdt_delete() { + TaskHandle_t handle=xTaskGetCurrentTaskHandle(); + wdt_task_t *wdttask=wdt_task_list; + //Wdt task list can't be empty + if (!wdt_task_list) { + ESP_LOGE(TAG, "task_wdt_delete: No tasks in list?"); + return; + } + if (handle==wdt_task_list) { + //Current task is first on list. + wdt_task_list=wdt_task_list->next; + free(wdttask); + } else { + //Find current task in list + while (wdttask->next!=NULL && wdttask->next->task_handle!=handle) wdttask=wdttask->next; + if (!wdttask->next) { + ESP_LOGE(TAG, "task_wdt_delete: Task never called task_wdt_feed!"); + return; + } + wdt_task_t *freeme=wdttask->next; + wdttask->next=wdttask->next->next; + free(freeme); + } +} + +void task_wdt_init() { + TIMERG0.wdt_wprotect=WDT_WRITE_KEY; + TIMERG0.wdt_config0.sys_reset_length=7; //3.2uS + TIMERG0.wdt_config0.cpu_reset_length=7; //3.2uS + TIMERG0.wdt_config0.level_int_en=1; + TIMERG0.wdt_config0.stg0=1; //1st stage timeout: interrupt + TIMERG0.wdt_config0.stg1=3; //2nd stage timeout: reset system + TIMERG0.wdt_config1.clk_prescale=80*500; //Prescaler: wdt counts in ticks of 0.5mS + TIMERG0.wdt_config2=CONFIG_TASK_WDT_TIMEOUT_S*2000; //Set timeout before interrupt + TIMERG0.wdt_config3=CONFIG_TASK_WDT_TIMEOUT_S*4000; //Set timeout before reset + TIMERG0.wdt_config0.en=1; + TIMERG0.wdt_feed=1; + TIMERG0.wdt_wprotect=0; + ESP_INTR_DISABLE(ETS_T0_WDT_INUM); + intr_matrix_set(xPortGetCoreID(), ETS_TG1_WDT_LEVEL_INTR_SOURCE, ETS_T0_WDT_INUM); + xt_set_interrupt_handler(ETS_T0_WDT_INUM, task_wdt_isr, NULL); + ESP_INTR_ENABLE(ETS_T0_WDT_INUM); +} + + +#if CONFIG_TASK_WDT_CHECK_IDLE_TASK +void vApplicationIdleHook(void) { + task_wdt_feed(); +} +#endif + +#endif \ No newline at end of file diff --git a/components/freertos/include/freertos/FreeRTOSConfig.h b/components/freertos/include/freertos/FreeRTOSConfig.h index d1958e7701..a5483d6bbd 100644 --- a/components/freertos/include/freertos/FreeRTOSConfig.h +++ b/components/freertos/include/freertos/FreeRTOSConfig.h @@ -152,9 +152,9 @@ *----------------------------------------------------------*/ #define configUSE_PREEMPTION 1 -#define configUSE_IDLE_HOOK 0 +#define configUSE_IDLE_HOOK ( CONFIG_TASK_WDT_CHECK_IDLE_TASK ) -#define configUSE_TICK_HOOK 0 +#define configUSE_TICK_HOOK ( CONFIG_INT_WDT ) #define configTICK_RATE_HZ ( CONFIG_FREERTOS_HZ ) From 2b8a49365954b1ecd74ccaef4523b0543ee73ff6 Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Fri, 21 Oct 2016 18:01:08 +0800 Subject: [PATCH 120/343] Add licenses to Trax files --- components/xtensa-debug-module/eri.c | 13 +++++++++++++ components/xtensa-debug-module/trax.c | 14 ++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/components/xtensa-debug-module/eri.c b/components/xtensa-debug-module/eri.c index e2c7e41eb3..fc96b531fe 100644 --- a/components/xtensa-debug-module/eri.c +++ b/components/xtensa-debug-module/eri.c @@ -1,3 +1,16 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. #include #include "eri.h" diff --git a/components/xtensa-debug-module/trax.c b/components/xtensa-debug-module/trax.c index d216a3df9a..5174e44776 100644 --- a/components/xtensa-debug-module/trax.c +++ b/components/xtensa-debug-module/trax.c @@ -1,3 +1,17 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #include #include "soc/dport_reg.h" #include "sdkconfig.h" From ae5c5630803c67964540d3943b661ea1a2c822cd Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Fri, 21 Oct 2016 19:30:29 +0800 Subject: [PATCH 121/343] Brownout works (in as far brownout can work...), int wdt works. --- components/esp32/Kconfig | 9 +++------ components/esp32/brownout.c | 12 +++--------- components/esp32/cpu_start.c | 6 ++++-- components/esp32/int_wdt.c | 9 +++------ components/freertos/xtensa_vectors.S | 13 ++++++++++--- 5 files changed, 23 insertions(+), 26 deletions(-) diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig index c40d7930d0..a2faa926a8 100644 --- a/components/esp32/Kconfig +++ b/components/esp32/Kconfig @@ -151,16 +151,13 @@ config INT_WDT interrupt handler did not return. It will try to invoke the panic handler first and failing that reset the SoC. -config INT_WDT_TIMEOUT_MS_MIN - default (2000/CONFIG_FREERTOS_HZ) - config INT_WDT_TIMEOUT_MS int "Interrupt watchdog timeout (ms)" depends on INT_WDT - default 100 - range INT_WDT_TIMEOUT_MS_MIN 10000 + default 10 + range INT_WDT_TIMEOUT_MIN 10000 help - The timeout of the watchdog, in miliseconds. + The timeout of the watchdog, in miliseconds. Make this higher than the FreeRTOS tick rate. config TASK_WDT bool "Task watchdog" diff --git a/components/esp32/brownout.c b/components/esp32/brownout.c index 173d63a0c1..8e8805b8e5 100644 --- a/components/esp32/brownout.c +++ b/components/esp32/brownout.c @@ -23,15 +23,9 @@ void esp_brownout_init() { -// WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, -// RTC_CNTL_BROWN_OUT_ENA | (CONFIG_BROWNOUT_DET_LVL << RTC_CNTL_DBROWN_OUT_THRES_S) | -// RTC_CNTL_BROWN_OUT_RST_ENA | (((CONFIG_BROWNOUT_DET_RESETDELAY*150)/1000) << RTC_CNTL_BROWN_OUT_RST_WAIT_S) | -// RTC_CNTL_BROWN_OUT_PD_RF_ENA|RTC_CNTL_BROWN_OUT_CLOSE_FLASH_ENA); - - WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, - RTC_CNTL_BROWN_OUT_ENA | (4 << RTC_CNTL_DBROWN_OUT_THRES_S) | - RTC_CNTL_BROWN_OUT_RST_ENA | (0x3FF << RTC_CNTL_BROWN_OUT_RST_WAIT_S) | - RTC_CNTL_BROWN_OUT_PD_RF_ENA | RTC_CNTL_BROWN_OUT_CLOSE_FLASH_ENA); + RTC_CNTL_BROWN_OUT_ENA | (CONFIG_BROWNOUT_DET_LVL << RTC_CNTL_DBROWN_OUT_THRES_S) | + RTC_CNTL_BROWN_OUT_RST_ENA | (((CONFIG_BROWNOUT_DET_RESETDELAY*150)/1000) << RTC_CNTL_BROWN_OUT_RST_WAIT_S) | + RTC_CNTL_BROWN_OUT_PD_RF_ENA|RTC_CNTL_BROWN_OUT_CLOSE_FLASH_ENA); } \ No newline at end of file diff --git a/components/esp32/cpu_start.c b/components/esp32/cpu_start.c index 6a482c539c..51f6cebb2b 100644 --- a/components/esp32/cpu_start.c +++ b/components/esp32/cpu_start.c @@ -44,6 +44,8 @@ #include "esp_log.h" #include "esp_brownout.h" +#include "esp_int_wdt.h" +#include "esp_task_wdt.h" void start_cpu0(void) __attribute__((weak, alias("start_cpu0_default"))); void start_cpu0_default(void) IRAM_ATTR; @@ -143,10 +145,10 @@ void start_cpu0_default(void) esp_brownout_init(); #endif #if CONFIG_INT_WDT - int_wdt_init() + int_wdt_init(); #endif #if CONFIG_TASK_WDT - task_wdt_init() + task_wdt_init(); #endif xTaskCreatePinnedToCore(&main_task, "main", diff --git a/components/esp32/int_wdt.c b/components/esp32/int_wdt.c index 392ed6b6a1..2b4d9e0841 100644 --- a/components/esp32/int_wdt.c +++ b/components/esp32/int_wdt.c @@ -47,11 +47,6 @@ This uses the TIMERG1 WDT. #define WDT_WRITE_KEY 0x50D83AA1 -static void esp_int_wdt_isr(void *arg) { - abort(); -} - - void int_wdt_init() { TIMERG1.wdt_wprotect=WDT_WRITE_KEY; TIMERG1.wdt_config0.sys_reset_length=7; //3.2uS @@ -67,7 +62,9 @@ void int_wdt_init() { TIMERG1.wdt_wprotect=0; ESP_INTR_DISABLE(WDT_INT_NUM); intr_matrix_set(xPortGetCoreID(), ETS_TG1_WDT_LEVEL_INTR_SOURCE, WDT_INT_NUM); - xt_set_interrupt_handler(WDT_INT_NUM, int_wdt_isr, NULL); + //We do not register a handler for the interrupt because it is interrupt level 4 which + //is not servicable from C. Instead, xtensa_vectors.S has a call to the panic handler for + //this interrupt. ESP_INTR_ENABLE(WDT_INT_NUM); } diff --git a/components/freertos/xtensa_vectors.S b/components/freertos/xtensa_vectors.S index 7c2fc29607..89a47f7415 100644 --- a/components/freertos/xtensa_vectors.S +++ b/components/freertos/xtensa_vectors.S @@ -339,12 +339,12 @@ _xt_panic: rsr a0, EXCSAVE_1 /* save interruptee's a0 */ s32i a0, sp, XT_STK_A0 - /* Set up PS for C, reenable hi-pri interrupts, and clear EXCM. */ - movi a0, PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM | PS_WOE + /* Set up PS for C, disable all interrupts, and clear EXCM. */ + movi a0, PS_INTLEVEL(7) | PS_UM | PS_WOE wsr a0, PS //Call panic handler - mov a2,sp + mov a6,sp call4 panicHandler 1: j 1b /* loop infinitely */ @@ -1607,6 +1607,13 @@ _xt_highint4: ADD HIGH PRIORITY LEVEL 4 INTERRUPT HANDLER CODE HERE. */ + /* On the ESP32, this level is used for the INT_WDT handler. If that triggers, the program is stuck with interrupts + off and the CPU should panic. */ + rsr a0, EXCSAVE_4 + wsr a0, EXCSAVE_1 /* panic handler reads this register */ + call0 _xt_panic + + .align 4 .L_xt_highint4_exit: rsr a0, EXCSAVE_4 /* restore a0 */ From 60fb9a8c813778ab2b3b149d84eb888d046992e2 Mon Sep 17 00:00:00 2001 From: liuzhifu Date: Sun, 23 Oct 2016 00:49:41 +0800 Subject: [PATCH 122/343] components/lwip - add per socket tcp window Add code to support per socket tcp window and tcp send buffer size configuration. --- components/lwip/api/api_msg.c | 12 +++++----- components/lwip/api/lwip_debug.c | 3 +++ components/lwip/api/sockets.c | 20 ++++++++++++++++ components/lwip/core/init.c | 16 ++++++------- components/lwip/core/tcp.c | 23 +++++++++++-------- components/lwip/core/tcp_in.c | 6 ++--- components/lwip/core/tcp_out.c | 21 ++++++++++++----- components/lwip/include/lwip/lwip/opt.h | 12 +++++----- .../lwip/include/lwip/lwip/priv/tcp_priv.h | 2 +- components/lwip/include/lwip/lwip/sockets.h | 6 ++++- components/lwip/include/lwip/lwip/tcp.h | 13 +++++++++-- components/lwip/include/lwip/port/lwipopts.h | 21 +++++++++-------- 12 files changed, 103 insertions(+), 52 deletions(-) diff --git a/components/lwip/api/api_msg.c b/components/lwip/api/api_msg.c index e8e967ef40..9cac2e0e90 100755 --- a/components/lwip/api/api_msg.c +++ b/components/lwip/api/api_msg.c @@ -314,8 +314,8 @@ poll_tcp(void *arg, struct tcp_pcb *pcb) if (conn->flags & NETCONN_FLAG_CHECK_WRITESPACE) { /* If the queued byte- or pbuf-count drops below the configured low-water limit, let select mark this pcb as writable again. */ - if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT) && - (tcp_sndqueuelen(conn->pcb.tcp) < TCP_SNDQUEUELOWAT)) { + if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT(conn->pcb.tcp)) && + (tcp_sndqueuelen(conn->pcb.tcp) < TCP_SNDQUEUELOWAT(conn->pcb.tcp))) { conn->flags &= ~NETCONN_FLAG_CHECK_WRITESPACE; API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); } @@ -348,8 +348,8 @@ sent_tcp(void *arg, struct tcp_pcb *pcb, u16_t len) /* If the queued byte- or pbuf-count drops below the configured low-water limit, let select mark this pcb as writable again. */ - if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT) && - (tcp_sndqueuelen(conn->pcb.tcp) < TCP_SNDQUEUELOWAT)) { + if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT(conn->pcb.tcp) && + (tcp_sndqueuelen(conn->pcb.tcp) < TCP_SNDQUEUELOWAT(conn->pcb.tcp)))) { conn->flags &= ~NETCONN_FLAG_CHECK_WRITESPACE; API_EVENT(conn, NETCONN_EVT_SENDPLUS, len); } @@ -1540,8 +1540,8 @@ err_mem: and let poll_tcp check writable space to mark the pcb writable again */ API_EVENT(conn, NETCONN_EVT_SENDMINUS, len); conn->flags |= NETCONN_FLAG_CHECK_WRITESPACE; - } else if ((tcp_sndbuf(conn->pcb.tcp) <= TCP_SNDLOWAT) || - (tcp_sndqueuelen(conn->pcb.tcp) >= TCP_SNDQUEUELOWAT)) { + } else if ((tcp_sndbuf(conn->pcb.tcp) <= TCP_SNDLOWAT(conn->pcb.tcp)) || + (tcp_sndqueuelen(conn->pcb.tcp) >= TCP_SNDQUEUELOWAT(conn->pcb.tcp))) { /* The queued byte- or pbuf-count exceeds the configured low-water limit, let select mark this pcb as non-writable. */ API_EVENT(conn, NETCONN_EVT_SENDMINUS, len); diff --git a/components/lwip/api/lwip_debug.c b/components/lwip/api/lwip_debug.c index 1e5fed40d3..d73a23e1a3 100644 --- a/components/lwip/api/lwip_debug.c +++ b/components/lwip/api/lwip_debug.c @@ -48,6 +48,9 @@ static void dbg_lwip_tcp_pcb_one_show(struct tcp_pcb* pcb) printf("rttest=%d rtseq=%d sa=%d sv=%d\n", pcb->rttest, pcb->rtseq, pcb->sa, pcb->sv); printf("rto=%d nrtx=%d\n", pcb->rto, pcb->nrtx); printf("dupacks=%d lastack=%d\n", pcb->dupacks, pcb->lastack); +#if ESP_PER_SOC_TCP_WND + printf("per_soc_window=%d per_soc_snd_buf=%d\n", pcb->per_soc_tcp_wnd, pcb->per_soc_tcp_snd_buf); +#endif printf("cwnd=%d ssthreash=%d\n", pcb->cwnd, pcb->ssthresh); printf("snd_next=%d snd_wl1=%d snd_wl2=%d\n", pcb->snd_nxt, pcb->snd_wl1, pcb->snd_wl2); printf("snd_lbb=%d snd_wnd=%d snd_wnd_max=%d\n", pcb->snd_lbb, pcb->snd_wnd, pcb->snd_wnd_max); diff --git a/components/lwip/api/sockets.c b/components/lwip/api/sockets.c index 350847b57c..15226be203 100755 --- a/components/lwip/api/sockets.c +++ b/components/lwip/api/sockets.c @@ -2395,6 +2395,16 @@ lwip_getsockopt_impl(int s, int level, int optname, void *optval, socklen_t *opt s, *(int *)optval)); break; #endif /* LWIP_TCP_KEEPALIVE */ + +#if ESP_PER_SOC_TCP_WND + case TCP_WINDOW: + *(int*)optval = (int)sock->conn->pcb.tcp->per_soc_tcp_wnd; + break; + case TCP_SNDBUF: + *(int*)optval = (int)sock->conn->pcb.tcp->per_soc_tcp_snd_buf; + break; +#endif + default: LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n", s, optname)); @@ -2792,6 +2802,16 @@ lwip_setsockopt_impl(int s, int level, int optname, const void *optval, socklen_ s, sock->conn->pcb.tcp->keep_cnt)); break; #endif /* LWIP_TCP_KEEPALIVE */ + +#if ESP_PER_SOC_TCP_WND + case TCP_WINDOW: + sock->conn->pcb.tcp->per_soc_tcp_wnd = ((u32_t)(*(const int*)optval)) * TCP_MSS; + break; + case TCP_SNDBUF: + sock->conn->pcb.tcp->per_soc_tcp_snd_buf = ((u32_t)(*(const int*)optval)) * TCP_MSS; + break; +#endif + default: LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n", s, optname)); diff --git a/components/lwip/core/init.c b/components/lwip/core/init.c index 2a410d0e46..f974aedaf8 100755 --- a/components/lwip/core/init.c +++ b/components/lwip/core/init.c @@ -135,13 +135,15 @@ //#endif #else /* LWIP_WND_SCALE */ -#ifndef LWIP_ESP8266 +#if (ESP_PER_SOC_TCP_WND == 0) #if (LWIP_TCP && (TCP_WND > 0xffff)) #error "If you want to use TCP, TCP_WND must fit in an u16_t, so, you have to reduce it in your lwipopts.h (or enable window scaling)" #endif #endif #endif /* LWIP_WND_SCALE */ + +#if (ESP_PER_SOC_TCP_WND == 0) #if (LWIP_TCP && (TCP_SND_QUEUELEN > 0xffff)) #error "If you want to use TCP, TCP_SND_QUEUELEN must fit in an u16_t, so, you have to reduce it in your lwipopts.h" #endif @@ -149,7 +151,6 @@ #error "TCP_SND_QUEUELEN must be at least 2 for no-copy TCP writes to work" #endif -#ifndef LWIP_ESP8266 #if (LWIP_TCP && ((TCP_MAXRTX > 12) || (TCP_SYNMAXRTX > 12))) #error "If you want to use TCP, TCP_MAXRTX and TCP_SYNMAXRTX must less or equal to 12 (due to tcp_backoff table), so, you have to reduce them in your lwipopts.h" #endif @@ -289,6 +290,8 @@ #if !MEMP_MEM_MALLOC && (MEMP_NUM_TCP_SEG < TCP_SND_QUEUELEN) #error "lwip_sanity_check: WARNING: MEMP_NUM_TCP_SEG should be at least as big as TCP_SND_QUEUELEN. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." #endif + +#if (ESP_PER_SOC_TCP_WND == 0) #if TCP_SND_BUF < (2 * TCP_MSS) #error "lwip_sanity_check: WARNING: TCP_SND_BUF must be at least as much as (2 * TCP_MSS) for things to work smoothly. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." #endif @@ -304,6 +307,8 @@ #if TCP_SNDQUEUELOWAT >= TCP_SND_QUEUELEN #error "lwip_sanity_check: WARNING: TCP_SNDQUEUELOWAT must be less than TCP_SND_QUEUELEN. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." #endif +#endif + #if !MEMP_MEM_MALLOC && (PBUF_POOL_BUFSIZE <= (PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN)) #error "lwip_sanity_check: WARNING: PBUF_POOL_BUFSIZE does not provide enough space for protocol headers. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." #endif @@ -328,13 +333,6 @@ void lwip_init(void) { -#ifdef LWIP_ESP8266 -// MEMP_NUM_TCP_PCB = 5; -// TCP_WND = (4 * TCP_MSS); -// TCP_MAXRTX = 12; -// TCP_SYNMAXRTX = 6; -#endif - /* Modules initialization */ stats_init(); #if !NO_SYS diff --git a/components/lwip/core/tcp.c b/components/lwip/core/tcp.c index e8fda52c8d..e7ea561031 100755 --- a/components/lwip/core/tcp.c +++ b/components/lwip/core/tcp.c @@ -638,7 +638,7 @@ u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb) { u32_t new_right_edge = pcb->rcv_nxt + pcb->rcv_wnd; - if (TCP_SEQ_GEQ(new_right_edge, pcb->rcv_ann_right_edge + LWIP_MIN((TCP_WND / 2), pcb->mss))) { + if (TCP_SEQ_GEQ(new_right_edge, pcb->rcv_ann_right_edge + LWIP_MIN((TCP_WND(pcb) / 2), pcb->mss))) { /* we can advertise more window */ pcb->rcv_ann_wnd = pcb->rcv_wnd; return new_right_edge - pcb->rcv_ann_right_edge; @@ -694,10 +694,10 @@ tcp_recved(struct tcp_pcb *pcb, u16_t len) wnd_inflation = tcp_update_rcv_ann_wnd(pcb); /* If the change in the right edge of window is significant (default - * watermark is TCP_WND/4), then send an explicit update now. + * watermark is TCP_WND(pcb)/4), then send an explicit update now. * Otherwise wait for a packet to be sent in the normal course of * events (or more window to be available later) */ - if (wnd_inflation >= TCP_WND_UPDATE_THRESHOLD) { + if (wnd_inflation >= TCP_WND_UPDATE_THRESHOLD(pcb)) { tcp_ack_now(pcb); tcp_output(pcb); } @@ -827,9 +827,9 @@ tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port, pcb->snd_lbb = iss - 1; /* Start with a window that does not need scaling. When window scaling is enabled and used, the window is enlarged when both sides agree on scaling. */ - pcb->rcv_wnd = pcb->rcv_ann_wnd = TCPWND_MIN16(TCP_WND); + pcb->rcv_wnd = pcb->rcv_ann_wnd = TCPWND_MIN16(TCP_WND(pcb)); pcb->rcv_ann_right_edge = pcb->rcv_nxt; - pcb->snd_wnd = TCP_WND; + pcb->snd_wnd = TCP_WND(pcb); /* As initial send MSS, we use TCP_MSS but limit it to 536. The send MSS is updated when an MSS option is received. */ pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS; @@ -837,7 +837,7 @@ tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port, pcb->mss = tcp_eff_send_mss(pcb->mss, &pcb->local_ip, &pcb->remote_ip); #endif /* TCP_CALCULATE_EFF_SEND_MSS */ pcb->cwnd = 1; - pcb->ssthresh = TCP_WND; + pcb->ssthresh = TCP_WND(pcb); #if LWIP_CALLBACK_API pcb->connected = connected; #else /* LWIP_CALLBACK_API */ @@ -1581,11 +1581,11 @@ tcp_alloc(u8_t prio) if (pcb != NULL) { memset(pcb, 0, sizeof(struct tcp_pcb)); pcb->prio = prio; - pcb->snd_buf = TCP_SND_BUF; + pcb->snd_buf = TCP_SND_BUF_DEFAULT; pcb->snd_queuelen = 0; /* Start with a window that does not need scaling. When window scaling is enabled and used, the window is enlarged when both sides agree on scaling. */ - pcb->rcv_wnd = pcb->rcv_ann_wnd = TCPWND_MIN16(TCP_WND); + pcb->rcv_wnd = pcb->rcv_ann_wnd = TCPWND_MIN16(TCP_WND(pcb)); #if LWIP_WND_SCALE /* snd_scale and rcv_scale are zero unless both sides agree to use scaling */ pcb->snd_scale = 0; @@ -1608,7 +1608,6 @@ tcp_alloc(u8_t prio) pcb->snd_lbb = iss; pcb->tmr = tcp_ticks; pcb->last_timer = tcp_timer_ctr; - pcb->polltmr = 0; #if LWIP_CALLBACK_API @@ -1624,7 +1623,13 @@ tcp_alloc(u8_t prio) #endif /* LWIP_TCP_KEEPALIVE */ pcb->keep_cnt_sent = 0; + +#if ESP_PER_SOC_TCP_WND + pcb->per_soc_tcp_wnd = TCP_WND_DEFAULT; + pcb->per_soc_tcp_snd_buf = TCP_SND_BUF_DEFAULT; +#endif } + return pcb; } diff --git a/components/lwip/core/tcp_in.c b/components/lwip/core/tcp_in.c index 25d7403851..90ebf17232 100755 --- a/components/lwip/core/tcp_in.c +++ b/components/lwip/core/tcp_in.c @@ -1745,9 +1745,9 @@ tcp_parseopt(struct tcp_pcb *pcb) pcb->rcv_scale = TCP_RCV_SCALE; pcb->flags |= TF_WND_SCALE; /* window scaling is enabled, we can use the full receive window */ - LWIP_ASSERT("window not at default value", pcb->rcv_wnd == TCPWND_MIN16(TCP_WND)); - LWIP_ASSERT("window not at default value", pcb->rcv_ann_wnd == TCPWND_MIN16(TCP_WND)); - pcb->rcv_wnd = pcb->rcv_ann_wnd = TCP_WND; + LWIP_ASSERT("window not at default value", pcb->rcv_wnd == TCPWND_MIN16(TCP_WND(pcb))); + LWIP_ASSERT("window not at default value", pcb->rcv_ann_wnd == TCPWND_MIN16(TCP_WND(pcb))); + pcb->rcv_wnd = pcb->rcv_ann_wnd = TCP_WND(pcb); } break; #endif diff --git a/components/lwip/core/tcp_out.c b/components/lwip/core/tcp_out.c index aac02e4ebe..5f10befae8 100755 --- a/components/lwip/core/tcp_out.c +++ b/components/lwip/core/tcp_out.c @@ -336,9 +336,9 @@ tcp_write_checks(struct tcp_pcb *pcb, u16_t len) /* If total number of pbufs on the unsent/unacked queues exceeds the * configured maximum, return an error */ /* check for configured max queuelen and possible overflow */ - if ((pcb->snd_queuelen >= TCP_SND_QUEUELEN) || (pcb->snd_queuelen > TCP_SNDQUEUELEN_OVERFLOW)) { + if ((pcb->snd_queuelen >= TCP_SND_QUEUELEN(pcb)) || (pcb->snd_queuelen > TCP_SNDQUEUELEN_OVERFLOW)) { LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("tcp_write: too long queue %"U16_F" (max %"U16_F")\n", - pcb->snd_queuelen, TCP_SND_QUEUELEN)); + pcb->snd_queuelen, TCP_SND_QUEUELEN(pcb))); TCP_STATS_INC(tcp.memerr); pcb->flags |= TF_NAGLEMEMERR; return ERR_MEM; @@ -606,9 +606,9 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) /* Now that there are more segments queued, we check again if the * length of the queue exceeds the configured maximum or * overflows. */ - if ((queuelen > TCP_SND_QUEUELEN) || (queuelen > TCP_SNDQUEUELEN_OVERFLOW)) { + if ((queuelen > TCP_SND_QUEUELEN(pcb)) || (queuelen > TCP_SNDQUEUELEN_OVERFLOW)) { LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_write: queue too long %"U16_F" (%d)\n", - queuelen, (int)TCP_SND_QUEUELEN)); + queuelen, (int)TCP_SND_QUEUELEN(pcb))); pbuf_free(p); goto memerr; } @@ -766,10 +766,10 @@ tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags) (flags & (TCP_SYN | TCP_FIN)) != 0); /* check for configured max queuelen and possible overflow (FIN flag should always come through!) */ - if (((pcb->snd_queuelen >= TCP_SND_QUEUELEN) || (pcb->snd_queuelen > TCP_SNDQUEUELEN_OVERFLOW)) && + if (((pcb->snd_queuelen >= TCP_SND_QUEUELEN(pcb)) || (pcb->snd_queuelen > TCP_SNDQUEUELEN_OVERFLOW)) && ((flags & TCP_FIN) == 0)) { LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("tcp_enqueue_flags: too long queue %"U16_F" (max %"U16_F")\n", - pcb->snd_queuelen, TCP_SND_QUEUELEN)); + pcb->snd_queuelen, TCP_SND_QUEUELEN(pcb))); TCP_STATS_INC(tcp.memerr); pcb->flags |= TF_NAGLEMEMERR; return ERR_MEM; @@ -1301,6 +1301,7 @@ tcp_rst(u32_t seqno, u32_t ackno, struct pbuf *p; struct tcp_hdr *tcphdr; struct netif *netif; + p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM); if (p == NULL) { LWIP_DEBUGF(TCP_DEBUG, ("tcp_rst: could not allocate memory for pbuf\n")); @@ -1315,10 +1316,18 @@ tcp_rst(u32_t seqno, u32_t ackno, tcphdr->seqno = htonl(seqno); tcphdr->ackno = htonl(ackno); TCPH_HDRLEN_FLAGS_SET(tcphdr, TCP_HLEN/4, TCP_RST | TCP_ACK); +#if ESP_PER_SOC_TCP_WND +#if LWIP_WND_SCALE + tcphdr->wnd = PP_HTONS(((TCP_WND_DEFAULT >> TCP_RCV_SCALE) & 0xFFFF)); +#else + tcphdr->wnd = PP_HTONS(TCP_WND_DEFAULT); +#endif +#else #if LWIP_WND_SCALE tcphdr->wnd = PP_HTONS(((TCP_WND >> TCP_RCV_SCALE) & 0xFFFF)); #else tcphdr->wnd = PP_HTONS(TCP_WND); +#endif #endif tcphdr->chksum = 0; tcphdr->urgp = 0; diff --git a/components/lwip/include/lwip/lwip/opt.h b/components/lwip/include/lwip/lwip/opt.h index 76fff88052..c286712e0d 100755 --- a/components/lwip/include/lwip/lwip/opt.h +++ b/components/lwip/include/lwip/lwip/opt.h @@ -986,7 +986,7 @@ * (2 * TCP_MSS) for things to work well */ #ifndef TCP_WND -#define TCP_WND (4 * TCP_MSS) +#define TCP_WND(pcb) (4 * TCP_MSS) #endif /** @@ -1040,7 +1040,7 @@ * To achieve good performance, this should be at least 2 * TCP_MSS. */ #ifndef TCP_SND_BUF -#define TCP_SND_BUF (2 * TCP_MSS) +#define TCP_SND_BUF(pcb) (2 * TCP_MSS) #endif /** @@ -1048,7 +1048,7 @@ * as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. */ #ifndef TCP_SND_QUEUELEN -#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS)) +#define TCP_SND_QUEUELEN(pcb) ((4 * (TCP_SND_BUF((pcb))) + (TCP_MSS - 1))/(TCP_MSS)) #endif /** @@ -1057,7 +1057,7 @@ * TCP snd_buf for select to return writable (combined with TCP_SNDQUEUELOWAT). */ #ifndef TCP_SNDLOWAT -#define TCP_SNDLOWAT LWIP_MIN(LWIP_MAX(((TCP_SND_BUF)/2), (2 * TCP_MSS) + 1), (TCP_SND_BUF) - 1) +#define TCP_SNDLOWAT(pcb) LWIP_MIN(LWIP_MAX(((TCP_SND_BUF((pcb)))/2), (2 * TCP_MSS) + 1), (TCP_SND_BUF((pcb))) - 1) #endif /** @@ -1066,7 +1066,7 @@ * this number, select returns writable (combined with TCP_SNDLOWAT). */ #ifndef TCP_SNDQUEUELOWAT -#define TCP_SNDQUEUELOWAT LWIP_MAX(((TCP_SND_QUEUELEN)/2), 5) +#define TCP_SNDQUEUELOWAT(pcb) LWIP_MAX(((TCP_SND_QUEUELEN((pcb)))/2), 5) #endif /** @@ -1134,7 +1134,7 @@ * explicit window update */ #ifndef TCP_WND_UPDATE_THRESHOLD -#define TCP_WND_UPDATE_THRESHOLD LWIP_MIN((TCP_WND / 4), (TCP_MSS * 4)) +#define TCP_WND_UPDATE_THRESHOLD(pcb) LWIP_MIN((TCP_WND((pcb)) / 4), (TCP_MSS * 4)) #endif /** diff --git a/components/lwip/include/lwip/lwip/priv/tcp_priv.h b/components/lwip/include/lwip/lwip/priv/tcp_priv.h index b5261b445c..0c498944b3 100755 --- a/components/lwip/include/lwip/lwip/priv/tcp_priv.h +++ b/components/lwip/include/lwip/lwip/priv/tcp_priv.h @@ -92,7 +92,7 @@ err_t tcp_process_refused_data(struct tcp_pcb *pcb); ((tpcb)->flags & (TF_NODELAY | TF_INFR)) || \ (((tpcb)->unsent != NULL) && (((tpcb)->unsent->next != NULL) || \ ((tpcb)->unsent->len >= (tpcb)->mss))) || \ - ((tcp_sndbuf(tpcb) == 0) || (tcp_sndqueuelen(tpcb) >= TCP_SND_QUEUELEN)) \ + ((tcp_sndbuf(tpcb) == 0) || (tcp_sndqueuelen(tpcb) >= TCP_SND_QUEUELEN(tpcb))) \ ) ? 1 : 0) #define tcp_output_nagle(tpcb) (tcp_do_output_nagle(tpcb) ? tcp_output(tpcb) : ERR_OK) diff --git a/components/lwip/include/lwip/lwip/sockets.h b/components/lwip/include/lwip/lwip/sockets.h index aafb3d5cf3..fc2b7e2d12 100755 --- a/components/lwip/include/lwip/lwip/sockets.h +++ b/components/lwip/include/lwip/lwip/sockets.h @@ -190,7 +190,6 @@ struct msghdr { #define SO_CONTIMEO 0x1009 /* Unimplemented: connect timeout */ #define SO_NO_CHECK 0x100a /* don't create UDP checksum */ - /* * Structure used for manipulating linger option. */ @@ -250,6 +249,11 @@ struct linger { #define TCP_KEEPIDLE 0x03 /* set pcb->keep_idle - Same as TCP_KEEPALIVE, but use seconds for get/setsockopt */ #define TCP_KEEPINTVL 0x04 /* set pcb->keep_intvl - Use seconds for get/setsockopt */ #define TCP_KEEPCNT 0x05 /* set pcb->keep_cnt - Use number of probes sent for get/setsockopt */ +#if ESP_PER_SOC_TCP_WND +#define TCP_WINDOW 0x06 /* set pcb->per_soc_tcp_wnd */ +#define TCP_SNDBUF 0x07 /* set pcb->per_soc_tcp_snd_buf */ +#endif + #endif /* LWIP_TCP */ #if LWIP_IPV6 diff --git a/components/lwip/include/lwip/lwip/tcp.h b/components/lwip/include/lwip/lwip/tcp.h index d52040f99c..6b8c4b6c48 100755 --- a/components/lwip/include/lwip/lwip/tcp.h +++ b/components/lwip/include/lwip/lwip/tcp.h @@ -129,14 +129,14 @@ typedef err_t (*tcp_connected_fn)(void *arg, struct tcp_pcb *tpcb, err_t err); #define RCV_WND_SCALE(pcb, wnd) (((wnd) >> (pcb)->rcv_scale)) #define SND_WND_SCALE(pcb, wnd) (((wnd) << (pcb)->snd_scale)) #define TCPWND16(x) ((u16_t)LWIP_MIN((x), 0xFFFF)) -#define TCP_WND_MAX(pcb) ((tcpwnd_size_t)(((pcb)->flags & TF_WND_SCALE) ? TCP_WND : TCPWND16(TCP_WND))) +#define TCP_WND_MAX(pcb) ((tcpwnd_size_t)(((pcb)->flags & TF_WND_SCALE) ? TCP_WND(pcb) : TCPWND16(TCP_WND(pcb)))) typedef u32_t tcpwnd_size_t; typedef u16_t tcpflags_t; #else #define RCV_WND_SCALE(pcb, wnd) (wnd) #define SND_WND_SCALE(pcb, wnd) (wnd) #define TCPWND16(x) (x) -#define TCP_WND_MAX(pcb) TCP_WND +#define TCP_WND_MAX(pcb) TCP_WND(pcb) typedef u16_t tcpwnd_size_t; typedef u8_t tcpflags_t; #endif @@ -236,6 +236,11 @@ struct tcp_pcb { u8_t dupacks; u32_t lastack; /* Highest acknowledged seqno. */ +#if ESP_PER_SOC_TCP_WND + tcpwnd_size_t per_soc_tcp_wnd; /* per tcp socket tcp window size */ + tcpwnd_size_t per_soc_tcp_snd_buf; /* per tcp socket tcp send buffer size */ +#endif + /* congestion avoidance/control variables */ tcpwnd_size_t cwnd; tcpwnd_size_t ssthresh; @@ -402,6 +407,10 @@ const char* tcp_debug_state_str(enum tcp_state s); /* for compatibility with older implementation */ #define tcp_new_ip6() tcp_new_ip_type(IPADDR_TYPE_V6) +#if ESP_PER_SOC_TCP_WND +#define PER_SOC_WND(pcb) (pcb->per_soc_wnd) +#endif + #ifdef __cplusplus } #endif diff --git a/components/lwip/include/lwip/port/lwipopts.h b/components/lwip/include/lwip/port/lwipopts.h index 2c24b2be92..5667e2d20b 100755 --- a/components/lwip/include/lwip/port/lwipopts.h +++ b/components/lwip/include/lwip/port/lwipopts.h @@ -225,18 +225,21 @@ extern unsigned long os_random(void); * TCP_WND: The size of a TCP window. This must be at least * (2 * TCP_MSS) for things to work well */ -#define PERF 1 + +#define ESP_PER_SOC_TCP_WND 1 +#if ESP_PER_SOC_TCP_WND +#define TCP_WND_DEFAULT (4*TCP_MSS) +#define TCP_SND_BUF_DEFAULT (2*TCP_MSS) + +#define TCP_WND(pcb) (pcb->per_soc_tcp_wnd) +#define TCP_SND_BUF(pcb) (pcb->per_soc_tcp_snd_buf) +#else #ifdef PERF extern unsigned char misc_prof_get_tcpw(void); extern unsigned char misc_prof_get_tcp_snd_buf(void); -#define TCP_WND (misc_prof_get_tcpw()*TCP_MSS) -#define TCP_SND_BUF (misc_prof_get_tcp_snd_buf()*TCP_MSS) - -#else - -#define TCP_WND (4 * TCP_MSS) -#define TCP_SND_BUF (2 * TCP_MSS) - +#define TCP_WND(pcb) (misc_prof_get_tcpw()*TCP_MSS) +#define TCP_SND_BUF(pcb) (misc_prof_get_tcp_snd_buf()*TCP_MSS) +#endif #endif From 288f4f63f0a108003e29c3a041b86de3bb64976a Mon Sep 17 00:00:00 2001 From: Wangjialin Date: Mon, 24 Oct 2016 09:17:10 +0800 Subject: [PATCH 123/343] Add UART driver 1. add uart.h and uart.c 2. add ESP_ERR_TIMEOUT in esp_err.h 3. add UART AHB FIFO address in uart_reg.h 4. modify xRingbufferSendFromISR return value in ringbuffer.c 5. add #include "soc/gpio_sig_map.h" in gpio.h --- components/driver/include/driver/gpio.h | 1 + components/driver/include/driver/uart.h | 688 +++++++++++++++++ components/driver/uart.c | 938 ++++++++++++++++++++++++ components/esp32/include/esp_err.h | 1 + components/esp32/include/soc/uart_reg.h | 4 +- components/freertos/ringbuf.c | 3 +- 6 files changed, 1632 insertions(+), 3 deletions(-) create mode 100644 components/driver/include/driver/uart.h create mode 100644 components/driver/uart.c diff --git a/components/driver/include/driver/gpio.h b/components/driver/include/driver/gpio.h index 9b47c88e69..c821b640eb 100644 --- a/components/driver/include/driver/gpio.h +++ b/components/driver/include/driver/gpio.h @@ -20,6 +20,7 @@ #include "soc/gpio_struct.h" #include "soc/rtc_io_reg.h" #include "soc/io_mux_reg.h" +#include "soc/gpio_sig_map.h" #include "rom/gpio.h" #include "esp_attr.h" diff --git a/components/driver/include/driver/uart.h b/components/driver/include/driver/uart.h new file mode 100644 index 0000000000..cd0725d2ce --- /dev/null +++ b/components/driver/include/driver/uart.h @@ -0,0 +1,688 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef _DRIVER_UART_H_ +#define _DRIVER_UART_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include "soc/uart_reg.h" +#include "soc/uart_struct.h" +#include "esp_err.h" +#include "driver/periph_ctrl.h" +#include + +extern const char* UART_TAG; +#define UART_FIFO_LEN (128) //Do Not Change it +#define UART_INTR_MASK 0x1ff +#define UART_LINE_INV_MASK (0x3f << 19) + +typedef enum { + UART_DATA_5_BITS = 0x0, //word length: 5bits + UART_DATA_6_BITS = 0x1, //word length: 6bits + UART_DATA_7_BITS = 0x2, //word length: 7bits + UART_DATA_8_BITS = 0x3, //word length: 8bits + UART_DATA_MAX_BITS = 0X4, +} uart_word_length_t; + +typedef enum { + UART_STOP_BITS_1 = 0x1, //stop bit: 1bit + UART_STOP_BITS_1_5 = 0x2, //stop bit: 1.5bits + UART_STOP_BITS_2 = 0x3, //stop bit: 2bits + UART_STOP_BITS_MAX = 0x4, +} uart_stop_bits_t; + +typedef enum { + UART_NUM_0 = 0x0, //base address 0x3ff40000 + UART_NUM_1 = 0x1, //base address 0x3ff50000 + UART_NUM_2 = 0x2, //base address 0x3ff6E000 + UART_NUM_MAX, +} uart_port_t; + +typedef enum { + UART_PARITY_DISABLE = 0x0, //Disable UART parity + UART_PARITY_EVEN = 0x10, //Enable UART even parity + UART_PARITY_ODD = 0x11 //Enable UART odd parity +} uart_parity_t; + +typedef enum { + UART_BITRATE_300 = 300, + UART_BITRATE_600 = 600, + UART_BITRATE_1200 = 1200, + UART_BITRATE_2400 = 2400, + UART_BITRATE_4800 = 4800, + UART_BITRATE_9600 = 9600, + UART_BITRATE_19200 = 19200, + UART_BITRATE_38400 = 38400, + UART_BITRATE_57600 = 57600, + UART_BITRATE_74880 = 74880, + UART_BITRATE_115200 = 115200, + UART_BITRATE_230400 = 230400, + UART_BITRATE_460800 = 460800, + UART_BITRATE_921600 = 921600, + UART_BITRATE_1843200 = 1843200, + UART_BITRATE_3686400 = 3686400, + UART_BITRATE_MAX = 5000000, +} uart_baudrate_t; //you can set any rate you need in this range + +typedef enum { + UART_HW_FLOWCTRL_DISABLE = 0x0, //disable hardware flow control + UART_HW_FLOWCTRL_RTS = 0x1, //enable RX hardware flow control (rts) + UART_HW_FLOWCTRL_CTS = 0x2, //enable TX hardware flow control (cts) + UART_HW_FLOWCTRL_CTS_RTS = 0x3, //enable hardware flow control + UART_HW_FLOWCTRL_MAX = 0x4, +} uart_hw_flowcontrol_t; + +typedef enum { + UART_INVERSE_DISABLE = 0x0, //Disable UART wire output inverse + UART_INVERSE_RXD = (uint32_t)UART_RXD_INV_M, //UART RXD input inverse + UART_INVERSE_CTS = (uint32_t)UART_CTS_INV_M, //UART CTS input inverse + UART_INVERSE_TXD = (uint32_t)UART_TXD_INV_M, //UART TXD output inverse + UART_INVERSE_RTS = (uint32_t)UART_RTS_INV_M, //UART RTS output inverse +} uart_inverse_t; + +typedef struct { + uart_baudrate_t baud_rate; //UART baudrate + uart_word_length_t data_bits; //UART byte size + uart_parity_t parity; //UART parity mode + uart_stop_bits_t stop_bits; //UART stop bits + uart_hw_flowcontrol_t flow_ctrl; //UART hw flow control mode(cts/rts) + uint8_t rx_flow_ctrl_thresh ; //UART hw RTS threshold +} uart_config_t; + +typedef struct { + uint32_t intr_enable_mask; //UART interrupt enable mask, choose from UART_XXXX_INT_ENA_M under UART_INT_ENA_REG(i), connect with bit-or operator + uint8_t rx_timeout_thresh; //UART timeout interrupt threshold(unit: time of sending one byte) + uint8_t txfifo_empty_intr_thresh; //UART TX empty interrupt threshold. + uint8_t rxfifo_full_thresh; //UART RX full interrupt threshold. +} uart_intr_config_t; + + +typedef enum { + UART_DATA, + UART_BREAK, + UART_BUFFER_FULL, + UART_FIFO_OVF, + UART_FRAME_ERR, + UART_PARITY_ERR, + UART_EVENT_MAX, +} uart_event_type_t; + +typedef struct { + uart_event_type_t type; + union { + struct { + size_t size; + } data; + + }; +} uart_event_t; + + + +/** + * @brief Set UART data bits. + * + * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param uart_word_length_t data_bit : UART data bits + * + * @return ESP_OK : Success + * ESP_FAIL: Parameter error + */ +esp_err_t uart_set_word_length(uart_port_t uart_num, uart_word_length_t data_bit); + +/** + * @brief Get UART data bits. + * + * @param uart_port_t uart_no: UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * + * @return ESP_FAIL (-1) : Parameter error + * UART_DATA_5_BITS (0): UART word length: 5 bits. + * UART_DATA_6_BITS (1): UART word length: 6 bits. + * UART_DATA_7_BITS (2): UART word length: 7 bits. + * UART_DATA_8_BITS (3): UART word length: 8 bits. + */ +int uart_get_word_length(uart_port_t uart_num); + +/** + * @brief Set UART stop bits. + * + * @param uart_port_t uart_no: UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param uart_stop_bits_t bit_num : UART stop bits + * + * @return ESP_OK : Success + * ESP_FAIL: Fail + */ +esp_err_t uart_set_stop_bits(uart_port_t uart_no, uart_stop_bits_t bit_num); + +/** + * @brief Set UART stop bits. + * + * @param uart_port_t uart_no: UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * + * @return ESP_FAIL (-1): Parameter error + * UART_STOP_BITS_1 (1): 1 stop bit + * UART_STOP_BITS_1_5 (2): 1.5 stop bits + * UART_STOP_BITS_1 (3): 2 stop bits + */ +int uart_get_stop_bits(uart_port_t uart_num); + +/** + * @brief Set UART parity. + * + * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param uart_parity_t parity_mode : the enum of uart parity configuration + * + * @return null + */ +esp_err_t uart_set_parity(uart_port_t uart_no, uart_parity_t parity_mode); + +/** + * @brief Get UART parity mode. + * + * @param uart_port_t uart_no: UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * + * @return ESP_FAIL (-1): Parameter error + * UART_PARITY_ODD (0x11): Odd parity check mode + * UART_PARITY_EVEN (0x10): Even parity check mode + * UART_PARITY_DISABLE(0x0) : parity check disabled + * + */ +int uart_get_parity(uart_port_t uart_num); + +/** + * @brief Set UART baud rate. + * + * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param uint32_t baud_rate : UART baud-rate, we can choose one from uart_baudrate_t, or set a value. + * + * @return null + */ +esp_err_t uart_set_baudrate(uart_port_t uart_no, uint32_t baud_rate); + +/** + * @brief Get UART bit-rate. + * + * @param uart_port_t uart_no: UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * + * @return ESP_FAIL(-1): Parameter error + * Others (>0): UART baud-rate + * + */ +int uart_get_baudrate(uart_port_t uart_num); + +/** + * @brief Set UART line inverse mode + * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param uint32_t inverse_mask : Choose the wires that need to be inversed + * (Should be chosen from uart_inverse_t, combine with OR-OPERATION) + * + * @return ESP_OK : Success + * ESP_FAIL: Parameter error + */ +esp_err_t uart_set_line_inverse(uart_port_t uart_no, uint32_t inverse_mask) ; + + +/** + * @brief Set hardware flow control. + * + * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param uart_hw_flowcontrol_t flow_ctrl : Hardware flow control mode + * @param uint8_t rx_thresh : Threshold of Hardware RX flow control(0 ~ UART_FIFO_LEN) + * + * @return ESP_OK : Success + * ESP_FAIL: Parameter error + */ +esp_err_t uart_set_hw_flow_ctrl(uart_port_t uart_no, uart_hw_flowcontrol_t flow_ctrl, uint8_t rx_thresh); + +/** + * @brief Get hardware flow control mode + * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * + * @return ESP_FAIL (-1): Parameter error + * UART_HW_FLOWCTRL_DISABLE (0): UART hw flow control disabled + * UART_HW_FLOWCTRL_RTS (1): UART RX flow control enabled + * UART_HW_FLOWCTRL_CTS (2): UART TX flow control enabled + * UART_HW_FLOWCTRL_CTS_RTS (3): UART TX/RX flow control enabled + */ +int uart_get_hw_flow_ctrl(uart_port_t uart_num); + +/** + * @brief Clear UART interrupt status + * + * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param uint32_t clr_mask : Bit mask of the status that to be cleared. + * enable_mask should be chosen from the fields of register UART_INT_CLR_REG + * + * @return ESP_OK : Success + * ESP_FAIL: Parameter error + */ +esp_err_t uart_clear_intr_status(uart_port_t uart_num, uint32_t clr_mask); + +/** + * @brief Set UART interrupt enable + * + * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param uint32_t enable_mask : Bit mask of the enable bits. + * enable_mask should be chosen from the fields of register UART_INT_ENA_REG + * + * @return ESP_OK : Success + * ESP_FAIL: Parameter error + */ +esp_err_t uart_enable_intr_mask(uart_port_t uart_num, uint32_t enable_mask); + +/** + * @brief Clear UART interrupt enable bits + * + * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param uint32_t disable_mask : Bit mask of the disable bits. + * Disable_mask should be chosen from the fields of register UART_INT_ENA_REG + * + * @return ESP_OK : Success + * ESP_FAIL: Parameter error + */ +esp_err_t uart_disable_intr_mask(uart_port_t uart_num, uint32_t disable_mask); + + +/** + * @brief Enable UART RX interrupt(RX_FULL & RX_TIMEOUT INTERRUPT) + * + * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * + * @return ESP_OK : Success + * ESP_FAIL: Parameter error + */ +esp_err_t uart_enable_rx_intr(uart_port_t uart_num); + +/** + * @brief Disable UART RX interrupt(RX_FULL & RX_TIMEOUT INTERRUPT) + * + * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * + * @return ESP_OK : Success + * ESP_FAIL: Parameter error + */ +esp_err_t uart_disable_rx_intr(uart_port_t uart_num); + +/** + * @brief Disable UART TX interrupt(RX_FULL & RX_TIMEOUT INTERRUPT) + * + * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * + * @return ESP_OK : Success + * ESP_FAIL: Parameter error + */ +esp_err_t uart_disable_tx_intr(uart_port_t uart_num); + +/** + * @brief Enable UART TX interrupt(RX_FULL & RX_TIMEOUT INTERRUPT) + * + * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param int enable : 1: enable; 0: disable + * @param int thresh : Threshold of TX interrupt, 0 ~ UART_FIFO_LEN + * + * @return ESP_OK : Success + * ESP_FAIL: Parameter error + */ +esp_err_t uart_enable_tx_intr(uart_port_t uart_num, int enable, int thresh); + +/** +* @brief register UART interrupt handler(ISR). + * UART ISR handler will be attached to the same CPU core that this function is running on. + * Users should know that which CPU is running and then pick a INUM that is not used by system. + * We can find the information of INUM and interrupt level in soc.h. + * + * + * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param uint8_t uart_intr_num : UART interrupt number,check the info in soc.h, and please refer to core-isa.h for more details + * @param void (* fn)(void* ) : Interrupt handler function. + * Note that the handler function MUST be defined with attribution of "IRAM_ATTR" for now. + * @param void * arg : parameter for handler function + * + * @return ESP_OK : Success + * ESP_FAIL: Parameter error + */ +esp_err_t uart_isr_register(uart_port_t uart_num, uint8_t uart_intr_num, void (*fn)(void*), void * arg); + +/** + * @brief Set UART pin number + * + * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param tx_io_num : UART TX pin GPIO number + * @param rx_io_num : UART RX pin GPIO number + * @param rts_io_num : UART RTS pin GPIO number + * @param cts_io_num : UART CTS pin GPIO number + * + * + * @return ESP_OK : Success + * ESP_FAIL: Parameter error + */ +esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int rts_io_num, int cts_io_num); + +/** + * @brief UART set RTS level (before inverse) + * UART rx hardware flow control should not be set. + * + * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param int level : 1: RTS output low(active) + * 0: RTS output high(block) + * + * @return ESP_OK : Success + * ESP_FAIL: Parameter error + */ +esp_err_t uart_set_rts(uart_port_t uart_num, int level); + +/** + * @brief UART set DTR level (before inverse) + * + * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param int level : 1: DTR output low + * 0: DTR output high + * + * @return ESP_OK : Success + * ESP_FAIL: Parameter error + */ +esp_err_t uart_set_dtr(uart_port_t uart_num, int level); + +/** +* @brief UART parameter configure + * + * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param uart_config_t *uart_config: UART parameter settings + * + * @return ESP_OK : Success + * ESP_FAIL: Parameter error + */ +esp_err_t uart_param_config(uart_port_t uart_num, uart_config_t *uart_config); + +/** +* @brief UART interrupt configure + * + * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param uart_intr_config_t *p_intr_conf: UART interrupt settings + * + * @return ESP_OK : Success + * ESP_FAIL: Parameter error + */ +esp_err_t uart_intr_config(uart_port_t uart_num, uart_intr_config_t *p_intr_conf); + +/** + * @brief Install UART driver. + * UART ISR handler will be attached to the same CPU core that this function is running on. + * Users should know that which CPU is running and then pick a INUM that is not used by system. + * We can find the information of INUM and interrupt level in soc.h. + * + * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param int buffer_size : UART ring buffer size + * @param int queue_size : UART event queue size/depth. + * @param int uart_intr_num : UART interrupt number,check the info in soc.h, and please refer to core-isa.h for more details + * + * @return ESP_OK : Success + * ESP_FAIL: Parameter error + */ +esp_err_t uart_driver_install(uart_port_t uart_num, int buffer_size, int queue_size, int uart_intr_num, void* uart_queue); + +/** + * @brief Uninstall UART driver. + * + * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * + * @return ESP_OK : Success + * ESP_FAIL: Parameter error + */ +esp_err_t uart_driver_delete(uart_port_t uart_num); + +/** + * @brief Wait UART TX FIFO empty + * + * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param TickType_t ticks_to_wait: Timeout, count in RTOS ticks + * + * @return ESP_OK : Success + * ESP_ERR_TIMEOUT: Timeout + */ +esp_err_t uart_wait_tx_fifo_empty(uart_port_t uart_num, TickType_t ticks_to_wait); + +/** + * @brief Send data to the UART port from a given buffer and length, + * This function will not wait for the space in TX FIFO, just fill the TX FIFO and return when the FIFO is full. + * + * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param char* buffer : data buffer address + * @param uint32_t len : data length to send + * + * @return The number of data that pushed to the TX FIFO + */ +int uart_tx_chars(uart_port_t uart_no, char* buffer, uint32_t len); + +/** + * @brief Send data to the UART port from a given buffer and length, + * This function will not return until all the data have been sent out, or at least pushed into TX FIFO. + * + * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param char* src : data buffer address + * @param size_t size : data length to send + * + * @return The number of data that sent out. + */ +int uart_tx_all_chars(uart_port_t uart_num, const char* src, size_t size); + +/** + * @brief Send data to the UART port from a given buffer and length, + * This function will not return until all the data and the break signal have been sent out. + * + * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param char* src : data buffer address + * @param size_t size : data length to send + * @param int brk_len : break signal length (unit: one bit's time@current_baudrate) + * + * @return The number of data that sent out. + */ +int uart_tx_all_chars_with_break(uart_port_t uart_num, const char* src, size_t size, int brk_len); + +/** +* @brief UART read one char + * + * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param TickType_t ticks_to_wait : ticks to wait. + * + * @return -1 : Error + * Others : return a char data from uart fifo. + */ +int uart_read_char(uart_port_t uart_num, TickType_t ticks_to_wait); + +/** +* @brief UART read bytes from UART buffer + * + * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param uint8_t* buf : pointer to the buffer. + * @param uint32_t length : data length + * @param TickType_t ticks_to_wait: timeout time( FreeRTOS ti c + * + * @return -1 : Error + * Others : return a char data from uart fifo. + */ +int uart_read_bytes(uart_port_t uart_num, uint8_t* buf, uint32_t length, TickType_t ticks_to_wait); + +/** + * @brief UART ring buffer flush + * + * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * + * @return ESP_OK : Success + * ESP_FAIL: Parameter error + */ +esp_err_t uart_flush(uart_port_t uart_num); + +/** + * @brief Set the serial output port for ets_printf function, not effective for ESP_LOGX macro. + * + * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * + * @return ESP_OK : Success + * ESP_FAIL: Parameter error, or UART driver not installed. + */ +esp_err_t uart_set_print_port(uart_port_t uart_no); + +/** + * @brief Get the current serial port for ets_printf function + * + * + * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * + * @return null + */ +int uart_get_print_port(); + +/***************************EXAMPLE********************************** + * + * + * ----------------EXAMPLE OF UART SETTING --------------------- + * //1. Setup UART + * #include "freertos/queue.h" + * #define UART_INTR_NUM 17 //choose one interrupt number from soc.h + * //a. Set UART parameter + * int uart_num = 0; //uart port number + * uart_config_t uart_config = { + * .baud_rate = UART_BITRATE_115200, //baudrate + * .data_bits = UART_DATA_8_BITS, //data bit mode + * .parity = UART_PARITY_DISABLE, //parity mode + * .stop_bits = UART_STOP_BITS_1, //stop bit mode + * .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, //hardware flow control(cts/rts) + * .rx_flow_ctrl_thresh = 120, //flow control threshold + * }; + * uart_param_config(uart_num, &uart_config); + * //b1. Setup UART driver(with UART queue) + * QueueHandle_t uart_queue; + * uart_driver_install(uart_num, 1024 * 2, 10, UART_INTR_NUM, &uart_queue);//parameters here are just an example + * //b2. Setup UART driver(without UART queue) + * uart_driver_install(uart_num, 1024 * 2, 10, UART_INTR_NUM, NULL); //parameters here are just an example + * + *-----------------------------------------------------------------------------* + * //2. Set UART pin + * uart_set_pin(uart_num, -1, -1, 15, 13); //set UART pin, not needed if use default pins. + * + *-----------------------------------------------------------------------------* + * //3. Read data from UART. + * uint8_t data[128]; + * int length = 0; + * length = uart_read_bytes(uart_num, data, sizeof(data), 100); + * + *-----------------------------------------------------------------------------* + * //4. Write data to UART. + * char* test_str = "This is a test string.\n" + * uart_tx_all_chars(uart_num, (const char*)test_str, strlen(test_str)); + * + *-----------------------------------------------------------------------------* + * //5. Write data to UART, end with a break signal. + * uart_tx_all_chars_with_break(0, "test break\n",strlen("test break\n"), 100); + * + *-----------------------------------------------------------------------------* + * + * //6. an example of echo test with hardware flow control on UART1 + * void uart_loop_back_test() + * { + * int uart_num = 1; + * uart_config_t uart_config = { + * .baud_rate = 115200, + * .data_bits = UART_DATA_8_BITS, + * .parity = UART_PARITY_DISABLE, + * .stop_bits = UART_STOP_BITS_1, + * .flow_ctrl = UART_HW_FLOWCTRL_CTS_RTS, + * .rx_flow_ctrl_thresh = 122, + * }; + * uart_param_config(uart_num, &uart_config); //Config UART1 parameters + * uart_set_pin(uart_num, 16, 17, 18, 19); //Set UART1 pins(TX: IO16, RX: IO17, RTS: IO18, CTS: IO19) + * esp_log_level_set(UART_TAG, ESP_LOG_ERROR); //Set UART log level + * uart_driver_install(uart_num, 1024 * 2, 10, 17, NULL); //Install UART driver( We don't need an event queue here) + * uint8_t data[1000]; + * while(1) { + * int len = uart_read_bytes(uart_num, data, sizeof(data), 10); //Read data from UART + * uart_tx_all_chars(uart_num, (const char*)data, len); //Write data back to UART + * } + * } + * + *-----------------------------------------------------------------------------* + * //7. An example of using UART event queue on UART0. + * + * #include "freertos/queue.h" + * QueueHandle_t uart0_queue; //A queue to handle UART event. + * void uart_task(void *pvParameters) + * { + * int uart_num = (int)pvParameters; + * uart_event_t event; + * uint8_t dtmp[1000]; + * for(;;) { + * if(xQueueReceive(uart0_queue, (void * )&event, (portTickType)portMAX_DELAY)) { //Waiting for UART event. + * ESP_LOGI(UART_TAG, "uart[%d] event:", uart_num); + * switch(event.type) { + * case UART_DATA: //Event of UART receving data + * ESP_LOGI(UART_TAG,"data, len: %d\n", event.data.size); + * int len = uart_read_bytes(uart_num, dtmp, event.data.size, 10); + * ESP_LOGI(UART_TAG, "uart read: %d\n", len); + * break; + * case UART_FIFO_OVF: //Event of HW FIFO overflow detected + * ESP_LOGI(UART_TAG, "hw fifo overflow\n"); + * while(1); + * break; + * case UART_BUFFER_FULL: //Event of UART ring buffer full + * ESP_LOGI(UART_TAG, "ring buffer full\n"); + * break; + * case UART_BREAK: + * ESP_LOGI(UART_TAG, "uart rx break\n"); //Event of UART RX break detected + * break; + * case UART_PARITY_ERR: //Event of UART parity check error + * ESP_LOGI(UART_TAG, "uart parity error\n"); + * break; + * case UART_FRAME_ERR: //Event of UART frame error + * ESP_LOGI(UART_TAG, "uart frame error\n"); + * break; + * default: //Others + * ESP_LOGI(UART_TAG, "uart event type: %d\n", event.type); + * break; + * } + * } + * } + * vTaskDelete(NULL); + * } + * + * void uart_queue_test() + * { + * int uart_num = 0; + * uart_config_t uart_config = { + * .baud_rate = 115200, + * .data_bits = UART_DATA_8_BITS, + * .parity = UART_PARITY_DISABLE, + * .stop_bits = UART_STOP_BITS_1, + * .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, + * .rx_flow_ctrl_thresh = 122, + * }; + * uart_param_config(uart_num, &uart_config); //Set UART parameters + * uart_set_pin(uart_num, -1, -1, 15, 13); //Set UART pins,(-1: default pin, no change.) + * esp_log_level_set(UART_TAG, ESP_LOG_INFO); //Set UART log level + * uart_driver_install(uart_num, 1024 * 2, 10, 17, &uart0_queue); //Install UART driver, and get the queue. + * xTaskCreate(uart_task, "uTask", 2048*8, (void*)uart_num, 10, NULL); //Create a task to handler UART event from ISR + * } + * + * + ***************************END OF EXAMPLE**********************************/ + +#ifdef __cplusplus +} +#endif + +#endif /*_DRIVER_UART_H_*/ diff --git a/components/driver/uart.c b/components/driver/uart.c new file mode 100644 index 0000000000..157e0c49c7 --- /dev/null +++ b/components/driver/uart.c @@ -0,0 +1,938 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include +#include "esp_types.h" +#include "esp_attr.h" +#include "esp_intr.h" +#include "esp_log.h" +#include "malloc.h" +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" +#include "freertos/xtensa_api.h" +#include "freertos/task.h" +#include "freertos/ringbuf.h" +#include "soc/dport_reg.h" +#include "rom/ets_sys.h" +#include "soc/uart_struct.h" +#include "driver/uart.h" +#include "driver/gpio.h" +#include "soc/uart_struct.h" + +const char* UART_TAG = "UART"; +#define UART_CHECK(a, str) if (!(a)) { \ + ESP_LOGE(UART_TAG,"%s:%d (%s):%s\n", __FILE__, __LINE__, __FUNCTION__, str); \ + return ESP_FAIL; \ + } +#define DEFAULT_EMPTY_THRESH 10 +#define DEFAULT_FULL_THRESH 120 +#define DEFAULT_TOUT_THRESH 10 +#define UART_ENTER_CRITICAL_ISR(mux) portENTER_CRITICAL_ISR(mux) +#define UART_EXIT_CRITICAL_ISR(mux) portEXIT_CRITICAL_ISR(mux) +#define UART_ENTER_CRITICAL(mux) portENTER_CRITICAL(mux) +#define UART_EXIT_CRITICAL(mux) portEXIT_CRITICAL(mux) + +typedef struct { + uart_port_t uart_num; + SemaphoreHandle_t tx_fifo_sem; + SemaphoreHandle_t tx_mutex; + SemaphoreHandle_t tx_done_sem; + SemaphoreHandle_t tx_brk_sem; + SemaphoreHandle_t rx_sem; + QueueHandle_t xQueueUart; + int queue_size; + int intr_num; + RingbufHandle_t ring_buffer; + bool buffer_full_flg; + bool tx_waiting; + int cur_remain; + uint8_t* rd_ptr; + uint8_t* head_ptr; + uint8_t data_buf[UART_FIFO_LEN]; + uint8_t data_len; +} uart_obj_t; + +static uart_obj_t *p_uart_obj[UART_NUM_MAX] = {0}; +static uart_dev_t* UART[UART_NUM_MAX] = {&UART0, &UART1, &UART2}; +static portMUX_TYPE uart_spinlock[UART_NUM_MAX] = {portMUX_INITIALIZER_UNLOCKED, portMUX_INITIALIZER_UNLOCKED, portMUX_INITIALIZER_UNLOCKED}; + +//Fill UART tx_fifo and return a number, +//This function by itself is not thread-safe, always call from within a muxed section. +static int uart_fill_fifo(uart_port_t uart_num, char* buffer, uint32_t len) +{ + uint8_t i = 0; + uint8_t tx_fifo_cnt = UART[uart_num]->status.txfifo_cnt; + uint8_t tx_remain_fifo_cnt = (UART_FIFO_LEN - tx_fifo_cnt); + uint8_t copy_cnt = (len >= tx_remain_fifo_cnt ? tx_remain_fifo_cnt : len); + for(i = 0; i < copy_cnt; i++) { + WRITE_PERI_REG(UART_FIFO_AHB_REG(uart_num), buffer[i]); + } + return copy_cnt; +} + +esp_err_t uart_set_word_length(uart_port_t uart_num, uart_word_length_t data_bit) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_CHECK((data_bit < UART_DATA_MAX_BITS), "data bit error"); + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + UART[uart_num]->conf0.bit_num = data_bit; + UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + return ESP_OK; +} + +int uart_get_word_length(uart_port_t uart_num) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + return UART[uart_num]->conf0.bit_num; +} + +esp_err_t uart_set_stop_bits(uart_port_t uart_num, uart_stop_bits_t stop_bit) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_CHECK((stop_bit < UART_STOP_BITS_MAX), "stop bit error"); + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + UART[uart_num]->conf0.stop_bit_num = stop_bit; + UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + return ESP_OK; +} + +int uart_get_stop_bits(uart_port_t uart_num) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + return UART[uart_num]->conf0.stop_bit_num; +} + +esp_err_t uart_set_parity(uart_port_t uart_num, uart_parity_t parity_mode) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + UART[uart_num]->conf0.parity = parity_mode & 0x1; + UART[uart_num]->conf0.parity_en = (parity_mode >> 1) & 0x1; + UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + return ESP_OK; +} + +int uart_get_parity(uart_port_t uart_num) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + int val = UART[uart_num]->conf0.val; + if(val & UART_PARITY_EN_M) { + if(val & UART_PARITY_M) { + return UART_PARITY_ODD; + } else { + return UART_PARITY_EVEN; + } + } else { + return UART_PARITY_DISABLE; + } +} + +esp_err_t uart_set_baudrate(uart_port_t uart_num, uint32_t baud_rate) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_CHECK((baud_rate < UART_BITRATE_MAX), "baud_rate error"); + uint32_t clk_div = (((UART_CLK_FREQ) << 4) / baud_rate); + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + UART[uart_num]->clk_div.div_int = clk_div >> 4; + UART[uart_num]->clk_div.div_frag = clk_div & 0xf; + UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + return ESP_OK; +} + +int uart_get_baudrate(uart_port_t uart_num) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + uint32_t clk_div = (UART[uart_num]->clk_div.div_int << 4) | UART[uart_num]->clk_div.div_frag; + UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + uint32_t baudrate = ((UART_CLK_FREQ) << 4) / clk_div; + return baudrate; +} + +esp_err_t uart_set_line_inverse(uart_port_t uart_num, uint32_t inverse_mask) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_CHECK((((inverse_mask & UART_LINE_INV_MASK) == 0) && (inverse_mask != 0)), "inverse_mask error"); + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + CLEAR_PERI_REG_MASK(UART_CONF0_REG(uart_num), UART_LINE_INV_MASK); + SET_PERI_REG_MASK(UART_CONF0_REG(uart_num), inverse_mask); + UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + return ESP_OK; +} + +//only when UART_HW_FLOWCTRL_RTS is set , will the rx_thresh value be set. +esp_err_t uart_set_hw_flow_ctrl(uart_port_t uart_num, uart_hw_flowcontrol_t flow_ctrl, uint8_t rx_thresh) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_CHECK((rx_thresh < UART_FIFO_LEN), "rx flow thresh error"); + UART_CHECK((flow_ctrl < UART_HW_FLOWCTRL_MAX), "hw_flowctrl mode error"); + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + if(flow_ctrl & UART_HW_FLOWCTRL_RTS) { + UART[uart_num]->conf1.rx_flow_thrhd = rx_thresh; + UART[uart_num]->conf1.rx_flow_en = 1; + } else { + UART[uart_num]->conf1.rx_flow_en = 0; + } + if(flow_ctrl & UART_HW_FLOWCTRL_CTS) { + UART[uart_num]->conf0.tx_flow_en = 1; + } else { + UART[uart_num]->conf0.tx_flow_en = 0; + } + UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + return ESP_OK; +} + +int uart_get_hw_flow_ctrl(uart_port_t uart_num) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + uart_hw_flowcontrol_t val = UART_HW_FLOWCTRL_DISABLE; + if(UART[uart_num]->conf1.rx_flow_en) { + val |= UART_HW_FLOWCTRL_RTS; + } + if(UART[uart_num]->conf0.tx_flow_en) { + val |= UART_HW_FLOWCTRL_CTS; + } + return val; +} + +static esp_err_t uart_reset_fifo(uart_port_t uart_num) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + UART[uart_num]->conf0.rxfifo_rst = 1; + UART[uart_num]->conf0.rxfifo_rst = 0; + UART[uart_num]->conf0.txfifo_rst = 1; + UART[uart_num]->conf0.txfifo_rst = 0; + UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + return ESP_OK; +} + +esp_err_t uart_clear_intr_status(uart_port_t uart_num, uint32_t clr_mask) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + //intr_clr register is write-only + UART[uart_num]->int_clr.val = clr_mask; + return ESP_OK; +} + +esp_err_t uart_enable_intr_mask(uart_port_t uart_num, uint32_t enable_mask) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + SET_PERI_REG_MASK(UART_INT_CLR_REG(uart_num), enable_mask); + SET_PERI_REG_MASK(UART_INT_ENA_REG(uart_num), enable_mask); + UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + return ESP_OK; +} + +esp_err_t uart_disable_intr_mask(uart_port_t uart_num, uint32_t disable_mask) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + CLEAR_PERI_REG_MASK(UART_INT_ENA_REG(uart_num), disable_mask); + UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + return ESP_OK; +} + +esp_err_t uart_enable_rx_intr(uart_port_t uart_num) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + SET_PERI_REG_MASK(UART_INT_ENA_REG(uart_num), UART_RXFIFO_FULL_INT_ENA|UART_RXFIFO_TOUT_INT_ENA); + UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + return ESP_OK; +} + +esp_err_t uart_disable_rx_intr(uart_port_t uart_num) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + CLEAR_PERI_REG_MASK(UART_INT_ENA_REG(uart_num), UART_RXFIFO_FULL_INT_ENA|UART_RXFIFO_TOUT_INT_ENA); + UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + return ESP_OK; +} + +esp_err_t uart_disable_tx_intr(uart_port_t uart_num) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + UART[uart_num]->int_ena.txfifo_empty = 0; + UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + return ESP_OK; +} + +esp_err_t uart_enable_tx_intr(uart_port_t uart_num, int enable, int thresh) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_CHECK((thresh < UART_FIFO_LEN), "empty intr threshold error"); + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + UART[uart_num]->int_clr.txfifo_empty = 1; + UART[uart_num]->conf1.txfifo_empty_thrhd = thresh & UART_TXFIFO_EMPTY_THRHD_V; + UART[uart_num]->int_ena.txfifo_empty = enable & 0x1; + UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + ESP_INTR_ENABLE(p_uart_obj[uart_num]->intr_num); + return ESP_OK; +} + +esp_err_t uart_isr_register(uart_port_t uart_num, uint8_t uart_intr_num, void (*fn)(void*), void * arg) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + ESP_INTR_DISABLE(uart_intr_num); + switch(uart_num) { + case UART_NUM_1: + intr_matrix_set(xPortGetCoreID(), ETS_UART1_INTR_SOURCE, uart_intr_num); + break; + case UART_NUM_2: + intr_matrix_set(xPortGetCoreID(), ETS_UART2_INTR_SOURCE, uart_intr_num); + break; + case UART_NUM_0: + default: + intr_matrix_set(xPortGetCoreID(), ETS_UART0_INTR_SOURCE, uart_intr_num); + break; + } + xt_set_interrupt_handler(uart_intr_num, fn, arg); + ESP_INTR_ENABLE(uart_intr_num); + UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + return ESP_OK; +} + +//internal signal can be output to multiple GPIO pads +//only one GPIO pad can connect with input signal +esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int rts_io_num, int cts_io_num) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_CHECK((tx_io_num < 0 || tx_io_num < GPIO_PIN_COUNT || GPIO_PIN_MUX_REG[tx_io_num] != 0), "tx_io_num error"); + UART_CHECK((rx_io_num < 0 || rx_io_num < GPIO_PIN_COUNT || GPIO_PIN_MUX_REG[rx_io_num] != 0), "rx_io_num error"); + UART_CHECK((rts_io_num < 0 || rts_io_num < GPIO_PIN_COUNT || GPIO_PIN_MUX_REG[rts_io_num] != 0), "rts_io_num error"); + UART_CHECK((cts_io_num < 0 || cts_io_num < GPIO_PIN_COUNT || GPIO_PIN_MUX_REG[cts_io_num] != 0), "cts_io_num error"); + + int tx_sig, rx_sig, rts_sig, cts_sig; + switch(uart_num) { + case UART_NUM_0: + tx_sig = U0TXD_OUT_IDX; + rx_sig = U0RXD_IN_IDX; + rts_sig = U0RTS_OUT_IDX; + cts_sig = U0CTS_IN_IDX; + break; + case UART_NUM_1: + tx_sig = U1TXD_OUT_IDX; + rx_sig = U1RXD_IN_IDX; + rts_sig = U1RTS_OUT_IDX; + cts_sig = U1CTS_IN_IDX; + break; + case UART_NUM_2: + tx_sig = U2TXD_OUT_IDX; + rx_sig = U2RXD_IN_IDX; + rts_sig = U2RTS_OUT_IDX; + cts_sig = U2CTS_IN_IDX; + break; + case UART_NUM_MAX: + default: + tx_sig = U0TXD_OUT_IDX; + rx_sig = U0RXD_IN_IDX; + rts_sig = U0RTS_OUT_IDX; + cts_sig = U0CTS_IN_IDX; + break; + } + if(tx_io_num >= 0) { + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[tx_io_num], PIN_FUNC_GPIO); + gpio_set_direction(tx_io_num, GPIO_MODE_OUTPUT); + gpio_matrix_out(tx_io_num, tx_sig, 0, 0); + } + + if(rx_io_num >= 0) { + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[rx_io_num], PIN_FUNC_GPIO); + gpio_set_direction(rx_io_num, GPIO_MODE_INPUT); + gpio_matrix_in(rx_io_num, rx_sig, 0); + } + if(rts_io_num >= 0) { + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[rts_io_num], PIN_FUNC_GPIO); + gpio_set_direction(rts_io_num, GPIO_MODE_OUTPUT); + gpio_matrix_out(rts_io_num, rts_sig, 0, 0); + } + if(cts_io_num >= 0) { + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[cts_io_num], PIN_FUNC_GPIO); + gpio_set_direction(cts_io_num, GPIO_MODE_INPUT); + gpio_matrix_in(cts_io_num, cts_sig, 0); + } + return ESP_OK; +} + +esp_err_t uart_set_rts(uart_port_t uart_num, int level) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_CHECK((UART[uart_num]->conf1.rx_flow_en != 1), "disable hw flowctrl before using sw control\n"); + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + UART[uart_num]->conf0.sw_rts = level & 0x1; + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + return ESP_OK; +} + +esp_err_t uart_set_dtr(uart_port_t uart_num, int level) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + UART[uart_num]->conf0.sw_dtr = level & 0x1; + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + return ESP_OK; +} + +esp_err_t uart_param_config(uart_port_t uart_num, uart_config_t *uart_config) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_CHECK((uart_config), "param null\n"); + if(uart_num == UART_NUM_0) { + periph_module_enable(PERIPH_UART0_MODULE); + } else if(uart_num == UART_NUM_1) { + periph_module_enable(PERIPH_UART1_MODULE); + } else if(uart_num == UART_NUM_2) { + periph_module_enable(PERIPH_UART2_MODULE); + } + uart_set_hw_flow_ctrl(uart_num, uart_config->flow_ctrl, uart_config->rx_flow_ctrl_thresh); + uart_set_baudrate(uart_num, uart_config->baud_rate); + UART[uart_num]->conf0.val = ( + (uart_config->parity << UART_PARITY_S) + | (uart_config->stop_bits << UART_STOP_BIT_NUM_S) + | (uart_config->data_bits << UART_BIT_NUM_S) + | ((uart_config->flow_ctrl & UART_HW_FLOWCTRL_CTS) ? UART_TX_FLOW_EN : 0x0) + | UART_TICK_REF_ALWAYS_ON_M); + return ESP_OK; +} + +esp_err_t uart_intr_config(uart_port_t uart_num, uart_intr_config_t *p_intr_conf) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_CHECK((p_intr_conf), "param null\n"); + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + UART[uart_num]->int_clr.val = UART_INTR_MASK; + if(p_intr_conf->intr_enable_mask & UART_RXFIFO_TOUT_INT_ENA_M) { + UART[uart_num]->conf1.rx_tout_thrhd = ((p_intr_conf->rx_timeout_thresh) & UART_RX_TOUT_THRHD_V); + UART[uart_num]->conf1.rx_tout_en = 1; + } else { + UART[uart_num]->conf1.rx_tout_en = 0; + } + if(p_intr_conf->intr_enable_mask & UART_RXFIFO_FULL_INT_ENA_M) { + UART[uart_num]->conf1.rxfifo_full_thrhd = p_intr_conf->rxfifo_full_thresh; + } + if(p_intr_conf->intr_enable_mask & UART_TXFIFO_EMPTY_INT_ENA_M) { + UART[uart_num]->conf1.txfifo_empty_thrhd = p_intr_conf->txfifo_empty_intr_thresh; + } + UART[uart_num]->int_ena.val = p_intr_conf->intr_enable_mask; + UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + return ESP_FAIL; +} + +//internal isr handler for default driver code. +static void IRAM_ATTR uart_rx_intr_handler_default(void *param) +{ + uart_obj_t *p_uart = (uart_obj_t*) param; + uint8_t uart_num = p_uart->uart_num; + uart_dev_t* uart_reg = UART[uart_num]; + + uint8_t buf_idx = 0; + uint32_t uart_intr_status = UART[uart_num]->int_st.val; + static int rx_fifo_len = 0; + uart_event_t uart_event; + portBASE_TYPE HPTaskAwoken = 0; + while(uart_intr_status != 0x0) { + buf_idx = 0; + uart_event.type = UART_EVENT_MAX; + if(uart_intr_status & UART_TXFIFO_EMPTY_INT_ST_M) { + UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); + uart_reg->int_ena.txfifo_empty = 0; + uart_reg->int_clr.txfifo_empty = 1; + UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); + if(p_uart->tx_waiting == true) { + p_uart->tx_waiting = false; + xSemaphoreGiveFromISR(p_uart->tx_fifo_sem, NULL); + } + } + else if((uart_intr_status & UART_RXFIFO_TOUT_INT_ST_M) || (uart_intr_status & UART_RXFIFO_FULL_INT_ST_M)) { + if(p_uart->buffer_full_flg == false) { + //Get the buffer from the FIFO + rx_fifo_len = uart_reg->status.rxfifo_cnt; + p_uart->data_len = rx_fifo_len; + memset(p_uart->data_buf, 0, sizeof(p_uart->data_buf)); + while(buf_idx < rx_fifo_len) { + p_uart->data_buf[buf_idx++] = uart_reg->fifo.rw_byte; + } + //After Copying the Data From FIFO ,Clear intr_status + UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); + uart_reg->int_clr.rxfifo_tout = 1; + uart_reg->int_clr.rxfifo_full = 1; + UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); + uart_event.type = UART_DATA; + uart_event.data.size = rx_fifo_len; + if(pdFALSE == xRingbufferSendFromISR(p_uart->ring_buffer, p_uart->data_buf, p_uart->data_len, &HPTaskAwoken)) { + UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); + uart_reg->int_ena.rxfifo_full = 0; + uart_reg->int_ena.rxfifo_tout = 0; + UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); + p_uart->buffer_full_flg = true; + uart_event.type = UART_BUFFER_FULL; + } else { + uart_event.type = UART_DATA; + } + } else { + UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); + uart_reg->int_ena.rxfifo_full = 0; + uart_reg->int_ena.rxfifo_tout = 0; + uart_reg->int_clr.val = UART_RXFIFO_FULL_INT_CLR_M | UART_RXFIFO_TOUT_INT_CLR_M; + UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); + uart_event.type = UART_BUFFER_FULL; + } + } else if(uart_intr_status & UART_RXFIFO_OVF_INT_ST_M) { + UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); + uart_reg->conf0.rxfifo_rst = 1; + uart_reg->conf0.rxfifo_rst = 0; + uart_reg->int_clr.rxfifo_ovf = 1; + UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); + uart_event.type = UART_FIFO_OVF; + } else if(uart_intr_status & UART_BRK_DET_INT_ST_M) { + uart_reg->int_clr.brk_det = 1; + uart_event.type = UART_BREAK; + } else if(uart_intr_status & UART_FRM_ERR_INT_ST_M) { + uart_reg->int_clr.parity_err = 1; + uart_event.type = UART_FRAME_ERR; + } else if(uart_intr_status & UART_PARITY_ERR_INT_ST_M) { + uart_reg->int_clr.frm_err = 1; + uart_event.type = UART_PARITY_ERR; + } else if(uart_intr_status & UART_TX_BRK_DONE_INT_ST_M) { + UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); + uart_reg->conf0.txd_brk = 0; + uart_reg->int_ena.tx_brk_done = 0; + uart_reg->int_clr.tx_brk_done = 1; + UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); + xSemaphoreGiveFromISR(p_uart->tx_brk_sem, &HPTaskAwoken); + } else if(uart_intr_status & UART_TX_BRK_IDLE_DONE_INT_ST_M) { + UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); + uart_reg->int_ena.tx_brk_idle_done = 0; + uart_reg->int_clr.tx_brk_idle_done = 1; + UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); + } else if(uart_intr_status & UART_TX_DONE_INT_ST_M) { + UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); + uart_reg->int_ena.tx_done = 0; + uart_reg->int_clr.tx_done = 1; + UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); + xSemaphoreGiveFromISR(p_uart_obj[uart_num]->tx_done_sem, &HPTaskAwoken); + } + else { + uart_reg->int_clr.val = uart_intr_status; /*simply clear all other intr status*/ + uart_event.type = UART_EVENT_MAX; + } + + if(uart_event.type != UART_EVENT_MAX && p_uart->xQueueUart) { + xQueueSendFromISR(p_uart->xQueueUart, (void * )&uart_event, &HPTaskAwoken); + } + uart_intr_status = uart_reg->int_st.val; + } +} + +/**************************************************************/ +esp_err_t uart_driver_install(uart_port_t uart_num, int buffer_size, int queue_size, int uart_intr_num, void* uart_queue) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + if(p_uart_obj[uart_num] == NULL) { + ESP_INTR_DISABLE(uart_intr_num); + p_uart_obj[uart_num] = (uart_obj_t*) malloc(sizeof(uart_obj_t)); + if(p_uart_obj[uart_num] == NULL) { + ESP_LOGE(UART_TAG, "UART driver malloc error\n"); + return ESP_FAIL; + } + p_uart_obj[uart_num]->uart_num = uart_num; + p_uart_obj[uart_num]->tx_fifo_sem = xSemaphoreCreateBinary(); + xSemaphoreGive(p_uart_obj[uart_num]->tx_fifo_sem); + p_uart_obj[uart_num]->tx_done_sem = xSemaphoreCreateBinary(); + xSemaphoreGive(p_uart_obj[uart_num]->tx_done_sem); + p_uart_obj[uart_num]->tx_brk_sem = xSemaphoreCreateBinary(); + + p_uart_obj[uart_num]->tx_mutex = xSemaphoreCreateMutex(); + p_uart_obj[uart_num]->rx_sem = xSemaphoreCreateMutex(); + p_uart_obj[uart_num]->intr_num = uart_intr_num; + p_uart_obj[uart_num]->queue_size = queue_size; + + if(uart_queue) { + p_uart_obj[uart_num]->xQueueUart = xQueueCreate(queue_size, sizeof(uart_event_t)); + *((QueueHandle_t*) uart_queue) = p_uart_obj[uart_num]->xQueueUart; + ESP_LOGI(UART_TAG, "queue free spaces: %d\n", uxQueueSpacesAvailable(p_uart_obj[uart_num]->xQueueUart)); + } else { + p_uart_obj[uart_num]->xQueueUart = NULL; + } + p_uart_obj[uart_num]->buffer_full_flg = false; + p_uart_obj[uart_num]->tx_waiting = false; + p_uart_obj[uart_num]->rd_ptr = NULL; + p_uart_obj[uart_num]->cur_remain = 0; + p_uart_obj[uart_num]->head_ptr = NULL; + p_uart_obj[uart_num]->ring_buffer = xRingbufferCreate(buffer_size, 0); + } else { + ESP_LOGE(UART_TAG, "UART driver already installed\n"); + return ESP_FAIL; + } + uart_isr_register(uart_num, uart_intr_num, uart_rx_intr_handler_default, p_uart_obj[uart_num]); + uart_intr_config_t uart_intr = { + .intr_enable_mask = UART_RXFIFO_FULL_INT_ENA_M + | UART_RXFIFO_TOUT_INT_ENA_M + | UART_FRM_ERR_INT_ENA_M + | UART_RXFIFO_OVF_INT_ENA_M + | UART_BRK_DET_INT_ENA_M, + .rxfifo_full_thresh = DEFAULT_FULL_THRESH, + .rx_timeout_thresh = DEFAULT_TOUT_THRESH, + .txfifo_empty_intr_thresh = DEFAULT_EMPTY_THRESH + }; + uart_intr_config(uart_num, &uart_intr); + ESP_INTR_ENABLE(uart_intr_num); + return ESP_OK; +} + +//Make sure no other tasks are still using UART before you call this function +esp_err_t uart_driver_delete(uart_port_t uart_num) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + if(p_uart_obj[uart_num] == NULL) { + ESP_LOGI(UART_TAG, "ALREADY NULL\n"); + return ESP_OK; + } + ESP_INTR_DISABLE(p_uart_obj[uart_num]->intr_num); + uart_disable_rx_intr(uart_num); + uart_disable_tx_intr(uart_num); + uart_isr_register(uart_num, p_uart_obj[uart_num]->intr_num, NULL, NULL); + + if(p_uart_obj[uart_num]->tx_fifo_sem) { + vSemaphoreDelete(p_uart_obj[uart_num]->tx_fifo_sem); + p_uart_obj[uart_num]->tx_fifo_sem = NULL; + } + if(p_uart_obj[uart_num]->tx_done_sem) { + vSemaphoreDelete(p_uart_obj[uart_num]->tx_done_sem); + p_uart_obj[uart_num]->tx_done_sem = NULL; + } + if(p_uart_obj[uart_num]->tx_brk_sem) { + vSemaphoreDelete(p_uart_obj[uart_num]->tx_brk_sem); + p_uart_obj[uart_num]->tx_brk_sem = NULL; + } + if(p_uart_obj[uart_num]->tx_mutex) { + vSemaphoreDelete(p_uart_obj[uart_num]->tx_mutex); + p_uart_obj[uart_num]->tx_mutex = NULL; + } + if(p_uart_obj[uart_num]->rx_sem) { + vSemaphoreDelete(p_uart_obj[uart_num]->rx_sem); + p_uart_obj[uart_num]->rx_sem = NULL; + } + if(p_uart_obj[uart_num]->xQueueUart) { + vQueueDelete(p_uart_obj[uart_num]->xQueueUart); + p_uart_obj[uart_num]->xQueueUart = NULL; + } + if(p_uart_obj[uart_num]->ring_buffer) { + vRingbufferDelete(p_uart_obj[uart_num]->ring_buffer); + p_uart_obj[uart_num]->ring_buffer = NULL; + } + free(p_uart_obj[uart_num]); + p_uart_obj[uart_num] = NULL; + return ESP_OK; +} + +esp_err_t uart_wait_tx_fifo_empty(uart_port_t uart_num, TickType_t ticks_to_wait) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_CHECK((p_uart_obj[uart_num]), "uart driver error"); + BaseType_t res; + portTickType ticks_end = xTaskGetTickCount() + ticks_to_wait; + //Take tx_mutex + res = xSemaphoreTake(p_uart_obj[uart_num]->tx_mutex, (portTickType)ticks_to_wait); + if(res == pdFALSE) { + return ESP_ERR_TIMEOUT; + } + ticks_to_wait = ticks_end - xTaskGetTickCount(); + //take 1st tx_done_sem + res = xSemaphoreTake(p_uart_obj[uart_num]->tx_done_sem, (portTickType)ticks_to_wait); + if(res == pdFALSE) { + ESP_LOGE(UART_TAG, "take uart done sem error, should not get here.\n"); + xSemaphoreGive(p_uart_obj[uart_num]->tx_done_sem); + xSemaphoreGive(p_uart_obj[uart_num]->tx_mutex); + return ESP_ERR_TIMEOUT; + } + ticks_to_wait = ticks_end - xTaskGetTickCount(); + if(UART[uart_num]->status.txfifo_cnt == 0) { + xSemaphoreGive(p_uart_obj[uart_num]->tx_done_sem); + xSemaphoreGive(p_uart_obj[uart_num]->tx_mutex); + return ESP_OK; + } + uart_enable_intr_mask(uart_num, UART_TX_DONE_INT_ENA_M); + //take 2nd tx_done_sem, wait given from ISR + res = xSemaphoreTake(p_uart_obj[uart_num]->tx_done_sem, (portTickType)ticks_to_wait); + if(res == pdFALSE) { + uart_disable_intr_mask(uart_num, UART_TX_DONE_INT_ENA_M); + xSemaphoreGive(p_uart_obj[uart_num]->tx_done_sem); + xSemaphoreGive(p_uart_obj[uart_num]->tx_mutex); + return ESP_ERR_TIMEOUT; + } + xSemaphoreGive(p_uart_obj[uart_num]->tx_done_sem); + xSemaphoreGive(p_uart_obj[uart_num]->tx_mutex); + return ESP_OK; +} + +static esp_err_t uart_set_break(uart_port_t uart_num, int break_num) +{ + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + UART[uart_num]->idle_conf.tx_brk_num = break_num; + UART[uart_num]->conf0.txd_brk = 1; + UART[uart_num]->int_clr.tx_brk_done = 1; + UART[uart_num]->int_ena.tx_brk_done = 1; + UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + return ESP_OK; +} + +int uart_tx_chars(uart_port_t uart_num, char* buffer, uint32_t len) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_CHECK((p_uart_obj[uart_num]), "uart driver error"); + UART_CHECK(buffer, "buffer null"); + if(len == 0) { + return 0; + } + xSemaphoreTake(p_uart_obj[uart_num]->tx_mutex, (portTickType)portMAX_DELAY); + int tx_len = uart_fill_fifo(uart_num, buffer, len); + xSemaphoreGive(p_uart_obj[uart_num]->tx_mutex); + return tx_len; +} + +static int uart_tx_all(uart_port_t uart_num, const char* src, size_t size, bool brk_en, int brk_len) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_CHECK((p_uart_obj[uart_num]), "uart driver error"); + UART_CHECK(src, "buffer null"); + if(size == 0) { + return 0; + } + //lock for uart_tx + xSemaphoreTake(p_uart_obj[uart_num]->tx_mutex, (portTickType)portMAX_DELAY); + size_t original_size = size; + while(size) { + //semaphore for tx_fifo available + if(pdTRUE == xSemaphoreTake(p_uart_obj[uart_num]->tx_fifo_sem, (portTickType)portMAX_DELAY)) { + size_t sent = uart_fill_fifo(uart_num, (char*) src, size); + if(sent < size) { + p_uart_obj[uart_num]->tx_waiting = true; + uart_enable_tx_intr(uart_num, 1, DEFAULT_EMPTY_THRESH); + } + size -= sent; + src += sent; + } + } + if(brk_en) { + uart_set_break(uart_num, brk_len); + xSemaphoreTake(p_uart_obj[uart_num]->tx_brk_sem, (portTickType)portMAX_DELAY); + } + xSemaphoreGive(p_uart_obj[uart_num]->tx_fifo_sem); + xSemaphoreGive(p_uart_obj[uart_num]->tx_mutex); + return original_size; +} + +int uart_tx_all_chars(uart_port_t uart_num, const char* src, size_t size) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_CHECK((p_uart_obj[uart_num]), "uart driver error"); + UART_CHECK(src, "buffer null"); + return uart_tx_all(uart_num, src, size, 0, 0); +} + +int uart_tx_all_chars_with_break(uart_port_t uart_num, const char* src, size_t size, int brk_len) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_CHECK((p_uart_obj[uart_num]), "uart driver error"); + UART_CHECK((size > 0), "uart size error"); + UART_CHECK((src), "uart data null"); + UART_CHECK((brk_len > 0 && brk_len < 256), "break_num error"); + return uart_tx_all(uart_num, src, size, 1, brk_len); +} + +int uart_read_char(uart_port_t uart_num, TickType_t ticks_to_wait) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_CHECK((p_uart_obj[uart_num]), "uart driver error"); + uint8_t* data; + size_t size; + int val; + portTickType ticks_end = xTaskGetTickCount() + ticks_to_wait; + if(xSemaphoreTake(p_uart_obj[uart_num]->rx_sem,(portTickType)ticks_to_wait) != pdTRUE) { + return -1; + } + if(p_uart_obj[uart_num]->cur_remain == 0) { + ticks_to_wait = ticks_end - xTaskGetTickCount(); + data = (uint8_t*) xRingbufferReceive(p_uart_obj[uart_num]->ring_buffer, &size, (portTickType) ticks_to_wait); + if(data) { + p_uart_obj[uart_num]->head_ptr = data; + p_uart_obj[uart_num]->rd_ptr = data; + p_uart_obj[uart_num]->cur_remain = size; + } else { + xSemaphoreGive(p_uart_obj[uart_num]->rx_sem); + return -1; + } + } + val = *(p_uart_obj[uart_num]->rd_ptr); + p_uart_obj[uart_num]->rd_ptr++; + p_uart_obj[uart_num]->cur_remain--; + if(p_uart_obj[uart_num]->cur_remain == 0) { + vRingbufferReturnItem(p_uart_obj[uart_num]->ring_buffer, p_uart_obj[uart_num]->head_ptr); + p_uart_obj[uart_num]->head_ptr = NULL; + p_uart_obj[uart_num]->rd_ptr = NULL; + if(p_uart_obj[uart_num]->buffer_full_flg) { + BaseType_t res = xRingbufferSend(p_uart_obj[uart_num]->ring_buffer, p_uart_obj[uart_num]->data_buf, p_uart_obj[uart_num]->data_len, 1); + if(res == pdTRUE) { + p_uart_obj[uart_num]->buffer_full_flg = false; + uart_enable_rx_intr(p_uart_obj[uart_num]->uart_num); + } + } + } + xSemaphoreGive(p_uart_obj[uart_num]->rx_sem); + return val; +} + +int uart_read_bytes(uart_port_t uart_num, uint8_t* buf, uint32_t length, TickType_t ticks_to_wait) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_CHECK((buf), "uart_num error"); + UART_CHECK((p_uart_obj[uart_num]), "uart driver error"); + + uint8_t* data = NULL; + size_t size; + size_t copy_len = 0; + int len_tmp; + if(xSemaphoreTake(p_uart_obj[uart_num]->rx_sem,(portTickType)ticks_to_wait) != pdTRUE) { + return -1; + } + while(length) { + if(p_uart_obj[uart_num]->cur_remain == 0) { + data = (uint8_t*) xRingbufferReceive(p_uart_obj[uart_num]->ring_buffer, &size, (portTickType) ticks_to_wait); + if(data) { + p_uart_obj[uart_num]->head_ptr = data; + p_uart_obj[uart_num]->rd_ptr = data; + p_uart_obj[uart_num]->cur_remain = size; + } else { + xSemaphoreGive(p_uart_obj[uart_num]->rx_sem); + return copy_len; + } + } + if(p_uart_obj[uart_num]->cur_remain > length) { + len_tmp = length; + } else { + len_tmp = p_uart_obj[uart_num]->cur_remain; + } + memcpy(buf + copy_len, p_uart_obj[uart_num]->rd_ptr, len_tmp); + p_uart_obj[uart_num]->rd_ptr += len_tmp; + p_uart_obj[uart_num]->cur_remain -= len_tmp; + copy_len += len_tmp; + length -= len_tmp; + if(p_uart_obj[uart_num]->cur_remain == 0) { + vRingbufferReturnItem(p_uart_obj[uart_num]->ring_buffer, p_uart_obj[uart_num]->head_ptr); + p_uart_obj[uart_num]->head_ptr = NULL; + p_uart_obj[uart_num]->rd_ptr = NULL; + if(p_uart_obj[uart_num]->buffer_full_flg) { + BaseType_t res = xRingbufferSend(p_uart_obj[uart_num]->ring_buffer, p_uart_obj[uart_num]->data_buf, p_uart_obj[uart_num]->data_len, 1); + if(res == pdTRUE) { + p_uart_obj[uart_num]->buffer_full_flg = false; + uart_enable_rx_intr(p_uart_obj[uart_num]->uart_num); + } + } + } + } + xSemaphoreGive(p_uart_obj[uart_num]->rx_sem); + return copy_len; +} + +esp_err_t uart_flush(uart_port_t uart_num) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_CHECK((p_uart_obj[uart_num]), "uart driver error"); + + uart_obj_t* p_uart = p_uart_obj[uart_num]; + uint8_t* data; + size_t size; + //rx sem protect the ring buffer read related functions + xSemaphoreTake(p_uart->rx_sem, (portTickType)portMAX_DELAY); + while(true) { + if(p_uart->head_ptr) { + vRingbufferReturnItem(p_uart->ring_buffer, p_uart->head_ptr); + p_uart->rd_ptr = NULL; + p_uart->cur_remain = 0; + p_uart->head_ptr = NULL; + } + data = (uint8_t*) xRingbufferReceive(p_uart->ring_buffer, &size, (portTickType) 0); + if(data == NULL) { + break; + } + vRingbufferReturnItem(p_uart->ring_buffer, data); + } + p_uart->rd_ptr = NULL; + p_uart->cur_remain = 0; + p_uart->head_ptr = NULL; + xSemaphoreGive(p_uart->rx_sem); + uart_wait_tx_fifo_empty(uart_num, portMAX_DELAY); + uart_reset_fifo(uart_num); + return ESP_OK; +} + +//----------------------------------- +//Should not enable hw flow control the debug print port. +//Use uart_tx_all_chars() as a thread-safe function to send data. +static int s_uart_print_nport = UART_NUM_0; +static void uart2_write_char(char chr) +{ + uart_tx_all_chars(UART_NUM_2, (const char*)&chr, 1); +} + +static void uart1_write_char(char chr) +{ + uart_tx_all_chars(UART_NUM_1, (const char*)&chr, 1); +} + +static void uart0_write_char(char chr) +{ + uart_tx_all_chars(UART_NUM_0, (const char*)&chr, 1); +} + +static void uart_ignore_char(char chr) +{ + +} + +//Only effective to ets_printf function, not ESP_LOGX macro. +esp_err_t uart_set_print_port(uart_port_t uart_num) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_CHECK((p_uart_obj[uart_num]), "UART driver error"); + + s_uart_print_nport = uart_num; + switch(s_uart_print_nport) { + case UART_NUM_0: + ets_install_putc1(uart0_write_char); + break; + case UART_NUM_1: + ets_install_putc1(uart1_write_char); + break; + case UART_NUM_2: + ets_install_putc1(uart2_write_char); + break; + case UART_NUM_MAX: + default: + ets_install_putc1(uart_ignore_char); + break; + } + return ESP_OK; +} + +int uart_get_print_port() +{ + return s_uart_print_nport; +} + diff --git a/components/esp32/include/esp_err.h b/components/esp32/include/esp_err.h index 4f013f91ab..5504c3d682 100644 --- a/components/esp32/include/esp_err.h +++ b/components/esp32/include/esp_err.h @@ -31,6 +31,7 @@ typedef int32_t esp_err_t; #define ESP_ERR_NO_MEM 0x101 #define ESP_ERR_INVALID_ARG 0x102 #define ESP_ERR_INVALID_STATE 0x103 +#define ESP_ERR_TIMEOUT 0x104 /** * Macro which can be used to check the error code, diff --git a/components/esp32/include/soc/uart_reg.h b/components/esp32/include/soc/uart_reg.h index 155700b293..8cac4bb832 100644 --- a/components/esp32/include/soc/uart_reg.h +++ b/components/esp32/include/soc/uart_reg.h @@ -18,8 +18,10 @@ #include "soc.h" #define REG_UART_BASE( i ) (DR_REG_UART_BASE + (i) * 0x10000 + ( i > 1 ? 0xe000 : 0 ) ) - +#define REG_UART_AHB_BASE(i) (0x60000000 + (i) * 0x10000 + ( i > 1 ? 0xe000 : 0 ) ) +#define UART_FIFO_AHB_REG(i) (REG_UART_AHB_BASE(i) + 0x0) #define UART_FIFO_REG(i) (REG_UART_BASE(i) + 0x0) + /* UART_RXFIFO_RD_BYTE : RO ;bitpos:[7:0] ;default: 8'b0 ; */ /*description: This register stores one byte data read by rx fifo.*/ #define UART_RXFIFO_RD_BYTE 0x000000FF diff --git a/components/freertos/ringbuf.c b/components/freertos/ringbuf.c index 6045c5a695..3651753147 100644 --- a/components/freertos/ringbuf.c +++ b/components/freertos/ringbuf.c @@ -371,8 +371,7 @@ BaseType_t xRingbufferSendFromISR(RingbufHandle_t ringbuf, void *data, size_t da //Does not fit in the remaining space in the ringbuffer. write_succeeded=pdFALSE; } else { - copyItemToRingbuf(rb, data, dataSize); - write_succeeded=pdTRUE; + write_succeeded = copyItemToRingbuf(rb, data, dataSize); } portEXIT_CRITICAL_ISR(&rb->mux); if (write_succeeded) { From 9098e64398e1af7418e7c27c6bba23f80b55810f Mon Sep 17 00:00:00 2001 From: Wangjialin Date: Mon, 24 Oct 2016 09:38:34 +0800 Subject: [PATCH 124/343] modify GPIO number check --- components/driver/uart.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/components/driver/uart.c b/components/driver/uart.c index 157e0c49c7..f585c0965d 100644 --- a/components/driver/uart.c +++ b/components/driver/uart.c @@ -312,10 +312,10 @@ esp_err_t uart_isr_register(uart_port_t uart_num, uint8_t uart_intr_num, void (* esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int rts_io_num, int cts_io_num) { UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); - UART_CHECK((tx_io_num < 0 || tx_io_num < GPIO_PIN_COUNT || GPIO_PIN_MUX_REG[tx_io_num] != 0), "tx_io_num error"); - UART_CHECK((rx_io_num < 0 || rx_io_num < GPIO_PIN_COUNT || GPIO_PIN_MUX_REG[rx_io_num] != 0), "rx_io_num error"); - UART_CHECK((rts_io_num < 0 || rts_io_num < GPIO_PIN_COUNT || GPIO_PIN_MUX_REG[rts_io_num] != 0), "rts_io_num error"); - UART_CHECK((cts_io_num < 0 || cts_io_num < GPIO_PIN_COUNT || GPIO_PIN_MUX_REG[cts_io_num] != 0), "cts_io_num error"); + UART_CHECK((tx_io_num < 0 || (GPIO_IS_VALID_OUTPUT_GPIO(tx_io_num))), "tx_io_num error"); + UART_CHECK((rx_io_num < 0 || (GPIO_IS_VALID_GPIO(rx_io_num))), "rx_io_num error"); + UART_CHECK((rts_io_num < 0 || (GPIO_IS_VALID_OUTPUT_GPIO(rts_io_num))), "rts_io_num error"); + UART_CHECK((cts_io_num < 0 || (GPIO_IS_VALID_GPIO(cts_io_num))), "cts_io_num error"); int tx_sig, rx_sig, rts_sig, cts_sig; switch(uart_num) { From 74aff2b9d2762578f1da7ff736e402c909755620 Mon Sep 17 00:00:00 2001 From: Wangjialin Date: Mon, 24 Oct 2016 15:57:23 +0800 Subject: [PATCH 125/343] Update UART driver 1. Use esp_log API for LEDC and GPIO code. 2. Modify some API return value. 3. Add ledc_set_pin() for LEDC 4. Modify typo in uart.h Questions: In uart driver ISR handler, I used xxxFromISR , like xSemaphoreGiveFromISR, do those FromISR functions need to be put in IRAM? --- components/driver/gpio.c | 123 ++++--------- components/driver/include/driver/gpio.h | 2 + components/driver/include/driver/ledc.h | 33 +++- components/driver/include/driver/uart.h | 71 ++++---- components/driver/ledc.c | 223 ++++++------------------ components/driver/uart.c | 40 +++-- 6 files changed, 169 insertions(+), 323 deletions(-) diff --git a/components/driver/gpio.c b/components/driver/gpio.c index 14dfc00b43..da0fedb895 100644 --- a/components/driver/gpio.c +++ b/components/driver/gpio.c @@ -18,34 +18,13 @@ #include "freertos/xtensa_api.h" #include "driver/gpio.h" #include "soc/soc.h" +#include "esp_log.h" -//TODO: move debug options to menuconfig -#define GPIO_DBG_ENABLE (0) -#define GPIO_WARNING_ENABLE (0) -#define GPIO_ERROR_ENABLE (0) -#define GPIO_INFO_ENABLE (0) -//DBG INFOR -#if GPIO_INFO_ENABLE -#define GPIO_INFO ets_printf -#else -#define GPIO_INFO(...) -#endif -#if GPIO_WARNING_ENABLE -#define GPIO_WARNING(format,...) do{\ - ets_printf("[waring][%s#%u]",__FUNCTION__,__LINE__);\ - ets_printf(format,##__VA_ARGS__);\ -}while(0) -#else -#define GPIO_WARNING(...) -#endif -#if GPIO_ERROR_ENABLE -#define GPIO_ERROR(format,...) do{\ - ets_printf("[error][%s#%u]",__FUNCTION__,__LINE__);\ - ets_printf(format,##__VA_ARGS__);\ -}while(0) -#else -#define GPIO_ERROR(...) -#endif +const char* GPIO_TAG = "GPIO"; +#define GPIO_CHECK(a, str, ret_val) if (!(a)) { \ + ESP_LOGE(GPIO_TAG,"%s:%d (%s):%s\n", __FILE__, __LINE__, __FUNCTION__, str); \ + return (ret_val); \ + } const uint32_t GPIO_PIN_MUX_REG[GPIO_PIN_COUNT] = { GPIO_PIN_REG_0, @@ -90,33 +69,17 @@ const uint32_t GPIO_PIN_MUX_REG[GPIO_PIN_COUNT] = { GPIO_PIN_REG_39 }; -static int is_valid_gpio(int gpio_num) -{ - if(gpio_num >= GPIO_PIN_COUNT || GPIO_PIN_MUX_REG[gpio_num] == 0) { - GPIO_ERROR("GPIO io_num=%d does not exist\n",gpio_num); - return 0; - } - return 1; -} - esp_err_t gpio_set_intr_type(gpio_num_t gpio_num, gpio_int_type_t intr_type) { - if(!is_valid_gpio(gpio_num)) { - return ESP_ERR_INVALID_ARG; - } - if(intr_type >= GPIO_INTR_MAX) { - GPIO_ERROR("Unknown GPIO intr:%u\n",intr_type); - return ESP_ERR_INVALID_ARG; - } + GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error\n", ESP_ERR_INVALID_ARG); + GPIO_CHECK(intr_type < GPIO_INTR_MAX, "GPIO interrupt type error\n", ESP_ERR_INVALID_ARG); GPIO.pin[gpio_num].int_type = intr_type; return ESP_OK; } esp_err_t gpio_intr_enable(gpio_num_t gpio_num) { - if(!is_valid_gpio(gpio_num)) { - return ESP_ERR_INVALID_ARG; - } + GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error\n", ESP_ERR_INVALID_ARG); if(xPortGetCoreID() == 0) { GPIO.pin[gpio_num].int_ena = GPIO_PRO_CPU_INTR_ENA; //enable pro cpu intr } else { @@ -127,18 +90,14 @@ esp_err_t gpio_intr_enable(gpio_num_t gpio_num) esp_err_t gpio_intr_disable(gpio_num_t gpio_num) { - if(!is_valid_gpio(gpio_num)) { - return ESP_ERR_INVALID_ARG; - } + GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error\n", ESP_ERR_INVALID_ARG); GPIO.pin[gpio_num].int_ena = 0; //disable GPIO intr return ESP_OK; } static esp_err_t gpio_output_disable(gpio_num_t gpio_num) { - if(!is_valid_gpio(gpio_num)) { - return ESP_ERR_INVALID_ARG; - } + GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error\n", ESP_ERR_INVALID_ARG); if(gpio_num < 32) { GPIO.enable_w1tc = (0x1 << gpio_num); } else { @@ -149,13 +108,7 @@ static esp_err_t gpio_output_disable(gpio_num_t gpio_num) static esp_err_t gpio_output_enable(gpio_num_t gpio_num) { - if(gpio_num >= 34) { - GPIO_ERROR("io_num=%d can only be input\n",gpio_num); - return ESP_ERR_INVALID_ARG; - } - if(!is_valid_gpio(gpio_num)) { - return ESP_ERR_INVALID_ARG; - } + GPIO_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "GPIO output gpio_num error\n", ESP_ERR_INVALID_ARG); if(gpio_num < 32) { GPIO.enable_w1ts = (0x1 << gpio_num); } else { @@ -166,9 +119,7 @@ static esp_err_t gpio_output_enable(gpio_num_t gpio_num) esp_err_t gpio_set_level(gpio_num_t gpio_num, uint32_t level) { - if(!GPIO_IS_VALID_GPIO(gpio_num)) { - return ESP_ERR_INVALID_ARG; - } + GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error\n", ESP_ERR_INVALID_ARG); if(level) { if(gpio_num < 32) { GPIO.out_w1ts = (1 << gpio_num); @@ -196,9 +147,8 @@ int gpio_get_level(gpio_num_t gpio_num) esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull) { - if(!is_valid_gpio(gpio_num)) { - return ESP_ERR_INVALID_ARG; - } + GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error\n", ESP_ERR_INVALID_ARG); + GPIO_CHECK(pull <= GPIO_FLOATING, "GPIO pull mode error\n", ESP_ERR_INVALID_ARG); esp_err_t ret = ESP_OK; switch(pull) { case GPIO_PULLUP_ONLY: @@ -218,7 +168,7 @@ esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull) PIN_PULLDWN_DIS(GPIO_PIN_MUX_REG[gpio_num]); break; default: - GPIO_ERROR("Unknown pull up/down mode,gpio_num=%u,pull=%u\n",gpio_num,pull); + ESP_LOGE(GPIO_TAG, "Unknown pull up/down mode,gpio_num=%u,pull=%u\n",gpio_num,pull); ret = ESP_ERR_INVALID_ARG; break; } @@ -227,11 +177,9 @@ esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull) esp_err_t gpio_set_direction(gpio_num_t gpio_num, gpio_mode_t mode) { - if(!is_valid_gpio(gpio_num)) { - return ESP_ERR_INVALID_ARG; - } + GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error\n", ESP_ERR_INVALID_ARG); if(gpio_num >= 34 && (mode & (GPIO_MODE_DEF_OUTPUT))) { - GPIO_ERROR("io_num=%d can only be input\n",gpio_num); + ESP_LOGE(GPIO_TAG, "io_num=%d can only be input\n",gpio_num); return ESP_ERR_INVALID_ARG; } esp_err_t ret = ESP_OK; @@ -268,52 +216,51 @@ esp_err_t gpio_config(gpio_config_t *pGPIOConfig) uint32_t io_num = 0; uint64_t bit_valid = 0; if(pGPIOConfig->pin_bit_mask == 0 || pGPIOConfig->pin_bit_mask >= (((uint64_t) 1) << GPIO_PIN_COUNT)) { - GPIO_ERROR("GPIO_PIN mask error \n"); + ESP_LOGE(GPIO_TAG, "GPIO_PIN mask error \n"); return ESP_ERR_INVALID_ARG; } if((pGPIOConfig->mode) & (GPIO_MODE_DEF_OUTPUT)) { //GPIO 34/35/36/37/38/39 can only be used as input mode; if((gpio_pin_mask & ( GPIO_SEL_34 | GPIO_SEL_35 | GPIO_SEL_36 | GPIO_SEL_37 | GPIO_SEL_38 | GPIO_SEL_39))) { - GPIO_ERROR("GPIO34-39 can only be used as input mode\n"); + ESP_LOGE(GPIO_TAG, "GPIO34-39 can only be used as input mode\n"); return ESP_ERR_INVALID_ARG; } } do { io_reg = GPIO_PIN_MUX_REG[io_num]; if(((gpio_pin_mask >> io_num) & BIT(0)) && io_reg) { - GPIO_INFO("Gpio%02d |Mode:",io_num); + ESP_LOGI(GPIO_TAG, "Gpio%02d |Mode:",io_num); if((pGPIOConfig->mode) & GPIO_MODE_DEF_INPUT) { - GPIO_INFO("INPUT "); + ESP_LOGI(GPIO_TAG, "INPUT "); PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[io_num]); } else { PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[io_num]); } if((pGPIOConfig->mode) & GPIO_MODE_DEF_OD) { - GPIO_INFO("OD "); + ESP_LOGI(GPIO_TAG, "OD "); GPIO.pin[io_num].pad_driver = 1; /*0x01 Open-drain */ } else { GPIO.pin[io_num].pad_driver = 0; /*0x00 Normal gpio output */ } if((pGPIOConfig->mode) & GPIO_MODE_DEF_OUTPUT) { - GPIO_INFO("OUTPUT "); + ESP_LOGI(GPIO_TAG, "OUTPUT "); gpio_output_enable(io_num); } else { gpio_output_disable(io_num); } - GPIO_INFO("|"); if(pGPIOConfig->pull_up_en) { - GPIO_INFO("PU "); + ESP_LOGI(GPIO_TAG, "PU "); PIN_PULLUP_EN(io_reg); } else { PIN_PULLUP_DIS(io_reg); } if(pGPIOConfig->pull_down_en) { - GPIO_INFO("PD "); + ESP_LOGI(GPIO_TAG, "PD "); PIN_PULLDWN_EN(io_reg); } else { PIN_PULLDWN_DIS(io_reg); } - GPIO_INFO("Intr:%d |\n",pGPIOConfig->intr_type); + ESP_LOGI(GPIO_TAG, "Intr:%d |\n",pGPIOConfig->intr_type); gpio_set_intr_type(io_num, pGPIOConfig->intr_type); if(pGPIOConfig->intr_type) { gpio_intr_enable(io_num); @@ -322,7 +269,7 @@ esp_err_t gpio_config(gpio_config_t *pGPIOConfig) } PIN_FUNC_SELECT(io_reg, PIN_FUNC_GPIO); /*function number 2 is GPIO_FUNC for each pin */ } else if(bit_valid && (io_reg == 0)) { - GPIO_WARNING("io_num=%d does not exist\n",io_num); + ESP_LOGW(GPIO_TAG, "io_num=%d does not exist\n",io_num); } io_num++; } while(io_num < GPIO_PIN_COUNT); @@ -331,9 +278,7 @@ esp_err_t gpio_config(gpio_config_t *pGPIOConfig) esp_err_t gpio_isr_register(uint32_t gpio_intr_num, void (*fn)(void*), void * arg) { - if(fn == NULL) { - return ESP_ERR_INVALID_ARG; - } + GPIO_CHECK(fn, "GPIO ISR null\n", ESP_ERR_INVALID_ARG); ESP_INTR_DISABLE(gpio_intr_num); intr_matrix_set(xPortGetCoreID(), ETS_GPIO_INTR_SOURCE, gpio_intr_num); xt_set_interrupt_handler(gpio_intr_num, fn, arg); @@ -344,15 +289,13 @@ esp_err_t gpio_isr_register(uint32_t gpio_intr_num, void (*fn)(void*), void * ar /*only level interrupt can be used for wake-up function*/ esp_err_t gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type) { - if(!is_valid_gpio(gpio_num)) { - return ESP_ERR_INVALID_ARG; - } + GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error\n", ESP_ERR_INVALID_ARG); esp_err_t ret = ESP_OK; if((intr_type == GPIO_INTR_LOW_LEVEL) || (intr_type == GPIO_INTR_HIGH_LEVEL)) { GPIO.pin[gpio_num].int_type = intr_type; GPIO.pin[gpio_num].wakeup_enable = 0x1; } else { - GPIO_ERROR("GPIO wakeup only support Level mode,but edge mode set. gpio_num:%u\n",gpio_num); + ESP_LOGE(GPIO_TAG, "GPIO wakeup only support Level mode,but edge mode set. gpio_num:%u\n",gpio_num); ret = ESP_ERR_INVALID_ARG; } return ret; @@ -360,9 +303,7 @@ esp_err_t gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type) esp_err_t gpio_wakeup_disable(gpio_num_t gpio_num) { - if(!is_valid_gpio(gpio_num)) { - return ESP_ERR_INVALID_ARG; - } + GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error\n", ESP_ERR_INVALID_ARG); GPIO.pin[gpio_num].wakeup_enable = 0; return ESP_OK; } diff --git a/components/driver/include/driver/gpio.h b/components/driver/include/driver/gpio.h index c821b640eb..5ed99e5976 100644 --- a/components/driver/include/driver/gpio.h +++ b/components/driver/include/driver/gpio.h @@ -28,6 +28,8 @@ extern "C" { #endif +extern const char* GPIO_TAG; + #define GPIO_SEL_0 (BIT(0)) /* Pin 0 selected */ #define GPIO_SEL_1 (BIT(1)) /* Pin 1 selected */ #define GPIO_SEL_2 (BIT(2)) /* Pin 2 selected */ diff --git a/components/driver/include/driver/ledc.h b/components/driver/include/driver/ledc.h index 79a6c7f9f3..d6ce9b86c9 100644 --- a/components/driver/include/driver/ledc.h +++ b/components/driver/include/driver/ledc.h @@ -26,6 +26,7 @@ extern "C" { #endif +extern const char* LEDC_TAG; #define LEDC_APB_CLK_HZ (APB_CLK_FREQ) #define LEDC_REF_CLK_HZ (1*1000000) @@ -338,6 +339,22 @@ esp_err_t ledc_timer_resume(ledc_mode_t speed_mode, uint32_t timer_sel); */ esp_err_t ledc_bind_channel_timer(ledc_mode_t speed_mode, uint32_t channel, uint32_t timer_idx); +/** + * @brief Set LEDC output signal to GPIO + * + * @param[in] gpio_num : GPIO number for LEDC signal output + * + * @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version + * + * @param[in] channel : LEDC channel index(0-7), select from ledc_channel_t + * + * + * @return ESP_ERR_INVALID_ARG: parameter error + * ESP_OK: success + * + */ +esp_err_t ledc_set_pin(int gpio_num,ledc_mode_t speed_mode, ledc_channel_t ledc_channel); + /***************************EXAMPLE********************************** * * @@ -349,21 +366,21 @@ esp_err_t ledc_bind_channel_timer(ledc_mode_t speed_mode, uint32_t channel, uint * ledc_timer_config_t timer_conf = { * .bit_num = LEDC_TIMER_12_BIT, //set timer counter bit number * .freq_hz = 1000, //set frequency of pwm, here, 1000Hz - * .speed_mode = LEDC_HIGH_SPEED_MODE //timer mode, + * .speed_mode = LEDC_HIGH_SPEED_MODE, //timer mode, * .timer_num = LEDC_TIMER_0, //timer number * }; * ledc_timer_config(&timer_conf); //setup timer. * * //3. set LEDC channel * ledc_channel_config_t ledc_conf = { - * .channel = LEDC_CHANNEL_0; //set LEDC channel 0 - * .duty = 1000; //set the duty for initialization.(duty range is 0 ~ ((2**bit_num)-1) - * .gpio_num = 16; //GPIO number - * .intr_type = LEDC_INTR_FADE_END; //GPIO INTR TYPE, as an example, we enable fade_end interrupt here. - * .speed_mode = LEDC_HIGH_SPEED_MODE; //set LEDC mode, from ledc_mode_t - * .timer_sel = LEDC_TIMER_0; //set LEDC timer source, if different channel use one timer, the frequency and bit_num of these channels should be the same + * .channel = LEDC_CHANNEL_0, //set LEDC channel 0 + * .duty = 1000, //set the duty for initialization.(duty range is 0 ~ ((2**bit_num)-1) + * .gpio_num = 16, //GPIO number + * .intr_type = LEDC_INTR_FADE_END, //GPIO INTR TYPE, as an example, we enable fade_end interrupt here. + * .speed_mode = LEDC_HIGH_SPEED_MODE, //set LEDC mode, from ledc_mode_t + * .timer_sel = LEDC_TIMER_0, //set LEDC timer source, if different channel use one timer, the frequency and bit_num of these channels should be the same * } - * ledc_channel_config(&ledc_conf); //setup the configuration + * ledc_channel_config(&ledc_conf); //setup the configuration * * ----------------EXAMPLE OF SETTING DUTY --- ----------------- * uint32_t ledc_channel = LEDC_CHANNEL_0; //LEDC channel(0-73) diff --git a/components/driver/include/driver/uart.h b/components/driver/include/driver/uart.h index cd0725d2ce..dafdf54a84 100644 --- a/components/driver/include/driver/uart.h +++ b/components/driver/include/driver/uart.h @@ -27,7 +27,7 @@ extern "C" { #include extern const char* UART_TAG; -#define UART_FIFO_LEN (128) //Do Not Change it +#define UART_FIFO_LEN (128) //Do not change this, this value describes the length of the gardware FIFO in the ESP32 #define UART_INTR_MASK 0x1ff #define UART_LINE_INV_MASK (0x3f << 19) @@ -150,13 +150,10 @@ esp_err_t uart_set_word_length(uart_port_t uart_num, uart_word_length_t data_bit * * @param uart_port_t uart_no: UART_NUM_0, UART_NUM_1 or UART_NUM_2 * - * @return ESP_FAIL (-1) : Parameter error - * UART_DATA_5_BITS (0): UART word length: 5 bits. - * UART_DATA_6_BITS (1): UART word length: 6 bits. - * UART_DATA_7_BITS (2): UART word length: 7 bits. - * UART_DATA_8_BITS (3): UART word length: 8 bits. + * @return ESP_FAIL : Parameter error + * ESP_OK : Success, result will be put in (*data_bit) */ -int uart_get_word_length(uart_port_t uart_num); +esp_err_t uart_get_word_length(uart_port_t uart_num, uart_word_length_t* data_bit); /** * @brief Set UART stop bits. @@ -174,12 +171,10 @@ esp_err_t uart_set_stop_bits(uart_port_t uart_no, uart_stop_bits_t bit_num); * * @param uart_port_t uart_no: UART_NUM_0, UART_NUM_1 or UART_NUM_2 * - * @return ESP_FAIL (-1): Parameter error - * UART_STOP_BITS_1 (1): 1 stop bit - * UART_STOP_BITS_1_5 (2): 1.5 stop bits - * UART_STOP_BITS_1 (3): 2 stop bits + * @return ESP_FAIL : Parameter error + * ESP_OK : Success, result will be put in (*stop_bit) */ -int uart_get_stop_bits(uart_port_t uart_num); +esp_err_t uart_get_stop_bits(uart_port_t uart_num, uart_stop_bits_t* stop_bit); /** * @brief Set UART parity. @@ -196,13 +191,11 @@ esp_err_t uart_set_parity(uart_port_t uart_no, uart_parity_t parity_mode); * * @param uart_port_t uart_no: UART_NUM_0, UART_NUM_1 or UART_NUM_2 * - * @return ESP_FAIL (-1): Parameter error - * UART_PARITY_ODD (0x11): Odd parity check mode - * UART_PARITY_EVEN (0x10): Even parity check mode - * UART_PARITY_DISABLE(0x0) : parity check disabled + * @return ESP_FAIL : Parameter error + * ESP_OK : Success, result will be put in (*parity_mode) * */ -int uart_get_parity(uart_port_t uart_num); +esp_err_t uart_get_parity(uart_port_t uart_num, uart_parity_t* parity_mode); /** * @brief Set UART baud rate. @@ -219,11 +212,11 @@ esp_err_t uart_set_baudrate(uart_port_t uart_no, uint32_t baud_rate); * * @param uart_port_t uart_no: UART_NUM_0, UART_NUM_1 or UART_NUM_2 * - * @return ESP_FAIL(-1): Parameter error - * Others (>0): UART baud-rate + * @return ESP_FAIL : Parameter error + * ESP_OK : Success, result will be put in (*baudrate) * */ -int uart_get_baudrate(uart_port_t uart_num); +esp_err_t uart_get_baudrate(uart_port_t uart_num, uint32_t* baudrate); /** * @brief Set UART line inverse mode @@ -253,13 +246,10 @@ esp_err_t uart_set_hw_flow_ctrl(uart_port_t uart_no, uart_hw_flowcontrol_t flow_ * @brief Get hardware flow control mode * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 * - * @return ESP_FAIL (-1): Parameter error - * UART_HW_FLOWCTRL_DISABLE (0): UART hw flow control disabled - * UART_HW_FLOWCTRL_RTS (1): UART RX flow control enabled - * UART_HW_FLOWCTRL_CTS (2): UART TX flow control enabled - * UART_HW_FLOWCTRL_CTS_RTS (3): UART TX/RX flow control enabled + * @return ESP_FAIL : Parameter error + * ESP_OK : Success, result will be put in (*flow_ctrl) */ -int uart_get_hw_flow_ctrl(uart_port_t uart_num); +esp_err_t uart_get_hw_flow_ctrl(uart_port_t uart_num, uart_hw_flowcontrol_t* flow_ctrl); /** * @brief Clear UART interrupt status @@ -453,6 +443,7 @@ esp_err_t uart_driver_delete(uart_port_t uart_num); * @param TickType_t ticks_to_wait: Timeout, count in RTOS ticks * * @return ESP_OK : Success + * ESP_FAIL : Parameter error * ESP_ERR_TIMEOUT: Timeout */ esp_err_t uart_wait_tx_fifo_empty(uart_port_t uart_num, TickType_t ticks_to_wait); @@ -465,7 +456,8 @@ esp_err_t uart_wait_tx_fifo_empty(uart_port_t uart_num, TickType_t ticks_to_wait * @param char* buffer : data buffer address * @param uint32_t len : data length to send * - * @return The number of data that pushed to the TX FIFO + * @return -1 : Parameter error + * OTHERS(>=0): The number of data that pushed to the TX FIFO */ int uart_tx_chars(uart_port_t uart_no, char* buffer, uint32_t len); @@ -477,7 +469,8 @@ int uart_tx_chars(uart_port_t uart_no, char* buffer, uint32_t len); * @param char* src : data buffer address * @param size_t size : data length to send * - * @return The number of data that sent out. + * @return -1 : Parameter error + * OTHERS(>=0): The number of data that pushed to the TX FIFO */ int uart_tx_all_chars(uart_port_t uart_num, const char* src, size_t size); @@ -490,7 +483,8 @@ int uart_tx_all_chars(uart_port_t uart_num, const char* src, size_t size); * @param size_t size : data length to send * @param int brk_len : break signal length (unit: one bit's time@current_baudrate) * - * @return The number of data that sent out. + * @return -1 : Parameter error + * OTHERS(>=0): The number of data that pushed to the TX FIFO */ int uart_tx_all_chars_with_break(uart_port_t uart_num, const char* src, size_t size, int brk_len); @@ -498,20 +492,20 @@ int uart_tx_all_chars_with_break(uart_port_t uart_num, const char* src, size_t s * @brief UART read one char * * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param TickType_t ticks_to_wait : ticks to wait. + * @param TickType_t ticks_to_wait : Timeout, count in RTOS ticks * * @return -1 : Error - * Others : return a char data from uart fifo. + * Others : return a char data from UART. */ int uart_read_char(uart_port_t uart_num, TickType_t ticks_to_wait); /** * @brief UART read bytes from UART buffer * - * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param uint8_t* buf : pointer to the buffer. - * @param uint32_t length : data length - * @param TickType_t ticks_to_wait: timeout time( FreeRTOS ti c + * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param uint8_t* buf : pointer to the buffer. + * @param uint32_t length : data length + * @param TickType_t ticks_to_wait: Timeout, count in RTOS ticks * * @return -1 : Error * Others : return a char data from uart fifo. @@ -542,9 +536,9 @@ esp_err_t uart_set_print_port(uart_port_t uart_no); * @brief Get the current serial port for ets_printf function * * - * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * - * @return null + * @return current print port: 0: UART0; + * 1: UART1; + * 2: UART2; */ int uart_get_print_port(); @@ -637,7 +631,6 @@ int uart_get_print_port(); * break; * case UART_FIFO_OVF: //Event of HW FIFO overflow detected * ESP_LOGI(UART_TAG, "hw fifo overflow\n"); - * while(1); * break; * case UART_BUFFER_FULL: //Event of UART ring buffer full * ESP_LOGI(UART_TAG, "ring buffer full\n"); diff --git a/components/driver/ledc.c b/components/driver/ledc.c index 386c93dfa6..771c4a17df 100644 --- a/components/driver/ledc.c +++ b/components/driver/ledc.c @@ -18,86 +18,19 @@ #include "freertos/xtensa_api.h" #include "soc/gpio_sig_map.h" #include "driver/ledc.h" +#include "esp_log.h" -//TODO: to use APIs in esp_log.h. -#define LEDC_DBG_WARING_ENABLE (0) -#define LEDC_DBG_ERROR_ENABLE (0) -#define LEDC_INFO_ENABLE (0) -#define LEDC_DBG_ENABLE (0) - -//DBG INFOR -#if LEDC_DBG_ENABLE -#define LEDC_DBG(format,...) do{\ - ets_printf("[dbg][%s#%u]",__FUNCTION__,__LINE__);\ - ets_printf(format,##__VA_ARGS__);\ -}while(0) -#else -#define LEDC_DBG(...) -#endif - -#if LEDC_INFO_ENABLE -#define LEDC_INFO(format,...) do{\ - ets_printf("[info][%s#%u]",__FUNCTION__,__LINE__);\ - ets_printf(format,##__VA_ARGS__);\ -}while(0) -#else -#define LEDC_INFO(...) -#endif - -#if LEDC_DBG_WARING_ENABLE -#define LEDC_WARING(format,...) do{\ - ets_printf("[waring][%s#%u]",__FUNCTION__,__LINE__);\ - ets_printf(format,##__VA_ARGS__);\ -}while(0) -#else -#define LEDC_WARING(...) -#endif -#if LEDC_DBG_ERROR_ENABLE -#define LEDC_ERROR(format,...) do{\ - ets_printf("[error][%s#%u]",__FUNCTION__,__LINE__);\ - ets_printf(format,##__VA_ARGS__);\ -}while(0) -#else -#define LEDC_ERROR(...) -#endif - +const char* LEDC_TAG = "LEDC"; static portMUX_TYPE ledc_spinlock = portMUX_INITIALIZER_UNLOCKED; - -static bool ledc_is_valid_channel(uint32_t channel) -{ - if(channel > LEDC_CHANNEL_7) { - LEDC_ERROR("LEDC CHANNEL ERR: %d\n",channel); - return false; - } - return true; -} - -static bool ledc_is_valid_mode(uint32_t mode) -{ - if(mode >= LEDC_SPEED_MODE_MAX) { - LEDC_ERROR("LEDC MODE ERR: %d\n",mode); - return false; - } - return true; -} - -static bool ledc_is_valid_timer(int timer) -{ - if(timer > LEDC_TIMER_3) { - LEDC_ERROR("LEDC TIMER ERR: %d\n", timer); - return false; - } - return true; -} +#define LEDC_CHECK(a, str, ret_val) if (!(a)) { \ + ESP_LOGE(LEDC_TAG,"%s:%d (%s):%s\n", __FILE__, __LINE__, __FUNCTION__, str); \ + return (ret_val); \ + } esp_err_t ledc_timer_set(ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t div_num, uint32_t bit_num, ledc_clk_src_t clk_src) { - if(!ledc_is_valid_mode(speed_mode)) { - return ESP_ERR_INVALID_ARG; - } - if(!ledc_is_valid_timer(timer_sel)) { - return ESP_ERR_INVALID_ARG; - } + LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error\n", ESP_ERR_INVALID_ARG); + LEDC_CHECK(timer_sel <= LEDC_TIMER_3, "ledc timer error\n", ESP_ERR_INVALID_ARG); portENTER_CRITICAL(&ledc_spinlock); LEDC.timer_group[speed_mode].timer[timer_sel].conf.div_num = div_num; LEDC.timer_group[speed_mode].timer[timer_sel].conf.tick_sel = clk_src; @@ -125,12 +58,8 @@ static esp_err_t ledc_duty_config(ledc_mode_t speed_mode, uint32_t channel_num, esp_err_t ledc_bind_channel_timer(ledc_mode_t speed_mode, uint32_t channel, uint32_t timer_idx) { - if(!ledc_is_valid_mode(speed_mode)) { - return ESP_ERR_INVALID_ARG; - } - if(!ledc_is_valid_timer(timer_idx)) { - return ESP_ERR_INVALID_ARG; - } + LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error\n", ESP_ERR_INVALID_ARG); + LEDC_CHECK(timer_idx <= LEDC_TIMER_3, "ledc timer error\n", ESP_ERR_INVALID_ARG); portENTER_CRITICAL(&ledc_spinlock); LEDC.channel_group[speed_mode].channel[channel].conf0.timer_sel = timer_idx; portEXIT_CRITICAL(&ledc_spinlock); @@ -139,12 +68,8 @@ esp_err_t ledc_bind_channel_timer(ledc_mode_t speed_mode, uint32_t channel, uint esp_err_t ledc_timer_rst(ledc_mode_t speed_mode, uint32_t timer_sel) { - if(!ledc_is_valid_mode(speed_mode)) { - return ESP_ERR_INVALID_ARG; - } - if(!ledc_is_valid_timer(timer_sel)) { - return ESP_ERR_INVALID_ARG; - } + LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error\n", ESP_ERR_INVALID_ARG); + LEDC_CHECK(timer_sel <= LEDC_TIMER_3, "ledc timer error\n", ESP_ERR_INVALID_ARG); portENTER_CRITICAL(&ledc_spinlock); LEDC.timer_group[speed_mode].timer[timer_sel].conf.rst = 1; LEDC.timer_group[speed_mode].timer[timer_sel].conf.rst = 0; @@ -154,12 +79,8 @@ esp_err_t ledc_timer_rst(ledc_mode_t speed_mode, uint32_t timer_sel) esp_err_t ledc_timer_pause(ledc_mode_t speed_mode, uint32_t timer_sel) { - if(!ledc_is_valid_mode(speed_mode)) { - return ESP_ERR_INVALID_ARG; - } - if(!ledc_is_valid_timer(timer_sel)) { - return ESP_ERR_INVALID_ARG; - } + LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error\n", ESP_ERR_INVALID_ARG); + LEDC_CHECK(timer_sel <= LEDC_TIMER_3, "ledc timer error\n", ESP_ERR_INVALID_ARG); portENTER_CRITICAL(&ledc_spinlock); LEDC.timer_group[speed_mode].timer[timer_sel].conf.pause = 1; portEXIT_CRITICAL(&ledc_spinlock); @@ -168,12 +89,8 @@ esp_err_t ledc_timer_pause(ledc_mode_t speed_mode, uint32_t timer_sel) esp_err_t ledc_timer_resume(ledc_mode_t speed_mode, uint32_t timer_sel) { - if(!ledc_is_valid_mode(speed_mode)) { - return ESP_ERR_INVALID_ARG; - } - if(!ledc_is_valid_timer(timer_sel)) { - return ESP_ERR_INVALID_ARG; - } + LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error\n", ESP_ERR_INVALID_ARG); + LEDC_CHECK(timer_sel <= LEDC_TIMER_3, "ledc timer error\n", ESP_ERR_INVALID_ARG); portENTER_CRITICAL(&ledc_spinlock); LEDC.timer_group[speed_mode].timer[timer_sel].conf.pause = 0; portEXIT_CRITICAL(&ledc_spinlock); @@ -182,9 +99,7 @@ esp_err_t ledc_timer_resume(ledc_mode_t speed_mode, uint32_t timer_sel) static esp_err_t ledc_enable_intr_type(ledc_mode_t speed_mode, uint32_t channel, ledc_intr_type_t type) { - if(!ledc_is_valid_mode(speed_mode)) { - return ESP_ERR_INVALID_ARG; - } + LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error\n", ESP_ERR_INVALID_ARG); uint32_t value; uint32_t intr_type = type; portENTER_CRITICAL(&ledc_spinlock); @@ -200,9 +115,7 @@ static esp_err_t ledc_enable_intr_type(ledc_mode_t speed_mode, uint32_t channel, esp_err_t ledc_isr_register(uint32_t ledc_intr_num, void (*fn)(void*), void * arg) { - if(fn == NULL) { - return ESP_ERR_INVALID_ARG; - } + LEDC_CHECK(fn, "ledc isr null\n", ESP_ERR_INVALID_ARG); portENTER_CRITICAL(&ledc_spinlock); ESP_INTR_DISABLE(ledc_intr_num); intr_matrix_set(xPortGetCoreID(), ETS_LEDC_INTR_SOURCE, ledc_intr_num); @@ -218,16 +131,13 @@ esp_err_t ledc_timer_config(ledc_timer_config_t* timer_conf) int bit_num = timer_conf->bit_num; int timer_num = timer_conf->timer_num; int speed_mode = timer_conf->speed_mode; - - if(!ledc_is_valid_mode(speed_mode)) { - return ESP_ERR_INVALID_ARG; - } + LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error\n", ESP_ERR_INVALID_ARG); if(freq_hz == 0 || bit_num == 0 || bit_num > LEDC_TIMER_15_BIT) { - LEDC_ERROR("freq_hz=%u bit_num=%u\n", freq_hz, bit_num); + ESP_LOGE(LEDC_TAG, "freq_hz=%u bit_num=%u\n", freq_hz, bit_num); return ESP_ERR_INVALID_ARG; } if(timer_num > LEDC_TIMER_3) { - LEDC_ERROR("Time Select %u\n", timer_num); + ESP_LOGE(LEDC_TAG, "Time Select %u\n", timer_num); return ESP_ERR_INVALID_ARG; } esp_err_t ret = ESP_OK; @@ -239,7 +149,7 @@ esp_err_t ledc_timer_config(ledc_timer_config_t* timer_conf) /*Selet the reference tick*/ div_param = ((uint64_t) LEDC_REF_CLK_HZ << 8) / freq_hz / precision; if(div_param <= 256 || div_param > LEDC_DIV_NUM_HSTIMER0_V) { - LEDC_ERROR("div param err,div_param=%u\n", div_param); + ESP_LOGE(LEDC_TAG, "div param err,div_param=%u\n", (uint32_t)div_param); ret = ESP_FAIL; } timer_clk_src = LEDC_REF_TICK; @@ -254,6 +164,21 @@ esp_err_t ledc_timer_config(ledc_timer_config_t* timer_conf) return ret; } +esp_err_t ledc_set_pin(int gpio_num, ledc_mode_t speed_mode, ledc_channel_t ledc_channel) +{ + LEDC_CHECK(ledc_channel <= LEDC_CHANNEL_7, "ledc channel error\n", ESP_ERR_INVALID_ARG); + LEDC_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "ledc GPIO output number error\n", ESP_ERR_INVALID_ARG); + LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error\n", ESP_ERR_INVALID_ARG); + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[gpio_num], PIN_FUNC_GPIO); + gpio_set_direction(gpio_num, GPIO_MODE_OUTPUT); + if(speed_mode == LEDC_HIGH_SPEED_MODE) { + gpio_matrix_out(gpio_num, LEDC_HS_SIG_OUT0_IDX + ledc_channel, 0, 0); + } else { + + } + return ESP_OK; +} + esp_err_t ledc_channel_config(ledc_channel_config_t* ledc_conf) { uint32_t speed_mode = ledc_conf->speed_mode; @@ -262,21 +187,10 @@ esp_err_t ledc_channel_config(ledc_channel_config_t* ledc_conf) uint32_t timer_select = ledc_conf->timer_sel; uint32_t intr_type = ledc_conf->intr_type; uint32_t duty = ledc_conf->duty; - - if(!ledc_is_valid_channel(ledc_channel)) { - return ESP_ERR_INVALID_ARG; - } - if(!ledc_is_valid_mode(speed_mode)) { - return ESP_ERR_INVALID_ARG; - } - if(!GPIO_IS_VALID_OUTPUT_GPIO(gpio_num)) { - LEDC_ERROR("GPIO number error: IO%d\n ", gpio_num); - return ESP_ERR_INVALID_ARG; - } - if(timer_select > LEDC_TIMER_3) { - LEDC_ERROR("Time Select %u\n", timer_select); - return ESP_ERR_INVALID_ARG; - } + LEDC_CHECK(ledc_channel <= LEDC_CHANNEL_7, "ledc channel error\n", ESP_ERR_INVALID_ARG); + LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error\n", ESP_ERR_INVALID_ARG); + LEDC_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "ledc GPIO output number error\n", ESP_ERR_INVALID_ARG); + LEDC_CHECK(timer_select <= LEDC_TIMER_3, "ledc timer error\n", ESP_ERR_INVALID_ARG); esp_err_t ret = ESP_OK; /*set channel parameters*/ /* channel parameters decide how the waveform looks like in one period*/ @@ -288,7 +202,7 @@ esp_err_t ledc_channel_config(ledc_channel_config_t* ledc_conf) ledc_bind_channel_timer(speed_mode, ledc_channel, timer_select); /*set interrupt type*/ ledc_enable_intr_type(speed_mode, ledc_channel, intr_type); - LEDC_INFO("LEDC_PWM CHANNEL %1u|GPIO %02u|Duty %04u|Time %01u\n", + ESP_LOGI(LEDC_TAG, "LEDC_PWM CHANNEL %1u|GPIO %02u|Duty %04u|Time %01u\n", ledc_channel, gpio_num, duty, timer_select ); /*set LEDC signal in gpio matrix*/ @@ -300,12 +214,8 @@ esp_err_t ledc_channel_config(ledc_channel_config_t* ledc_conf) esp_err_t ledc_update_duty(ledc_mode_t speed_mode, ledc_channel_t channel) { - if(!ledc_is_valid_mode(speed_mode)) { - return ESP_ERR_INVALID_ARG; - } - if(!ledc_is_valid_channel(channel)) { - return ESP_ERR_INVALID_ARG; - } + LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error\n", ESP_ERR_INVALID_ARG); + LEDC_CHECK(channel <= LEDC_CHANNEL_7, "ledc channel error\n", ESP_ERR_INVALID_ARG); portENTER_CRITICAL(&ledc_spinlock); LEDC.channel_group[speed_mode].channel[channel].conf0.sig_out_en = 1; LEDC.channel_group[speed_mode].channel[channel].conf1.duty_start = 1; @@ -315,12 +225,8 @@ esp_err_t ledc_update_duty(ledc_mode_t speed_mode, ledc_channel_t channel) esp_err_t ledc_stop(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t idle_level) { - if(!ledc_is_valid_mode(speed_mode)) { - return ESP_ERR_INVALID_ARG; - } - if(!ledc_is_valid_channel(channel)) { - return ESP_ERR_INVALID_ARG; - } + LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error\n", ESP_ERR_INVALID_ARG); + LEDC_CHECK(channel <= LEDC_CHANNEL_7, "ledc channel error\n", ESP_ERR_INVALID_ARG); portENTER_CRITICAL(&ledc_spinlock); LEDC.channel_group[speed_mode].channel[channel].conf0.idle_lv = idle_level & 0x1; LEDC.channel_group[speed_mode].channel[channel].conf0.sig_out_en = 0; @@ -331,18 +237,11 @@ esp_err_t ledc_stop(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t idl esp_err_t ledc_set_fade(ledc_mode_t speed_mode, uint32_t channel, uint32_t duty, ledc_duty_direction_t fade_direction, uint32_t step_num, uint32_t duty_cyle_num, uint32_t duty_scale) { - if(!ledc_is_valid_mode(speed_mode)) { - return ESP_ERR_INVALID_ARG; - } - if(!ledc_is_valid_channel(channel)) { - return ESP_ERR_INVALID_ARG; - } - if(fade_direction > LEDC_DUTY_DIR_INCREASE) { - LEDC_ERROR("Duty direction err\n"); - return ESP_ERR_INVALID_ARG; - } + LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error\n", ESP_ERR_INVALID_ARG); + LEDC_CHECK(channel <= LEDC_CHANNEL_7, "ledc channel error\n", ESP_ERR_INVALID_ARG); + LEDC_CHECK(fade_direction <= LEDC_DUTY_DIR_INCREASE, "ledc fade direction error\n", ESP_ERR_INVALID_ARG); if(step_num > LEDC_DUTY_NUM_HSCH0_V || duty_cyle_num > LEDC_DUTY_CYCLE_HSCH0_V || duty_scale > LEDC_DUTY_SCALE_HSCH0_V) { - LEDC_ERROR("step_num=%u duty_cyle_num=%u duty_scale=%u\n", step_num, duty_cyle_num, duty_scale); + ESP_LOGE(LEDC_TAG, "step_num=%u duty_cyle_num=%u duty_scale=%u\n", step_num, duty_cyle_num, duty_scale); return ESP_ERR_INVALID_ARG; } ledc_duty_config(speed_mode, @@ -359,12 +258,8 @@ esp_err_t ledc_set_fade(ledc_mode_t speed_mode, uint32_t channel, uint32_t duty, esp_err_t ledc_set_duty(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t duty) { - if(!ledc_is_valid_mode(speed_mode)) { - return ESP_ERR_INVALID_ARG; - } - if(!ledc_is_valid_channel(channel)) { - return ESP_ERR_INVALID_ARG; - } + LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error\n", ESP_ERR_INVALID_ARG); + LEDC_CHECK(channel <= LEDC_CHANNEL_7, "ledc channel error\n", ESP_ERR_INVALID_ARG); ledc_duty_config(speed_mode, channel, //uint32_t chan_num, 0, //uint32_t hpoint_val, @@ -379,18 +274,14 @@ esp_err_t ledc_set_duty(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t int ledc_get_duty(ledc_mode_t speed_mode, ledc_channel_t channel) { - if(!ledc_is_valid_mode(speed_mode)) { - return -1; - } + LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error\n", (-1)); uint32_t duty = (LEDC.channel_group[speed_mode].channel[channel].duty_rd.duty_read >> 4); return duty; } esp_err_t ledc_set_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num, uint32_t freq_hz) { - if(!ledc_is_valid_mode(speed_mode)) { - return ESP_ERR_INVALID_ARG; - } + LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error\n", ESP_ERR_INVALID_ARG); portENTER_CRITICAL(&ledc_spinlock); esp_err_t ret = ESP_OK; uint32_t div_num = 0; @@ -403,7 +294,7 @@ esp_err_t ledc_set_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num, uint32_t div_num = ((uint64_t) LEDC_REF_CLK_HZ << 8) / freq_hz / precision; } if(div_num <= 256 || div_num > LEDC_DIV_NUM_HSTIMER0) { - LEDC_ERROR("div param err,div_param=%u\n", div_num); + ESP_LOGE(LEDC_TAG, "div param err,div_param=%u\n", div_num); ret = ESP_FAIL; } LEDC.timer_group[speed_mode].timer[timer_num].conf.div_num = div_num; @@ -413,9 +304,7 @@ esp_err_t ledc_set_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num, uint32_t uint32_t ledc_get_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num) { - if(!ledc_is_valid_mode(speed_mode)) { - return 0; - } + LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error\n", (0)); portENTER_CRITICAL(&ledc_spinlock); uint32_t freq = 0; uint32_t timer_source_clk = LEDC.timer_group[speed_mode].timer[timer_num].conf.tick_sel; diff --git a/components/driver/uart.c b/components/driver/uart.c index f585c0965d..29e4522d6d 100644 --- a/components/driver/uart.c +++ b/components/driver/uart.c @@ -90,10 +90,11 @@ esp_err_t uart_set_word_length(uart_port_t uart_num, uart_word_length_t data_bit return ESP_OK; } -int uart_get_word_length(uart_port_t uart_num) +esp_err_t uart_get_word_length(uart_port_t uart_num, uart_word_length_t* data_bit) { UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); - return UART[uart_num]->conf0.bit_num; + *(data_bit) = UART[uart_num]->conf0.bit_num; + return ESP_OK; } esp_err_t uart_set_stop_bits(uart_port_t uart_num, uart_stop_bits_t stop_bit) @@ -106,10 +107,11 @@ esp_err_t uart_set_stop_bits(uart_port_t uart_num, uart_stop_bits_t stop_bit) return ESP_OK; } -int uart_get_stop_bits(uart_port_t uart_num) +esp_err_t uart_get_stop_bits(uart_port_t uart_num, uart_stop_bits_t* stop_bit) { UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); - return UART[uart_num]->conf0.stop_bit_num; + (*stop_bit) = UART[uart_num]->conf0.stop_bit_num; + return ESP_OK; } esp_err_t uart_set_parity(uart_port_t uart_num, uart_parity_t parity_mode) @@ -122,19 +124,20 @@ esp_err_t uart_set_parity(uart_port_t uart_num, uart_parity_t parity_mode) return ESP_OK; } -int uart_get_parity(uart_port_t uart_num) +esp_err_t uart_get_parity(uart_port_t uart_num, uart_parity_t* parity_mode) { UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); int val = UART[uart_num]->conf0.val; if(val & UART_PARITY_EN_M) { if(val & UART_PARITY_M) { - return UART_PARITY_ODD; + (*parity_mode) = UART_PARITY_ODD; } else { - return UART_PARITY_EVEN; + (*parity_mode) = UART_PARITY_EVEN; } } else { - return UART_PARITY_DISABLE; + (*parity_mode) = UART_PARITY_DISABLE; } + return ESP_OK; } esp_err_t uart_set_baudrate(uart_port_t uart_num, uint32_t baud_rate) @@ -149,14 +152,14 @@ esp_err_t uart_set_baudrate(uart_port_t uart_num, uint32_t baud_rate) return ESP_OK; } -int uart_get_baudrate(uart_port_t uart_num) +esp_err_t uart_get_baudrate(uart_port_t uart_num, uint32_t* baudrate) { UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); uint32_t clk_div = (UART[uart_num]->clk_div.div_int << 4) | UART[uart_num]->clk_div.div_frag; UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); - uint32_t baudrate = ((UART_CLK_FREQ) << 4) / clk_div; - return baudrate; + (*baudrate) = ((UART_CLK_FREQ) << 4) / clk_div; + return ESP_OK; } esp_err_t uart_set_line_inverse(uart_port_t uart_num, uint32_t inverse_mask) @@ -192,7 +195,7 @@ esp_err_t uart_set_hw_flow_ctrl(uart_port_t uart_num, uart_hw_flowcontrol_t flow return ESP_OK; } -int uart_get_hw_flow_ctrl(uart_port_t uart_num) +esp_err_t uart_get_hw_flow_ctrl(uart_port_t uart_num, uart_hw_flowcontrol_t* flow_ctrl) { UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); uart_hw_flowcontrol_t val = UART_HW_FLOWCTRL_DISABLE; @@ -202,7 +205,8 @@ int uart_get_hw_flow_ctrl(uart_port_t uart_num) if(UART[uart_num]->conf0.tx_flow_en) { val |= UART_HW_FLOWCTRL_CTS; } - return val; + (*flow_ctrl) = val; + return ESP_OK; } static esp_err_t uart_reset_fifo(uart_port_t uart_num) @@ -311,11 +315,11 @@ esp_err_t uart_isr_register(uart_port_t uart_num, uint8_t uart_intr_num, void (* //only one GPIO pad can connect with input signal esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int rts_io_num, int cts_io_num) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); - UART_CHECK((tx_io_num < 0 || (GPIO_IS_VALID_OUTPUT_GPIO(tx_io_num))), "tx_io_num error"); - UART_CHECK((rx_io_num < 0 || (GPIO_IS_VALID_GPIO(rx_io_num))), "rx_io_num error"); - UART_CHECK((rts_io_num < 0 || (GPIO_IS_VALID_OUTPUT_GPIO(rts_io_num))), "rts_io_num error"); - UART_CHECK((cts_io_num < 0 || (GPIO_IS_VALID_GPIO(cts_io_num))), "cts_io_num error"); +// UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); +// UART_CHECK((tx_io_num < 0 || (GPIO_IS_VALID_OUTPUT_GPIO(tx_io_num))), "tx_io_num error"); +// UART_CHECK((rx_io_num < 0 || (GPIO_IS_VALID_GPIO(rx_io_num))), "rx_io_num error"); +// UART_CHECK((rts_io_num < 0 || (GPIO_IS_VALID_OUTPUT_GPIO(rts_io_num))), "rts_io_num error"); +// UART_CHECK((cts_io_num < 0 || (GPIO_IS_VALID_GPIO(cts_io_num))), "cts_io_num error"); int tx_sig, rx_sig, rts_sig, cts_sig; switch(uart_num) { From abd4dc7d438d51711913591fe6f4d88643015448 Mon Sep 17 00:00:00 2001 From: Yinling Date: Mon, 24 Oct 2016 18:42:40 +0800 Subject: [PATCH 126/343] add know issue ^WIFI_CONN_0601: in STA+AP mode, when STA reconencting to enternal AP, external STA can't connect to AP --- components/idf_test/integration_test/KnownIssues | 1 + 1 file changed, 1 insertion(+) diff --git a/components/idf_test/integration_test/KnownIssues b/components/idf_test/integration_test/KnownIssues index 85b5b2f218..e0991f39b0 100644 --- a/components/idf_test/integration_test/KnownIssues +++ b/components/idf_test/integration_test/KnownIssues @@ -56,6 +56,7 @@ WIFI_CONN_0901 # Wifi connect issue WIFI_CONN_0104 ^WIFI_CONN_0104 +^WIFI_CONN_0601 # Wifi scan issue WIFI_SCAN_0303 From 3edcf5b096fa64ddca7772cf0cef8964d67a1bd9 Mon Sep 17 00:00:00 2001 From: Yinling Date: Mon, 24 Oct 2016 18:59:56 +0800 Subject: [PATCH 127/343] fix bug for case WIFI_CONN_0102: after set AP, STA will disconnected and do reconnect. scan could fail as reconnect also use scan --- components/idf_test/integration_test/TestCaseAll.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/idf_test/integration_test/TestCaseAll.yml b/components/idf_test/integration_test/TestCaseAll.yml index 3b2242787c..9e4823a297 100644 --- a/components/idf_test/integration_test/TestCaseAll.yml +++ b/components/idf_test/integration_test/TestCaseAll.yml @@ -5868,6 +5868,8 @@ test cases: - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] - - SSC SSC1 ap -S -s -n 15 - ['R SSC1 C +SAP:OK'] + - - SSC SSC2 sta -C -s -p + - ['R SSC2 RE "\+JAP:CONNECTED,%%s"%%()'] - - SSC SSC2 sta -S - ['R SSC2 RE "\+SCAN:%%s,.+,\d+,1"%%()'] comment: '' From d9005e739dbf1e32aab0b2cbce01eae100d43ef6 Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Mon, 24 Oct 2016 21:18:02 +0800 Subject: [PATCH 128/343] Add bytebuffer support to ringbuf.c --- .../freertos/include/freertos/ringbuf.h | 50 ++- components/freertos/ringbuf.c | 344 +++++++++++++----- 2 files changed, 303 insertions(+), 91 deletions(-) diff --git a/components/freertos/include/freertos/ringbuf.h b/components/freertos/include/freertos/ringbuf.h index 7884e9856e..93ba30758e 100644 --- a/components/freertos/include/freertos/ringbuf.h +++ b/components/freertos/include/freertos/ringbuf.h @@ -18,22 +18,34 @@ to this bit of memory will block. The requirement for items to be contiguous is slightly problematic when the only way to place the next item would involve a wraparound from the end to the beginning of the ringbuffer. This can -be solved in two ways: -- allow_split_items = pdTRUE: The insertion code will split the item in two items; one which fits +be solved (or not) in a few ways: +- type = RINGBUF_TYPE_ALLOWSPLIT: The insertion code will split the item in two items; one which fits in the space left at the end of the ringbuffer, one that contains the remaining data which is placed in the beginning. Two xRingbufferReceive calls will be needed to retrieve the data. -- allow_split_items = pdFALSE: The insertion code will leave the room at the end of the ringbuffer +- type = RINGBUF_TYPE_NOSPLIT: The insertion code will leave the room at the end of the ringbuffer unused and instead will put the entire item at the start of the ringbuffer, as soon as there is enough free space. +- type = RINGBUF_TYPE_BYTEBUF: This is your conventional byte-based ringbuffer. It does have no +overhead, but it has no item contiguousness either: a read will just give you the entire written +buffer space, or the space up to the end of the buffer, and writes can be broken up in any way +possible. Note that this type cannot do a 2nd read before returning the memory of the 1st. The maximum size of an item will be affected by this decision. When split items are allowed, it's acceptable to push items of (buffer_size)-16 bytes into the buffer. When it's not allowed, the -maximum size is (buffer_size/2)-8 bytes. +maximum size is (buffer_size/2)-8 bytes. The bytebuf can fill the entire buffer with data, it has +no overhead. */ //An opaque handle for a ringbuff object. typedef void * RingbufHandle_t; +//The various types of buffer +typedef enum { + RINGBUF_TYPE_NOSPLIT = 0, + RINGBUF_TYPE_ALLOWSPLIT, + RINGBUF_TYPE_BYTEBUF +} ringbuf_type_t; + /** * @brief Create a ring buffer @@ -45,7 +57,7 @@ typedef void * RingbufHandle_t; * * @return A RingbufHandle_t handle to the created ringbuffer, or NULL in case of error. */ -RingbufHandle_t xRingbufferCreate(size_t buf_length, BaseType_t allow_split_items); +RingbufHandle_t xRingbufferCreate(size_t buf_length, ringbuf_type_t type); /** @@ -120,6 +132,34 @@ void *xRingbufferReceive(RingbufHandle_t ringbuf, size_t *item_size, TickType_t void *xRingbufferReceiveFromISR(RingbufHandle_t ringbuf, size_t *item_size); +/** + * @brief Retrieve bytes from a ByteBuf type of ring buffer, specifying the maximum amount of bytes + * to return + * + * @param ringbuf - Ring buffer to retrieve the item from + * @param item_size - Pointer to a variable to which the size of the retrieved item will be written. + * @param xTicksToWait - Ticks to wait for items in the ringbuffer. + * + * @return Pointer to the retrieved item on success; *item_size filled with the length of the + * item. NULL on timeout, *item_size is untouched in that case. + */ +void *xRingbufferReceiveUpTo(RingbufHandle_t ringbuf, size_t *item_size, TickType_t ticks_to_wait, size_t wanted_size); + + +/** + * @brief Retrieve bytes from a ByteBuf type of ring buffer, specifying the maximum amount of bytes + * to return. Call this from an ISR. + * + * @param ringbuf - Ring buffer to retrieve the item from + * @param item_size - Pointer to a variable to which the size of the retrieved item will be written. + * + * @return Pointer to the retrieved item on success; *item_size filled with the length of the + * item. NULL when the ringbuffer is empty, *item_size is untouched in that case. + */ +void *xRingbufferReceiveUpToFromISR(RingbufHandle_t ringbuf, size_t *item_size, size_t wanted_size); + + + /** * @brief Return a previously-retrieved item to the ringbuffer * diff --git a/components/freertos/ringbuf.c b/components/freertos/ringbuf.c index 3651753147..77eb362843 100644 --- a/components/freertos/ringbuf.c +++ b/components/freertos/ringbuf.c @@ -18,6 +18,7 @@ #include "freertos/queue.h" #include "freertos/xtensa_api.h" #include "freertos/ringbuf.h" +#include "esp_attr.h" #include #include #include @@ -25,6 +26,7 @@ typedef enum { flag_allowsplit = 1, + flag_bytebuf = 2, } rbflag_t; typedef enum { @@ -33,8 +35,10 @@ typedef enum { } itemflag_t; +typedef struct ringbuf_t ringbuf_t; + //The ringbuffer structure -typedef struct { +struct ringbuf_t { SemaphoreHandle_t free_space_sem; //Binary semaphore, wakes up writing threads when there's more free space SemaphoreHandle_t items_buffered_sem; //Binary semaphore, indicates there are new packets in the circular buffer. See remark. size_t size; //Size of the data storage @@ -44,7 +48,12 @@ typedef struct { uint8_t *data; //Data storage portMUX_TYPE mux; //Spinlock for actual data/ptr/struct modification rbflag_t flags; -} ringbuf_t; + size_t maxItemSize; + //The following keep function pointers to hold different implementations for ringbuffer management. + BaseType_t (*copyItemToRingbufImpl)(ringbuf_t *rb, uint8_t *buffer, size_t buffer_size); + uint8_t *(*getItemFromRingbufImpl)(ringbuf_t *rb, size_t *length, int wanted_length); + void (*returnItemToRingbufImpl)(ringbuf_t *rb, void *item); +}; @@ -73,14 +82,16 @@ static int ringbufferFreeMem(ringbuf_t *rb) return free_size-1; } -//Copies a single item to the ring buffer. Assumes there is space in the ringbuffer and + +//Copies a single item to the ring buffer; refuses to split items. Assumes there is space in the ringbuffer and //the ringbuffer is locked. Increases write_ptr to the next item. Returns pdTRUE on //success, pdFALSE if it can't make the item fit and the calling routine needs to retry //later or fail. //This function by itself is not threadsafe, always call from within a muxed section. -static BaseType_t copyItemToRingbuf(ringbuf_t *rb, uint8_t *buffer, size_t buffer_size) +static BaseType_t copyItemToRingbufNoSplit(ringbuf_t *rb, uint8_t *buffer, size_t buffer_size) { - size_t rbuffer_size=(buffer_size+3)&~3; //Payload length, rounded to next 32-bit value + size_t rbuffer_size; + rbuffer_size=(buffer_size+3)&~3; //Payload length, rounded to next 32-bit value configASSERT(((int)rb->write_ptr&3)==0); //write_ptr needs to be 32-bit aligned configASSERT(rb->write_ptr-(rb->data+rb->size) >= sizeof(buf_entry_hdr_t)); //need to have at least the size //of a header to the end of the ringbuff @@ -88,65 +99,28 @@ static BaseType_t copyItemToRingbuf(ringbuf_t *rb, uint8_t *buffer, size_t buffe //See if we have enough contiguous space to write the buffer. if (rem_len < rbuffer_size + sizeof(buf_entry_hdr_t)) { - //The buffer can't be contiguously written to the ringbuffer, but needs special handling. Do - //that depending on how the ringbuffer is configured. - //The code here is also expected to check if the buffer, mangled in whatever way is implemented, - //will still fit, and return pdFALSE if that is not the case. - if (rb->flags & flag_allowsplit) { - //Buffer plus header is not going to fit in the room from wr_pos to the end of the - //ringbuffer... we need to split the write in two. - //First, see if this will fit at all. - if (ringbufferFreeMem(rb) < (sizeof(buf_entry_hdr_t)*2)+rbuffer_size) { - //Will not fit. - return pdFALSE; - } - //Because the code at the end of the function makes sure we always have - //room for a header, this should never assert. - configASSERT(rem_len>=sizeof(buf_entry_hdr_t)); - //Okay, it should fit. Write everything. - //First, place bit of buffer that does fit. Write header first... - buf_entry_hdr_t *hdr=(buf_entry_hdr_t *)rb->write_ptr; - hdr->flags=0; - hdr->len=rem_len-sizeof(buf_entry_hdr_t); - rb->write_ptr+=sizeof(buf_entry_hdr_t); - rem_len-=sizeof(buf_entry_hdr_t); - if (rem_len!=0) { - //..then write the data bit that fits. - memcpy(rb->write_ptr, buffer, rem_len); - //Update vars so the code later on will write the rest of the data. - buffer+=rem_len; - rbuffer_size-=rem_len; - buffer_size-=rem_len; - } else { - //Huh, only the header fit. Mark as dummy so the receive function doesn't receive - //an useless zero-byte packet. - hdr->flags|=iflag_dummydata; - } - rb->write_ptr=rb->data; - } else { - //Buffer plus header is not going to fit in the room from wr_pos to the end of the - //ringbuffer... but we're not allowed to split the buffer. We need to fill the - //rest of the ringbuffer with a dummy item so we can place the data at the _start_ of - //the ringbuffer.. - //First, find out if we actually have enough space at the start of the ringbuffer to - //make this work (Again, we need 4 bytes extra because otherwise read_ptr==free_ptr) - if (rb->free_ptr-rb->data < rbuffer_size+sizeof(buf_entry_hdr_t)+4) { - //Will not fit. - return pdFALSE; - } - //If the read buffer hasn't wrapped around yet, there's no way this will work either. - if (rb->free_ptr > rb->write_ptr) { - //No luck. - return pdFALSE; - } - - //Okay, it will fit. Mark the rest of the ringbuffer space with a dummy packet. - buf_entry_hdr_t *hdr=(buf_entry_hdr_t *)rb->write_ptr; - hdr->flags=iflag_dummydata; - //Reset the write pointer to the start of the ringbuffer so the code later on can - //happily write the data. - rb->write_ptr=rb->data; + //Buffer plus header is not going to fit in the room from wr_pos to the end of the + //ringbuffer... but we're not allowed to split the buffer. We need to fill the + //rest of the ringbuffer with a dummy item so we can place the data at the _start_ of + //the ringbuffer.. + //First, find out if we actually have enough space at the start of the ringbuffer to + //make this work (Again, we need 4 bytes extra because otherwise read_ptr==free_ptr) + if (rb->free_ptr-rb->data < rbuffer_size+sizeof(buf_entry_hdr_t)+4) { + //Will not fit. + return pdFALSE; } + //If the read buffer hasn't wrapped around yet, there's no way this will work either. + if (rb->free_ptr > rb->write_ptr) { + //No luck. + return pdFALSE; + } + + //Okay, it will fit. Mark the rest of the ringbuffer space with a dummy packet. + buf_entry_hdr_t *hdr=(buf_entry_hdr_t *)rb->write_ptr; + hdr->flags=iflag_dummydata; + //Reset the write pointer to the start of the ringbuffer so the code later on can + //happily write the data. + rb->write_ptr=rb->data; } else { //No special handling needed. Checking if it's gonna fit probably still is a good idea. if (ringbufferFreeMem(rb) < sizeof(buf_entry_hdr_t)+rbuffer_size) { @@ -174,9 +148,117 @@ static BaseType_t copyItemToRingbuf(ringbuf_t *rb, uint8_t *buffer, size_t buffe return pdTRUE; } +//Copies a single item to the ring buffer; allows split items. Assumes there is space in the ringbuffer and +//the ringbuffer is locked. Increases write_ptr to the next item. Returns pdTRUE on +//success, pdFALSE if it can't make the item fit and the calling routine needs to retry +//later or fail. +//This function by itself is not threadsafe, always call from within a muxed section. +static BaseType_t copyItemToRingbufAllowSplit(ringbuf_t *rb, uint8_t *buffer, size_t buffer_size) +{ + size_t rbuffer_size; + rbuffer_size=(buffer_size+3)&~3; //Payload length, rounded to next 32-bit value + configASSERT(((int)rb->write_ptr&3)==0); //write_ptr needs to be 32-bit aligned + configASSERT(rb->write_ptr-(rb->data+rb->size) >= sizeof(buf_entry_hdr_t)); //need to have at least the size + //of a header to the end of the ringbuff + size_t rem_len=(rb->data + rb->size) - rb->write_ptr; //length remaining until end of ringbuffer + + //See if we have enough contiguous space to write the buffer. + if (rem_len < rbuffer_size + sizeof(buf_entry_hdr_t)) { + //The buffer can't be contiguously written to the ringbuffer, but needs special handling. Do + //that depending on how the ringbuffer is configured. + //The code here is also expected to check if the buffer, mangled in whatever way is implemented, + //will still fit, and return pdFALSE if that is not the case. + //Buffer plus header is not going to fit in the room from wr_pos to the end of the + //ringbuffer... we need to split the write in two. + //First, see if this will fit at all. + if (ringbufferFreeMem(rb) < (sizeof(buf_entry_hdr_t)*2)+rbuffer_size) { + //Will not fit. + return pdFALSE; + } + //Because the code at the end of the function makes sure we always have + //room for a header, this should never assert. + configASSERT(rem_len>=sizeof(buf_entry_hdr_t)); + //Okay, it should fit. Write everything. + //First, place bit of buffer that does fit. Write header first... + buf_entry_hdr_t *hdr=(buf_entry_hdr_t *)rb->write_ptr; + hdr->flags=0; + hdr->len=rem_len-sizeof(buf_entry_hdr_t); + rb->write_ptr+=sizeof(buf_entry_hdr_t); + rem_len-=sizeof(buf_entry_hdr_t); + if (rem_len!=0) { + //..then write the data bit that fits. + memcpy(rb->write_ptr, buffer, rem_len); + //Update vars so the code later on will write the rest of the data. + buffer+=rem_len; + rbuffer_size-=rem_len; + buffer_size-=rem_len; + } else { + //Huh, only the header fit. Mark as dummy so the receive function doesn't receive + //an useless zero-byte packet. + hdr->flags|=iflag_dummydata; + } + rb->write_ptr=rb->data; + } else { + //No special handling needed. Checking if it's gonna fit probably still is a good idea. + if (ringbufferFreeMem(rb) < sizeof(buf_entry_hdr_t)+rbuffer_size) { + //Buffer is not going to fit, period. + return pdFALSE; + } + } + + //If we are here, the buffer is guaranteed to fit in the space starting at the write pointer. + buf_entry_hdr_t *hdr=(buf_entry_hdr_t *)rb->write_ptr; + hdr->len=buffer_size; + hdr->flags=0; + rb->write_ptr+=sizeof(buf_entry_hdr_t); + memcpy(rb->write_ptr, buffer, buffer_size); + rb->write_ptr+=rbuffer_size; + + //The buffer will wrap around if we don't have room for a header anymore. + if ((rb->data+rb->size)-rb->write_ptr < sizeof(buf_entry_hdr_t)) { + //'Forward' the write buffer until we are at the start of the ringbuffer. + //The read pointer will always be at the start of a full header, which cannot + //exist at the point of the current write pointer, so there's no chance of overtaking + //that. + rb->write_ptr=rb->data; + } + return pdTRUE; +} + + +//Copies a bunch of daya to the ring bytebuffer. Assumes there is space in the ringbuffer and +//the ringbuffer is locked. Increases write_ptr to the next item. Returns pdTRUE on +//success, pdFALSE if it can't make the item fit and the calling routine needs to retry +//later or fail. +//This function by itself is not threadsafe, always call from within a muxed section. +static BaseType_t copyItemToRingbufByteBuf(ringbuf_t *rb, uint8_t *buffer, size_t buffer_size) +{ + size_t rem_len=(rb->data + rb->size) - rb->write_ptr; //length remaining until end of ringbuffer + + //See if we have enough contiguous space to write the buffer. + if (rem_len < buffer_size) { + //...Nope. Write the data bit that fits. + memcpy(rb->write_ptr, buffer, rem_len); + //Update vars so the code later on will write the rest of the data. + buffer+=rem_len; + buffer_size-=rem_len; + rb->write_ptr=rb->data; + } + + //If we are here, the buffer is guaranteed to fit in the space starting at the write pointer. + memcpy(rb->write_ptr, buffer, buffer_size); + rb->write_ptr+=buffer_size; + //The buffer will wrap around if we're at the end. + if ((rb->data+rb->size)==rb->write_ptr) { + rb->write_ptr=rb->data; + } + return pdTRUE; +} + //Retrieves a pointer to the data of the next item, or NULL if this is not possible. //This function by itself is not threadsafe, always call from within a muxed section. -static uint8_t *getItemFromRingbuf(ringbuf_t *rb, size_t *length) +//Because we always return one item, this function ignores the wanted_length variable. +static uint8_t *getItemFromRingbufDefault(ringbuf_t *rb, size_t *length, int wanted_length) { uint8_t *ret; configASSERT(((int)rb->read_ptr&3)==0); @@ -210,10 +292,48 @@ static uint8_t *getItemFromRingbuf(ringbuf_t *rb, size_t *length) return ret; } +//Retrieves a pointer to the data in the buffer, or NULL if this is not possible. +//This function by itself is not threadsafe, always call from within a muxed section. +//This function honours the wanted_length and will never return more data than this. +static uint8_t *getItemFromRingbufByteBuf(ringbuf_t *rb, size_t *length, int wanted_length) +{ + uint8_t *ret; + if (rb->read_ptr != rb->free_ptr) { + //This type of ringbuff does not support multiple outstanding buffers. + return NULL; + } + if (rb->read_ptr == rb->write_ptr) { + //No data available. + return NULL; + } + ret=rb->read_ptr; + if (rb->read_ptr > rb->write_ptr) { + //Available data wraps around. Give data until the end of the buffer. + *length=rb->size-(rb->read_ptr - rb->data); + if (wanted_length != 0 && *length > wanted_length) { + *length=wanted_length; + rb->read_ptr+=wanted_length; + } else { + rb->read_ptr=rb->data; + } + } else { + //Return data up to write pointer. + *length=rb->write_ptr -rb->read_ptr; + if (wanted_length != 0 && *length > wanted_length) { + *length=wanted_length; + rb->read_ptr+=wanted_length; + } else { + rb->read_ptr=rb->write_ptr; + } + } + return ret; +} + + //Returns an item to the ringbuffer. Will mark the item as free, and will see if the free pointer //can be increase. //This function by itself is not threadsafe, always call from within a muxed section. -static void returnItemToRingbuf(ringbuf_t *rb, void *item) { +static void returnItemToRingbufDefault(ringbuf_t *rb, void *item) { uint8_t *data=(uint8_t*)item; configASSERT(((int)rb->free_ptr&3)==0); configASSERT(data >= rb->data); @@ -249,6 +369,17 @@ static void returnItemToRingbuf(ringbuf_t *rb, void *item) { } +//Returns an item to the ringbuffer. Will mark the item as free, and will see if the free pointer +//can be increase. +//This function by itself is not threadsafe, always call from within a muxed section. +static void returnItemToRingbufBytebuf(ringbuf_t *rb, void *item) { + uint8_t *data=(uint8_t*)item; + configASSERT(data >= rb->data); + configASSERT(data < rb->data+rb->size); + //Free the read memory. + rb->free_ptr=rb->read_ptr; +} + void xRingbufferPrintInfo(RingbufHandle_t ringbuf) { ringbuf_t *rb=(ringbuf_t *)ringbuf; @@ -259,7 +390,7 @@ void xRingbufferPrintInfo(RingbufHandle_t ringbuf) -RingbufHandle_t xRingbufferCreate(size_t buf_length, BaseType_t allow_split_items) +RingbufHandle_t xRingbufferCreate(size_t buf_length, ringbuf_type_t type) { ringbuf_t *rb = malloc(sizeof(ringbuf_t)); if (rb==NULL) goto err; @@ -273,9 +404,35 @@ RingbufHandle_t xRingbufferCreate(size_t buf_length, BaseType_t allow_split_item rb->free_space_sem = xSemaphoreCreateBinary(); rb->items_buffered_sem = xSemaphoreCreateBinary(); rb->flags=0; - if (allow_split_items) rb->flags|=flag_allowsplit; + if (type==RINGBUF_TYPE_ALLOWSPLIT) { + rb->flags|=flag_allowsplit; + rb->copyItemToRingbufImpl=copyItemToRingbufAllowSplit; + rb->getItemFromRingbufImpl=getItemFromRingbufDefault; + rb->returnItemToRingbufImpl=returnItemToRingbufDefault; + //Calculate max item size. Worst case, we need to split an item into two, which means two headers of overhead. + rb->maxItemSize=rb->size-(sizeof(buf_entry_hdr_t)*2)-4; + } else if (type==RINGBUF_TYPE_BYTEBUF) { + rb->flags|=flag_bytebuf; + rb->copyItemToRingbufImpl=copyItemToRingbufByteBuf; + rb->getItemFromRingbufImpl=getItemFromRingbufByteBuf; + rb->returnItemToRingbufImpl=returnItemToRingbufBytebuf; + //Calculate max item size. We have no headers and can split anywhere -> size is total size minus one. + rb->maxItemSize=rb->size-1; + } else if (type==RINGBUF_TYPE_NOSPLIT) { + rb->copyItemToRingbufImpl=copyItemToRingbufNoSplit; + rb->getItemFromRingbufImpl=getItemFromRingbufDefault; + rb->returnItemToRingbufImpl=returnItemToRingbufDefault; + //Calculate max item size. Worst case, we have the write ptr in such a position that we are lacking four bytes of free + //memory to put an item into the rest of the memory. If this happens, we have to dummy-fill + //(item_data-4) bytes of buffer, then we only have (size-(item_data-4) bytes left to fill + //with the real item. (item size being header+data) + rb->maxItemSize=(rb->size/2)-sizeof(buf_entry_hdr_t)-4; + } else { + configASSERT(0); + } if (rb->free_space_sem == NULL || rb->items_buffered_sem == NULL) goto err; vPortCPUInitializeMutex(&rb->mux); + return (RingbufHandle_t)rb; err: @@ -303,18 +460,7 @@ size_t xRingbufferGetMaxItemSize(RingbufHandle_t ringbuf) { ringbuf_t *rb=(ringbuf_t *)ringbuf; configASSERT(rb); - //In both cases, we return 4 bytes less than what we actually can have. If the ringbuffer is - //indeed entirely filled, read_ptr==free_ptr, which throws off the free space calculation. - if (rb->flags & flag_allowsplit) { - //Worst case, we need to split an item into two, which means two headers of overhead. - return rb->size-(sizeof(buf_entry_hdr_t)*2)-4; - } else { - //Worst case, we have the write ptr in such a position that we are lacking four bytes of free - //memory to put an item into the rest of the memory. If this happens, we have to dummy-fill - //(item_data-4) bytes of buffer, then we only have (size-(item_data-4) bytes left to fill - //with the real item. (item size being header+data) - return (rb->size/2)-sizeof(buf_entry_hdr_t)-4; - } + return rb->maxItemSize; } BaseType_t xRingbufferSend(RingbufHandle_t ringbuf, void *data, size_t dataSize, TickType_t ticks_to_wait) @@ -352,7 +498,7 @@ BaseType_t xRingbufferSend(RingbufHandle_t ringbuf, void *data, size_t dataSize, portENTER_CRITICAL(&rb->mux); //Another thread may have been able to sneak its write first. Check again now we locked the ringbuff, and retry //everything if this is the case. Otherwise, we can write and are done. - done=copyItemToRingbuf(rb, data, dataSize); + done=rb->copyItemToRingbufImpl(rb, data, dataSize); portEXIT_CRITICAL(&rb->mux); } xSemaphoreGive(rb->items_buffered_sem); @@ -371,7 +517,7 @@ BaseType_t xRingbufferSendFromISR(RingbufHandle_t ringbuf, void *data, size_t da //Does not fit in the remaining space in the ringbuffer. write_succeeded=pdFALSE; } else { - write_succeeded = copyItemToRingbuf(rb, data, dataSize); + write_succeeded = rb->copyItemToRingbufImpl(rb, data, dataSize); } portEXIT_CRITICAL_ISR(&rb->mux); if (write_succeeded) { @@ -381,7 +527,7 @@ BaseType_t xRingbufferSendFromISR(RingbufHandle_t ringbuf, void *data, size_t da } -void *xRingbufferReceive(RingbufHandle_t ringbuf, size_t *item_size, TickType_t ticks_to_wait) +static void *xRingbufferReceiveGeneric(RingbufHandle_t ringbuf, size_t *item_size, TickType_t ticks_to_wait, size_t wanted_size) { ringbuf_t *rb=(ringbuf_t *)ringbuf; uint8_t *itemData; @@ -398,7 +544,7 @@ void *xRingbufferReceive(RingbufHandle_t ringbuf, size_t *item_size, TickType_t } //Okay, we seem to have data in the buffer. Grab the mux and copy it out if it's still there. portENTER_CRITICAL(&rb->mux); - itemData=getItemFromRingbuf(rb, item_size); + itemData=rb->getItemFromRingbufImpl(rb, item_size, wanted_size); portEXIT_CRITICAL(&rb->mux); if (itemData) { //We managed to get an item. @@ -408,6 +554,11 @@ void *xRingbufferReceive(RingbufHandle_t ringbuf, size_t *item_size, TickType_t return (void*)itemData; } +void *xRingbufferReceive(RingbufHandle_t ringbuf, size_t *item_size, TickType_t ticks_to_wait) +{ + return xRingbufferReceiveGeneric(ringbuf, item_size, ticks_to_wait, 0); +} + void *xRingbufferReceiveFromISR(RingbufHandle_t ringbuf, size_t *item_size) { @@ -415,7 +566,28 @@ void *xRingbufferReceiveFromISR(RingbufHandle_t ringbuf, size_t *item_size) uint8_t *itemData; configASSERT(rb); portENTER_CRITICAL_ISR(&rb->mux); - itemData=getItemFromRingbuf(rb, item_size); + itemData=rb->getItemFromRingbufImpl(rb, item_size, 0); + portEXIT_CRITICAL_ISR(&rb->mux); + return (void*)itemData; +} + +void *xRingbufferReceiveUpTo(RingbufHandle_t ringbuf, size_t *item_size, TickType_t ticks_to_wait, size_t wanted_size) { + ringbuf_t *rb=(ringbuf_t *)ringbuf; + if (wanted_size == 0) return NULL; + configASSERT(rb); + configASSERT(rb->flags & flag_bytebuf); + return xRingbufferReceiveGeneric(ringbuf, item_size, ticks_to_wait, wanted_size); +} + +void *xRingbufferReceiveUpToFromISR(RingbufHandle_t ringbuf, size_t *item_size, size_t wanted_size) +{ + ringbuf_t *rb=(ringbuf_t *)ringbuf; + uint8_t *itemData; + if (wanted_size == 0) return NULL; + configASSERT(rb); + configASSERT(rb->flags & flag_bytebuf); + portENTER_CRITICAL_ISR(&rb->mux); + itemData=rb->getItemFromRingbufImpl(rb, item_size, 0); portEXIT_CRITICAL_ISR(&rb->mux); return (void*)itemData; } @@ -425,7 +597,7 @@ void vRingbufferReturnItem(RingbufHandle_t ringbuf, void *item) { ringbuf_t *rb=(ringbuf_t *)ringbuf; portENTER_CRITICAL_ISR(&rb->mux); - returnItemToRingbuf(rb, item); + rb->returnItemToRingbufImpl(rb, item); portEXIT_CRITICAL_ISR(&rb->mux); xSemaphoreGive(rb->free_space_sem); } @@ -435,7 +607,7 @@ void vRingbufferReturnItemFromISR(RingbufHandle_t ringbuf, void *item, BaseType_ { ringbuf_t *rb=(ringbuf_t *)ringbuf; portENTER_CRITICAL_ISR(&rb->mux); - returnItemToRingbuf(rb, item); + rb->returnItemToRingbufImpl(rb, item); portEXIT_CRITICAL_ISR(&rb->mux); xSemaphoreGiveFromISR(rb->free_space_sem, higher_prio_task_awoken); } From d7ea61734b2474460fde113833a382a81ba88fb6 Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Mon, 24 Oct 2016 21:25:48 +0800 Subject: [PATCH 129/343] Tabs -> spaces --- components/freertos/ringbuf.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/components/freertos/ringbuf.c b/components/freertos/ringbuf.c index 77eb362843..ce5504596a 100644 --- a/components/freertos/ringbuf.c +++ b/components/freertos/ringbuf.c @@ -556,7 +556,7 @@ static void *xRingbufferReceiveGeneric(RingbufHandle_t ringbuf, size_t *item_siz void *xRingbufferReceive(RingbufHandle_t ringbuf, size_t *item_size, TickType_t ticks_to_wait) { - return xRingbufferReceiveGeneric(ringbuf, item_size, ticks_to_wait, 0); + return xRingbufferReceiveGeneric(ringbuf, item_size, ticks_to_wait, 0); } @@ -573,17 +573,17 @@ void *xRingbufferReceiveFromISR(RingbufHandle_t ringbuf, size_t *item_size) void *xRingbufferReceiveUpTo(RingbufHandle_t ringbuf, size_t *item_size, TickType_t ticks_to_wait, size_t wanted_size) { ringbuf_t *rb=(ringbuf_t *)ringbuf; - if (wanted_size == 0) return NULL; + if (wanted_size == 0) return NULL; configASSERT(rb); configASSERT(rb->flags & flag_bytebuf); - return xRingbufferReceiveGeneric(ringbuf, item_size, ticks_to_wait, wanted_size); + return xRingbufferReceiveGeneric(ringbuf, item_size, ticks_to_wait, wanted_size); } void *xRingbufferReceiveUpToFromISR(RingbufHandle_t ringbuf, size_t *item_size, size_t wanted_size) { ringbuf_t *rb=(ringbuf_t *)ringbuf; uint8_t *itemData; - if (wanted_size == 0) return NULL; + if (wanted_size == 0) return NULL; configASSERT(rb); configASSERT(rb->flags & flag_bytebuf); portENTER_CRITICAL_ISR(&rb->mux); From 700ed6365123f30a15f5b80ffef9d3b489c160d4 Mon Sep 17 00:00:00 2001 From: liuzhifu Date: Tue, 25 Oct 2016 09:26:10 +0800 Subject: [PATCH 130/343] component/tcpip_adapter: not update dhcps status when it is stopped after mode switch When switch the mode from WIFI_MODE_STA/WIFI_MODE_NULL to WIFI_MODE_AP/WIFI_MODE_APSTA, if the dhcp server is STOPPED, then dhcp server will not start automatically. --- components/tcpip_adapter/tcpip_adapter_lwip.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/components/tcpip_adapter/tcpip_adapter_lwip.c b/components/tcpip_adapter/tcpip_adapter_lwip.c index 78fecf2cbf..12cf05f95f 100644 --- a/components/tcpip_adapter/tcpip_adapter_lwip.c +++ b/components/tcpip_adapter/tcpip_adapter_lwip.c @@ -103,7 +103,9 @@ esp_err_t tcpip_adapter_stop(tcpip_adapter_if_t tcpip_if) if (tcpip_if == TCPIP_ADAPTER_IF_AP) { dhcps_stop(esp_netif[tcpip_if]); // TODO: dhcps checks status by its self - dhcps_status = TCPIP_ADAPTER_DHCP_INIT; + if (TCPIP_ADAPTER_DHCP_STOPPED != dhcps_status){ + dhcps_status = TCPIP_ADAPTER_DHCP_INIT; + } } else if (tcpip_if == TCPIP_ADAPTER_IF_STA) { dhcp_release(esp_netif[tcpip_if]); dhcp_stop(esp_netif[tcpip_if]); From 75a11589a16a0f0a6e451ed2eecf9279ce2eb2bc Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Tue, 25 Oct 2016 17:05:13 +0800 Subject: [PATCH 131/343] Disable brown-out WDT, fix thread WDT, add panic reason indication to _xt_panic() --- components/esp32/Kconfig | 12 +++-- components/esp32/brownout.c | 10 +++- components/esp32/int_wdt.c | 12 +++-- components/esp32/task_wdt.c | 43 ++++++++++----- .../include/freertos/FreeRTOSConfig.h | 1 + components/freertos/include/freertos/panic.h | 13 +++++ components/freertos/panic.c | 54 ++++++++++++++++++- components/freertos/tasks.c | 1 - components/freertos/xtensa_vectors.S | 11 ++++ 9 files changed, 134 insertions(+), 23 deletions(-) diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig index a2faa926a8..dbd1cfb6f6 100644 --- a/components/esp32/Kconfig +++ b/components/esp32/Kconfig @@ -140,7 +140,6 @@ config ULP_COPROC_RESERVE_MEM default 0 depends on !ULP_COPROC_ENABLED -menu "Watchdogs & brown-out detection" config INT_WDT bool "Interrupt watchdog" @@ -155,7 +154,7 @@ config INT_WDT_TIMEOUT_MS int "Interrupt watchdog timeout (ms)" depends on INT_WDT default 10 - range INT_WDT_TIMEOUT_MIN 10000 + range 10 10000 help The timeout of the watchdog, in miliseconds. Make this higher than the FreeRTOS tick rate. @@ -190,11 +189,15 @@ config TASK_WDT_CHECK_IDLE_TASK With this turned on, the task WDT can detect if the idle task is not called within the task watchdog timeout period. The idle task not being called usually is a symptom of another task hoarding the CPU. It is also a bad thing because FreeRTOS household tasks depend on the - idle task getting some runtime every now and then. + idle task getting some runtime every now and then. Take Care: With this disabled, this + watchdog will trigger if no tasks register themselves within the timeout value. +#The brownout detector code is disabled (by making it depend on a nonexisting symbol) because the current revision of ESP32 +#silicon has a bug in the brown-out detector, rendering it unusable for resetting the CPU. config BROWNOUT_DET bool "Hardware brownout detect & reset" default y + depends on NEEDS_ESP32_NEW_SILICON_REV help The ESP32 has a built-in brownout detector which can detect if the voltage is lower than a specific value. If this happens, it will reset the chip in order to prevent unintended @@ -207,6 +210,8 @@ choice BROWNOUT_DET_LVL_SEL help The brownout detector will reset the chip when the supply voltage is below this level. +#The voltage levels here are estimates, more work needs to be done to figure out the exact voltages +#of the brownout threshold levels. config BROWNOUT_DET_LVL_SEL_0 bool "2.1V" config BROWNOUT_DET_LVL_SEL_1 @@ -246,7 +251,6 @@ config BROWNOUT_DET_RESETDELAY The brownout detector can reset the chip after a certain delay, in order to make sure e.g. a voltage dip has entirely passed before trying to restart the chip. You can set the delay here. -endmenu diff --git a/components/esp32/brownout.c b/components/esp32/brownout.c index 8e8805b8e5..97846ae8c0 100644 --- a/components/esp32/brownout.c +++ b/components/esp32/brownout.c @@ -22,10 +22,18 @@ #include "soc/rtc_cntl_reg.h" +#if CONFIG_BROWNOUT_DET +/* +This file ins included in esp-idf, but the menuconfig option for this is disabled because a silicon bug +prohibits the brownout detector from functioning correctly on the ESP32. +*/ + void esp_brownout_init() { WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, RTC_CNTL_BROWN_OUT_ENA | (CONFIG_BROWNOUT_DET_LVL << RTC_CNTL_DBROWN_OUT_THRES_S) | RTC_CNTL_BROWN_OUT_RST_ENA | (((CONFIG_BROWNOUT_DET_RESETDELAY*150)/1000) << RTC_CNTL_BROWN_OUT_RST_WAIT_S) | RTC_CNTL_BROWN_OUT_PD_RF_ENA|RTC_CNTL_BROWN_OUT_CLOSE_FLASH_ENA); -} \ No newline at end of file +} + +#endif \ No newline at end of file diff --git a/components/esp32/int_wdt.c b/components/esp32/int_wdt.c index 2b4d9e0841..5fb7a63bae 100644 --- a/components/esp32/int_wdt.c +++ b/components/esp32/int_wdt.c @@ -44,7 +44,6 @@ This uses the TIMERG1 WDT. #define WDT_INT_NUM 24 - #define WDT_WRITE_KEY 0x50D83AA1 void int_wdt_init() { @@ -55,11 +54,15 @@ void int_wdt_init() { TIMERG1.wdt_config0.stg0=1; //1st stage timeout: interrupt TIMERG1.wdt_config0.stg1=3; //2nd stage timeout: reset system TIMERG1.wdt_config1.clk_prescale=80*500; //Prescaler: wdt counts in ticks of 0.5mS - TIMERG1.wdt_config2=CONFIG_INT_WDT_TIMEOUT_MS*2; //Set timeout before interrupt - TIMERG1.wdt_config3=CONFIG_INT_WDT_TIMEOUT_MS*4; //Set timeout before reset + //The timer configs initially are set to 5 seconds, to make sure the CPU can start up. The tick hook sets + //it to their actual value. + TIMERG1.wdt_config2=10000; + TIMERG1.wdt_config3=10000; TIMERG1.wdt_config0.en=1; TIMERG1.wdt_feed=1; TIMERG1.wdt_wprotect=0; + TIMERG1.int_clr_timers.wdt=1; + TIMERG1.int_ena.wdt=1; ESP_INTR_DISABLE(WDT_INT_NUM); intr_matrix_set(xPortGetCoreID(), ETS_TG1_WDT_LEVEL_INTR_SOURCE, WDT_INT_NUM); //We do not register a handler for the interrupt because it is interrupt level 4 which @@ -69,9 +72,10 @@ void int_wdt_init() { } - void vApplicationTickHook(void) { TIMERG1.wdt_wprotect=WDT_WRITE_KEY; + TIMERG1.wdt_config2=CONFIG_INT_WDT_TIMEOUT_MS*2; //Set timeout before interrupt + TIMERG1.wdt_config3=CONFIG_INT_WDT_TIMEOUT_MS*4; //Set timeout before reset TIMERG1.wdt_feed=1; TIMERG1.wdt_wprotect=0; } diff --git a/components/esp32/task_wdt.c b/components/esp32/task_wdt.c index 7ae3dfb2e8..3e4c436394 100644 --- a/components/esp32/task_wdt.c +++ b/components/esp32/task_wdt.c @@ -33,6 +33,7 @@ This uses the TIMERG0 WDT. #include #include "esp_err.h" #include "esp_intr.h" +#include "esp_attr.h" #include "soc/timer_group_struct.h" #include "esp_log.h" @@ -42,7 +43,6 @@ This uses the TIMERG0 WDT. static const char* TAG = "task_wdt"; - typedef struct wdt_task_t wdt_task_t; struct wdt_task_t { TaskHandle_t task_handle; @@ -50,16 +50,35 @@ struct wdt_task_t { wdt_task_t *next; }; - static wdt_task_t *wdt_task_list=NULL; +//We use this interrupt number on whatever task calls task_wdt_init. #define WDT_INT_NUM 24 - #define WDT_WRITE_KEY 0x50D83AA1 -static void task_wdt_isr(void *arg) { +static void IRAM_ATTR task_wdt_isr(void *arg) { + wdt_task_t *wdttask; + const char *cpu; + //Feed the watchdog so we do not reset + TIMERG0.wdt_wprotect=WDT_WRITE_KEY; + TIMERG0.wdt_feed=1; + TIMERG0.wdt_wprotect=0; + //Ack interrupt + TIMERG0.int_clr_timers.wdt=1; + //Watchdog got triggered because at least one task did not report in. + ets_printf("Task watchdog got triggered. The following tasks did not feed the watchdog in time:\n"); + for (wdttask=wdt_task_list; wdttask!=NULL; wdttask=wdttask->next) { + if (!wdttask->fed_watchdog) { + cpu=xTaskGetAffinity(wdttask->task_handle)==0?"CPU 0":"CPU 1"; + if (xTaskGetAffinity(wdttask->task_handle)==tskNO_AFFINITY) cpu="CPU 0/1"; + printf(" - %s (%s)\n", pcTaskGetTaskName(wdttask->task_handle), cpu); + } + } +#if CONFIG_TASK_WDT_PANIC + ets_printf("Aborting.\n"); abort(); +#endif } @@ -69,7 +88,7 @@ void task_wdt_feed() { TaskHandle_t handle=xTaskGetCurrentTaskHandle(); //Walk the linked list of wdt tasks to find this one, as well as see if we need to feed //the real watchdog timer. - while (wdttask!=NULL) { + for (wdttask=wdt_task_list; wdttask!=NULL; wdttask=wdttask->next) { //See if we are at the current task. if (wdttask->task_handle == handle) { wdttask->fed_watchdog=true; @@ -77,8 +96,6 @@ void task_wdt_feed() { } //If even one task in the list doesn't have the do_feed_wdt var set, we do not feed the watchdog. if (!wdttask->fed_watchdog) do_feed_wdt=false; - //Next entry. - wdttask=wdttask->next; } if (!found_task) { @@ -91,9 +108,8 @@ void task_wdt_feed() { if (wdt_task_list == NULL) { wdt_task_list=newtask; } else { - wdttask=wdt_task_list; - while (!(wdttask->next == NULL)) wdttask=wdttask->next; - wdttask->next=wdttask; + for (wdttask=wdt_task_list; wdttask->next!=NULL; wdttask=wdttask->next) ; + wdttask->next=newtask; } } if (do_feed_wdt) { @@ -101,6 +117,8 @@ void task_wdt_feed() { TIMERG0.wdt_wprotect=WDT_WRITE_KEY; TIMERG0.wdt_feed=1; TIMERG0.wdt_wprotect=0; + //Reset fed_watchdog status + for (wdttask=wdt_task_list; wdttask->next!=NULL; wdttask=wdttask->next) wdttask->fed_watchdog=false; } } @@ -143,12 +161,13 @@ void task_wdt_init() { TIMERG0.wdt_feed=1; TIMERG0.wdt_wprotect=0; ESP_INTR_DISABLE(ETS_T0_WDT_INUM); - intr_matrix_set(xPortGetCoreID(), ETS_TG1_WDT_LEVEL_INTR_SOURCE, ETS_T0_WDT_INUM); + intr_matrix_set(xPortGetCoreID(), ETS_TG0_WDT_LEVEL_INTR_SOURCE, ETS_T0_WDT_INUM); xt_set_interrupt_handler(ETS_T0_WDT_INUM, task_wdt_isr, NULL); + TIMERG0.int_clr_timers.wdt=1; + TIMERG0.int_ena.wdt=1; ESP_INTR_ENABLE(ETS_T0_WDT_INUM); } - #if CONFIG_TASK_WDT_CHECK_IDLE_TASK void vApplicationIdleHook(void) { task_wdt_feed(); diff --git a/components/freertos/include/freertos/FreeRTOSConfig.h b/components/freertos/include/freertos/FreeRTOSConfig.h index a5483d6bbd..b732d1c07b 100644 --- a/components/freertos/include/freertos/FreeRTOSConfig.h +++ b/components/freertos/include/freertos/FreeRTOSConfig.h @@ -231,6 +231,7 @@ #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_pcTaskGetTaskName 1 #if CONFIG_ENABLE_MEMORY_DEBUG #define configENABLE_MEMORY_DEBUG 1 diff --git a/components/freertos/include/freertos/panic.h b/components/freertos/include/freertos/panic.h index 9e902ed20b..ba47e3d439 100644 --- a/components/freertos/include/freertos/panic.h +++ b/components/freertos/include/freertos/panic.h @@ -1,7 +1,20 @@ #ifndef PANIC_H #define PANIC_H + +#define PANIC_RSN_NONE 0 +#define PANIC_RSN_DEBUGEXCEPTION 1 +#define PANIC_RSN_DOUBLEEXCEPTION 2 +#define PANIC_RSN_KERNELEXCEPTION 3 +#define PANIC_RSN_COPROCEXCEPTION 4 +#define PANIC_RSN_INTWDT 5 +#define PANIC_RSN_MAX 5 + + +#ifndef __ASSEMBLER__ + void setBreakpointIfJtag(void *fn); +#endif #endif \ No newline at end of file diff --git a/components/freertos/panic.c b/components/freertos/panic.c index 6a87679d13..0c912e56fc 100644 --- a/components/freertos/panic.c +++ b/components/freertos/panic.c @@ -25,8 +25,13 @@ #include "soc/io_mux_reg.h" #include "soc/dport_reg.h" #include "soc/rtc_cntl_reg.h" +#include "soc/timer_group_struct.h" #include "gdbstub.h" +#include "panic.h" + +#define WDT_WRITE_KEY 0x50D83AA1 + /* Panic handlers; these get called when an unhandled exception occurs or the assembly-level @@ -130,10 +135,25 @@ static int inOCDMode() { } void panicHandler(XtExcFrame *frame) { + int *regs=(int*)frame; + //Please keep in sync with PANIC_RSN_* defines + const char *reasons[]={ + "Unknown reason", + "Unhandled debug exception", + "Double exception", + "Unhandled kernel exception", + "Coprocessor exception", + "Interrupt wdt timeout" + }; + const char *reason=reasons[0]; + //The panic reason is stored in the EXCCAUSE register. + if (regs[20]<=PANIC_RSN_MAX) reason=reasons[regs[20]]; haltOtherCore(); panicPutStr("Guru Meditation Error: Core "); panicPutDec(xPortGetCoreID()); - panicPutStr(" panic'ed.\r\n"); + panicPutStr(" panic'ed ("); + panicPutStr(reason); + panicPutStr(")\r\n"); if (inOCDMode()) { asm("break.n 1"); @@ -175,6 +195,33 @@ void xt_unhandled_exception(XtExcFrame *frame) { } +//Disables all but one WDT, and allows enough time on that WDT to do what we need to do. +static void reconfigureAllWdts() { + TIMERG0.wdt_wprotect=WDT_WRITE_KEY; + TIMERG0.wdt_feed=1; + TIMERG0.wdt_config0.sys_reset_length=7; //3.2uS + TIMERG0.wdt_config0.cpu_reset_length=7; //3.2uS + TIMERG0.wdt_config0.stg0=3; //1st stage timeout: reset system + TIMERG0.wdt_config1.clk_prescale=80*500; //Prescaler: wdt counts in ticks of 0.5mS + TIMERG0.wdt_config2=2000; //1 second before reset + TIMERG0.wdt_config0.en=1; + TIMERG0.wdt_wprotect=0; + //Disable wdt 1 + TIMERG1.wdt_wprotect=WDT_WRITE_KEY; + TIMERG1.wdt_config0.en=0; + TIMERG1.wdt_wprotect=0; +} + +static void disableAllWdts() { + TIMERG0.wdt_wprotect=WDT_WRITE_KEY; + TIMERG0.wdt_config0.en=0; + TIMERG0.wdt_wprotect=0; + TIMERG1.wdt_wprotect=WDT_WRITE_KEY; + TIMERG1.wdt_config0.en=0; + TIMERG0.wdt_wprotect=0; +} + + /* We arrive here after a panic or unhandled exception, when no OCD is detected. Dump the registers to the serial port and either jump to the gdb stub, halt the CPU or reboot. @@ -187,6 +234,9 @@ void commonErrorHandler(XtExcFrame *frame) { "A6 ","A7 ","A8 ","A9 ","A10 ","A11 ","A12 ","A13 ", "A14 ","A15 ","SAR ","EXCCAUSE","EXCVADDR","LBEG ","LEND ","LCOUNT "}; + //Feed the watchdogs, so they will give us time to print out debug info + reconfigureAllWdts(); + panicPutStr("Register dump:\r\n"); for (x=0; x<24; x+=4) { @@ -201,6 +251,7 @@ void commonErrorHandler(XtExcFrame *frame) { panicPutStr("\r\n"); } #if CONFIG_FREERTOS_PANIC_GDBSTUB + disableAllWdts(); panicPutStr("Entering gdb stub now.\r\n"); gdbstubPanicHandler(frame); #elif CONFIG_FREERTOS_PANIC_PRINT_REBOOT || CONFIG_FREERTOS_PANIC_SILENT_REBOOT @@ -208,6 +259,7 @@ void commonErrorHandler(XtExcFrame *frame) { for (x=0; x<100; x++) ets_delay_us(1000); software_reset(); #else + disableAllWdts(); panicPutStr("CPU halted.\r\n"); while(1); #endif diff --git a/components/freertos/tasks.c b/components/freertos/tasks.c index 3cde3bf136..221bf476c6 100644 --- a/components/freertos/tasks.c +++ b/components/freertos/tasks.c @@ -1832,7 +1832,6 @@ UBaseType_t uxTaskGetNumberOfTasks( void ) /*-----------------------------------------------------------*/ #if ( INCLUDE_pcTaskGetTaskName == 1 ) - char *pcTaskGetTaskName( TaskHandle_t xTaskToQuery ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ { TCB_t *pxTCB; diff --git a/components/freertos/xtensa_vectors.S b/components/freertos/xtensa_vectors.S index 89a47f7415..5b31eb0a87 100644 --- a/components/freertos/xtensa_vectors.S +++ b/components/freertos/xtensa_vectors.S @@ -91,6 +91,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *******************************************************************************/ #include "xtensa_rtos.h" +#include "panic.h" /* Define for workaround: pin no-cpu-affinity tasks to a cpu when fpu is used. @@ -462,6 +463,8 @@ _DebugExceptionVector: jx a3 #else wsr a0, EXCSAVE+XCHAL_DEBUGLEVEL /* save original a0 somewhere */ + movi a0,PANIC_RSN_DEBUGEXCEPTION + wsr a0,EXCCAUSE call0 _xt_panic /* does not return */ rfi XCHAL_DEBUGLEVEL /* make a0 point here not later */ #endif @@ -489,6 +492,8 @@ _DoubleExceptionVector: #if XCHAL_HAVE_DEBUG break 1, 4 /* unhandled double exception */ #endif + movi a0,PANIC_RSN_DOUBLEEXCEPTION + wsr a0,EXCCAUSE call0 _xt_panic /* does not return */ rfde /* make a0 point here not later */ @@ -522,6 +527,8 @@ _xt_kernel_exc: #if XCHAL_HAVE_DEBUG break 1, 0 /* unhandled kernel exception */ #endif + movi a0,PANIC_RSN_KERNELEXCEPTION + wsr a0,EXCCAUSE call0 _xt_panic /* does not return */ rfe /* make a0 point here not there */ @@ -1024,6 +1031,8 @@ _xt_coproc_exc: #if XCHAL_HAVE_DEBUG break 1, 1 /* unhandled user exception */ #endif + movi a0,PANIC_RSN_COPROCEXCEPTION + wsr a0,EXCCAUSE call0 _xt_panic /* not in a thread (invalid) */ /* never returns */ @@ -1611,6 +1620,8 @@ _xt_highint4: off and the CPU should panic. */ rsr a0, EXCSAVE_4 wsr a0, EXCSAVE_1 /* panic handler reads this register */ + movi a0,PANIC_RSN_INTWDT + wsr a0,EXCCAUSE call0 _xt_panic From 89f7752cddc2e2a30885292e4d0c9002c5958705 Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Tue, 25 Oct 2016 18:08:55 +0800 Subject: [PATCH 132/343] Make CPU1 int wdt / idle task wdt configurable, panic now properly disables other cpu, tick handler now also is called on cpu1, task wdt prints currently running tasks. --- components/esp32/Kconfig | 16 ++++++++++- components/esp32/int_wdt.c | 23 +++++++++++++++ components/esp32/task_wdt.c | 8 ++++++ components/freertos/include/freertos/panic.h | 5 ++-- components/freertos/include/freertos/task.h | 11 +++++++ components/freertos/panic.c | 19 +++++++------ components/freertos/tasks.c | 30 ++++++++++++++++++++ components/freertos/xtensa_vectors.S | 17 +++++++++-- 8 files changed, 115 insertions(+), 14 deletions(-) diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig index dbd1cfb6f6..6fb47ebd07 100644 --- a/components/esp32/Kconfig +++ b/components/esp32/Kconfig @@ -158,6 +158,13 @@ config INT_WDT_TIMEOUT_MS help The timeout of the watchdog, in miliseconds. Make this higher than the FreeRTOS tick rate. +config INT_WDT_CHECK_CPU1 + bool "Also watch CPU1 tick interrupt" + depends on INT_WDT && !FREERTOS_UNICORE + default y + help + Also detect if interrupts on CPU 1 are disabled for too long. + config TASK_WDT bool "Task watchdog" default y @@ -182,7 +189,7 @@ config TASK_WDT_TIMEOUT_S Timeout for the task WDT, in seconds. config TASK_WDT_CHECK_IDLE_TASK - bool "Task watchdog watches idle tasks" + bool "Task watchdog watches CPU0 idle task" depends on TASK_WDT default y help @@ -192,6 +199,13 @@ config TASK_WDT_CHECK_IDLE_TASK idle task getting some runtime every now and then. Take Care: With this disabled, this watchdog will trigger if no tasks register themselves within the timeout value. +config TASK_WDT_CHECK_IDLE_TASK_CPU1 + bool "Task watchdog also watches CPU1 idle task" + depends on TASK_WDT_CHECK_IDLE_TASK && !FREERTOS_UNICORE + default y + help + Also check the idle task that runs on CPU1. + #The brownout detector code is disabled (by making it depend on a nonexisting symbol) because the current revision of ESP32 #silicon has a bug in the brown-out detector, rendering it unusable for resetting the CPU. config BROWNOUT_DET diff --git a/components/esp32/int_wdt.c b/components/esp32/int_wdt.c index 5fb7a63bae..8eadbeb8d4 100644 --- a/components/esp32/int_wdt.c +++ b/components/esp32/int_wdt.c @@ -30,6 +30,7 @@ This uses the TIMERG1 WDT. #include #include #include +#include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include @@ -72,12 +73,34 @@ void int_wdt_init() { } +#if CONFIG_INT_WDT_CHECK_CPU1 +//Not static; the ISR assembly checks this. +bool int_wdt_app_cpu_ticked=false; + void vApplicationTickHook(void) { + if (xPortGetCoreID()!=0) { + int_wdt_app_cpu_ticked=true; + } else { + //Only feed wdt if app cpu also ticked. + if (int_wdt_app_cpu_ticked) { + TIMERG1.wdt_wprotect=WDT_WRITE_KEY; + TIMERG1.wdt_config2=CONFIG_INT_WDT_TIMEOUT_MS*2; //Set timeout before interrupt + TIMERG1.wdt_config3=CONFIG_INT_WDT_TIMEOUT_MS*4; //Set timeout before reset + TIMERG1.wdt_feed=1; + TIMERG1.wdt_wprotect=0; + int_wdt_app_cpu_ticked=false; + } + } +} +#else +void vApplicationTickHook(void) { + if (xPortGetCoreID()!=0) return; TIMERG1.wdt_wprotect=WDT_WRITE_KEY; TIMERG1.wdt_config2=CONFIG_INT_WDT_TIMEOUT_MS*2; //Set timeout before interrupt TIMERG1.wdt_config3=CONFIG_INT_WDT_TIMEOUT_MS*4; //Set timeout before reset TIMERG1.wdt_feed=1; TIMERG1.wdt_wprotect=0; } +#endif #endif \ No newline at end of file diff --git a/components/esp32/task_wdt.c b/components/esp32/task_wdt.c index 3e4c436394..6da0901fba 100644 --- a/components/esp32/task_wdt.c +++ b/components/esp32/task_wdt.c @@ -75,6 +75,11 @@ static void IRAM_ATTR task_wdt_isr(void *arg) { printf(" - %s (%s)\n", pcTaskGetTaskName(wdttask->task_handle), cpu); } } + ets_printf("Tasks currently running:\n"); + for (int x=0; x Date: Tue, 25 Oct 2016 18:18:11 +0800 Subject: [PATCH 133/343] Add licenses, docbook, general cleanup --- components/esp32/brownout.c | 2 +- components/esp32/include/esp_brownout.h | 19 ++- components/esp32/include/esp_int_wdt.h | 44 ++++- components/esp32/include/esp_task_wdt.h | 73 +++++++- components/esp32/int_wdt.c | 82 ++++----- components/esp32/task_wdt.c | 210 ++++++++++++------------ 6 files changed, 275 insertions(+), 155 deletions(-) diff --git a/components/esp32/brownout.c b/components/esp32/brownout.c index 97846ae8c0..1dcde078e3 100644 --- a/components/esp32/brownout.c +++ b/components/esp32/brownout.c @@ -24,7 +24,7 @@ #if CONFIG_BROWNOUT_DET /* -This file ins included in esp-idf, but the menuconfig option for this is disabled because a silicon bug +This file is included in esp-idf, but the menuconfig option for this is disabled because a silicon bug prohibits the brownout detector from functioning correctly on the ESP32. */ diff --git a/components/esp32/include/esp_brownout.h b/components/esp32/include/esp_brownout.h index acce05e0db..5a0b1aec00 100644 --- a/components/esp32/include/esp_brownout.h +++ b/components/esp32/include/esp_brownout.h @@ -1,5 +1,20 @@ -#ifndef BROWNOUT_H -#define BROWNOUT_H +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +#ifndef __ESP_BROWNOUT_H +#define __ESP_BROWNOUT_H void esp_brownout_init(); diff --git a/components/esp32/include/esp_int_wdt.h b/components/esp32/include/esp_int_wdt.h index 81404e3053..dc5bd0dda1 100644 --- a/components/esp32/include/esp_int_wdt.h +++ b/components/esp32/include/esp_int_wdt.h @@ -1,6 +1,46 @@ -#ifndef INT_WDT_H -#define INT_WDT_H +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef __ESP_INT_WDT_H +#define __ESP_INT_WDT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup Watchdog_APIs + * @{ + */ + +/** + * @brief Initialize the interrupt watchdog. This is called in the init code, no need to + * call it explicitly. + * + * @param null + * + * @return null + */ void int_wdt_init(); + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + #endif \ No newline at end of file diff --git a/components/esp32/include/esp_task_wdt.h b/components/esp32/include/esp_task_wdt.h index 9163e6907a..c050616af6 100644 --- a/components/esp32/include/esp_task_wdt.h +++ b/components/esp32/include/esp_task_wdt.h @@ -1,8 +1,73 @@ -#ifndef TASK_WDT_H -#define TASK_WDT_H +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at -void task_wdt_feed(); -void task_wdt_delete(); +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef __ESP_TASK_WDT_H +#define __ESP_TASK_WDT_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/** \defgroup Watchdog_APIs Watchdog APIs + * @brief Watchdog APIs + */ + +/** @addtogroup Watchdog_APIs + * @{ + */ + +/** + * @brief Initialize the task watchdog. This is called in the init code, no need to + * call it explicitly. + * + * @param null + * + * @return null + */ void task_wdt_init(); +/** + * @brief Feed the watchdog. After the first feeding session, the watchdog will expect the calling + * task to keep feeding the watchdog until task_wdt_delete() is called. + * + * @param null + * + * @return null + */ + +void task_wdt_feed(); + + +/** + * @brief Delete the watchdog for the current task. + * + * @param null + * + * @return null + */ +void task_wdt_delete(); + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + + + #endif \ No newline at end of file diff --git a/components/esp32/int_wdt.c b/components/esp32/int_wdt.c index 8eadbeb8d4..8c506bde1f 100644 --- a/components/esp32/int_wdt.c +++ b/components/esp32/int_wdt.c @@ -48,28 +48,28 @@ This uses the TIMERG1 WDT. #define WDT_WRITE_KEY 0x50D83AA1 void int_wdt_init() { - TIMERG1.wdt_wprotect=WDT_WRITE_KEY; - TIMERG1.wdt_config0.sys_reset_length=7; //3.2uS - TIMERG1.wdt_config0.cpu_reset_length=7; //3.2uS - TIMERG1.wdt_config0.level_int_en=1; - TIMERG1.wdt_config0.stg0=1; //1st stage timeout: interrupt - TIMERG1.wdt_config0.stg1=3; //2nd stage timeout: reset system - TIMERG1.wdt_config1.clk_prescale=80*500; //Prescaler: wdt counts in ticks of 0.5mS - //The timer configs initially are set to 5 seconds, to make sure the CPU can start up. The tick hook sets - //it to their actual value. - TIMERG1.wdt_config2=10000; - TIMERG1.wdt_config3=10000; - TIMERG1.wdt_config0.en=1; - TIMERG1.wdt_feed=1; - TIMERG1.wdt_wprotect=0; - TIMERG1.int_clr_timers.wdt=1; - TIMERG1.int_ena.wdt=1; - ESP_INTR_DISABLE(WDT_INT_NUM); - intr_matrix_set(xPortGetCoreID(), ETS_TG1_WDT_LEVEL_INTR_SOURCE, WDT_INT_NUM); - //We do not register a handler for the interrupt because it is interrupt level 4 which - //is not servicable from C. Instead, xtensa_vectors.S has a call to the panic handler for - //this interrupt. - ESP_INTR_ENABLE(WDT_INT_NUM); + TIMERG1.wdt_wprotect=WDT_WRITE_KEY; + TIMERG1.wdt_config0.sys_reset_length=7; //3.2uS + TIMERG1.wdt_config0.cpu_reset_length=7; //3.2uS + TIMERG1.wdt_config0.level_int_en=1; + TIMERG1.wdt_config0.stg0=1; //1st stage timeout: interrupt + TIMERG1.wdt_config0.stg1=3; //2nd stage timeout: reset system + TIMERG1.wdt_config1.clk_prescale=80*500; //Prescaler: wdt counts in ticks of 0.5mS + //The timer configs initially are set to 5 seconds, to make sure the CPU can start up. The tick hook sets + //it to their actual value. + TIMERG1.wdt_config2=10000; + TIMERG1.wdt_config3=10000; + TIMERG1.wdt_config0.en=1; + TIMERG1.wdt_feed=1; + TIMERG1.wdt_wprotect=0; + TIMERG1.int_clr_timers.wdt=1; + TIMERG1.int_ena.wdt=1; + ESP_INTR_DISABLE(WDT_INT_NUM); + intr_matrix_set(xPortGetCoreID(), ETS_TG1_WDT_LEVEL_INTR_SOURCE, WDT_INT_NUM); + //We do not register a handler for the interrupt because it is interrupt level 4 which + //is not servicable from C. Instead, xtensa_vectors.S has a call to the panic handler for + //this interrupt. + ESP_INTR_ENABLE(WDT_INT_NUM); } @@ -78,28 +78,28 @@ void int_wdt_init() { bool int_wdt_app_cpu_ticked=false; void vApplicationTickHook(void) { - if (xPortGetCoreID()!=0) { - int_wdt_app_cpu_ticked=true; - } else { - //Only feed wdt if app cpu also ticked. - if (int_wdt_app_cpu_ticked) { - TIMERG1.wdt_wprotect=WDT_WRITE_KEY; - TIMERG1.wdt_config2=CONFIG_INT_WDT_TIMEOUT_MS*2; //Set timeout before interrupt - TIMERG1.wdt_config3=CONFIG_INT_WDT_TIMEOUT_MS*4; //Set timeout before reset - TIMERG1.wdt_feed=1; - TIMERG1.wdt_wprotect=0; - int_wdt_app_cpu_ticked=false; - } - } + if (xPortGetCoreID()!=0) { + int_wdt_app_cpu_ticked=true; + } else { + //Only feed wdt if app cpu also ticked. + if (int_wdt_app_cpu_ticked) { + TIMERG1.wdt_wprotect=WDT_WRITE_KEY; + TIMERG1.wdt_config2=CONFIG_INT_WDT_TIMEOUT_MS*2; //Set timeout before interrupt + TIMERG1.wdt_config3=CONFIG_INT_WDT_TIMEOUT_MS*4; //Set timeout before reset + TIMERG1.wdt_feed=1; + TIMERG1.wdt_wprotect=0; + int_wdt_app_cpu_ticked=false; + } + } } #else void vApplicationTickHook(void) { - if (xPortGetCoreID()!=0) return; - TIMERG1.wdt_wprotect=WDT_WRITE_KEY; - TIMERG1.wdt_config2=CONFIG_INT_WDT_TIMEOUT_MS*2; //Set timeout before interrupt - TIMERG1.wdt_config3=CONFIG_INT_WDT_TIMEOUT_MS*4; //Set timeout before reset - TIMERG1.wdt_feed=1; - TIMERG1.wdt_wprotect=0; + if (xPortGetCoreID()!=0) return; + TIMERG1.wdt_wprotect=WDT_WRITE_KEY; + TIMERG1.wdt_config2=CONFIG_INT_WDT_TIMEOUT_MS*2; //Set timeout before interrupt + TIMERG1.wdt_config3=CONFIG_INT_WDT_TIMEOUT_MS*4; //Set timeout before reset + TIMERG1.wdt_feed=1; + TIMERG1.wdt_wprotect=0; } #endif diff --git a/components/esp32/task_wdt.c b/components/esp32/task_wdt.c index 6da0901fba..e6a4620882 100644 --- a/components/esp32/task_wdt.c +++ b/components/esp32/task_wdt.c @@ -45,9 +45,9 @@ static const char* TAG = "task_wdt"; typedef struct wdt_task_t wdt_task_t; struct wdt_task_t { - TaskHandle_t task_handle; - bool fed_watchdog; - wdt_task_t *next; + TaskHandle_t task_handle; + bool fed_watchdog; + wdt_task_t *next; }; static wdt_task_t *wdt_task_list=NULL; @@ -58,127 +58,127 @@ static wdt_task_t *wdt_task_list=NULL; #define WDT_WRITE_KEY 0x50D83AA1 static void IRAM_ATTR task_wdt_isr(void *arg) { - wdt_task_t *wdttask; - const char *cpu; - //Feed the watchdog so we do not reset - TIMERG0.wdt_wprotect=WDT_WRITE_KEY; - TIMERG0.wdt_feed=1; - TIMERG0.wdt_wprotect=0; - //Ack interrupt - TIMERG0.int_clr_timers.wdt=1; - //Watchdog got triggered because at least one task did not report in. - ets_printf("Task watchdog got triggered. The following tasks did not feed the watchdog in time:\n"); - for (wdttask=wdt_task_list; wdttask!=NULL; wdttask=wdttask->next) { - if (!wdttask->fed_watchdog) { - cpu=xTaskGetAffinity(wdttask->task_handle)==0?"CPU 0":"CPU 1"; - if (xTaskGetAffinity(wdttask->task_handle)==tskNO_AFFINITY) cpu="CPU 0/1"; - printf(" - %s (%s)\n", pcTaskGetTaskName(wdttask->task_handle), cpu); - } - } - ets_printf("Tasks currently running:\n"); - for (int x=0; xnext) { + if (!wdttask->fed_watchdog) { + cpu=xTaskGetAffinity(wdttask->task_handle)==0?"CPU 0":"CPU 1"; + if (xTaskGetAffinity(wdttask->task_handle)==tskNO_AFFINITY) cpu="CPU 0/1"; + printf(" - %s (%s)\n", pcTaskGetTaskName(wdttask->task_handle), cpu); + } + } + ets_printf("Tasks currently running:\n"); + for (int x=0; xnext) { - //See if we are at the current task. - if (wdttask->task_handle == handle) { - wdttask->fed_watchdog=true; - found_task=true; - } - //If even one task in the list doesn't have the do_feed_wdt var set, we do not feed the watchdog. - if (!wdttask->fed_watchdog) do_feed_wdt=false; - } - - if (!found_task) { - //This is the first time the task calls the task_wdt_feed function. Create a new entry for it in - //the linked list. - wdt_task_t *newtask=malloc(sizeof(wdt_task_t)); - memset(newtask, 0, sizeof(wdt_task_t)); - newtask->task_handle=handle; - newtask->fed_watchdog=true; - if (wdt_task_list == NULL) { - wdt_task_list=newtask; - } else { - for (wdttask=wdt_task_list; wdttask->next!=NULL; wdttask=wdttask->next) ; - wdttask->next=newtask; - } - } - if (do_feed_wdt) { - //All tasks have checked in; time to feed the hw watchdog. - TIMERG0.wdt_wprotect=WDT_WRITE_KEY; - TIMERG0.wdt_feed=1; - TIMERG0.wdt_wprotect=0; - //Reset fed_watchdog status - for (wdttask=wdt_task_list; wdttask->next!=NULL; wdttask=wdttask->next) wdttask->fed_watchdog=false; - } + wdt_task_t *wdttask=wdt_task_list; + bool found_task=false, do_feed_wdt=true; + TaskHandle_t handle=xTaskGetCurrentTaskHandle(); + //Walk the linked list of wdt tasks to find this one, as well as see if we need to feed + //the real watchdog timer. + for (wdttask=wdt_task_list; wdttask!=NULL; wdttask=wdttask->next) { + //See if we are at the current task. + if (wdttask->task_handle == handle) { + wdttask->fed_watchdog=true; + found_task=true; + } + //If even one task in the list doesn't have the do_feed_wdt var set, we do not feed the watchdog. + if (!wdttask->fed_watchdog) do_feed_wdt=false; + } + + if (!found_task) { + //This is the first time the task calls the task_wdt_feed function. Create a new entry for it in + //the linked list. + wdt_task_t *newtask=malloc(sizeof(wdt_task_t)); + memset(newtask, 0, sizeof(wdt_task_t)); + newtask->task_handle=handle; + newtask->fed_watchdog=true; + if (wdt_task_list == NULL) { + wdt_task_list=newtask; + } else { + for (wdttask=wdt_task_list; wdttask->next!=NULL; wdttask=wdttask->next) ; + wdttask->next=newtask; + } + } + if (do_feed_wdt) { + //All tasks have checked in; time to feed the hw watchdog. + TIMERG0.wdt_wprotect=WDT_WRITE_KEY; + TIMERG0.wdt_feed=1; + TIMERG0.wdt_wprotect=0; + //Reset fed_watchdog status + for (wdttask=wdt_task_list; wdttask->next!=NULL; wdttask=wdttask->next) wdttask->fed_watchdog=false; + } } void task_wdt_delete() { - TaskHandle_t handle=xTaskGetCurrentTaskHandle(); - wdt_task_t *wdttask=wdt_task_list; - //Wdt task list can't be empty - if (!wdt_task_list) { - ESP_LOGE(TAG, "task_wdt_delete: No tasks in list?"); - return; - } - if (handle==wdt_task_list) { - //Current task is first on list. - wdt_task_list=wdt_task_list->next; - free(wdttask); - } else { - //Find current task in list - while (wdttask->next!=NULL && wdttask->next->task_handle!=handle) wdttask=wdttask->next; - if (!wdttask->next) { - ESP_LOGE(TAG, "task_wdt_delete: Task never called task_wdt_feed!"); - return; - } - wdt_task_t *freeme=wdttask->next; - wdttask->next=wdttask->next->next; - free(freeme); - } + TaskHandle_t handle=xTaskGetCurrentTaskHandle(); + wdt_task_t *wdttask=wdt_task_list; + //Wdt task list can't be empty + if (!wdt_task_list) { + ESP_LOGE(TAG, "task_wdt_delete: No tasks in list?"); + return; + } + if (handle==wdt_task_list) { + //Current task is first on list. + wdt_task_list=wdt_task_list->next; + free(wdttask); + } else { + //Find current task in list + while (wdttask->next!=NULL && wdttask->next->task_handle!=handle) wdttask=wdttask->next; + if (!wdttask->next) { + ESP_LOGE(TAG, "task_wdt_delete: Task never called task_wdt_feed!"); + return; + } + wdt_task_t *freeme=wdttask->next; + wdttask->next=wdttask->next->next; + free(freeme); + } } void task_wdt_init() { - TIMERG0.wdt_wprotect=WDT_WRITE_KEY; - TIMERG0.wdt_config0.sys_reset_length=7; //3.2uS - TIMERG0.wdt_config0.cpu_reset_length=7; //3.2uS - TIMERG0.wdt_config0.level_int_en=1; - TIMERG0.wdt_config0.stg0=1; //1st stage timeout: interrupt - TIMERG0.wdt_config0.stg1=3; //2nd stage timeout: reset system - TIMERG0.wdt_config1.clk_prescale=80*500; //Prescaler: wdt counts in ticks of 0.5mS - TIMERG0.wdt_config2=CONFIG_TASK_WDT_TIMEOUT_S*2000; //Set timeout before interrupt - TIMERG0.wdt_config3=CONFIG_TASK_WDT_TIMEOUT_S*4000; //Set timeout before reset - TIMERG0.wdt_config0.en=1; - TIMERG0.wdt_feed=1; - TIMERG0.wdt_wprotect=0; - ESP_INTR_DISABLE(ETS_T0_WDT_INUM); - intr_matrix_set(xPortGetCoreID(), ETS_TG0_WDT_LEVEL_INTR_SOURCE, ETS_T0_WDT_INUM); - xt_set_interrupt_handler(ETS_T0_WDT_INUM, task_wdt_isr, NULL); - TIMERG0.int_clr_timers.wdt=1; - TIMERG0.int_ena.wdt=1; - ESP_INTR_ENABLE(ETS_T0_WDT_INUM); + TIMERG0.wdt_wprotect=WDT_WRITE_KEY; + TIMERG0.wdt_config0.sys_reset_length=7; //3.2uS + TIMERG0.wdt_config0.cpu_reset_length=7; //3.2uS + TIMERG0.wdt_config0.level_int_en=1; + TIMERG0.wdt_config0.stg0=1; //1st stage timeout: interrupt + TIMERG0.wdt_config0.stg1=3; //2nd stage timeout: reset system + TIMERG0.wdt_config1.clk_prescale=80*500; //Prescaler: wdt counts in ticks of 0.5mS + TIMERG0.wdt_config2=CONFIG_TASK_WDT_TIMEOUT_S*2000; //Set timeout before interrupt + TIMERG0.wdt_config3=CONFIG_TASK_WDT_TIMEOUT_S*4000; //Set timeout before reset + TIMERG0.wdt_config0.en=1; + TIMERG0.wdt_feed=1; + TIMERG0.wdt_wprotect=0; + ESP_INTR_DISABLE(ETS_T0_WDT_INUM); + intr_matrix_set(xPortGetCoreID(), ETS_TG0_WDT_LEVEL_INTR_SOURCE, ETS_T0_WDT_INUM); + xt_set_interrupt_handler(ETS_T0_WDT_INUM, task_wdt_isr, NULL); + TIMERG0.int_clr_timers.wdt=1; + TIMERG0.int_ena.wdt=1; + ESP_INTR_ENABLE(ETS_T0_WDT_INUM); } #if CONFIG_TASK_WDT_CHECK_IDLE_TASK void vApplicationIdleHook(void) { #if !CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1 - if (xPortGetCoreID()!=0) return; + if (xPortGetCoreID()!=0) return; #endif - task_wdt_feed(); + task_wdt_feed(); } #endif From 1ca97f5adbc426e2968f446685de4e365586bf2a Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Wed, 26 Oct 2016 11:06:53 +0800 Subject: [PATCH 134/343] Move panic handler code from FreeRTOS to esp32 component --- .../include/freertos/panic.h => esp32/include/esp_panic.h} | 0 components/{freertos => esp32}/panic.c | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename components/{freertos/include/freertos/panic.h => esp32/include/esp_panic.h} (100%) rename components/{freertos => esp32}/panic.c (100%) diff --git a/components/freertos/include/freertos/panic.h b/components/esp32/include/esp_panic.h similarity index 100% rename from components/freertos/include/freertos/panic.h rename to components/esp32/include/esp_panic.h diff --git a/components/freertos/panic.c b/components/esp32/panic.c similarity index 100% rename from components/freertos/panic.c rename to components/esp32/panic.c From 7d254eb3f0486b9c81d02f769080325336d996a0 Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Wed, 26 Oct 2016 12:23:01 +0800 Subject: [PATCH 135/343] Move panic handler and gdbstub into esp32 component, clean up wdt according to merge req suggestions --- components/esp32/Kconfig | 41 +++++++ components/esp32/cpu_start.c | 12 +-- components/{freertos => esp32}/gdbstub.c | 2 +- .../gdbstub.h => esp32/include/esp_gdbstub.h} | 2 +- components/esp32/include/esp_int_wdt.h | 20 +++- components/esp32/include/esp_panic.h | 2 +- components/esp32/include/esp_task_wdt.h | 20 +++- components/esp32/include/soc/rtc_cntl_reg.h | 2 + .../esp32/include/soc/timer_group_reg.h | 2 + components/esp32/int_wdt.c | 17 +-- components/esp32/panic.c | 22 ++-- components/esp32/task_wdt.c | 22 +--- components/freertos/Kconfig | 39 ------- components/freertos/port.c | 4 +- components/freertos/xtensa_vectors.S | 100 +++++++++--------- 15 files changed, 161 insertions(+), 146 deletions(-) rename components/{freertos => esp32}/gdbstub.c (99%) rename components/{freertos/gdbstub.h => esp32/include/esp_gdbstub.h} (93%) diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig index 7fc5090f4e..9e141529be 100644 --- a/components/esp32/Kconfig +++ b/components/esp32/Kconfig @@ -81,8 +81,10 @@ config TRACEMEM_RESERVE_DRAM default 0x4000 if MEMMAP_TRACEMEM && !MEMMAP_TRACEMEM_TWOBANKS default 0x0 +# Not implemented and/or needs new silicon rev to work config MEMMAP_SPISRAM bool "Use external SPI SRAM chip as main memory" + depends on ESP32_NEEDS_NEW_SILICON_REV default "n" help The ESP32 can control an external SPI SRAM chip, adding the memory it contains to the @@ -153,6 +155,45 @@ config ULP_COPROC_RESERVE_MEM depends on !ULP_COPROC_ENABLED +choice ESP32_PANIC + prompt "Panic handler behaviour" + default FREERTOS_PANIC_PRINT_REBOOT + help + If FreeRTOS detects unexpected behaviour or an unhandled exception, the panic handler is + invoked. Configure the panic handlers action here. + +config ESP32_PANIC_PRINT_HALT + bool "Print registers and halt" + help + Outputs the relevant registers over the serial port and halt the + processor. Needs a manual reset to restart. + +config ESP32_PANIC_PRINT_REBOOT + bool "Print registers and reboot" + help + Outputs the relevant registers over the serial port and immediately + reset the processor. + +config ESP32_PANIC_SILENT_REBOOT + bool "Silent reboot" + help + Just resets the processor without outputting anything + +config ESP32_PANIC_GDBSTUB + bool "Invoke GDBStub" + help + Invoke gdbstub on the serial port, allowing for gdb to attach to it to do a postmortem + of the crash. +endchoice + +config ESP32_DEBUG_OCDAWARE + bool "Make exception and panic handlers JTAG/OCD aware" + default y + help + The FreeRTOS panic and unhandled exception handers can detect a JTAG OCD debugger and + instead of panicking, have the debugger stop on the offending instruction. + + config INT_WDT bool "Interrupt watchdog" default y diff --git a/components/esp32/cpu_start.c b/components/esp32/cpu_start.c index aecea66ef9..37205dcd9a 100644 --- a/components/esp32/cpu_start.c +++ b/components/esp32/cpu_start.c @@ -147,19 +147,19 @@ void start_cpu0_default(void) #endif esp_set_cpu_freq(); // set CPU frequency configured in menuconfig uart_div_modify(0, (APB_CLK_FREQ << 4) / 115200); - ets_setup_syscalls(); - do_global_ctors(); - esp_ipc_init(); - spi_flash_init(); #if CONFIG_BROWNOUT_DET esp_brownout_init(); #endif #if CONFIG_INT_WDT - int_wdt_init(); + esp_int_wdt_init(); #endif #if CONFIG_TASK_WDT - task_wdt_init(); + esp_task_wdt_init(); #endif + ets_setup_syscalls(); + do_global_ctors(); + esp_ipc_init(); + spi_flash_init(); xTaskCreatePinnedToCore(&main_task, "main", ESP_TASK_MAIN_STACK, NULL, diff --git a/components/freertos/gdbstub.c b/components/esp32/gdbstub.c similarity index 99% rename from components/freertos/gdbstub.c rename to components/esp32/gdbstub.c index 1a92299bdd..d75fced4cd 100644 --- a/components/freertos/gdbstub.c +++ b/components/esp32/gdbstub.c @@ -24,7 +24,7 @@ #include "soc/uart_reg.h" #include "soc/io_mux_reg.h" -#include "gdbstub.h" +#include "esp_gdbstub.h" //Length of buffer used to reserve GDB commands. Has to be at least able to fit the G command, which //implies a minimum size of about 320 bytes. diff --git a/components/freertos/gdbstub.h b/components/esp32/include/esp_gdbstub.h similarity index 93% rename from components/freertos/gdbstub.h rename to components/esp32/include/esp_gdbstub.h index 5e97213c92..bc26f2941a 100644 --- a/components/freertos/gdbstub.h +++ b/components/esp32/include/esp_gdbstub.h @@ -17,6 +17,6 @@ #include #include "freertos/xtensa_api.h" -void gdbstubPanicHandler(XtExcFrame *frame); +void esp_gdbstub_panic_handler(XtExcFrame *frame); #endif \ No newline at end of file diff --git a/components/esp32/include/esp_int_wdt.h b/components/esp32/include/esp_int_wdt.h index dc5bd0dda1..4387400396 100644 --- a/components/esp32/include/esp_int_wdt.h +++ b/components/esp32/include/esp_int_wdt.h @@ -23,15 +23,29 @@ extern "C" { * @{ */ +/* +This routine enables a watchdog to catch instances of processes disabling +interrupts for too long, or code within interrupt handlers taking too long. +It does this by setting up a watchdog which gets fed from the FreeRTOS +task switch interrupt. When this watchdog times out, initially it will call +a high-level interrupt routine that will panic FreeRTOS in order to allow +for forensic examination of the state of the CPU. When this interrupt +handler is not called and the watchdog times out a second time, it will +reset the SoC. + +This uses the TIMERG1 WDT. +*/ + + /** - * @brief Initialize the interrupt watchdog. This is called in the init code, no need to - * call it explicitly. + * @brief Initialize the interrupt watchdog. This is called in the init code if + * the interrupt watchdog is enabled in menuconfig. * * @param null * * @return null */ -void int_wdt_init(); +void esp_int_wdt_init(); /** diff --git a/components/esp32/include/esp_panic.h b/components/esp32/include/esp_panic.h index 89dee5b249..6aba6c5f48 100644 --- a/components/esp32/include/esp_panic.h +++ b/components/esp32/include/esp_panic.h @@ -14,7 +14,7 @@ #ifndef __ASSEMBLER__ -void setBreakpointIfJtag(void *fn); +void esp_set_breakpoint_if_jtag(void *fn); #endif diff --git a/components/esp32/include/esp_task_wdt.h b/components/esp32/include/esp_task_wdt.h index c050616af6..bbc4995674 100644 --- a/components/esp32/include/esp_task_wdt.h +++ b/components/esp32/include/esp_task_wdt.h @@ -28,15 +28,25 @@ extern "C" { * @{ */ +/* +This routine enables a more general-purpose task watchdog: tasks can individually +feed the watchdog and the watchdog will bark if one or more tasks haven't fed the +watchdog within the specified time. Optionally, the idle tasks can also configured +to feed the watchdog in a similar fashion, to detect CPU starvation. + +This uses the TIMERG0 WDT. +*/ + + /** - * @brief Initialize the task watchdog. This is called in the init code, no need to - * call it explicitly. + * @brief Initialize the task watchdog. This is called in the init code, if the + * task watchdog is enabled in menuconfig. * * @param null * * @return null */ -void task_wdt_init(); +void esp_task_wdt_init(); /** * @brief Feed the watchdog. After the first feeding session, the watchdog will expect the calling @@ -47,7 +57,7 @@ void task_wdt_init(); * @return null */ -void task_wdt_feed(); +void esp_task_wdt_feed(); /** @@ -57,7 +67,7 @@ void task_wdt_feed(); * * @return null */ -void task_wdt_delete(); +void esp_task_wdt_delete(); /** * @} diff --git a/components/esp32/include/soc/rtc_cntl_reg.h b/components/esp32/include/soc/rtc_cntl_reg.h index 47328611e0..24e0f1403c 100644 --- a/components/esp32/include/soc/rtc_cntl_reg.h +++ b/components/esp32/include/soc/rtc_cntl_reg.h @@ -14,6 +14,8 @@ #ifndef _SOC_RTC_CNTL_REG_H_ #define _SOC_RTC_CNTL_REG_H_ +#define WDT_WRITE_KEY 0x50D83AA1 + #include "soc.h" #define RTC_CNTL_OPTIONS0_REG (DR_REG_RTCCNTL_BASE + 0x0) diff --git a/components/esp32/include/soc/timer_group_reg.h b/components/esp32/include/soc/timer_group_reg.h index 96a5eb7905..0d67cab517 100644 --- a/components/esp32/include/soc/timer_group_reg.h +++ b/components/esp32/include/soc/timer_group_reg.h @@ -15,6 +15,8 @@ #define __TIMG_REG_H__ #include "soc.h" +#define WDT_WRITE_KEY 0x50D83AA1 + #define REG_TIMG_BASE(i) (DR_REG_TIMERGROUP0_BASE + i*0x1000) #define TIMG_T0CONFIG_REG(i) (REG_TIMG_BASE(i) + 0x0000) /* TIMG_T0_EN : R/W ;bitpos:[31] ;default: 1'h0 ; */ diff --git a/components/esp32/int_wdt.c b/components/esp32/int_wdt.c index 8c506bde1f..5f123ee368 100644 --- a/components/esp32/int_wdt.c +++ b/components/esp32/int_wdt.c @@ -13,18 +13,6 @@ // limitations under the License. -/* -This routine enables a watchdog to catch instances of processes disabling -interrupts for too long, or code within interrupt handlers taking too long. -It does this by setting up a watchdog which gets fed from the FreeRTOS -task switch interrupt. When this watchdog times out, initially it will call -a high-level interrupt routine that will panic FreeRTOS in order to allow -for forensic examination of the state of the CPU. When this interrupt -handler is not called and the watchdog times out a second time, it will -reset the SoC. - -This uses the TIMERG1 WDT. -*/ #include "sdkconfig.h" #include @@ -37,6 +25,7 @@ This uses the TIMERG1 WDT. #include "esp_err.h" #include "esp_intr.h" #include "soc/timer_group_struct.h" +#include "soc/timer_group_reg.h" #include "esp_int_wdt.h" @@ -45,9 +34,8 @@ This uses the TIMERG1 WDT. #define WDT_INT_NUM 24 -#define WDT_WRITE_KEY 0x50D83AA1 -void int_wdt_init() { +void esp_int_wdt_init() { TIMERG1.wdt_wprotect=WDT_WRITE_KEY; TIMERG1.wdt_config0.sys_reset_length=7; //3.2uS TIMERG1.wdt_config0.cpu_reset_length=7; //3.2uS @@ -73,6 +61,7 @@ void int_wdt_init() { } +//Take care: the tick hook can also be called before esp_int_wdt_init() is called. #if CONFIG_INT_WDT_CHECK_CPU1 //Not static; the ISR assembly checks this. bool int_wdt_app_cpu_ticked=false; diff --git a/components/esp32/panic.c b/components/esp32/panic.c index 0735e6b045..758d581d09 100644 --- a/components/esp32/panic.c +++ b/components/esp32/panic.c @@ -26,11 +26,10 @@ #include "soc/dport_reg.h" #include "soc/rtc_cntl_reg.h" #include "soc/timer_group_struct.h" +#include "soc/timer_group_reg.h" -#include "gdbstub.h" -#include "panic.h" - -#define WDT_WRITE_KEY 0x50D83AA1 +#include "esp_gdbstub.h" +#include "esp_panic.h" /* @@ -196,7 +195,13 @@ void xt_unhandled_exception(XtExcFrame *frame) { } -//Disables all but one WDT, and allows enough time on that WDT to do what we need to do. +/* +If watchdogs are enabled, the panic handler runs the risk of getting aborted pre-emptively because +an overzealous watchdog decides to reset it. On the other hand, if we disable all watchdogs, we run +the risk of somehow halting in the panic handler and not resetting. That is why this routine kills +all watchdogs except the timer group 0 watchdog, and it reconfigures that to reset the chip after +one second. +*/ static void reconfigureAllWdts() { TIMERG0.wdt_wprotect=WDT_WRITE_KEY; TIMERG0.wdt_feed=1; @@ -213,6 +218,9 @@ static void reconfigureAllWdts() { TIMERG1.wdt_wprotect=0; } +/* +This disables all the watchdogs for when we call the gdbstub. +*/ static void disableAllWdts() { TIMERG0.wdt_wprotect=WDT_WRITE_KEY; TIMERG0.wdt_config0.en=0; @@ -254,7 +262,7 @@ void commonErrorHandler(XtExcFrame *frame) { #if CONFIG_FREERTOS_PANIC_GDBSTUB disableAllWdts(); panicPutStr("Entering gdb stub now.\r\n"); - gdbstubPanicHandler(frame); + esp_gdbstub_panic_handler(frame); #elif CONFIG_FREERTOS_PANIC_PRINT_REBOOT || CONFIG_FREERTOS_PANIC_SILENT_REBOOT panicPutStr("Rebooting...\r\n"); for (x=0; x<100; x++) ets_delay_us(1000); @@ -267,7 +275,7 @@ void commonErrorHandler(XtExcFrame *frame) { } -void setBreakpointIfJtag(void *fn) { +void esp_set_breakpoint_if_jtag(void *fn) { if (!inOCDMode()) return; setFirstBreakpoint((uint32_t)fn); } diff --git a/components/esp32/task_wdt.c b/components/esp32/task_wdt.c index e6a4620882..24d3977b18 100644 --- a/components/esp32/task_wdt.c +++ b/components/esp32/task_wdt.c @@ -13,14 +13,6 @@ // limitations under the License. -/* -This routine enables a more general-purpose task watchdog: tasks can individually -feed the watchdog and the watchdog will bark if one or more tasks haven't fed the -watchdog within the specified time. Optionally, the idle tasks can also configured -to feed the watchdog in a similar fashion, to detect CPU starvation. - -This uses the TIMERG0 WDT. -*/ #include #include @@ -35,6 +27,7 @@ This uses the TIMERG0 WDT. #include "esp_intr.h" #include "esp_attr.h" #include "soc/timer_group_struct.h" +#include "soc/timer_group_reg.h" #include "esp_log.h" #include "esp_task_wdt.h" @@ -52,11 +45,6 @@ struct wdt_task_t { static wdt_task_t *wdt_task_list=NULL; -//We use this interrupt number on whatever task calls task_wdt_init. -#define WDT_INT_NUM 24 - -#define WDT_WRITE_KEY 0x50D83AA1 - static void IRAM_ATTR task_wdt_isr(void *arg) { wdt_task_t *wdttask; const char *cpu; @@ -87,7 +75,7 @@ static void IRAM_ATTR task_wdt_isr(void *arg) { } -void task_wdt_feed() { +void esp_task_wdt_feed() { wdt_task_t *wdttask=wdt_task_list; bool found_task=false, do_feed_wdt=true; TaskHandle_t handle=xTaskGetCurrentTaskHandle(); @@ -127,7 +115,7 @@ void task_wdt_feed() { } } -void task_wdt_delete() { +void esp_task_wdt_delete() { TaskHandle_t handle=xTaskGetCurrentTaskHandle(); wdt_task_t *wdttask=wdt_task_list; //Wdt task list can't be empty @@ -152,7 +140,7 @@ void task_wdt_delete() { } } -void task_wdt_init() { +void esp_task_wdt_init() { TIMERG0.wdt_wprotect=WDT_WRITE_KEY; TIMERG0.wdt_config0.sys_reset_length=7; //3.2uS TIMERG0.wdt_config0.cpu_reset_length=7; //3.2uS @@ -178,7 +166,7 @@ void vApplicationIdleHook(void) { #if !CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1 if (xPortGetCoreID()!=0) return; #endif - task_wdt_feed(); + esp_task_wdt_feed(); } #endif diff --git a/components/freertos/Kconfig b/components/freertos/Kconfig index 1a65e1eeb7..413c710d22 100644 --- a/components/freertos/Kconfig +++ b/components/freertos/Kconfig @@ -93,45 +93,6 @@ config FREERTOS_THREAD_LOCAL_STORAGE_POINTERS If using the WiFi stack, this value must be at least 1. -#This still needs to be implemented. -choice FREERTOS_PANIC - prompt "Panic handler behaviour" - default FREERTOS_PANIC_PRINT_REBOOT - help - If FreeRTOS detects unexpected behaviour or an unhandled exception, the panic handler is - invoked. Configure the panic handlers action here. - -config FREERTOS_PANIC_PRINT_HALT - bool "Print registers and halt" - help - Outputs the relevant registers over the serial port and halt the - processor. Needs a manual reset to restart. - -config FREERTOS_PANIC_PRINT_REBOOT - bool "Print registers and reboot" - help - Outputs the relevant registers over the serial port and immediately - reset the processor. - -config FREERTOS_PANIC_SILENT_REBOOT - bool "Silent reboot" - help - Just resets the processor without outputting anything - -config FREERTOS_PANIC_GDBSTUB - bool "Invoke GDBStub" - help - Invoke gdbstub on the serial port, allowing for gdb to attach to it to do a postmortem - of the crash. -endchoice - -config FREERTOS_DEBUG_OCDAWARE - bool "Make exception and panic handlers JTAG/OCD aware" - default y - help - The FreeRTOS panic and unhandled exception handers can detect a JTAG OCD debugger and - instead of panicking, have the debugger stop on the offending instruction. - choice FREERTOS_ASSERT prompt "FreeRTOS assertions" default FREERTOS_ASSERT_FAIL_ABORT diff --git a/components/freertos/port.c b/components/freertos/port.c index a982db7d42..834d787bea 100644 --- a/components/freertos/port.c +++ b/components/freertos/port.c @@ -101,7 +101,7 @@ #include "FreeRTOS.h" #include "task.h" -#include "panic.h" +#include "esp_panic.h" /* Defined in portasm.h */ extern void _frxt_tick_timer_init(void); @@ -375,7 +375,7 @@ portBASE_TYPE vPortCPUReleaseMutex(portMUX_TYPE *mux) { #if CONFIG_FREERTOS_BREAK_ON_SCHEDULER_START_JTAG void vPortFirstTaskHook(TaskFunction_t function) { - setBreakpointIfJtag(function); + esp_set_breakpoint_if_jtag(function); } #endif diff --git a/components/freertos/xtensa_vectors.S b/components/freertos/xtensa_vectors.S index fcf9af1cd1..94acbd896e 100644 --- a/components/freertos/xtensa_vectors.S +++ b/components/freertos/xtensa_vectors.S @@ -91,7 +91,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *******************************************************************************/ #include "xtensa_rtos.h" -#include "panic.h" +#include "esp_panic.h" #include "sdkconfig.h" /* Define for workaround: pin no-cpu-affinity tasks to a cpu when fpu is used. @@ -303,12 +303,12 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ .section .iram1,"ax" - .global panicHandler + .global panicHandler .global _xt_panic .type _xt_panic,@function .align 4 - .literal_position + .literal_position .align 4 _xt_panic: @@ -344,41 +344,41 @@ _xt_panic: movi a0, PS_INTLEVEL(7) | PS_UM | PS_WOE wsr a0, PS - //Call panic handler - mov a6,sp - call4 panicHandler + //Call panic handler + mov a6,sp + call4 panicHandler 1: j 1b /* loop infinitely */ - retw + retw - .align 4 + .align 4 //Call using call0. Prints the hex char in a2. Kills a3, a4, a5 panic_print_hex: - movi a3,0x60000000 - movi a4,8 + movi a3,0x60000000 + movi a4,8 panic_print_hex_loop: - l32i a5, a3, 0x1c - extui a5, a5, 16, 8 - bgei a5,64,panic_print_hex_loop + l32i a5, a3, 0x1c + extui a5, a5, 16, 8 + bgei a5,64,panic_print_hex_loop - srli a5,a2,28 - bgei a5,10,panic_print_hex_a - addi a5,a5,'0' - j panic_print_hex_ok + srli a5,a2,28 + bgei a5,10,panic_print_hex_a + addi a5,a5,'0' + j panic_print_hex_ok panic_print_hex_a: - addi a5,a5,'A'-10 + addi a5,a5,'A'-10 panic_print_hex_ok: - s32i a5,a3,0 - slli a2,a2,4 - - addi a4,a4,-1 - bnei a4,0,panic_print_hex_loop - movi a5,' ' - s32i a5,a3,0 + s32i a5,a3,0 + slli a2,a2,4 + + addi a4,a4,-1 + bnei a4,0,panic_print_hex_loop + movi a5,' ' + s32i a5,a3,0 - ret + ret @@ -463,8 +463,8 @@ _DebugExceptionVector: jx a3 #else wsr a0, EXCSAVE+XCHAL_DEBUGLEVEL /* save original a0 somewhere */ - movi a0,PANIC_RSN_DEBUGEXCEPTION - wsr a0,EXCCAUSE + movi a0,PANIC_RSN_DEBUGEXCEPTION + wsr a0,EXCCAUSE call0 _xt_panic /* does not return */ rfi XCHAL_DEBUGLEVEL /* make a0 point here not later */ #endif @@ -492,8 +492,8 @@ _DoubleExceptionVector: #if XCHAL_HAVE_DEBUG break 1, 4 /* unhandled double exception */ #endif - movi a0,PANIC_RSN_DOUBLEEXCEPTION - wsr a0,EXCCAUSE + movi a0,PANIC_RSN_DOUBLEEXCEPTION + wsr a0,EXCCAUSE call0 _xt_panic /* does not return */ rfde /* make a0 point here not later */ @@ -527,8 +527,8 @@ _xt_kernel_exc: #if XCHAL_HAVE_DEBUG break 1, 0 /* unhandled kernel exception */ #endif - movi a0,PANIC_RSN_KERNELEXCEPTION - wsr a0,EXCCAUSE + movi a0,PANIC_RSN_KERNELEXCEPTION + wsr a0,EXCCAUSE call0 _xt_panic /* does not return */ rfe /* make a0 point here not there */ @@ -916,11 +916,11 @@ _xt_coproc_exc: addi a2, a2, TASKTCB_XCOREID_OFFSET /* offset to xCoreID in tcb struct */ s32i a3, a2, 0 /* store current cpuid */ - /* Grab correct xt_coproc_owner_sa for this core */ - movi a2, XCHAL_CP_MAX << 2 - mull a2, a2, a3 + /* Grab correct xt_coproc_owner_sa for this core */ + movi a2, XCHAL_CP_MAX << 2 + mull a2, a2, a3 movi a3, _xt_coproc_owner_sa /* a3 = base of owner array */ - add a3, a3, a2 + add a3, a3, a2 extui a2, a0, 0, 16 /* coprocessor bitmask portion */ or a4, a4, a2 /* a4 = CPENABLE | (1 << n) */ @@ -1031,8 +1031,8 @@ _xt_coproc_exc: #if XCHAL_HAVE_DEBUG break 1, 1 /* unhandled user exception */ #endif - movi a0,PANIC_RSN_COPROCEXCEPTION - wsr a0,EXCCAUSE + movi a0,PANIC_RSN_COPROCEXCEPTION + wsr a0,EXCCAUSE call0 _xt_panic /* not in a thread (invalid) */ /* never returns */ @@ -1620,19 +1620,19 @@ _xt_highint4: /* On the ESP32, this level is used for the INT_WDT handler. If that triggers, the program is stuck with interrupts off and the CPU should panic. */ - rsr a0, EXCSAVE_4 - wsr a0, EXCSAVE_1 /* panic handler reads this register */ - /* Set EXCCAUSE to reflect cause of the wdt int trigger */ - movi a0,PANIC_RSN_INTWDT_CPU0 - wsr a0,EXCCAUSE + rsr a0, EXCSAVE_4 + wsr a0, EXCSAVE_1 /* panic handler reads this register */ + /* Set EXCCAUSE to reflect cause of the wdt int trigger */ + movi a0,PANIC_RSN_INTWDT_CPU0 + wsr a0,EXCCAUSE #if CONFIG_INT_WDT_CHECK_CPU1 - /* Check if the cause is the app cpu failing to tick.*/ - movi a0, int_wdt_app_cpu_ticked - l32i a0, a0, 0 - bnez a0, 1f - /* It is. Modify cause. */ - movi a0,PANIC_RSN_INTWDT_CPU1 - wsr a0,EXCCAUSE + /* Check if the cause is the app cpu failing to tick.*/ + movi a0, int_wdt_app_cpu_ticked + l32i a0, a0, 0 + bnez a0, 1f + /* It is. Modify cause. */ + movi a0,PANIC_RSN_INTWDT_CPU1 + wsr a0,EXCCAUSE 1: #endif call0 _xt_panic From bb1efe50c3c86c6d466834cef8f5110c0163f404 Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Wed, 26 Oct 2016 12:23:35 +0800 Subject: [PATCH 136/343] Remove superfluous backup files --- components/freertos/xtensa_vectors.S-new | 1915 -------------------- components/freertos/xtensa_vectors.S-old | 2064 ---------------------- 2 files changed, 3979 deletions(-) delete mode 100644 components/freertos/xtensa_vectors.S-new delete mode 100644 components/freertos/xtensa_vectors.S-old diff --git a/components/freertos/xtensa_vectors.S-new b/components/freertos/xtensa_vectors.S-new deleted file mode 100644 index 88349eee9f..0000000000 --- a/components/freertos/xtensa_vectors.S-new +++ /dev/null @@ -1,1915 +0,0 @@ -/******************************************************************************* -Copyright (c) 2006-2015 Cadence Design Systems Inc. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------------------------------- - - XTENSA VECTORS AND LOW LEVEL HANDLERS FOR AN RTOS - - Xtensa low level exception and interrupt vectors and handlers for an RTOS. - - Interrupt handlers and user exception handlers support interaction with - the RTOS by calling XT_RTOS_INT_ENTER and XT_RTOS_INT_EXIT before and - after user's specific interrupt handlers. These macros are defined in - xtensa_.h to call suitable functions in a specific RTOS. - - Users can install application-specific interrupt handlers for low and - medium level interrupts, by calling xt_set_interrupt_handler(). These - handlers can be written in C, and must obey C calling convention. The - handler table is indexed by the interrupt number. Each handler may be - provided with an argument. - - Note that the system timer interrupt is handled specially, and is - dispatched to the RTOS-specific handler. This timer cannot be hooked - by application code. - - Optional hooks are also provided to install a handler per level at - run-time, made available by compiling this source file with - '-DXT_INTEXC_HOOKS' (useful for automated testing). - -!! This file is a template that usually needs to be modified to handle !! -!! application specific interrupts. Search USER_EDIT for helpful comments !! -!! on where to insert handlers and how to write them. !! - - Users can also install application-specific exception handlers in the - same way, by calling xt_set_exception_handler(). One handler slot is - provided for each exception type. Note that some exceptions are handled - by the porting layer itself, and cannot be taken over by application - code in this manner. These are the alloca, syscall, and coprocessor - exceptions. - - The exception handlers can be written in C, and must follow C calling - convention. Each handler is passed a pointer to an exception frame as - its single argument. The exception frame is created on the stack, and - holds the saved context of the thread that took the exception. If the - handler returns, the context will be restored and the instruction that - caused the exception will be retried. If the handler makes any changes - to the saved state in the exception frame, the changes will be applied - when restoring the context. - - Because Xtensa is a configurable architecture, this port supports all user - generated configurations (except restrictions stated in the release notes). - This is accomplished by conditional compilation using macros and functions - defined in the Xtensa HAL (hardware adaptation layer) for your configuration. - Only the relevant parts of this file will be included in your RTOS build. - For example, this file provides interrupt vector templates for all types and - all priority levels, but only the ones in your configuration are built. - - NOTES on the use of 'call0' for long jumps instead of 'j': - 1. This file should be assembled with the -mlongcalls option to xt-xcc. - 2. The -mlongcalls compiler option causes 'call0 dest' to be expanded to - a sequence 'l32r a0, dest' 'callx0 a0' which works regardless of the - distance from the call to the destination. The linker then relaxes - it back to 'call0 dest' if it determines that dest is within range. - This allows more flexibility in locating code without the performance - overhead of the 'l32r' literal data load in cases where the destination - is in range of 'call0'. There is an additional benefit in that 'call0' - has a longer range than 'j' due to the target being word-aligned, so - the 'l32r' sequence is less likely needed. - 3. The use of 'call0' with -mlongcalls requires that register a0 not be - live at the time of the call, which is always the case for a function - call but needs to be ensured if 'call0' is used as a jump in lieu of 'j'. - 4. This use of 'call0' is independent of the C function call ABI. - -*******************************************************************************/ - -#include "xtensa_rtos.h" - - -/* Enable stack backtrace across exception/interrupt - see below */ -#define XT_DEBUG_BACKTRACE 1 - - -/* --------------------------------------------------------------------------------- - Defines used to access _xtos_interrupt_table. --------------------------------------------------------------------------------- -*/ -#define XIE_HANDLER 0 -#define XIE_ARG 4 -#define XIE_SIZE 8 - -/* --------------------------------------------------------------------------------- - Macro extract_msb - return the input with only the highest bit set. - - Input : "ain" - Input value, clobbered. - Output : "aout" - Output value, has only one bit set, MSB of "ain". - The two arguments must be different AR registers. --------------------------------------------------------------------------------- -*/ - - .macro extract_msb aout ain -1: - addi \aout, \ain, -1 /* aout = ain - 1 */ - and \ain, \ain, \aout /* ain = ain & aout */ - bnez \ain, 1b /* repeat until ain == 0 */ - addi \aout, \aout, 1 /* return aout + 1 */ - .endm - -/* --------------------------------------------------------------------------------- - Macro dispatch_c_isr - dispatch interrupts to user ISRs. - This will dispatch to user handlers (if any) that are registered in the - XTOS dispatch table (_xtos_interrupt_table). These handlers would have - been registered by calling _xtos_set_interrupt_handler(). There is one - exception - the timer interrupt used by the OS will not be dispatched - to a user handler - this must be handled by the caller of this macro. - - Level triggered and software interrupts are automatically deasserted by - this code. - - ASSUMPTIONS: - -- PS.INTLEVEL is set to "level" at entry - -- PS.EXCM = 0, C calling enabled - - NOTE: For CALL0 ABI, a12-a15 have not yet been saved. - - NOTE: This macro will use registers a0 and a2-a6. The arguments are: - level -- interrupt level - mask -- interrupt bitmask for this level --------------------------------------------------------------------------------- -*/ - - .macro dispatch_c_isr level mask - - /* Get mask of pending, enabled interrupts at this level into a2. */ - -.L_xt_user_int_&level&: - rsr a2, INTENABLE - rsr a3, INTERRUPT - movi a4, \mask - and a2, a2, a3 - and a2, a2, a4 - beqz a2, 9f /* nothing to do */ - - /* This bit of code provides a nice debug backtrace in the debugger. - It does take a few more instructions, so undef XT_DEBUG_BACKTRACE - if you want to save the cycles. - */ - #if XT_DEBUG_BACKTRACE - #ifndef __XTENSA_CALL0_ABI__ - rsr a0, EPC_1 + \level - 1 /* return address */ - movi a4, 0xC0000000 /* constant with top 2 bits set (call size) */ - or a0, a0, a4 /* set top 2 bits */ - addx2 a0, a4, a0 /* clear top bit -- simulating call4 size */ - #endif - #endif - - #ifdef XT_INTEXC_HOOKS - /* Call interrupt hook if present to (pre)handle interrupts. */ - movi a4, _xt_intexc_hooks - l32i a4, a4, \level << 2 - beqz a4, 2f - #ifdef __XTENSA_CALL0_ABI__ - callx0 a4 - beqz a2, 9f - #else - mov a6, a2 - callx4 a4 - beqz a6, 9f - mov a2, a6 - #endif -2: - #endif - - /* Now look up in the dispatch table and call user ISR if any. */ - /* If multiple bits are set then MSB has highest priority. */ - - extract_msb a4, a2 /* a4 = MSB of a2, a2 trashed */ - - #ifdef XT_USE_SWPRI - /* Enable all interrupts at this level that are numerically higher - than the one we just selected, since they are treated as higher - priority. - */ - movi a3, \mask /* a3 = all interrupts at this level */ - add a2, a4, a4 /* a2 = a4 << 1 */ - addi a2, a2, -1 /* a2 = mask of 1's <= a4 bit */ - and a2, a2, a3 /* a2 = mask of all bits <= a4 at this level */ - movi a3, _xt_intdata - l32i a6, a3, 4 /* a6 = _xt_vpri_mask */ - neg a2, a2 - addi a2, a2, -1 /* a2 = mask to apply */ - and a5, a6, a2 /* mask off all bits <= a4 bit */ - s32i a5, a3, 4 /* update _xt_vpri_mask */ - rsr a3, INTENABLE - and a3, a3, a2 /* mask off all bits <= a4 bit */ - wsr a3, INTENABLE - rsil a3, \level - 1 /* lower interrupt level by 1 */ - #endif - - movi a3, XT_TIMER_INTEN /* a3 = timer interrupt bit */ - wsr a4, INTCLEAR /* clear sw or edge-triggered interrupt */ - beq a3, a4, 7f /* if timer interrupt then skip table */ - - find_ms_setbit a3, a4, a3, 0 /* a3 = interrupt number */ - - movi a4, _xt_interrupt_table - addx8 a3, a3, a4 /* a3 = address of interrupt table entry */ - l32i a4, a3, XIE_HANDLER /* a4 = handler address */ - #ifdef __XTENSA_CALL0_ABI__ - mov a12, a6 /* save in callee-saved reg */ - l32i a2, a3, XIE_ARG /* a2 = handler arg */ - callx0 a4 /* call handler */ - mov a2, a12 - #else - mov a2, a6 /* save in windowed reg */ - l32i a6, a3, XIE_ARG /* a6 = handler arg */ - callx4 a4 /* call handler */ - #endif - - #ifdef XT_USE_SWPRI - j 8f - #else - j .L_xt_user_int_&level& /* check for more interrupts */ - #endif - -7: - - .ifeq XT_TIMER_INTPRI - \level -.L_xt_user_int_timer_&level&: - /* - Interrupt handler for the RTOS tick timer if at this level. - We'll be reading the interrupt state again after this call - so no need to preserve any registers except a6 (vpri_mask). - */ - - #ifdef __XTENSA_CALL0_ABI__ - mov a12, a6 - call0 XT_RTOS_TIMER_INT - mov a2, a12 - #else - mov a2, a6 - call4 XT_RTOS_TIMER_INT - #endif - .endif - - #ifdef XT_USE_SWPRI - j 8f - #else - j .L_xt_user_int_&level& /* check for more interrupts */ - #endif - - #ifdef XT_USE_SWPRI -8: - /* Restore old value of _xt_vpri_mask from a2. Also update INTENABLE from - virtual _xt_intenable which _could_ have changed during interrupt - processing. */ - - movi a3, _xt_intdata - l32i a4, a3, 0 /* a4 = _xt_intenable */ - s32i a2, a3, 4 /* update _xt_vpri_mask */ - and a4, a4, a2 /* a4 = masked intenable */ - wsr a4, INTENABLE /* update INTENABLE */ - #endif - -9: - /* done */ - - .endm - - -/* --------------------------------------------------------------------------------- - Panic handler. - Should be reached by call0 (preferable) or jump only. If call0, a0 says where - from. If on simulator, display panic message and abort, else loop indefinitely. --------------------------------------------------------------------------------- -*/ - - .text - .global _xt_panic - .type _xt_panic,@function - .align 4 - -_xt_panic: - #ifdef XT_SIMULATOR - addi a4, a0, -3 /* point to call0 */ - movi a3, _xt_panic_message - movi a2, SYS_log_msg - simcall - movi a2, SYS_gdb_abort - simcall - #else - rsil a2, XCHAL_EXCM_LEVEL /* disable all low & med ints */ -1: j 1b /* loop infinitely */ - #endif - - .section .rodata, "a" - .align 4 - -_xt_panic_message: - .string "\n*** _xt_panic() was called from 0x%08x or jumped to. ***\n" - - -/* --------------------------------------------------------------------------------- - Hooks to dynamically install handlers for exceptions and interrupts. - Allows automated regression frameworks to install handlers per test. - Consists of an array of function pointers indexed by interrupt level, - with index 0 containing the entry for user exceptions. - Initialized with all 0s, meaning no handler is installed at each level. - See comment in xtensa_rtos.h for more details. --------------------------------------------------------------------------------- -*/ - - #ifdef XT_INTEXC_HOOKS - .data - .global _xt_intexc_hooks - .type _xt_intexc_hooks,@object - .align 4 - -_xt_intexc_hooks: - .fill XT_INTEXC_HOOK_NUM, 4, 0 - #endif - - -/* --------------------------------------------------------------------------------- - EXCEPTION AND LEVEL 1 INTERRUPT VECTORS AND LOW LEVEL HANDLERS - (except window exception vectors). - - Each vector goes at a predetermined location according to the Xtensa - hardware configuration, which is ensured by its placement in a special - section known to the Xtensa linker support package (LSP). It performs - the minimum necessary before jumping to the handler in the .text section. - - The corresponding handler goes in the normal .text section. It sets up - the appropriate stack frame, saves a few vector-specific registers and - calls XT_RTOS_INT_ENTER to save the rest of the interrupted context - and enter the RTOS, then sets up a C environment. It then calls the - user's interrupt handler code (which may be coded in C) and finally - calls XT_RTOS_INT_EXIT to transfer control to the RTOS for scheduling. - - While XT_RTOS_INT_EXIT does not return directly to the interruptee, - eventually the RTOS scheduler will want to dispatch the interrupted - task or handler. The scheduler will return to the exit point that was - saved in the interrupt stack frame at XT_STK_EXIT. --------------------------------------------------------------------------------- -*/ - - -/* --------------------------------------------------------------------------------- -Debug Exception. --------------------------------------------------------------------------------- -*/ - -#if XCHAL_HAVE_DEBUG - - .begin literal_prefix .DebugExceptionVector - .section .DebugExceptionVector.text, "ax" - .global _DebugExceptionVector - .align 4 - -_DebugExceptionVector: - - #ifdef XT_SIMULATOR - /* - In the simulator, let the debugger (if any) handle the debug exception, - or simply stop the simulation: - */ - wsr a2, EXCSAVE+XCHAL_DEBUGLEVEL /* save a2 where sim expects it */ - movi a2, SYS_gdb_enter_sktloop - simcall /* have ISS handle debug exc. */ - #elif 0 /* change condition to 1 to use the HAL minimal debug handler */ - wsr a3, EXCSAVE+XCHAL_DEBUGLEVEL - movi a3, xthal_debugexc_defhndlr_nw /* use default debug handler */ - jx a3 - #else - wsr a0, EXCSAVE+XCHAL_DEBUGLEVEL /* save original a0 somewhere */ - call0 _xt_panic /* does not return */ - rfi XCHAL_DEBUGLEVEL /* make a0 point here not later */ - #endif - - .end literal_prefix - -#endif - -/* --------------------------------------------------------------------------------- -Double Exception. -Double exceptions are not a normal occurrence. They indicate a bug of some kind. --------------------------------------------------------------------------------- -*/ - -#ifdef XCHAL_DOUBLEEXC_VECTOR_VADDR - - .begin literal_prefix .DoubleExceptionVector - .section .DoubleExceptionVector.text, "ax" - .global _DoubleExceptionVector - .align 4 - -_DoubleExceptionVector: - - #if XCHAL_HAVE_DEBUG - break 1, 4 /* unhandled double exception */ - #endif - call0 _xt_panic /* does not return */ - rfde /* make a0 point here not later */ - - .end literal_prefix - -#endif /* XCHAL_DOUBLEEXC_VECTOR_VADDR */ - -/* --------------------------------------------------------------------------------- -Kernel Exception (including Level 1 Interrupt from kernel mode). --------------------------------------------------------------------------------- -*/ - - .begin literal_prefix .KernelExceptionVector - .section .KernelExceptionVector.text, "ax" - .global _KernelExceptionVector - .align 4 - -_KernelExceptionVector: - - wsr a0, EXCSAVE_1 /* preserve a0 */ - call0 _xt_kernel_exc /* kernel exception handler */ - /* never returns here - call0 is used as a jump (see note at top) */ - - .end literal_prefix - - .text - .align 4 - -_xt_kernel_exc: - #if XCHAL_HAVE_DEBUG - break 1, 0 /* unhandled kernel exception */ - #endif - call0 _xt_panic /* does not return */ - rfe /* make a0 point here not there */ - - -/* --------------------------------------------------------------------------------- -User Exception (including Level 1 Interrupt from user mode). --------------------------------------------------------------------------------- -*/ - - .begin literal_prefix .UserExceptionVector - .section .UserExceptionVector.text, "ax" - .global _UserExceptionVector - .type _UserExceptionVector,@function - .align 4 - -_UserExceptionVector: - - wsr a0, EXCSAVE_1 /* preserve a0 */ - call0 _xt_user_exc /* user exception handler */ - /* never returns here - call0 is used as a jump (see note at top) */ - - .end literal_prefix - -/* --------------------------------------------------------------------------------- - Insert some waypoints for jumping beyond the signed 8-bit range of - conditional branch instructions, so the conditional branchces to specific - exception handlers are not taken in the mainline. Saves some cycles in the - mainline. --------------------------------------------------------------------------------- -*/ - - .text - - #if XCHAL_HAVE_WINDOWED - .align 4 -_xt_to_alloca_exc: - call0 _xt_alloca_exc /* in window vectors section */ - /* never returns here - call0 is used as a jump (see note at top) */ - #endif - - .align 4 -_xt_to_syscall_exc: - call0 _xt_syscall_exc - /* never returns here - call0 is used as a jump (see note at top) */ - - #if XCHAL_CP_NUM > 0 - .align 4 -_xt_to_coproc_exc: - call0 _xt_coproc_exc - /* never returns here - call0 is used as a jump (see note at top) */ - #endif - - -/* --------------------------------------------------------------------------------- - User exception handler. --------------------------------------------------------------------------------- -*/ - - .type _xt_user_exc,@function - .align 4 - -_xt_user_exc: - - /* If level 1 interrupt then jump to the dispatcher */ - rsr a0, EXCCAUSE - beqi a0, EXCCAUSE_LEVEL1INTERRUPT, _xt_lowint1 - - /* Handle any coprocessor exceptions. Rely on the fact that exception - numbers above EXCCAUSE_CP0_DISABLED all relate to the coprocessors. - */ - #if XCHAL_CP_NUM > 0 - bgeui a0, EXCCAUSE_CP0_DISABLED, _xt_to_coproc_exc - #endif - - /* Handle alloca and syscall exceptions */ - #if XCHAL_HAVE_WINDOWED - beqi a0, EXCCAUSE_ALLOCA, _xt_to_alloca_exc - #endif - beqi a0, EXCCAUSE_SYSCALL, _xt_to_syscall_exc - - /* Handle all other exceptions. All can have user-defined handlers. */ - /* NOTE: we'll stay on the user stack for exception handling. */ - - /* Allocate exception frame and save minimal context. */ - mov a0, sp - addi sp, sp, -XT_STK_FRMSZ - s32i a0, sp, XT_STK_A1 - #if XCHAL_HAVE_WINDOWED - s32e a0, sp, -12 /* for debug backtrace */ - #endif - rsr a0, PS /* save interruptee's PS */ - s32i a0, sp, XT_STK_PS - rsr a0, EPC_1 /* save interruptee's PC */ - s32i a0, sp, XT_STK_PC - rsr a0, EXCSAVE_1 /* save interruptee's a0 */ - s32i a0, sp, XT_STK_A0 - #if XCHAL_HAVE_WINDOWED - s32e a0, sp, -16 /* for debug backtrace */ - #endif - s32i a12, sp, XT_STK_A12 /* _xt_context_save requires A12- */ - s32i a13, sp, XT_STK_A13 /* A13 to have already been saved */ - call0 _xt_context_save - - /* Save exc cause and vaddr into exception frame */ - rsr a0, EXCCAUSE - s32i a0, sp, XT_STK_EXCCAUSE - rsr a0, EXCVADDR - s32i a0, sp, XT_STK_EXCVADDR - - /* Set up PS for C, reenable hi-pri interrupts, and clear EXCM. */ - #ifdef __XTENSA_CALL0_ABI__ - movi a0, PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM - #else - movi a0, PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM | PS_WOE - #endif - wsr a0, PS - - #ifdef XT_DEBUG_BACKTRACE - #ifndef __XTENSA_CALL0_ABI__ - rsr a0, EPC_1 /* return address for debug backtrace */ - movi a5, 0xC0000000 /* constant with top 2 bits set (call size) */ - rsync /* wait for WSR.PS to complete */ - or a0, a0, a5 /* set top 2 bits */ - addx2 a0, a5, a0 /* clear top bit -- thus simulating call4 size */ - #else - rsync /* wait for WSR.PS to complete */ - #endif - #endif - - rsr a2, EXCCAUSE /* recover exc cause */ - - #ifdef XT_INTEXC_HOOKS - /* - Call exception hook to pre-handle exceptions (if installed). - Pass EXCCAUSE in a2, and check result in a2 (if -1, skip default handling). - */ - movi a4, _xt_intexc_hooks - l32i a4, a4, 0 /* user exception hook index 0 */ - beqz a4, 1f -.Ln_xt_user_exc_call_hook: - #ifdef __XTENSA_CALL0_ABI__ - callx0 a4 - beqi a2, -1, .L_xt_user_done - #else - mov a6, a2 - callx4 a4 - beqi a6, -1, .L_xt_user_done - mov a2, a6 - #endif -1: - #endif - - rsr a2, EXCCAUSE /* recover exc cause */ - movi a3, _xt_exception_table - addx4 a4, a2, a3 /* a4 = address of exception table entry */ - l32i a4, a4, 0 /* a4 = handler address */ - #ifdef __XTENSA_CALL0_ABI__ - mov a2, sp /* a2 = pointer to exc frame */ - callx0 a4 /* call handler */ - #else - mov a6, sp /* a6 = pointer to exc frame */ - callx4 a4 /* call handler */ - #endif - -.L_xt_user_done: - - /* Restore context and return */ - call0 _xt_context_restore - l32i a0, sp, XT_STK_PS /* retrieve interruptee's PS */ - wsr a0, PS - l32i a0, sp, XT_STK_PC /* retrieve interruptee's PC */ - wsr a0, EPC_1 - l32i a0, sp, XT_STK_A0 /* retrieve interruptee's A0 */ - l32i sp, sp, XT_STK_A1 /* remove exception frame */ - rsync /* ensure PS and EPC written */ - rfe /* PS.EXCM is cleared */ - - -/* --------------------------------------------------------------------------------- - Exit point for dispatch. Saved in interrupt stack frame at XT_STK_EXIT - on entry and used to return to a thread or interrupted interrupt handler. --------------------------------------------------------------------------------- -*/ - - .global _xt_user_exit - .type _xt_user_exit,@function - .align 4 -_xt_user_exit: - l32i a0, sp, XT_STK_PS /* retrieve interruptee's PS */ - wsr a0, PS - l32i a0, sp, XT_STK_PC /* retrieve interruptee's PC */ - wsr a0, EPC_1 - l32i a0, sp, XT_STK_A0 /* retrieve interruptee's A0 */ - l32i sp, sp, XT_STK_A1 /* remove interrupt stack frame */ - rsync /* ensure PS and EPC written */ - rfe /* PS.EXCM is cleared */ - - -/* --------------------------------------------------------------------------------- -Syscall Exception Handler (jumped to from User Exception Handler). -Syscall 0 is required to spill the register windows (no-op in Call 0 ABI). -Only syscall 0 is handled here. Other syscalls return -1 to caller in a2. --------------------------------------------------------------------------------- -*/ - - .text - .type _xt_syscall_exc,@function - .align 4 -_xt_syscall_exc: - - #ifdef __XTENSA_CALL0_ABI__ - /* - Save minimal regs for scratch. Syscall 0 does nothing in Call0 ABI. - Use a minimal stack frame (16B) to save A2 & A3 for scratch. - PS.EXCM could be cleared here, but unlikely to improve worst-case latency. - rsr a0, PS - addi a0, a0, -PS_EXCM_MASK - wsr a0, PS - */ - addi sp, sp, -16 - s32i a2, sp, 8 - s32i a3, sp, 12 - #else /* Windowed ABI */ - /* - Save necessary context and spill the register windows. - PS.EXCM is still set and must remain set until after the spill. - Reuse context save function though it saves more than necessary. - For this reason, a full interrupt stack frame is allocated. - */ - addi sp, sp, -XT_STK_FRMSZ /* allocate interrupt stack frame */ - s32i a12, sp, XT_STK_A12 /* _xt_context_save requires A12- */ - s32i a13, sp, XT_STK_A13 /* A13 to have already been saved */ - call0 _xt_context_save - #endif - - /* - Grab the interruptee's PC and skip over the 'syscall' instruction. - If it's at the end of a zero-overhead loop and it's not on the last - iteration, decrement loop counter and skip to beginning of loop. - */ - rsr a2, EPC_1 /* a2 = PC of 'syscall' */ - addi a3, a2, 3 /* ++PC */ - #if XCHAL_HAVE_LOOPS - rsr a0, LEND /* if (PC == LEND */ - bne a3, a0, 1f - rsr a0, LCOUNT /* && LCOUNT != 0) */ - beqz a0, 1f /* { */ - addi a0, a0, -1 /* --LCOUNT */ - rsr a3, LBEG /* PC = LBEG */ - wsr a0, LCOUNT /* } */ - #endif -1: wsr a3, EPC_1 /* update PC */ - - /* Restore interruptee's context and return from exception. */ - #ifdef __XTENSA_CALL0_ABI__ - l32i a2, sp, 8 - l32i a3, sp, 12 - addi sp, sp, 16 - #else - call0 _xt_context_restore - addi sp, sp, XT_STK_FRMSZ - #endif - movi a0, -1 - movnez a2, a0, a2 /* return -1 if not syscall 0 */ - rsr a0, EXCSAVE_1 - rfe - -/* --------------------------------------------------------------------------------- -Co-Processor Exception Handler (jumped to from User Exception Handler). -These exceptions are generated by co-processor instructions, which are only -allowed in thread code (not in interrupts or kernel code). This restriction is -deliberately imposed to reduce the burden of state-save/restore in interrupts. --------------------------------------------------------------------------------- -*/ -#if XCHAL_CP_NUM > 0 - - .section .rodata, "a" - -/* Offset to CP n save area in thread's CP save area. */ - .global _xt_coproc_sa_offset - .type _xt_coproc_sa_offset,@object - .align 16 /* minimize crossing cache boundaries */ -_xt_coproc_sa_offset: - .word XT_CP0_SA, XT_CP1_SA, XT_CP2_SA, XT_CP3_SA - .word XT_CP4_SA, XT_CP5_SA, XT_CP6_SA, XT_CP7_SA - -/* Bitmask for CP n's CPENABLE bit. */ - .type _xt_coproc_mask,@object - .align 16,,8 /* try to keep it all in one cache line */ - .set i, 0 -_xt_coproc_mask: - .rept XCHAL_CP_MAX - .long (i<<16) | (1<= 2 - - .begin literal_prefix .Level2InterruptVector - .section .Level2InterruptVector.text, "ax" - .global _Level2Vector - .type _Level2Vector,@function - .align 4 -_Level2Vector: - wsr a0, EXCSAVE_2 /* preserve a0 */ - call0 _xt_medint2 /* load interrupt handler */ - /* never returns here - call0 is used as a jump (see note at top) */ - - .end literal_prefix - - .text - .type _xt_medint2,@function - .align 4 -_xt_medint2: - mov a0, sp /* sp == a1 */ - addi sp, sp, -XT_STK_FRMSZ /* allocate interrupt stack frame */ - s32i a0, sp, XT_STK_A1 /* save pre-interrupt SP */ - rsr a0, EPS_2 /* save interruptee's PS */ - s32i a0, sp, XT_STK_PS - rsr a0, EPC_2 /* save interruptee's PC */ - s32i a0, sp, XT_STK_PC - rsr a0, EXCSAVE_2 /* save interruptee's a0 */ - s32i a0, sp, XT_STK_A0 - movi a0, _xt_medint2_exit /* save exit point for dispatch */ - s32i a0, sp, XT_STK_EXIT - - /* Save rest of interrupt context and enter RTOS. */ - call0 XT_RTOS_INT_ENTER /* common RTOS interrupt entry */ - - /* !! We are now on the RTOS system stack !! */ - - /* Set up PS for C, enable interrupts above this level and clear EXCM. */ - #ifdef __XTENSA_CALL0_ABI__ - movi a0, PS_INTLEVEL(2) | PS_UM - #else - movi a0, PS_INTLEVEL(2) | PS_UM | PS_WOE - #endif - wsr a0, PS - rsync - - /* OK to call C code at this point, dispatch user ISRs */ - - dispatch_c_isr 2 XCHAL_INTLEVEL2_MASK - - /* Done handling interrupts, transfer control to OS */ - call0 XT_RTOS_INT_EXIT /* does not return directly here */ - - /* - Exit point for dispatch. Saved in interrupt stack frame at XT_STK_EXIT - on entry and used to return to a thread or interrupted interrupt handler. - */ - .global _xt_medint2_exit - .type _xt_medint2_exit,@function - .align 4 -_xt_medint2_exit: - /* Restore only level-specific regs (the rest were already restored) */ - l32i a0, sp, XT_STK_PS /* retrieve interruptee's PS */ - wsr a0, EPS_2 - l32i a0, sp, XT_STK_PC /* retrieve interruptee's PC */ - wsr a0, EPC_2 - l32i a0, sp, XT_STK_A0 /* retrieve interruptee's A0 */ - l32i sp, sp, XT_STK_A1 /* remove interrupt stack frame */ - rsync /* ensure EPS and EPC written */ - rfi 2 - -#endif /* Level 2 */ - -#if XCHAL_EXCM_LEVEL >= 3 - - .begin literal_prefix .Level3InterruptVector - .section .Level3InterruptVector.text, "ax" - .global _Level3Vector - .type _Level3Vector,@function - .align 4 -_Level3Vector: - wsr a0, EXCSAVE_3 /* preserve a0 */ - call0 _xt_medint3 /* load interrupt handler */ - /* never returns here - call0 is used as a jump (see note at top) */ - - .end literal_prefix - - .text - .type _xt_medint3,@function - .align 4 -_xt_medint3: - mov a0, sp /* sp == a1 */ - addi sp, sp, -XT_STK_FRMSZ /* allocate interrupt stack frame */ - s32i a0, sp, XT_STK_A1 /* save pre-interrupt SP */ - rsr a0, EPS_3 /* save interruptee's PS */ - s32i a0, sp, XT_STK_PS - rsr a0, EPC_3 /* save interruptee's PC */ - s32i a0, sp, XT_STK_PC - rsr a0, EXCSAVE_3 /* save interruptee's a0 */ - s32i a0, sp, XT_STK_A0 - movi a0, _xt_medint3_exit /* save exit point for dispatch */ - s32i a0, sp, XT_STK_EXIT - - /* Save rest of interrupt context and enter RTOS. */ - call0 XT_RTOS_INT_ENTER /* common RTOS interrupt entry */ - - /* !! We are now on the RTOS system stack !! */ - - /* Set up PS for C, enable interrupts above this level and clear EXCM. */ - #ifdef __XTENSA_CALL0_ABI__ - movi a0, PS_INTLEVEL(3) | PS_UM - #else - movi a0, PS_INTLEVEL(3) | PS_UM | PS_WOE - #endif - wsr a0, PS - rsync - - /* OK to call C code at this point, dispatch user ISRs */ - - dispatch_c_isr 3 XCHAL_INTLEVEL3_MASK - - /* Done handling interrupts, transfer control to OS */ - call0 XT_RTOS_INT_EXIT /* does not return directly here */ - - /* - Exit point for dispatch. Saved in interrupt stack frame at XT_STK_EXIT - on entry and used to return to a thread or interrupted interrupt handler. - */ - .global _xt_medint3_exit - .type _xt_medint3_exit,@function - .align 4 -_xt_medint3_exit: - /* Restore only level-specific regs (the rest were already restored) */ - l32i a0, sp, XT_STK_PS /* retrieve interruptee's PS */ - wsr a0, EPS_3 - l32i a0, sp, XT_STK_PC /* retrieve interruptee's PC */ - wsr a0, EPC_3 - l32i a0, sp, XT_STK_A0 /* retrieve interruptee's A0 */ - l32i sp, sp, XT_STK_A1 /* remove interrupt stack frame */ - rsync /* ensure EPS and EPC written */ - rfi 3 - -#endif /* Level 3 */ - -#if XCHAL_EXCM_LEVEL >= 4 - - .begin literal_prefix .Level4InterruptVector - .section .Level4InterruptVector.text, "ax" - .global _Level4Vector - .type _Level4Vector,@function - .align 4 -_Level4Vector: - wsr a0, EXCSAVE_4 /* preserve a0 */ - call0 _xt_medint4 /* load interrupt handler */ - - .end literal_prefix - - .text - .type _xt_medint4,@function - .align 4 -_xt_medint4: - mov a0, sp /* sp == a1 */ - addi sp, sp, -XT_STK_FRMSZ /* allocate interrupt stack frame */ - s32i a0, sp, XT_STK_A1 /* save pre-interrupt SP */ - rsr a0, EPS_4 /* save interruptee's PS */ - s32i a0, sp, XT_STK_PS - rsr a0, EPC_4 /* save interruptee's PC */ - s32i a0, sp, XT_STK_PC - rsr a0, EXCSAVE_4 /* save interruptee's a0 */ - s32i a0, sp, XT_STK_A0 - movi a0, _xt_medint4_exit /* save exit point for dispatch */ - s32i a0, sp, XT_STK_EXIT - - /* Save rest of interrupt context and enter RTOS. */ - call0 XT_RTOS_INT_ENTER /* common RTOS interrupt entry */ - - /* !! We are now on the RTOS system stack !! */ - - /* Set up PS for C, enable interrupts above this level and clear EXCM. */ - #ifdef __XTENSA_CALL0_ABI__ - movi a0, PS_INTLEVEL(4) | PS_UM - #else - movi a0, PS_INTLEVEL(4) | PS_UM | PS_WOE - #endif - wsr a0, PS - rsync - - /* OK to call C code at this point, dispatch user ISRs */ - - dispatch_c_isr 4 XCHAL_INTLEVEL4_MASK - - /* Done handling interrupts, transfer control to OS */ - call0 XT_RTOS_INT_EXIT /* does not return directly here */ - - /* - Exit point for dispatch. Saved in interrupt stack frame at XT_STK_EXIT - on entry and used to return to a thread or interrupted interrupt handler. - */ - .global _xt_medint4_exit - .type _xt_medint4_exit,@function - .align 4 -_xt_medint4_exit: - /* Restore only level-specific regs (the rest were already restored) */ - l32i a0, sp, XT_STK_PS /* retrieve interruptee's PS */ - wsr a0, EPS_4 - l32i a0, sp, XT_STK_PC /* retrieve interruptee's PC */ - wsr a0, EPC_4 - l32i a0, sp, XT_STK_A0 /* retrieve interruptee's A0 */ - l32i sp, sp, XT_STK_A1 /* remove interrupt stack frame */ - rsync /* ensure EPS and EPC written */ - rfi 4 - -#endif /* Level 4 */ - -#if XCHAL_EXCM_LEVEL >= 5 - - .begin literal_prefix .Level5InterruptVector - .section .Level5InterruptVector.text, "ax" - .global _Level5Vector - .type _Level5Vector,@function - .align 4 -_Level5Vector: - wsr a0, EXCSAVE_5 /* preserve a0 */ - call0 _xt_medint5 /* load interrupt handler */ - - .end literal_prefix - - .text - .type _xt_medint5,@function - .align 4 -_xt_medint5: - mov a0, sp /* sp == a1 */ - addi sp, sp, -XT_STK_FRMSZ /* allocate interrupt stack frame */ - s32i a0, sp, XT_STK_A1 /* save pre-interrupt SP */ - rsr a0, EPS_5 /* save interruptee's PS */ - s32i a0, sp, XT_STK_PS - rsr a0, EPC_5 /* save interruptee's PC */ - s32i a0, sp, XT_STK_PC - rsr a0, EXCSAVE_5 /* save interruptee's a0 */ - s32i a0, sp, XT_STK_A0 - movi a0, _xt_medint5_exit /* save exit point for dispatch */ - s32i a0, sp, XT_STK_EXIT - - /* Save rest of interrupt context and enter RTOS. */ - call0 XT_RTOS_INT_ENTER /* common RTOS interrupt entry */ - - /* !! We are now on the RTOS system stack !! */ - - /* Set up PS for C, enable interrupts above this level and clear EXCM. */ - #ifdef __XTENSA_CALL0_ABI__ - movi a0, PS_INTLEVEL(5) | PS_UM - #else - movi a0, PS_INTLEVEL(5) | PS_UM | PS_WOE - #endif - wsr a0, PS - rsync - - /* OK to call C code at this point, dispatch user ISRs */ - - dispatch_c_isr 5 XCHAL_INTLEVEL5_MASK - - /* Done handling interrupts, transfer control to OS */ - call0 XT_RTOS_INT_EXIT /* does not return directly here */ - - /* - Exit point for dispatch. Saved in interrupt stack frame at XT_STK_EXIT - on entry and used to return to a thread or interrupted interrupt handler. - */ - .global _xt_medint5_exit - .type _xt_medint5_exit,@function - .align 4 -_xt_medint5_exit: - /* Restore only level-specific regs (the rest were already restored) */ - l32i a0, sp, XT_STK_PS /* retrieve interruptee's PS */ - wsr a0, EPS_5 - l32i a0, sp, XT_STK_PC /* retrieve interruptee's PC */ - wsr a0, EPC_5 - l32i a0, sp, XT_STK_A0 /* retrieve interruptee's A0 */ - l32i sp, sp, XT_STK_A1 /* remove interrupt stack frame */ - rsync /* ensure EPS and EPC written */ - rfi 5 - -#endif /* Level 5 */ - -#if XCHAL_EXCM_LEVEL >= 6 - - .begin literal_prefix .Level6InterruptVector - .section .Level6InterruptVector.text, "ax" - .global _Level6Vector - .type _Level6Vector,@function - .align 4 -_Level6Vector: - wsr a0, EXCSAVE_6 /* preserve a0 */ - call0 _xt_medint6 /* load interrupt handler */ - - .end literal_prefix - - .text - .type _xt_medint6,@function - .align 4 -_xt_medint6: - mov a0, sp /* sp == a1 */ - addi sp, sp, -XT_STK_FRMSZ /* allocate interrupt stack frame */ - s32i a0, sp, XT_STK_A1 /* save pre-interrupt SP */ - rsr a0, EPS_6 /* save interruptee's PS */ - s32i a0, sp, XT_STK_PS - rsr a0, EPC_6 /* save interruptee's PC */ - s32i a0, sp, XT_STK_PC - rsr a0, EXCSAVE_6 /* save interruptee's a0 */ - s32i a0, sp, XT_STK_A0 - movi a0, _xt_medint6_exit /* save exit point for dispatch */ - s32i a0, sp, XT_STK_EXIT - - /* Save rest of interrupt context and enter RTOS. */ - call0 XT_RTOS_INT_ENTER /* common RTOS interrupt entry */ - - /* !! We are now on the RTOS system stack !! */ - - /* Set up PS for C, enable interrupts above this level and clear EXCM. */ - #ifdef __XTENSA_CALL0_ABI__ - movi a0, PS_INTLEVEL(6) | PS_UM - #else - movi a0, PS_INTLEVEL(6) | PS_UM | PS_WOE - #endif - wsr a0, PS - rsync - - /* OK to call C code at this point, dispatch user ISRs */ - - dispatch_c_isr 6 XCHAL_INTLEVEL6_MASK - - /* Done handling interrupts, transfer control to OS */ - call0 XT_RTOS_INT_EXIT /* does not return directly here */ - - /* - Exit point for dispatch. Saved in interrupt stack frame at XT_STK_EXIT - on entry and used to return to a thread or interrupted interrupt handler. - */ - .global _xt_medint6_exit - .type _xt_medint6_exit,@function - .align 4 -_xt_medint6_exit: - /* Restore only level-specific regs (the rest were already restored) */ - l32i a0, sp, XT_STK_PS /* retrieve interruptee's PS */ - wsr a0, EPS_6 - l32i a0, sp, XT_STK_PC /* retrieve interruptee's PC */ - wsr a0, EPC_6 - l32i a0, sp, XT_STK_A0 /* retrieve interruptee's A0 */ - l32i sp, sp, XT_STK_A1 /* remove interrupt stack frame */ - rsync /* ensure EPS and EPC written */ - rfi 6 - -#endif /* Level 6 */ - - -/******************************************************************************* - -HIGH PRIORITY (LEVEL > XCHAL_EXCM_LEVEL) INTERRUPT VECTORS AND HANDLERS - -High priority interrupts are by definition those with priorities greater -than XCHAL_EXCM_LEVEL. This includes non-maskable (NMI). High priority -interrupts cannot interact with the RTOS, that is they must save all regs -they use and not call any RTOS function. - -A further restriction imposed by the Xtensa windowed architecture is that -high priority interrupts must not modify the stack area even logically -"above" the top of the interrupted stack (they need to provide their -own stack or static save area). - -Cadence Design Systems recommends high priority interrupt handlers be coded in assembly -and used for purposes requiring very short service times. - -Here are templates for high priority (level 2+) interrupt vectors. -They assume only one interrupt per level to avoid the burden of identifying -which interrupts at this level are pending and enabled. This allows for -minimum latency and avoids having to save/restore a2 in addition to a0. -If more than one interrupt per high priority level is configured, this burden -is on the handler which in any case must provide a way to save and restore -registers it uses without touching the interrupted stack. - -Each vector goes at a predetermined location according to the Xtensa -hardware configuration, which is ensured by its placement in a special -section known to the Xtensa linker support package (LSP). It performs -the minimum necessary before jumping to the handler in the .text section. - -*******************************************************************************/ - -/* -Currently only shells for high priority interrupt handlers are provided -here. However a template and example can be found in the Cadence Design Systems tools -documentation: "Microprocessor Programmer's Guide". -*/ - -#if XCHAL_NUM_INTLEVELS >=2 && XCHAL_EXCM_LEVEL <2 && XCHAL_DEBUGLEVEL !=2 - - .begin literal_prefix .Level2InterruptVector - .section .Level2InterruptVector.text, "ax" - .global _Level2Vector - .type _Level2Vector,@function - .align 4 -_Level2Vector: - wsr a0, EXCSAVE_2 /* preserve a0 */ - call0 _xt_highint2 /* load interrupt handler */ - - .end literal_prefix - - .text - .type _xt_highint2,@function - .align 4 -_xt_highint2: - - #ifdef XT_INTEXC_HOOKS - /* Call interrupt hook if present to (pre)handle interrupts. */ - movi a0, _xt_intexc_hooks - l32i a0, a0, 2<<2 - beqz a0, 1f -.Ln_xt_highint2_call_hook: - callx0 a0 /* must NOT disturb stack! */ -1: - #endif - - /* USER_EDIT: - ADD HIGH PRIORITY LEVEL 2 INTERRUPT HANDLER CODE HERE. - */ - - .align 4 -.L_xt_highint2_exit: - rsr a0, EXCSAVE_2 /* restore a0 */ - rfi 2 - -#endif /* Level 2 */ - -#if XCHAL_NUM_INTLEVELS >=3 && XCHAL_EXCM_LEVEL <3 && XCHAL_DEBUGLEVEL !=3 - - .begin literal_prefix .Level3InterruptVector - .section .Level3InterruptVector.text, "ax" - .global _Level3Vector - .type _Level3Vector,@function - .align 4 -_Level3Vector: - wsr a0, EXCSAVE_3 /* preserve a0 */ - call0 _xt_highint3 /* load interrupt handler */ - /* never returns here - call0 is used as a jump (see note at top) */ - - .end literal_prefix - - .text - .type _xt_highint3,@function - .align 4 -_xt_highint3: - - #ifdef XT_INTEXC_HOOKS - /* Call interrupt hook if present to (pre)handle interrupts. */ - movi a0, _xt_intexc_hooks - l32i a0, a0, 3<<2 - beqz a0, 1f -.Ln_xt_highint3_call_hook: - callx0 a0 /* must NOT disturb stack! */ -1: - #endif - - /* USER_EDIT: - ADD HIGH PRIORITY LEVEL 3 INTERRUPT HANDLER CODE HERE. - */ - - .align 4 -.L_xt_highint3_exit: - rsr a0, EXCSAVE_3 /* restore a0 */ - rfi 3 - -#endif /* Level 3 */ - -#if XCHAL_NUM_INTLEVELS >=4 && XCHAL_EXCM_LEVEL <4 && XCHAL_DEBUGLEVEL !=4 - - .begin literal_prefix .Level4InterruptVector - .section .Level4InterruptVector.text, "ax" - .global _Level4Vector - .type _Level4Vector,@function - .align 4 -_Level4Vector: - wsr a0, EXCSAVE_4 /* preserve a0 */ - call0 _xt_highint4 /* load interrupt handler */ - /* never returns here - call0 is used as a jump (see note at top) */ - - .end literal_prefix - - .text - .type _xt_highint4,@function - .align 4 -_xt_highint4: - - #ifdef XT_INTEXC_HOOKS - /* Call interrupt hook if present to (pre)handle interrupts. */ - movi a0, _xt_intexc_hooks - l32i a0, a0, 4<<2 - beqz a0, 1f -.Ln_xt_highint4_call_hook: - callx0 a0 /* must NOT disturb stack! */ -1: - #endif - - /* USER_EDIT: - ADD HIGH PRIORITY LEVEL 4 INTERRUPT HANDLER CODE HERE. - */ - - .align 4 -.L_xt_highint4_exit: - rsr a0, EXCSAVE_4 /* restore a0 */ - rfi 4 - -#endif /* Level 4 */ - -#if XCHAL_NUM_INTLEVELS >=5 && XCHAL_EXCM_LEVEL <5 && XCHAL_DEBUGLEVEL !=5 - - .begin literal_prefix .Level5InterruptVector - .section .Level5InterruptVector.text, "ax" - .global _Level5Vector - .type _Level5Vector,@function - .align 4 -_Level5Vector: - wsr a0, EXCSAVE_5 /* preserve a0 */ - call0 _xt_highint5 /* load interrupt handler */ - /* never returns here - call0 is used as a jump (see note at top) */ - - .end literal_prefix - - .text - .type _xt_highint5,@function - .align 4 -_xt_highint5: - - #ifdef XT_INTEXC_HOOKS - /* Call interrupt hook if present to (pre)handle interrupts. */ - movi a0, _xt_intexc_hooks - l32i a0, a0, 5<<2 - beqz a0, 1f -.Ln_xt_highint5_call_hook: - callx0 a0 /* must NOT disturb stack! */ -1: - #endif - - /* USER_EDIT: - ADD HIGH PRIORITY LEVEL 5 INTERRUPT HANDLER CODE HERE. - */ - - .align 4 -.L_xt_highint5_exit: - rsr a0, EXCSAVE_5 /* restore a0 */ - rfi 5 - -#endif /* Level 5 */ - -#if XCHAL_NUM_INTLEVELS >=6 && XCHAL_EXCM_LEVEL <6 && XCHAL_DEBUGLEVEL !=6 - - .begin literal_prefix .Level6InterruptVector - .section .Level6InterruptVector.text, "ax" - .global _Level6Vector - .type _Level6Vector,@function - .align 4 -_Level6Vector: - wsr a0, EXCSAVE_6 /* preserve a0 */ - call0 _xt_highint6 /* load interrupt handler */ - /* never returns here - call0 is used as a jump (see note at top) */ - - .end literal_prefix - - .text - .type _xt_highint6,@function - .align 4 -_xt_highint6: - - #ifdef XT_INTEXC_HOOKS - /* Call interrupt hook if present to (pre)handle interrupts. */ - movi a0, _xt_intexc_hooks - l32i a0, a0, 6<<2 - beqz a0, 1f -.Ln_xt_highint6_call_hook: - callx0 a0 /* must NOT disturb stack! */ -1: - #endif - - /* USER_EDIT: - ADD HIGH PRIORITY LEVEL 6 INTERRUPT HANDLER CODE HERE. - */ - - .align 4 -.L_xt_highint6_exit: - rsr a0, EXCSAVE_6 /* restore a0 */ - rfi 6 - -#endif /* Level 6 */ - -#if XCHAL_HAVE_NMI - - .begin literal_prefix .NMIExceptionVector - .section .NMIExceptionVector.text, "ax" - .global _NMIExceptionVector - .type _NMIExceptionVector,@function - .align 4 -_NMIExceptionVector: - wsr a0, EXCSAVE + XCHAL_NMILEVEL _ /* preserve a0 */ - call0 _xt_nmi /* load interrupt handler */ - /* never returns here - call0 is used as a jump (see note at top) */ - - .end literal_prefix - - .text - .type _xt_nmi,@function - .align 4 -_xt_nmi: - - #ifdef XT_INTEXC_HOOKS - /* Call interrupt hook if present to (pre)handle interrupts. */ - movi a0, _xt_intexc_hooks - l32i a0, a0, XCHAL_NMILEVEL<<2 - beqz a0, 1f -.Ln_xt_nmi_call_hook: - callx0 a0 /* must NOT disturb stack! */ -1: - #endif - - /* USER_EDIT: - ADD HIGH PRIORITY NON-MASKABLE INTERRUPT (NMI) HANDLER CODE HERE. - */ - - .align 4 -.L_xt_nmi_exit: - rsr a0, EXCSAVE + XCHAL_NMILEVEL /* restore a0 */ - rfi XCHAL_NMILEVEL - -#endif /* NMI */ - - -/******************************************************************************* - -WINDOW OVERFLOW AND UNDERFLOW EXCEPTION VECTORS AND ALLOCA EXCEPTION HANDLER - -Here is the code for each window overflow/underflow exception vector and -(interspersed) efficient code for handling the alloca exception cause. -Window exceptions are handled entirely in the vector area and are very -tight for performance. The alloca exception is also handled entirely in -the window vector area so comes at essentially no cost in code size. -Users should never need to modify them and Cadence Design Systems recommends -they do not. - -Window handlers go at predetermined vector locations according to the -Xtensa hardware configuration, which is ensured by their placement in a -special section known to the Xtensa linker support package (LSP). Since -their offsets in that section are always the same, the LSPs do not define -a section per vector. - -These things are coded for XEA2 only (XEA1 is not supported). - -Note on Underflow Handlers: -The underflow handler for returning from call[i+1] to call[i] -must preserve all the registers from call[i+1]'s window. -In particular, a0 and a1 must be preserved because the RETW instruction -will be reexecuted (and may even underflow if an intervening exception -has flushed call[i]'s registers). -Registers a2 and up may contain return values. - -*******************************************************************************/ - -#if XCHAL_HAVE_WINDOWED - - .section .WindowVectors.text, "ax" - -/* --------------------------------------------------------------------------------- -Window Overflow Exception for Call4. - -Invoked if a call[i] referenced a register (a4-a15) -that contains data from ancestor call[j]; -call[j] had done a call4 to call[j+1]. -On entry here: - window rotated to call[j] start point; - a0-a3 are registers to be saved; - a4-a15 must be preserved; - a5 is call[j+1]'s stack pointer. --------------------------------------------------------------------------------- -*/ - - .org 0x0 - .global _WindowOverflow4 -_WindowOverflow4: - - s32e a0, a5, -16 /* save a0 to call[j+1]'s stack frame */ - s32e a1, a5, -12 /* save a1 to call[j+1]'s stack frame */ - s32e a2, a5, -8 /* save a2 to call[j+1]'s stack frame */ - s32e a3, a5, -4 /* save a3 to call[j+1]'s stack frame */ - rfwo /* rotates back to call[i] position */ - -/* --------------------------------------------------------------------------------- -Window Underflow Exception for Call4 - -Invoked by RETW returning from call[i+1] to call[i] -where call[i]'s registers must be reloaded (not live in ARs); -where call[i] had done a call4 to call[i+1]. -On entry here: - window rotated to call[i] start point; - a0-a3 are undefined, must be reloaded with call[i].reg[0..3]; - a4-a15 must be preserved (they are call[i+1].reg[0..11]); - a5 is call[i+1]'s stack pointer. --------------------------------------------------------------------------------- -*/ - - .org 0x40 - .global _WindowUnderflow4 -_WindowUnderflow4: - - l32e a0, a5, -16 /* restore a0 from call[i+1]'s stack frame */ - l32e a1, a5, -12 /* restore a1 from call[i+1]'s stack frame */ - l32e a2, a5, -8 /* restore a2 from call[i+1]'s stack frame */ - l32e a3, a5, -4 /* restore a3 from call[i+1]'s stack frame */ - rfwu - -/* --------------------------------------------------------------------------------- -Handle alloca exception generated by interruptee executing 'movsp'. -This uses space between the window vectors, so is essentially "free". -All interruptee's regs are intact except a0 which is saved in EXCSAVE_1, -and PS.EXCM has been set by the exception hardware (can't be interrupted). -The fact the alloca exception was taken means the registers associated with -the base-save area have been spilled and will be restored by the underflow -handler, so those 4 registers are available for scratch. -The code is optimized to avoid unaligned branches and minimize cache misses. --------------------------------------------------------------------------------- -*/ - - .align 4 - .global _xt_alloca_exc -_xt_alloca_exc: - - rsr a0, WINDOWBASE /* grab WINDOWBASE before rotw changes it */ - rotw -1 /* WINDOWBASE goes to a4, new a0-a3 are scratch */ - rsr a2, PS - extui a3, a2, XCHAL_PS_OWB_SHIFT, XCHAL_PS_OWB_BITS - xor a3, a3, a4 /* bits changed from old to current windowbase */ - rsr a4, EXCSAVE_1 /* restore original a0 (now in a4) */ - slli a3, a3, XCHAL_PS_OWB_SHIFT - xor a2, a2, a3 /* flip changed bits in old window base */ - wsr a2, PS /* update PS.OWB to new window base */ - rsync - - _bbci.l a4, 31, _WindowUnderflow4 - rotw -1 /* original a0 goes to a8 */ - _bbci.l a8, 30, _WindowUnderflow8 - rotw -1 - j _WindowUnderflow12 - -/* --------------------------------------------------------------------------------- -Window Overflow Exception for Call8 - -Invoked if a call[i] referenced a register (a4-a15) -that contains data from ancestor call[j]; -call[j] had done a call8 to call[j+1]. -On entry here: - window rotated to call[j] start point; - a0-a7 are registers to be saved; - a8-a15 must be preserved; - a9 is call[j+1]'s stack pointer. --------------------------------------------------------------------------------- -*/ - - .org 0x80 - .global _WindowOverflow8 -_WindowOverflow8: - - s32e a0, a9, -16 /* save a0 to call[j+1]'s stack frame */ - l32e a0, a1, -12 /* a0 <- call[j-1]'s sp - (used to find end of call[j]'s frame) */ - s32e a1, a9, -12 /* save a1 to call[j+1]'s stack frame */ - s32e a2, a9, -8 /* save a2 to call[j+1]'s stack frame */ - s32e a3, a9, -4 /* save a3 to call[j+1]'s stack frame */ - s32e a4, a0, -32 /* save a4 to call[j]'s stack frame */ - s32e a5, a0, -28 /* save a5 to call[j]'s stack frame */ - s32e a6, a0, -24 /* save a6 to call[j]'s stack frame */ - s32e a7, a0, -20 /* save a7 to call[j]'s stack frame */ - rfwo /* rotates back to call[i] position */ - -/* --------------------------------------------------------------------------------- -Window Underflow Exception for Call8 - -Invoked by RETW returning from call[i+1] to call[i] -where call[i]'s registers must be reloaded (not live in ARs); -where call[i] had done a call8 to call[i+1]. -On entry here: - window rotated to call[i] start point; - a0-a7 are undefined, must be reloaded with call[i].reg[0..7]; - a8-a15 must be preserved (they are call[i+1].reg[0..7]); - a9 is call[i+1]'s stack pointer. --------------------------------------------------------------------------------- -*/ - - .org 0xC0 - .global _WindowUnderflow8 -_WindowUnderflow8: - - l32e a0, a9, -16 /* restore a0 from call[i+1]'s stack frame */ - l32e a1, a9, -12 /* restore a1 from call[i+1]'s stack frame */ - l32e a2, a9, -8 /* restore a2 from call[i+1]'s stack frame */ - l32e a7, a1, -12 /* a7 <- call[i-1]'s sp - (used to find end of call[i]'s frame) */ - l32e a3, a9, -4 /* restore a3 from call[i+1]'s stack frame */ - l32e a4, a7, -32 /* restore a4 from call[i]'s stack frame */ - l32e a5, a7, -28 /* restore a5 from call[i]'s stack frame */ - l32e a6, a7, -24 /* restore a6 from call[i]'s stack frame */ - l32e a7, a7, -20 /* restore a7 from call[i]'s stack frame */ - rfwu - -/* --------------------------------------------------------------------------------- -Window Overflow Exception for Call12 - -Invoked if a call[i] referenced a register (a4-a15) -that contains data from ancestor call[j]; -call[j] had done a call12 to call[j+1]. -On entry here: - window rotated to call[j] start point; - a0-a11 are registers to be saved; - a12-a15 must be preserved; - a13 is call[j+1]'s stack pointer. --------------------------------------------------------------------------------- -*/ - - .org 0x100 - .global _WindowOverflow12 -_WindowOverflow12: - - s32e a0, a13, -16 /* save a0 to call[j+1]'s stack frame */ - l32e a0, a1, -12 /* a0 <- call[j-1]'s sp - (used to find end of call[j]'s frame) */ - s32e a1, a13, -12 /* save a1 to call[j+1]'s stack frame */ - s32e a2, a13, -8 /* save a2 to call[j+1]'s stack frame */ - s32e a3, a13, -4 /* save a3 to call[j+1]'s stack frame */ - s32e a4, a0, -48 /* save a4 to end of call[j]'s stack frame */ - s32e a5, a0, -44 /* save a5 to end of call[j]'s stack frame */ - s32e a6, a0, -40 /* save a6 to end of call[j]'s stack frame */ - s32e a7, a0, -36 /* save a7 to end of call[j]'s stack frame */ - s32e a8, a0, -32 /* save a8 to end of call[j]'s stack frame */ - s32e a9, a0, -28 /* save a9 to end of call[j]'s stack frame */ - s32e a10, a0, -24 /* save a10 to end of call[j]'s stack frame */ - s32e a11, a0, -20 /* save a11 to end of call[j]'s stack frame */ - rfwo /* rotates back to call[i] position */ - -/* --------------------------------------------------------------------------------- -Window Underflow Exception for Call12 - -Invoked by RETW returning from call[i+1] to call[i] -where call[i]'s registers must be reloaded (not live in ARs); -where call[i] had done a call12 to call[i+1]. -On entry here: - window rotated to call[i] start point; - a0-a11 are undefined, must be reloaded with call[i].reg[0..11]; - a12-a15 must be preserved (they are call[i+1].reg[0..3]); - a13 is call[i+1]'s stack pointer. --------------------------------------------------------------------------------- -*/ - - .org 0x140 - .global _WindowUnderflow12 -_WindowUnderflow12: - - l32e a0, a13, -16 /* restore a0 from call[i+1]'s stack frame */ - l32e a1, a13, -12 /* restore a1 from call[i+1]'s stack frame */ - l32e a2, a13, -8 /* restore a2 from call[i+1]'s stack frame */ - l32e a11, a1, -12 /* a11 <- call[i-1]'s sp - (used to find end of call[i]'s frame) */ - l32e a3, a13, -4 /* restore a3 from call[i+1]'s stack frame */ - l32e a4, a11, -48 /* restore a4 from end of call[i]'s stack frame */ - l32e a5, a11, -44 /* restore a5 from end of call[i]'s stack frame */ - l32e a6, a11, -40 /* restore a6 from end of call[i]'s stack frame */ - l32e a7, a11, -36 /* restore a7 from end of call[i]'s stack frame */ - l32e a8, a11, -32 /* restore a8 from end of call[i]'s stack frame */ - l32e a9, a11, -28 /* restore a9 from end of call[i]'s stack frame */ - l32e a10, a11, -24 /* restore a10 from end of call[i]'s stack frame */ - l32e a11, a11, -20 /* restore a11 from end of call[i]'s stack frame */ - rfwu - -#endif /* XCHAL_HAVE_WINDOWED */ - - .section .UserEnter.text, "ax" - .global call_user_start - .type call_user_start,@function - .align 4 - .literal_position - - -call_user_start: - - movi a2, 0x40040000 /* note: absolute symbol, not a ptr */ - wsr a2, vecbase - call0 user_start /* user exception handler */ diff --git a/components/freertos/xtensa_vectors.S-old b/components/freertos/xtensa_vectors.S-old deleted file mode 100644 index 2d0f7a99d2..0000000000 --- a/components/freertos/xtensa_vectors.S-old +++ /dev/null @@ -1,2064 +0,0 @@ -/******************************************************************************* -Copyright (c) 2006-2015 Cadence Design Systems Inc. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------------------------------- - - XTENSA VECTORS AND LOW LEVEL HANDLERS FOR AN RTOS - - Xtensa low level exception and interrupt vectors and handlers for an RTOS. - - Interrupt handlers and user exception handlers support interaction with - the RTOS by calling XT_RTOS_INT_ENTER and XT_RTOS_INT_EXIT before and - after user's specific interrupt handlers. These macros are defined in - xtensa_.h to call suitable functions in a specific RTOS. - - Users can install application-specific interrupt handlers for low and - medium level interrupts, by calling xt_set_interrupt_handler(). These - handlers can be written in C, and must obey C calling convention. The - handler table is indexed by the interrupt number. Each handler may be - provided with an argument. - - Note that the system timer interrupt is handled specially, and is - dispatched to the RTOS-specific handler. This timer cannot be hooked - by application code. - - Optional hooks are also provided to install a handler per level at - run-time, made available by compiling this source file with - '-DXT_INTEXC_HOOKS' (useful for automated testing). - -!! This file is a template that usually needs to be modified to handle !! -!! application specific interrupts. Search USER_EDIT for helpful comments !! -!! on where to insert handlers and how to write them. !! - - Users can also install application-specific exception handlers in the - same way, by calling xt_set_exception_handler(). One handler slot is - provided for each exception type. Note that some exceptions are handled - by the porting layer itself, and cannot be taken over by application - code in this manner. These are the alloca, syscall, and coprocessor - exceptions. - - The exception handlers can be written in C, and must follow C calling - convention. Each handler is passed a pointer to an exception frame as - its single argument. The exception frame is created on the stack, and - holds the saved context of the thread that took the exception. If the - handler returns, the context will be restored and the instruction that - caused the exception will be retried. If the handler makes any changes - to the saved state in the exception frame, the changes will be applied - when restoring the context. - - Because Xtensa is a configurable architecture, this port supports all user - generated configurations (except restrictions stated in the release notes). - This is accomplished by conditional compilation using macros and functions - defined in the Xtensa HAL (hardware adaptation layer) for your configuration. - Only the relevant parts of this file will be included in your RTOS build. - For example, this file provides interrupt vector templates for all types and - all priority levels, but only the ones in your configuration are built. - - NOTES on the use of 'call0' for long jumps instead of 'j': - 1. This file should be assembled with the -mlongcalls option to xt-xcc. - 2. The -mlongcalls compiler option causes 'call0 dest' to be expanded to - a sequence 'l32r a0, dest' 'callx0 a0' which works regardless of the - distance from the call to the destination. The linker then relaxes - it back to 'call0 dest' if it determines that dest is within range. - This allows more flexibility in locating code without the performance - overhead of the 'l32r' literal data load in cases where the destination - is in range of 'call0'. There is an additional benefit in that 'call0' - has a longer range than 'j' due to the target being word-aligned, so - the 'l32r' sequence is less likely needed. - 3. The use of 'call0' with -mlongcalls requires that register a0 not be - live at the time of the call, which is always the case for a function - call but needs to be ensured if 'call0' is used as a jump in lieu of 'j'. - 4. This use of 'call0' is independent of the C function call ABI. - -*******************************************************************************/ - -#include "xtensa_rtos.h" - - -/* Enable stack backtrace across exception/interrupt - see below */ -#define XT_DEBUG_BACKTRACE 0 - - -/* --------------------------------------------------------------------------------- - Defines used to access _xtos_interrupt_table. --------------------------------------------------------------------------------- -*/ -#define XIE_HANDLER 0 -#define XIE_ARG 4 -#define XIE_SIZE 8 - -/* --------------------------------------------------------------------------------- - Macro extract_msb - return the input with only the highest bit set. - - Input : "ain" - Input value, clobbered. - Output : "aout" - Output value, has only one bit set, MSB of "ain". - The two arguments must be different AR registers. --------------------------------------------------------------------------------- -*/ - - .macro extract_msb aout ain -1: - addi \aout, \ain, -1 /* aout = ain - 1 */ - and \ain, \ain, \aout /* ain = ain & aout */ - bnez \ain, 1b /* repeat until ain == 0 */ - addi \aout, \aout, 1 /* return aout + 1 */ - .endm - -/* --------------------------------------------------------------------------------- - Macro dispatch_c_isr - dispatch interrupts to user ISRs. - This will dispatch to user handlers (if any) that are registered in the - XTOS dispatch table (_xtos_interrupt_table). These handlers would have - been registered by calling _xtos_set_interrupt_handler(). There is one - exception - the timer interrupt used by the OS will not be dispatched - to a user handler - this must be handled by the caller of this macro. - - Level triggered and software interrupts are automatically deasserted by - this code. - - ASSUMPTIONS: - -- PS.INTLEVEL is set to "level" at entry - -- PS.EXCM = 0, C calling enabled - - NOTE: For CALL0 ABI, a12-a15 have not yet been saved. - - NOTE: This macro will use registers a0 and a2-a6. The arguments are: - level -- interrupt level - mask -- interrupt bitmask for this level --------------------------------------------------------------------------------- -*/ - - .macro dispatch_c_isr level mask - - /* Get mask of pending, enabled interrupts at this level into a2. */ - -.L_xt_user_int_&level&: - rsr a2, INTENABLE - rsr a3, INTERRUPT - movi a4, \mask - and a2, a2, a3 - and a2, a2, a4 - beqz a2, 9f /* nothing to do */ - - /* This bit of code provides a nice debug backtrace in the debugger. - It does take a few more instructions, so undef XT_DEBUG_BACKTRACE - if you want to save the cycles. - */ - #if XT_DEBUG_BACKTRACE - #ifndef __XTENSA_CALL0_ABI__ - rsr a0, EPC_1 + \level - 1 /* return address */ - movi a4, 0xC0000000 /* constant with top 2 bits set (call size) */ - or a0, a0, a4 /* set top 2 bits */ - addx2 a0, a4, a0 /* clear top bit -- simulating call4 size */ - #endif - #endif - - #ifdef XT_INTEXC_HOOKS - /* Call interrupt hook if present to (pre)handle interrupts. */ - movi a4, _xt_intexc_hooks - l32i a4, a4, \level << 2 - beqz a4, 2f - #ifdef __XTENSA_CALL0_ABI__ - callx0 a4 - beqz a2, 9f - #else - mov a6, a2 - callx4 a4 - beqz a6, 9f - mov a2, a6 - #endif -2: - #endif - - /* Now look up in the dispatch table and call user ISR if any. */ - /* If multiple bits are set then MSB has highest priority. */ - - extract_msb a4, a2 /* a4 = MSB of a2, a2 trashed */ - - #ifdef XT_USE_SWPRI - /* Enable all interrupts at this level that are numerically higher - than the one we just selected, since they are treated as higher - priority. - */ - movi a3, \mask /* a3 = all interrupts at this level */ - add a2, a4, a4 /* a2 = a4 << 1 */ - addi a2, a2, -1 /* a2 = mask of 1's <= a4 bit */ - and a2, a2, a3 /* a2 = mask of all bits <= a4 at this level */ - movi a3, _xt_intdata - l32i a6, a3, 4 /* a6 = _xt_vpri_mask */ - neg a2, a2 - addi a2, a2, -1 /* a2 = mask to apply */ - and a5, a6, a2 /* mask off all bits <= a4 bit */ - s32i a5, a3, 4 /* update _xt_vpri_mask */ - rsr a3, INTENABLE - and a3, a3, a2 /* mask off all bits <= a4 bit */ - wsr a3, INTENABLE - rsil a3, \level - 1 /* lower interrupt level by 1 */ - #endif - - movi a3, XT_TIMER_INTEN /* a3 = timer interrupt bit */ - wsr a4, INTCLEAR /* clear sw or edge-triggered interrupt */ - beq a3, a4, 7f /* if timer interrupt then skip table */ - - find_ms_setbit a3, a4, a3, 0 /* a3 = interrupt number */ - - movi a4, _xt_interrupt_table - addx8 a3, a3, a4 /* a3 = address of interrupt table entry */ - l32i a4, a3, XIE_HANDLER /* a4 = handler address */ - #ifdef __XTENSA_CALL0_ABI__ - mov a12, a6 /* save in callee-saved reg */ - l32i a2, a3, XIE_ARG /* a2 = handler arg */ - callx0 a4 /* call handler */ - mov a2, a12 - #else - mov a2, a6 /* save in windowed reg */ - l32i a6, a3, XIE_ARG /* a6 = handler arg */ - callx4 a4 /* call handler */ - #endif - - #ifdef XT_USE_SWPRI - j 8f - #else - j .L_xt_user_int_&level& /* check for more interrupts */ - #endif - -7: - - .ifeq XT_TIMER_INTPRI - \level -.L_xt_user_int_timer_&level&: - /* - Interrupt handler for the RTOS tick timer if at this level. - We'll be reading the interrupt state again after this call - so no need to preserve any registers except a6 (vpri_mask). - */ - - #ifdef __XTENSA_CALL0_ABI__ - mov a12, a6 - call0 XT_RTOS_TIMER_INT - mov a2, a12 - #else - mov a2, a6 - call4 XT_RTOS_TIMER_INT - #endif - .endif - - #ifdef XT_USE_SWPRI - j 8f - #else - j .L_xt_user_int_&level& /* check for more interrupts */ - #endif - - #ifdef XT_USE_SWPRI -8: - /* Restore old value of _xt_vpri_mask from a2. Also update INTENABLE from - virtual _xt_intenable which _could_ have changed during interrupt - processing. */ - - movi a3, _xt_intdata - l32i a4, a3, 0 /* a4 = _xt_intenable */ - s32i a2, a3, 4 /* update _xt_vpri_mask */ - and a4, a4, a2 /* a4 = masked intenable */ - wsr a4, INTENABLE /* update INTENABLE */ - #endif - -9: - /* done */ - - .endm - - -/* --------------------------------------------------------------------------------- - Panic handler. - Should be reached by call0 (preferable) or jump only. If call0, a0 says where - from. If on simulator, display panic message and abort, else loop indefinitely. --------------------------------------------------------------------------------- -*/ - - .text - .global panicHandlerRegs - .global panicHandler - .global panicStack - - .global _xt_panic - .type _xt_panic,@function - .align 4 - -_xt_panic: - //ToDo: save registers - movi a2, panicHandlerRegs - s32i a0,a2,0 - s32i a1,a2,4 - s32i a2,a2,8 - s32i a3,a2,12 - s32i a4,a2,16 - s32i a5,a2,20 - s32i a6,a2,24 - s32i a7,a2,28 - s32i a8,a2,32 - s32i a9,a2,36 - s32i a10,a2,40 - s32i a11,a2,44 - s32i a12,a2,48 - s32i a13,a2,52 - s32i a14,a2,56 - s32i a15,a2,60 - - rsr a3, EXCSAVE - s32i a3,a2,64 - rsr a3, EXCSAVE+1 - s32i a3,a2,68 - rsr a3, EXCSAVE+2 - s32i a3,a2,72 - rsr a3, EXCSAVE+3 - s32i a3,a2,76 - rsr a3, EXCSAVE+4 - s32i a3,a2,80 - rsr a3, EXCSAVE+5 - s32i a3,a2,84 - rsr a3, EXCSAVE+6 - s32i a3,a2,88 - rsr a3, EXCSAVE+7 - s32i a3,a2,92 - - rsr a3, EPC - s32i a3,a2,96 - rsr a3, EPC+1 - s32i a3,a2,100 - rsr a3, EPC+2 - s32i a3,a2,104 - rsr a3, EPC+3 - s32i a3,a2,108 - rsr a3, EPC+4 - s32i a3,a2,112 - rsr a3, EPC+5 - s32i a3,a2,116 - rsr a3, EPC+6 - s32i a3,a2,120 - rsr a3, EPC+7 - s32i a3,a2,124 - - rsr a3, DEPC - s32i a3,a2,128 - rsr a3, EXCVADDR - s32i a3,a2,132 - - //Reset window start / base to 0 - movi a2, 1 - wsr a2, windowstart - movi a2, 0 - wsr a2, windowbase - rsync - - //Clear EXCM, set WOE flags - rsr a2, ps - movi a3, ~(PS_EXCM_MASK) - and a2, a2, a3 - movi a3, PS_WOE_MASK - or a2, a2, a3 - wsr a2, ps - rsync - - //Switch to private stack - movi a1,panicStack+(255*4) - rsil a2, XCHAL_EXCM_LEVEL /* disable all low & med ints */ - - - // Debug: output '!' on serport - movi a2,0x60000000 - movi a3,'!' - s32i a3,a2,0 - - movi a3, panicHandlerRegs - l32i a2,a3,0 - call0 panic_print_hex - rsr a2, EXCCAUSE - call0 panic_print_hex - rsr a2, EXCVADDR - call0 panic_print_hex - rsr a2,EPC+1 - call0 panic_print_hex - rsr a2,EPC+2 - call0 panic_print_hex - rsr a2,EPC+3 - call0 panic_print_hex - rsr a2,EPC+6 - call0 panic_print_hex - rsr a2,EXCSAVE_1 - call0 panic_print_hex - rsr a2,DEPC - call0 panic_print_hex - - //Call panic handler -// movi a4, panicHandler -// callx4 a4 - call4 panicHandler - - movi a2,0x60000000 - movi a3,'d' - s32i a3,a2,0 - - -1: j 1b /* loop infinitely */ - - .align 4 -panicHandlerz: - entry a1,32 - movi a2,0x60000000 - movi a3,'h' - memw - s32i a3,a2,0 - - retw - - - .align 4 -//Call using call0. Prints the hex char in a2. Kills a3, a4, a5 -panic_print_hex: - movi a3,0x60000000 - movi a4,8 -panic_print_hex_loop: - l32i a5, a3, 0x1c - extui a5, a5, 16, 8 - bgei a5,64,panic_print_hex_loop - - srli a5,a2,28 - bgei a5,10,panic_print_hex_a - addi a5,a5,'0' - j panic_print_hex_ok -panic_print_hex_a: - addi a5,a5,'A'-10 -panic_print_hex_ok: - s32i a5,a3,0 - slli a2,a2,4 - - addi a4,a4,-1 - bnei a4,0,panic_print_hex_loop - movi a5,' ' - s32i a5,a3,0 - - ret - - - - .section .rodata, "a" - .align 4 - - - -/* --------------------------------------------------------------------------------- - Hooks to dynamically install handlers for exceptions and interrupts. - Allows automated regression frameworks to install handlers per test. - Consists of an array of function pointers indexed by interrupt level, - with index 0 containing the entry for user exceptions. - Initialized with all 0s, meaning no handler is installed at each level. - See comment in xtensa_rtos.h for more details. --------------------------------------------------------------------------------- -*/ - - #ifdef XT_INTEXC_HOOKS - .data - .global _xt_intexc_hooks - .type _xt_intexc_hooks,@object - .align 4 - -_xt_intexc_hooks: - .fill XT_INTEXC_HOOK_NUM, 4, 0 - #endif - - -/* --------------------------------------------------------------------------------- - EXCEPTION AND LEVEL 1 INTERRUPT VECTORS AND LOW LEVEL HANDLERS - (except window exception vectors). - - Each vector goes at a predetermined location according to the Xtensa - hardware configuration, which is ensured by its placement in a special - section known to the Xtensa linker support package (LSP). It performs - the minimum necessary before jumping to the handler in the .text section. - - The corresponding handler goes in the normal .text section. It sets up - the appropriate stack frame, saves a few vector-specific registers and - calls XT_RTOS_INT_ENTER to save the rest of the interrupted context - and enter the RTOS, then sets up a C environment. It then calls the - user's interrupt handler code (which may be coded in C) and finally - calls XT_RTOS_INT_EXIT to transfer control to the RTOS for scheduling. - - While XT_RTOS_INT_EXIT does not return directly to the interruptee, - eventually the RTOS scheduler will want to dispatch the interrupted - task or handler. The scheduler will return to the exit point that was - saved in the interrupt stack frame at XT_STK_EXIT. --------------------------------------------------------------------------------- -*/ - - -/* --------------------------------------------------------------------------------- -Debug Exception. --------------------------------------------------------------------------------- -*/ - -#if XCHAL_HAVE_DEBUG - - .begin literal_prefix .DebugExceptionVector - .section .DebugExceptionVector.text, "ax" - .global _DebugExceptionVector - .align 4 - -_DebugExceptionVector: - - #ifdef XT_SIMULATOR - /* - In the simulator, let the debugger (if any) handle the debug exception, - or simply stop the simulation: - */ - wsr a2, EXCSAVE+XCHAL_DEBUGLEVEL /* save a2 where sim expects it */ - movi a2, SYS_gdb_enter_sktloop - simcall /* have ISS handle debug exc. */ - #elif 0 /* change condition to 1 to use the HAL minimal debug handler */ - wsr a3, EXCSAVE+XCHAL_DEBUGLEVEL - movi a3, xthal_debugexc_defhndlr_nw /* use default debug handler */ - jx a3 - #else - wsr a0, EXCSAVE+XCHAL_DEBUGLEVEL /* save original a0 somewhere */ - call0 _xt_panic /* does not return */ - rfi XCHAL_DEBUGLEVEL /* make a0 point here not later */ - #endif - - .end literal_prefix - -#endif - -/* --------------------------------------------------------------------------------- -Double Exception. -Double exceptions are not a normal occurrence. They indicate a bug of some kind. --------------------------------------------------------------------------------- -*/ - -#ifdef XCHAL_DOUBLEEXC_VECTOR_VADDR - - .begin literal_prefix .DoubleExceptionVector - .section .DoubleExceptionVector.text, "ax" - .global _DoubleExceptionVector - .align 4 - -_DoubleExceptionVector: - - #if XCHAL_HAVE_DEBUG - break 1, 4 /* unhandled double exception */ - #endif - call0 _xt_panic /* does not return */ - rfde /* make a0 point here not later */ - - .end literal_prefix - -#endif /* XCHAL_DOUBLEEXC_VECTOR_VADDR */ - -/* --------------------------------------------------------------------------------- -Kernel Exception (including Level 1 Interrupt from kernel mode). --------------------------------------------------------------------------------- -*/ - - .begin literal_prefix .KernelExceptionVector - .section .KernelExceptionVector.text, "ax" - .global _KernelExceptionVector - .align 4 - -_KernelExceptionVector: - - wsr a0, EXCSAVE_1 /* preserve a0 */ - call0 _xt_kernel_exc /* kernel exception handler */ - /* never returns here - call0 is used as a jump (see note at top) */ - - .end literal_prefix - - .text - .align 4 - -_xt_kernel_exc: - #if XCHAL_HAVE_DEBUG - break 1, 0 /* unhandled kernel exception */ - #endif - call0 _xt_panic /* does not return */ - rfe /* make a0 point here not there */ - - -/* --------------------------------------------------------------------------------- -User Exception (including Level 1 Interrupt from user mode). --------------------------------------------------------------------------------- -*/ - - .begin literal_prefix .UserExceptionVector - .section .UserExceptionVector.text, "ax" - .global _UserExceptionVector - .type _UserExceptionVector,@function - .align 4 - -_UserExceptionVector: - - wsr a0, EXCSAVE_1 /* preserve a0 */ - call0 _xt_user_exc /* user exception handler */ - /* never returns here - call0 is used as a jump (see note at top) */ - - .end literal_prefix - -/* --------------------------------------------------------------------------------- - Insert some waypoints for jumping beyond the signed 8-bit range of - conditional branch instructions, so the conditional branchces to specific - exception handlers are not taken in the mainline. Saves some cycles in the - mainline. --------------------------------------------------------------------------------- -*/ - - .text - - #if XCHAL_HAVE_WINDOWED - .align 4 -_xt_to_alloca_exc: - call0 _xt_alloca_exc /* in window vectors section */ - /* never returns here - call0 is used as a jump (see note at top) */ - #endif - - .align 4 -_xt_to_syscall_exc: - call0 _xt_syscall_exc - /* never returns here - call0 is used as a jump (see note at top) */ - - #if XCHAL_CP_NUM > 0 - .align 4 -_xt_to_coproc_exc: - call0 _xt_coproc_exc - /* never returns here - call0 is used as a jump (see note at top) */ - #endif - - -/* --------------------------------------------------------------------------------- - User exception handler. --------------------------------------------------------------------------------- -*/ - - .type _xt_user_exc,@function - .align 4 - -_xt_user_exc: - - /* If level 1 interrupt then jump to the dispatcher */ - rsr a0, EXCCAUSE - beqi a0, EXCCAUSE_LEVEL1INTERRUPT, _xt_lowint1 - - /* Handle any coprocessor exceptions. Rely on the fact that exception - numbers above EXCCAUSE_CP0_DISABLED all relate to the coprocessors. - */ - #if XCHAL_CP_NUM > 0 - bgeui a0, EXCCAUSE_CP0_DISABLED, _xt_to_coproc_exc - #endif - - /* Handle alloca and syscall exceptions */ - #if XCHAL_HAVE_WINDOWED - beqi a0, EXCCAUSE_ALLOCA, _xt_to_alloca_exc - #endif - beqi a0, EXCCAUSE_SYSCALL, _xt_to_syscall_exc - - //HACK! No custom vector stuff, just call panic handler directly. ToDo: remove this when possible. -JD - call0 _xt_panic - - /* Handle all other exceptions. All can have user-defined handlers. */ - /* NOTE: we'll stay on the user stack for exception handling. */ - - /* Allocate exception frame and save minimal context. */ - mov a0, sp - addi sp, sp, -XT_STK_FRMSZ - s32i a0, sp, XT_STK_A1 - #if XCHAL_HAVE_WINDOWED - s32e a0, sp, -12 /* for debug backtrace */ - #endif - rsr a0, PS /* save interruptee's PS */ - s32i a0, sp, XT_STK_PS - rsr a0, EPC_1 /* save interruptee's PC */ - s32i a0, sp, XT_STK_PC - rsr a0, EXCSAVE_1 /* save interruptee's a0 */ - s32i a0, sp, XT_STK_A0 - #if XCHAL_HAVE_WINDOWED - s32e a0, sp, -16 /* for debug backtrace */ - #endif - s32i a12, sp, XT_STK_A12 /* _xt_context_save requires A12- */ - s32i a13, sp, XT_STK_A13 /* A13 to have already been saved */ - call0 _xt_context_save - - /* Save exc cause and vaddr into exception frame */ - rsr a0, EXCCAUSE - s32i a0, sp, XT_STK_EXCCAUSE - rsr a0, EXCVADDR - s32i a0, sp, XT_STK_EXCVADDR - - /* Set up PS for C, reenable hi-pri interrupts, and clear EXCM. */ - #ifdef __XTENSA_CALL0_ABI__ - movi a0, PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM - #else - movi a0, PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM | PS_WOE - #endif - wsr a0, PS - - #ifdef XT_DEBUG_BACKTRACE - #ifndef __XTENSA_CALL0_ABI__ - rsr a0, EPC_1 /* return address for debug backtrace */ - movi a5, 0xC0000000 /* constant with top 2 bits set (call size) */ - rsync /* wait for WSR.PS to complete */ - or a0, a0, a5 /* set top 2 bits */ - addx2 a0, a5, a0 /* clear top bit -- thus simulating call4 size */ - #else - rsync /* wait for WSR.PS to complete */ - #endif - #endif - - rsr a2, EXCCAUSE /* recover exc cause */ - - #ifdef XT_INTEXC_HOOKS - /* - Call exception hook to pre-handle exceptions (if installed). - Pass EXCCAUSE in a2, and check result in a2 (if -1, skip default handling). - */ - movi a4, _xt_intexc_hooks - l32i a4, a4, 0 /* user exception hook index 0 */ - beqz a4, 1f -.Ln_xt_user_exc_call_hook: - #ifdef __XTENSA_CALL0_ABI__ - callx0 a4 - beqi a2, -1, .L_xt_user_done - #else - mov a6, a2 - callx4 a4 - beqi a6, -1, .L_xt_user_done - mov a2, a6 - #endif -1: - #endif - - rsr a2, EXCCAUSE /* recover exc cause */ - movi a3, _xt_exception_table - addx4 a4, a2, a3 /* a4 = address of exception table entry */ - l32i a4, a4, 0 /* a4 = handler address */ - #ifdef __XTENSA_CALL0_ABI__ - mov a2, sp /* a2 = pointer to exc frame */ - callx0 a4 /* call handler */ - #else - mov a6, sp /* a6 = pointer to exc frame */ - callx4 a4 /* call handler */ - #endif - -.L_xt_user_done: - - /* Restore context and return */ - call0 _xt_context_restore - l32i a0, sp, XT_STK_PS /* retrieve interruptee's PS */ - wsr a0, PS - l32i a0, sp, XT_STK_PC /* retrieve interruptee's PC */ - wsr a0, EPC_1 - l32i a0, sp, XT_STK_A0 /* retrieve interruptee's A0 */ - l32i sp, sp, XT_STK_A1 /* remove exception frame */ - rsync /* ensure PS and EPC written */ - rfe /* PS.EXCM is cleared */ - - -/* --------------------------------------------------------------------------------- - Exit point for dispatch. Saved in interrupt stack frame at XT_STK_EXIT - on entry and used to return to a thread or interrupted interrupt handler. --------------------------------------------------------------------------------- -*/ - - .global _xt_user_exit - .type _xt_user_exit,@function - .align 4 -_xt_user_exit: - l32i a0, sp, XT_STK_PS /* retrieve interruptee's PS */ - wsr a0, PS - l32i a0, sp, XT_STK_PC /* retrieve interruptee's PC */ - wsr a0, EPC_1 - l32i a0, sp, XT_STK_A0 /* retrieve interruptee's A0 */ - l32i sp, sp, XT_STK_A1 /* remove interrupt stack frame */ - rsync /* ensure PS and EPC written */ - rfe /* PS.EXCM is cleared */ - - -/* --------------------------------------------------------------------------------- -Syscall Exception Handler (jumped to from User Exception Handler). -Syscall 0 is required to spill the register windows (no-op in Call 0 ABI). -Only syscall 0 is handled here. Other syscalls return -1 to caller in a2. --------------------------------------------------------------------------------- -*/ - - .text - .type _xt_syscall_exc,@function - .align 4 -_xt_syscall_exc: - - #ifdef __XTENSA_CALL0_ABI__ - /* - Save minimal regs for scratch. Syscall 0 does nothing in Call0 ABI. - Use a minimal stack frame (16B) to save A2 & A3 for scratch. - PS.EXCM could be cleared here, but unlikely to improve worst-case latency. - rsr a0, PS - addi a0, a0, -PS_EXCM_MASK - wsr a0, PS - */ - addi sp, sp, -16 - s32i a2, sp, 8 - s32i a3, sp, 12 - #else /* Windowed ABI */ - /* - Save necessary context and spill the register windows. - PS.EXCM is still set and must remain set until after the spill. - Reuse context save function though it saves more than necessary. - For this reason, a full interrupt stack frame is allocated. - */ - addi sp, sp, -XT_STK_FRMSZ /* allocate interrupt stack frame */ - s32i a12, sp, XT_STK_A12 /* _xt_context_save requires A12- */ - s32i a13, sp, XT_STK_A13 /* A13 to have already been saved */ - call0 _xt_context_save - #endif - - /* - Grab the interruptee's PC and skip over the 'syscall' instruction. - If it's at the end of a zero-overhead loop and it's not on the last - iteration, decrement loop counter and skip to beginning of loop. - */ - rsr a2, EPC_1 /* a2 = PC of 'syscall' */ - addi a3, a2, 3 /* ++PC */ - #if XCHAL_HAVE_LOOPS - rsr a0, LEND /* if (PC == LEND */ - bne a3, a0, 1f - rsr a0, LCOUNT /* && LCOUNT != 0) */ - beqz a0, 1f /* { */ - addi a0, a0, -1 /* --LCOUNT */ - rsr a3, LBEG /* PC = LBEG */ - wsr a0, LCOUNT /* } */ - #endif -1: wsr a3, EPC_1 /* update PC */ - - /* Restore interruptee's context and return from exception. */ - #ifdef __XTENSA_CALL0_ABI__ - l32i a2, sp, 8 - l32i a3, sp, 12 - addi sp, sp, 16 - #else - call0 _xt_context_restore - addi sp, sp, XT_STK_FRMSZ - #endif - movi a0, -1 - movnez a2, a0, a2 /* return -1 if not syscall 0 */ - rsr a0, EXCSAVE_1 - rfe - -/* --------------------------------------------------------------------------------- -Co-Processor Exception Handler (jumped to from User Exception Handler). -These exceptions are generated by co-processor instructions, which are only -allowed in thread code (not in interrupts or kernel code). This restriction is -deliberately imposed to reduce the burden of state-save/restore in interrupts. --------------------------------------------------------------------------------- -*/ -#if XCHAL_CP_NUM > 0 - - .section .rodata, "a" - -/* Offset to CP n save area in thread's CP save area. */ - .global _xt_coproc_sa_offset - .type _xt_coproc_sa_offset,@object - .align 16 /* minimize crossing cache boundaries */ -_xt_coproc_sa_offset: - .word XT_CP0_SA, XT_CP1_SA, XT_CP2_SA, XT_CP3_SA - .word XT_CP4_SA, XT_CP5_SA, XT_CP6_SA, XT_CP7_SA - -/* Bitmask for CP n's CPENABLE bit. */ - .type _xt_coproc_mask,@object - .align 16,,8 /* try to keep it all in one cache line */ - .set i, 0 -_xt_coproc_mask: - .rept XCHAL_CP_MAX - .long (i<<16) | (1<= 2 - - .begin literal_prefix .Level2InterruptVector - .section .Level2InterruptVector.text, "ax" - .global _Level2Vector - .type _Level2Vector,@function - .align 4 -_Level2Vector: - wsr a0, EXCSAVE_2 /* preserve a0 */ - call0 _xt_medint2 /* load interrupt handler */ - /* never returns here - call0 is used as a jump (see note at top) */ - - .end literal_prefix - - .text - .type _xt_medint2,@function - .align 4 -_xt_medint2: - mov a0, sp /* sp == a1 */ - addi sp, sp, -XT_STK_FRMSZ /* allocate interrupt stack frame */ - s32i a0, sp, XT_STK_A1 /* save pre-interrupt SP */ - rsr a0, EPS_2 /* save interruptee's PS */ - s32i a0, sp, XT_STK_PS - rsr a0, EPC_2 /* save interruptee's PC */ - s32i a0, sp, XT_STK_PC - rsr a0, EXCSAVE_2 /* save interruptee's a0 */ - s32i a0, sp, XT_STK_A0 - movi a0, _xt_medint2_exit /* save exit point for dispatch */ - s32i a0, sp, XT_STK_EXIT - - /* Save rest of interrupt context and enter RTOS. */ - call0 XT_RTOS_INT_ENTER /* common RTOS interrupt entry */ - - /* !! We are now on the RTOS system stack !! */ - - /* Set up PS for C, enable interrupts above this level and clear EXCM. */ - #ifdef __XTENSA_CALL0_ABI__ - movi a0, PS_INTLEVEL(2) | PS_UM - #else - movi a0, PS_INTLEVEL(2) | PS_UM | PS_WOE - #endif - wsr a0, PS - rsync - - /* OK to call C code at this point, dispatch user ISRs */ - - dispatch_c_isr 2 XCHAL_INTLEVEL2_MASK - - /* Done handling interrupts, transfer control to OS */ - call0 XT_RTOS_INT_EXIT /* does not return directly here */ - - /* - Exit point for dispatch. Saved in interrupt stack frame at XT_STK_EXIT - on entry and used to return to a thread or interrupted interrupt handler. - */ - .global _xt_medint2_exit - .type _xt_medint2_exit,@function - .align 4 -_xt_medint2_exit: - /* Restore only level-specific regs (the rest were already restored) */ - l32i a0, sp, XT_STK_PS /* retrieve interruptee's PS */ - wsr a0, EPS_2 - l32i a0, sp, XT_STK_PC /* retrieve interruptee's PC */ - wsr a0, EPC_2 - l32i a0, sp, XT_STK_A0 /* retrieve interruptee's A0 */ - l32i sp, sp, XT_STK_A1 /* remove interrupt stack frame */ - rsync /* ensure EPS and EPC written */ - rfi 2 - -#endif /* Level 2 */ - -#if XCHAL_EXCM_LEVEL >= 3 - - .begin literal_prefix .Level3InterruptVector - .section .Level3InterruptVector.text, "ax" - .global _Level3Vector - .type _Level3Vector,@function - .align 4 -_Level3Vector: - wsr a0, EXCSAVE_3 /* preserve a0 */ - call0 _xt_medint3 /* load interrupt handler */ - /* never returns here - call0 is used as a jump (see note at top) */ - - .end literal_prefix - - .text - .type _xt_medint3,@function - .align 4 -_xt_medint3: - mov a0, sp /* sp == a1 */ - addi sp, sp, -XT_STK_FRMSZ /* allocate interrupt stack frame */ - s32i a0, sp, XT_STK_A1 /* save pre-interrupt SP */ - rsr a0, EPS_3 /* save interruptee's PS */ - s32i a0, sp, XT_STK_PS - rsr a0, EPC_3 /* save interruptee's PC */ - s32i a0, sp, XT_STK_PC - rsr a0, EXCSAVE_3 /* save interruptee's a0 */ - s32i a0, sp, XT_STK_A0 - movi a0, _xt_medint3_exit /* save exit point for dispatch */ - s32i a0, sp, XT_STK_EXIT - - /* Save rest of interrupt context and enter RTOS. */ - call0 XT_RTOS_INT_ENTER /* common RTOS interrupt entry */ - - /* !! We are now on the RTOS system stack !! */ - - /* Set up PS for C, enable interrupts above this level and clear EXCM. */ - #ifdef __XTENSA_CALL0_ABI__ - movi a0, PS_INTLEVEL(3) | PS_UM - #else - movi a0, PS_INTLEVEL(3) | PS_UM | PS_WOE - #endif - wsr a0, PS - rsync - - /* OK to call C code at this point, dispatch user ISRs */ - - dispatch_c_isr 3 XCHAL_INTLEVEL3_MASK - - /* Done handling interrupts, transfer control to OS */ - call0 XT_RTOS_INT_EXIT /* does not return directly here */ - - /* - Exit point for dispatch. Saved in interrupt stack frame at XT_STK_EXIT - on entry and used to return to a thread or interrupted interrupt handler. - */ - .global _xt_medint3_exit - .type _xt_medint3_exit,@function - .align 4 -_xt_medint3_exit: - /* Restore only level-specific regs (the rest were already restored) */ - l32i a0, sp, XT_STK_PS /* retrieve interruptee's PS */ - wsr a0, EPS_3 - l32i a0, sp, XT_STK_PC /* retrieve interruptee's PC */ - wsr a0, EPC_3 - l32i a0, sp, XT_STK_A0 /* retrieve interruptee's A0 */ - l32i sp, sp, XT_STK_A1 /* remove interrupt stack frame */ - rsync /* ensure EPS and EPC written */ - rfi 3 - -#endif /* Level 3 */ - -#if XCHAL_EXCM_LEVEL >= 4 - - .begin literal_prefix .Level4InterruptVector - .section .Level4InterruptVector.text, "ax" - .global _Level4Vector - .type _Level4Vector,@function - .align 4 -_Level4Vector: - wsr a0, EXCSAVE_4 /* preserve a0 */ - call0 _xt_medint4 /* load interrupt handler */ - - .end literal_prefix - - .text - .type _xt_medint4,@function - .align 4 -_xt_medint4: - mov a0, sp /* sp == a1 */ - addi sp, sp, -XT_STK_FRMSZ /* allocate interrupt stack frame */ - s32i a0, sp, XT_STK_A1 /* save pre-interrupt SP */ - rsr a0, EPS_4 /* save interruptee's PS */ - s32i a0, sp, XT_STK_PS - rsr a0, EPC_4 /* save interruptee's PC */ - s32i a0, sp, XT_STK_PC - rsr a0, EXCSAVE_4 /* save interruptee's a0 */ - s32i a0, sp, XT_STK_A0 - movi a0, _xt_medint4_exit /* save exit point for dispatch */ - s32i a0, sp, XT_STK_EXIT - - /* Save rest of interrupt context and enter RTOS. */ - call0 XT_RTOS_INT_ENTER /* common RTOS interrupt entry */ - - /* !! We are now on the RTOS system stack !! */ - - /* Set up PS for C, enable interrupts above this level and clear EXCM. */ - #ifdef __XTENSA_CALL0_ABI__ - movi a0, PS_INTLEVEL(4) | PS_UM - #else - movi a0, PS_INTLEVEL(4) | PS_UM | PS_WOE - #endif - wsr a0, PS - rsync - - /* OK to call C code at this point, dispatch user ISRs */ - - dispatch_c_isr 4 XCHAL_INTLEVEL4_MASK - - /* Done handling interrupts, transfer control to OS */ - call0 XT_RTOS_INT_EXIT /* does not return directly here */ - - /* - Exit point for dispatch. Saved in interrupt stack frame at XT_STK_EXIT - on entry and used to return to a thread or interrupted interrupt handler. - */ - .global _xt_medint4_exit - .type _xt_medint4_exit,@function - .align 4 -_xt_medint4_exit: - /* Restore only level-specific regs (the rest were already restored) */ - l32i a0, sp, XT_STK_PS /* retrieve interruptee's PS */ - wsr a0, EPS_4 - l32i a0, sp, XT_STK_PC /* retrieve interruptee's PC */ - wsr a0, EPC_4 - l32i a0, sp, XT_STK_A0 /* retrieve interruptee's A0 */ - l32i sp, sp, XT_STK_A1 /* remove interrupt stack frame */ - rsync /* ensure EPS and EPC written */ - rfi 4 - -#endif /* Level 4 */ - -#if XCHAL_EXCM_LEVEL >= 5 - - .begin literal_prefix .Level5InterruptVector - .section .Level5InterruptVector.text, "ax" - .global _Level5Vector - .type _Level5Vector,@function - .align 4 -_Level5Vector: - wsr a0, EXCSAVE_5 /* preserve a0 */ - call0 _xt_medint5 /* load interrupt handler */ - - .end literal_prefix - - .text - .type _xt_medint5,@function - .align 4 -_xt_medint5: - mov a0, sp /* sp == a1 */ - addi sp, sp, -XT_STK_FRMSZ /* allocate interrupt stack frame */ - s32i a0, sp, XT_STK_A1 /* save pre-interrupt SP */ - rsr a0, EPS_5 /* save interruptee's PS */ - s32i a0, sp, XT_STK_PS - rsr a0, EPC_5 /* save interruptee's PC */ - s32i a0, sp, XT_STK_PC - rsr a0, EXCSAVE_5 /* save interruptee's a0 */ - s32i a0, sp, XT_STK_A0 - movi a0, _xt_medint5_exit /* save exit point for dispatch */ - s32i a0, sp, XT_STK_EXIT - - /* Save rest of interrupt context and enter RTOS. */ - call0 XT_RTOS_INT_ENTER /* common RTOS interrupt entry */ - - /* !! We are now on the RTOS system stack !! */ - - /* Set up PS for C, enable interrupts above this level and clear EXCM. */ - #ifdef __XTENSA_CALL0_ABI__ - movi a0, PS_INTLEVEL(5) | PS_UM - #else - movi a0, PS_INTLEVEL(5) | PS_UM | PS_WOE - #endif - wsr a0, PS - rsync - - /* OK to call C code at this point, dispatch user ISRs */ - - dispatch_c_isr 5 XCHAL_INTLEVEL5_MASK - - /* Done handling interrupts, transfer control to OS */ - call0 XT_RTOS_INT_EXIT /* does not return directly here */ - - /* - Exit point for dispatch. Saved in interrupt stack frame at XT_STK_EXIT - on entry and used to return to a thread or interrupted interrupt handler. - */ - .global _xt_medint5_exit - .type _xt_medint5_exit,@function - .align 4 -_xt_medint5_exit: - /* Restore only level-specific regs (the rest were already restored) */ - l32i a0, sp, XT_STK_PS /* retrieve interruptee's PS */ - wsr a0, EPS_5 - l32i a0, sp, XT_STK_PC /* retrieve interruptee's PC */ - wsr a0, EPC_5 - l32i a0, sp, XT_STK_A0 /* retrieve interruptee's A0 */ - l32i sp, sp, XT_STK_A1 /* remove interrupt stack frame */ - rsync /* ensure EPS and EPC written */ - rfi 5 - -#endif /* Level 5 */ - -#if XCHAL_EXCM_LEVEL >= 6 - - .begin literal_prefix .Level6InterruptVector - .section .Level6InterruptVector.text, "ax" - .global _Level6Vector - .type _Level6Vector,@function - .align 4 -_Level6Vector: - wsr a0, EXCSAVE_6 /* preserve a0 */ - call0 _xt_medint6 /* load interrupt handler */ - - .end literal_prefix - - .text - .type _xt_medint6,@function - .align 4 -_xt_medint6: - mov a0, sp /* sp == a1 */ - addi sp, sp, -XT_STK_FRMSZ /* allocate interrupt stack frame */ - s32i a0, sp, XT_STK_A1 /* save pre-interrupt SP */ - rsr a0, EPS_6 /* save interruptee's PS */ - s32i a0, sp, XT_STK_PS - rsr a0, EPC_6 /* save interruptee's PC */ - s32i a0, sp, XT_STK_PC - rsr a0, EXCSAVE_6 /* save interruptee's a0 */ - s32i a0, sp, XT_STK_A0 - movi a0, _xt_medint6_exit /* save exit point for dispatch */ - s32i a0, sp, XT_STK_EXIT - - /* Save rest of interrupt context and enter RTOS. */ - call0 XT_RTOS_INT_ENTER /* common RTOS interrupt entry */ - - /* !! We are now on the RTOS system stack !! */ - - /* Set up PS for C, enable interrupts above this level and clear EXCM. */ - #ifdef __XTENSA_CALL0_ABI__ - movi a0, PS_INTLEVEL(6) | PS_UM - #else - movi a0, PS_INTLEVEL(6) | PS_UM | PS_WOE - #endif - wsr a0, PS - rsync - - /* OK to call C code at this point, dispatch user ISRs */ - - dispatch_c_isr 6 XCHAL_INTLEVEL6_MASK - - /* Done handling interrupts, transfer control to OS */ - call0 XT_RTOS_INT_EXIT /* does not return directly here */ - - /* - Exit point for dispatch. Saved in interrupt stack frame at XT_STK_EXIT - on entry and used to return to a thread or interrupted interrupt handler. - */ - .global _xt_medint6_exit - .type _xt_medint6_exit,@function - .align 4 -_xt_medint6_exit: - /* Restore only level-specific regs (the rest were already restored) */ - l32i a0, sp, XT_STK_PS /* retrieve interruptee's PS */ - wsr a0, EPS_6 - l32i a0, sp, XT_STK_PC /* retrieve interruptee's PC */ - wsr a0, EPC_6 - l32i a0, sp, XT_STK_A0 /* retrieve interruptee's A0 */ - l32i sp, sp, XT_STK_A1 /* remove interrupt stack frame */ - rsync /* ensure EPS and EPC written */ - rfi 6 - -#endif /* Level 6 */ - - -/******************************************************************************* - -HIGH PRIORITY (LEVEL > XCHAL_EXCM_LEVEL) INTERRUPT VECTORS AND HANDLERS - -High priority interrupts are by definition those with priorities greater -than XCHAL_EXCM_LEVEL. This includes non-maskable (NMI). High priority -interrupts cannot interact with the RTOS, that is they must save all regs -they use and not call any RTOS function. - -A further restriction imposed by the Xtensa windowed architecture is that -high priority interrupts must not modify the stack area even logically -"above" the top of the interrupted stack (they need to provide their -own stack or static save area). - -Cadence Design Systems recommends high priority interrupt handlers be coded in assembly -and used for purposes requiring very short service times. - -Here are templates for high priority (level 2+) interrupt vectors. -They assume only one interrupt per level to avoid the burden of identifying -which interrupts at this level are pending and enabled. This allows for -minimum latency and avoids having to save/restore a2 in addition to a0. -If more than one interrupt per high priority level is configured, this burden -is on the handler which in any case must provide a way to save and restore -registers it uses without touching the interrupted stack. - -Each vector goes at a predetermined location according to the Xtensa -hardware configuration, which is ensured by its placement in a special -section known to the Xtensa linker support package (LSP). It performs -the minimum necessary before jumping to the handler in the .text section. - -*******************************************************************************/ - -/* -Currently only shells for high priority interrupt handlers are provided -here. However a template and example can be found in the Cadence Design Systems tools -documentation: "Microprocessor Programmer's Guide". -*/ - -#if XCHAL_NUM_INTLEVELS >=2 && XCHAL_EXCM_LEVEL <2 && XCHAL_DEBUGLEVEL !=2 - - .begin literal_prefix .Level2InterruptVector - .section .Level2InterruptVector.text, "ax" - .global _Level2Vector - .type _Level2Vector,@function - .align 4 -_Level2Vector: - wsr a0, EXCSAVE_2 /* preserve a0 */ - call0 _xt_highint2 /* load interrupt handler */ - - .end literal_prefix - - .text - .type _xt_highint2,@function - .align 4 -_xt_highint2: - - #ifdef XT_INTEXC_HOOKS - /* Call interrupt hook if present to (pre)handle interrupts. */ - movi a0, _xt_intexc_hooks - l32i a0, a0, 2<<2 - beqz a0, 1f -.Ln_xt_highint2_call_hook: - callx0 a0 /* must NOT disturb stack! */ -1: - #endif - - /* USER_EDIT: - ADD HIGH PRIORITY LEVEL 2 INTERRUPT HANDLER CODE HERE. - */ - - .align 4 -.L_xt_highint2_exit: - rsr a0, EXCSAVE_2 /* restore a0 */ - rfi 2 - -#endif /* Level 2 */ - -#if XCHAL_NUM_INTLEVELS >=3 && XCHAL_EXCM_LEVEL <3 && XCHAL_DEBUGLEVEL !=3 - - .begin literal_prefix .Level3InterruptVector - .section .Level3InterruptVector.text, "ax" - .global _Level3Vector - .type _Level3Vector,@function - .align 4 -_Level3Vector: - wsr a0, EXCSAVE_3 /* preserve a0 */ - call0 _xt_highint3 /* load interrupt handler */ - /* never returns here - call0 is used as a jump (see note at top) */ - - .end literal_prefix - - .text - .type _xt_highint3,@function - .align 4 -_xt_highint3: - - #ifdef XT_INTEXC_HOOKS - /* Call interrupt hook if present to (pre)handle interrupts. */ - movi a0, _xt_intexc_hooks - l32i a0, a0, 3<<2 - beqz a0, 1f -.Ln_xt_highint3_call_hook: - callx0 a0 /* must NOT disturb stack! */ -1: - #endif - - /* USER_EDIT: - ADD HIGH PRIORITY LEVEL 3 INTERRUPT HANDLER CODE HERE. - */ - - .align 4 -.L_xt_highint3_exit: - rsr a0, EXCSAVE_3 /* restore a0 */ - rfi 3 - -#endif /* Level 3 */ - -#if XCHAL_NUM_INTLEVELS >=4 && XCHAL_EXCM_LEVEL <4 && XCHAL_DEBUGLEVEL !=4 - - .begin literal_prefix .Level4InterruptVector - .section .Level4InterruptVector.text, "ax" - .global _Level4Vector - .type _Level4Vector,@function - .align 4 -_Level4Vector: - wsr a0, EXCSAVE_4 /* preserve a0 */ - call0 _xt_highint4 /* load interrupt handler */ - /* never returns here - call0 is used as a jump (see note at top) */ - - .end literal_prefix - - .text - .type _xt_highint4,@function - .align 4 -_xt_highint4: - - #ifdef XT_INTEXC_HOOKS - /* Call interrupt hook if present to (pre)handle interrupts. */ - movi a0, _xt_intexc_hooks - l32i a0, a0, 4<<2 - beqz a0, 1f -.Ln_xt_highint4_call_hook: - callx0 a0 /* must NOT disturb stack! */ -1: - #endif - - /* USER_EDIT: - ADD HIGH PRIORITY LEVEL 4 INTERRUPT HANDLER CODE HERE. - */ - - .align 4 -.L_xt_highint4_exit: - rsr a0, EXCSAVE_4 /* restore a0 */ - rfi 4 - -#endif /* Level 4 */ - -#if XCHAL_NUM_INTLEVELS >=5 && XCHAL_EXCM_LEVEL <5 && XCHAL_DEBUGLEVEL !=5 - - .begin literal_prefix .Level5InterruptVector - .section .Level5InterruptVector.text, "ax" - .global _Level5Vector - .type _Level5Vector,@function - .align 4 -_Level5Vector: - wsr a0, EXCSAVE_5 /* preserve a0 */ - call0 _xt_highint5 /* load interrupt handler */ - /* never returns here - call0 is used as a jump (see note at top) */ - - .end literal_prefix - - .text - .type _xt_highint5,@function - .align 4 -_xt_highint5: - - #ifdef XT_INTEXC_HOOKS - /* Call interrupt hook if present to (pre)handle interrupts. */ - movi a0, _xt_intexc_hooks - l32i a0, a0, 5<<2 - beqz a0, 1f -.Ln_xt_highint5_call_hook: - callx0 a0 /* must NOT disturb stack! */ -1: - #endif - - /* USER_EDIT: - ADD HIGH PRIORITY LEVEL 5 INTERRUPT HANDLER CODE HERE. - */ - - .align 4 -.L_xt_highint5_exit: - rsr a0, EXCSAVE_5 /* restore a0 */ - rfi 5 - -#endif /* Level 5 */ - -#if XCHAL_NUM_INTLEVELS >=6 && XCHAL_EXCM_LEVEL <6 && XCHAL_DEBUGLEVEL !=6 - - .begin literal_prefix .Level6InterruptVector - .section .Level6InterruptVector.text, "ax" - .global _Level6Vector - .type _Level6Vector,@function - .align 4 -_Level6Vector: - wsr a0, EXCSAVE_6 /* preserve a0 */ - call0 _xt_highint6 /* load interrupt handler */ - /* never returns here - call0 is used as a jump (see note at top) */ - - .end literal_prefix - - .text - .type _xt_highint6,@function - .align 4 -_xt_highint6: - - #ifdef XT_INTEXC_HOOKS - /* Call interrupt hook if present to (pre)handle interrupts. */ - movi a0, _xt_intexc_hooks - l32i a0, a0, 6<<2 - beqz a0, 1f -.Ln_xt_highint6_call_hook: - callx0 a0 /* must NOT disturb stack! */ -1: - #endif - - /* USER_EDIT: - ADD HIGH PRIORITY LEVEL 6 INTERRUPT HANDLER CODE HERE. - */ - - .align 4 -.L_xt_highint6_exit: - rsr a0, EXCSAVE_6 /* restore a0 */ - rfi 6 - -#endif /* Level 6 */ - -#if XCHAL_HAVE_NMI - - .begin literal_prefix .NMIExceptionVector - .section .NMIExceptionVector.text, "ax" - .global _NMIExceptionVector - .type _NMIExceptionVector,@function - .align 4 -_NMIExceptionVector: - wsr a0, EXCSAVE + XCHAL_NMILEVEL _ /* preserve a0 */ - call0 _xt_nmi /* load interrupt handler */ - /* never returns here - call0 is used as a jump (see note at top) */ - - .end literal_prefix - - .text - .type _xt_nmi,@function - .align 4 -_xt_nmi: - - #ifdef XT_INTEXC_HOOKS - /* Call interrupt hook if present to (pre)handle interrupts. */ - movi a0, _xt_intexc_hooks - l32i a0, a0, XCHAL_NMILEVEL<<2 - beqz a0, 1f -.Ln_xt_nmi_call_hook: - callx0 a0 /* must NOT disturb stack! */ -1: - #endif - - /* USER_EDIT: - ADD HIGH PRIORITY NON-MASKABLE INTERRUPT (NMI) HANDLER CODE HERE. - */ - - .align 4 -.L_xt_nmi_exit: - rsr a0, EXCSAVE + XCHAL_NMILEVEL /* restore a0 */ - rfi XCHAL_NMILEVEL - -#endif /* NMI */ - - -/******************************************************************************* - -WINDOW OVERFLOW AND UNDERFLOW EXCEPTION VECTORS AND ALLOCA EXCEPTION HANDLER - -Here is the code for each window overflow/underflow exception vector and -(interspersed) efficient code for handling the alloca exception cause. -Window exceptions are handled entirely in the vector area and are very -tight for performance. The alloca exception is also handled entirely in -the window vector area so comes at essentially no cost in code size. -Users should never need to modify them and Cadence Design Systems recommends -they do not. - -Window handlers go at predetermined vector locations according to the -Xtensa hardware configuration, which is ensured by their placement in a -special section known to the Xtensa linker support package (LSP). Since -their offsets in that section are always the same, the LSPs do not define -a section per vector. - -These things are coded for XEA2 only (XEA1 is not supported). - -Note on Underflow Handlers: -The underflow handler for returning from call[i+1] to call[i] -must preserve all the registers from call[i+1]'s window. -In particular, a0 and a1 must be preserved because the RETW instruction -will be reexecuted (and may even underflow if an intervening exception -has flushed call[i]'s registers). -Registers a2 and up may contain return values. - -*******************************************************************************/ - -#if XCHAL_HAVE_WINDOWED - - .section .WindowVectors.text, "ax" - -/* --------------------------------------------------------------------------------- -Window Overflow Exception for Call4. - -Invoked if a call[i] referenced a register (a4-a15) -that contains data from ancestor call[j]; -call[j] had done a call4 to call[j+1]. -On entry here: - window rotated to call[j] start point; - a0-a3 are registers to be saved; - a4-a15 must be preserved; - a5 is call[j+1]'s stack pointer. --------------------------------------------------------------------------------- -*/ - - .org 0x0 - .global _WindowOverflow4 -_WindowOverflow4: - - s32e a0, a5, -16 /* save a0 to call[j+1]'s stack frame */ - s32e a1, a5, -12 /* save a1 to call[j+1]'s stack frame */ - s32e a2, a5, -8 /* save a2 to call[j+1]'s stack frame */ - s32e a3, a5, -4 /* save a3 to call[j+1]'s stack frame */ - rfwo /* rotates back to call[i] position */ - -/* --------------------------------------------------------------------------------- -Window Underflow Exception for Call4 - -Invoked by RETW returning from call[i+1] to call[i] -where call[i]'s registers must be reloaded (not live in ARs); -where call[i] had done a call4 to call[i+1]. -On entry here: - window rotated to call[i] start point; - a0-a3 are undefined, must be reloaded with call[i].reg[0..3]; - a4-a15 must be preserved (they are call[i+1].reg[0..11]); - a5 is call[i+1]'s stack pointer. --------------------------------------------------------------------------------- -*/ - - .org 0x40 - .global _WindowUnderflow4 -_WindowUnderflow4: - - l32e a0, a5, -16 /* restore a0 from call[i+1]'s stack frame */ - l32e a1, a5, -12 /* restore a1 from call[i+1]'s stack frame */ - l32e a2, a5, -8 /* restore a2 from call[i+1]'s stack frame */ - l32e a3, a5, -4 /* restore a3 from call[i+1]'s stack frame */ - rfwu - -/* --------------------------------------------------------------------------------- -Handle alloca exception generated by interruptee executing 'movsp'. -This uses space between the window vectors, so is essentially "free". -All interruptee's regs are intact except a0 which is saved in EXCSAVE_1, -and PS.EXCM has been set by the exception hardware (can't be interrupted). -The fact the alloca exception was taken means the registers associated with -the base-save area have been spilled and will be restored by the underflow -handler, so those 4 registers are available for scratch. -The code is optimized to avoid unaligned branches and minimize cache misses. --------------------------------------------------------------------------------- -*/ - - .align 4 - .global _xt_alloca_exc -_xt_alloca_exc: - - rsr a0, WINDOWBASE /* grab WINDOWBASE before rotw changes it */ - rotw -1 /* WINDOWBASE goes to a4, new a0-a3 are scratch */ - rsr a2, PS - extui a3, a2, XCHAL_PS_OWB_SHIFT, XCHAL_PS_OWB_BITS - xor a3, a3, a4 /* bits changed from old to current windowbase */ - rsr a4, EXCSAVE_1 /* restore original a0 (now in a4) */ - slli a3, a3, XCHAL_PS_OWB_SHIFT - xor a2, a2, a3 /* flip changed bits in old window base */ - wsr a2, PS /* update PS.OWB to new window base */ - rsync - - _bbci.l a4, 31, _WindowUnderflow4 - rotw -1 /* original a0 goes to a8 */ - _bbci.l a8, 30, _WindowUnderflow8 - rotw -1 - j _WindowUnderflow12 - -/* --------------------------------------------------------------------------------- -Window Overflow Exception for Call8 - -Invoked if a call[i] referenced a register (a4-a15) -that contains data from ancestor call[j]; -call[j] had done a call8 to call[j+1]. -On entry here: - window rotated to call[j] start point; - a0-a7 are registers to be saved; - a8-a15 must be preserved; - a9 is call[j+1]'s stack pointer. --------------------------------------------------------------------------------- -*/ - - .org 0x80 - .global _WindowOverflow8 -_WindowOverflow8: - - s32e a0, a9, -16 /* save a0 to call[j+1]'s stack frame */ - l32e a0, a1, -12 /* a0 <- call[j-1]'s sp - (used to find end of call[j]'s frame) */ - s32e a1, a9, -12 /* save a1 to call[j+1]'s stack frame */ - s32e a2, a9, -8 /* save a2 to call[j+1]'s stack frame */ - s32e a3, a9, -4 /* save a3 to call[j+1]'s stack frame */ - s32e a4, a0, -32 /* save a4 to call[j]'s stack frame */ - s32e a5, a0, -28 /* save a5 to call[j]'s stack frame */ - s32e a6, a0, -24 /* save a6 to call[j]'s stack frame */ - s32e a7, a0, -20 /* save a7 to call[j]'s stack frame */ - rfwo /* rotates back to call[i] position */ - -/* --------------------------------------------------------------------------------- -Window Underflow Exception for Call8 - -Invoked by RETW returning from call[i+1] to call[i] -where call[i]'s registers must be reloaded (not live in ARs); -where call[i] had done a call8 to call[i+1]. -On entry here: - window rotated to call[i] start point; - a0-a7 are undefined, must be reloaded with call[i].reg[0..7]; - a8-a15 must be preserved (they are call[i+1].reg[0..7]); - a9 is call[i+1]'s stack pointer. --------------------------------------------------------------------------------- -*/ - - .org 0xC0 - .global _WindowUnderflow8 -_WindowUnderflow8: - - l32e a0, a9, -16 /* restore a0 from call[i+1]'s stack frame */ - l32e a1, a9, -12 /* restore a1 from call[i+1]'s stack frame */ - l32e a2, a9, -8 /* restore a2 from call[i+1]'s stack frame */ - l32e a7, a1, -12 /* a7 <- call[i-1]'s sp - (used to find end of call[i]'s frame) */ - l32e a3, a9, -4 /* restore a3 from call[i+1]'s stack frame */ - l32e a4, a7, -32 /* restore a4 from call[i]'s stack frame */ - l32e a5, a7, -28 /* restore a5 from call[i]'s stack frame */ - l32e a6, a7, -24 /* restore a6 from call[i]'s stack frame */ - l32e a7, a7, -20 /* restore a7 from call[i]'s stack frame */ - rfwu - -/* --------------------------------------------------------------------------------- -Window Overflow Exception for Call12 - -Invoked if a call[i] referenced a register (a4-a15) -that contains data from ancestor call[j]; -call[j] had done a call12 to call[j+1]. -On entry here: - window rotated to call[j] start point; - a0-a11 are registers to be saved; - a12-a15 must be preserved; - a13 is call[j+1]'s stack pointer. --------------------------------------------------------------------------------- -*/ - - .org 0x100 - .global _WindowOverflow12 -_WindowOverflow12: - - s32e a0, a13, -16 /* save a0 to call[j+1]'s stack frame */ - l32e a0, a1, -12 /* a0 <- call[j-1]'s sp - (used to find end of call[j]'s frame) */ - s32e a1, a13, -12 /* save a1 to call[j+1]'s stack frame */ - s32e a2, a13, -8 /* save a2 to call[j+1]'s stack frame */ - s32e a3, a13, -4 /* save a3 to call[j+1]'s stack frame */ - s32e a4, a0, -48 /* save a4 to end of call[j]'s stack frame */ - s32e a5, a0, -44 /* save a5 to end of call[j]'s stack frame */ - s32e a6, a0, -40 /* save a6 to end of call[j]'s stack frame */ - s32e a7, a0, -36 /* save a7 to end of call[j]'s stack frame */ - s32e a8, a0, -32 /* save a8 to end of call[j]'s stack frame */ - s32e a9, a0, -28 /* save a9 to end of call[j]'s stack frame */ - s32e a10, a0, -24 /* save a10 to end of call[j]'s stack frame */ - s32e a11, a0, -20 /* save a11 to end of call[j]'s stack frame */ - rfwo /* rotates back to call[i] position */ - -/* --------------------------------------------------------------------------------- -Window Underflow Exception for Call12 - -Invoked by RETW returning from call[i+1] to call[i] -where call[i]'s registers must be reloaded (not live in ARs); -where call[i] had done a call12 to call[i+1]. -On entry here: - window rotated to call[i] start point; - a0-a11 are undefined, must be reloaded with call[i].reg[0..11]; - a12-a15 must be preserved (they are call[i+1].reg[0..3]); - a13 is call[i+1]'s stack pointer. --------------------------------------------------------------------------------- -*/ - - .org 0x140 - .global _WindowUnderflow12 -_WindowUnderflow12: - - l32e a0, a13, -16 /* restore a0 from call[i+1]'s stack frame */ - l32e a1, a13, -12 /* restore a1 from call[i+1]'s stack frame */ - l32e a2, a13, -8 /* restore a2 from call[i+1]'s stack frame */ - l32e a11, a1, -12 /* a11 <- call[i-1]'s sp - (used to find end of call[i]'s frame) */ - l32e a3, a13, -4 /* restore a3 from call[i+1]'s stack frame */ - l32e a4, a11, -48 /* restore a4 from end of call[i]'s stack frame */ - l32e a5, a11, -44 /* restore a5 from end of call[i]'s stack frame */ - l32e a6, a11, -40 /* restore a6 from end of call[i]'s stack frame */ - l32e a7, a11, -36 /* restore a7 from end of call[i]'s stack frame */ - l32e a8, a11, -32 /* restore a8 from end of call[i]'s stack frame */ - l32e a9, a11, -28 /* restore a9 from end of call[i]'s stack frame */ - l32e a10, a11, -24 /* restore a10 from end of call[i]'s stack frame */ - l32e a11, a11, -20 /* restore a11 from end of call[i]'s stack frame */ - rfwu - -#endif /* XCHAL_HAVE_WINDOWED */ - - .section .UserEnter.text, "ax" - .global call_user_start - .type call_user_start,@function - .align 4 - .literal_position - - -call_user_start: - - movi a2, 0x40040000 /* note: absolute symbol, not a ptr */ - wsr a2, vecbase - call0 user_start /* user exception handler */ From 74a658c76596eed678f7595867606d2a23ca38ad Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Wed, 26 Oct 2016 12:25:53 +0800 Subject: [PATCH 137/343] nvs: fix memory leaks in HashList and nvs_close Fixes TW8162. Associated test case is run under Instruments on macOS, until I set up valgrind to test this automatically on Linux. --- components/nvs_flash/src/nvs_api.cpp | 1 + .../nvs_flash/src/nvs_item_hash_list.cpp | 11 ++++++++++- .../nvs_flash/src/nvs_item_hash_list.hpp | 10 ++++++++-- components/nvs_flash/src/nvs_page.cpp | 2 +- components/nvs_flash/test/test_nvs.cpp | 18 ++++++++++++++++++ 5 files changed, 38 insertions(+), 4 deletions(-) diff --git a/components/nvs_flash/src/nvs_api.cpp b/components/nvs_flash/src/nvs_api.cpp index 0a56925c0c..c1a910260e 100644 --- a/components/nvs_flash/src/nvs_api.cpp +++ b/components/nvs_flash/src/nvs_api.cpp @@ -116,6 +116,7 @@ extern "C" void nvs_close(nvs_handle handle) return; } s_nvs_handles.erase(it); + delete static_cast(it); } extern "C" esp_err_t nvs_erase_key(nvs_handle handle, const char* key) diff --git a/components/nvs_flash/src/nvs_item_hash_list.cpp b/components/nvs_flash/src/nvs_item_hash_list.cpp index 7fa019dffe..cf48477d61 100644 --- a/components/nvs_flash/src/nvs_item_hash_list.cpp +++ b/components/nvs_flash/src/nvs_item_hash_list.cpp @@ -17,7 +17,11 @@ namespace nvs { -HashList::~HashList() +HashList::HashList() +{ +} + +void HashList::clear() { for (auto it = mBlockList.begin(); it != mBlockList.end();) { auto tmp = it; @@ -26,6 +30,11 @@ HashList::~HashList() delete static_cast(tmp); } } + +HashList::~HashList() +{ + clear(); +} HashList::HashListBlock::HashListBlock() { diff --git a/components/nvs_flash/src/nvs_item_hash_list.hpp b/components/nvs_flash/src/nvs_item_hash_list.hpp index b40a53d615..3f8dcc850a 100644 --- a/components/nvs_flash/src/nvs_item_hash_list.hpp +++ b/components/nvs_flash/src/nvs_item_hash_list.hpp @@ -25,11 +25,18 @@ namespace nvs class HashList { public: + HashList(); ~HashList(); + void insert(const Item& item, size_t index); void erase(const size_t index); size_t find(size_t start, const Item& item); - + void clear(); + +private: + HashList(const HashList& other); + const HashList& operator= (const HashList& rhs); + protected: struct HashListNode { @@ -57,7 +64,6 @@ protected: HashListNode mNodes[ENTRY_COUNT]; }; - typedef intrusive_list TBlockList; TBlockList mBlockList; }; // class HashList diff --git a/components/nvs_flash/src/nvs_page.cpp b/components/nvs_flash/src/nvs_page.cpp index f4fc5430cd..64f7bd9852 100644 --- a/components/nvs_flash/src/nvs_page.cpp +++ b/components/nvs_flash/src/nvs_page.cpp @@ -741,7 +741,7 @@ esp_err_t Page::erase() mFirstUsedEntry = INVALID_ENTRY; mNextFreeEntry = INVALID_ENTRY; mState = PageState::UNINITIALIZED; - mHashList = HashList(); + mHashList.clear(); return ESP_OK; } diff --git a/components/nvs_flash/test/test_nvs.cpp b/components/nvs_flash/test/test_nvs.cpp index 3db9b45aeb..ce552578db 100644 --- a/components/nvs_flash/test/test_nvs.cpp +++ b/components/nvs_flash/test/test_nvs.cpp @@ -933,6 +933,24 @@ TEST_CASE("test recovery from sudden poweroff", "[.][long][nvs][recovery][monkey } } +TEST_CASE("test for memory leaks in open/set", "[leaks]") +{ + SpiFlashEmulator emu(10); + const uint32_t NVS_FLASH_SECTOR = 6; + const uint32_t NVS_FLASH_SECTOR_COUNT_MIN = 3; + emu.setBounds(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR + NVS_FLASH_SECTOR_COUNT_MIN); + TEST_ESP_OK(nvs_flash_init_custom(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN)); + + for (int i = 0; i < 100000; ++i) { + nvs_handle light_handle = 0; + char lightbulb[1024] = {12, 13, 14, 15, 16}; + TEST_ESP_OK(nvs_open("light", NVS_READWRITE, &light_handle)); + TEST_ESP_OK(nvs_set_blob(light_handle, "key", lightbulb, sizeof(lightbulb))); + TEST_ESP_OK(nvs_commit(light_handle)); + nvs_close(light_handle); + } +} + TEST_CASE("dump all performance data", "[nvs]") { std::cout << "====================" << std::endl << "Dumping benchmarks" << std::endl; From 612aaa69e4927baa9ce413237006bb5123361954 Mon Sep 17 00:00:00 2001 From: liuzhifu Date: Wed, 26 Oct 2016 13:23:35 +0800 Subject: [PATCH 138/343] lwip/esp32: move the extern wifi calls into esp_wifi_internal.h 1. Add esp_wifi_internal.h 2. Rename system_pp_recycle_rx_pkt to esp_wifi_internal_free_rx_buffer 3. rename esp_wifi_tx_is_stop to esp_wifi_internal_tx_is_stop 4. rename ieee80211_output to esp_wifi_internal_tx --- components/esp32/include/esp_wifi_internal.h | 80 +++++++++++++++++++ components/lwip/api/sockets.c | 8 +- components/lwip/core/pbuf.c | 4 +- .../lwip/include/lwip/port/netif/wlanif.h | 4 +- components/lwip/port/netif/wlanif.c | 4 +- 5 files changed, 89 insertions(+), 11 deletions(-) create mode 100644 components/esp32/include/esp_wifi_internal.h diff --git a/components/esp32/include/esp_wifi_internal.h b/components/esp32/include/esp_wifi_internal.h new file mode 100644 index 0000000000..5100010e52 --- /dev/null +++ b/components/esp32/include/esp_wifi_internal.h @@ -0,0 +1,80 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/* + * All the APIs declared here are internal only APIs, it can only be used by + * espressif internal modules, such as SSC, LWIP, TCPIP adapter etc, espressif + * customers are not recommended to use them. + * + * If someone really want to use specified APIs declared in here, please contact + * espressif AE/developer to make sure you know the limitations or risk of + * the API, otherwise you may get unexpected behavior!!! + * + */ + + +#ifndef __ESP_WIFI_INTERNAL_H__ +#define __ESP_WIFI_INTERNAL_H__ + +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/queue.h" +#include "rom/queue.h" +#include "esp_err.h" +#include "esp_wifi_types.h" +#include "esp_event.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief get whether the wifi driver is allowed to transmit data or not + * + * @param none + * + * @return true : upper layer should stop to transmit data to wifi driver + * @return false : upper layer can transmit data to wifi driver + */ +bool esp_wifi_internal_tx_is_stop(void); + +/** + * @brief free the rx buffer which allocated by wifi driver + * + * @param void* buffer: rx buffer pointer + * + * @return nonoe + */ +void esp_wifi_internal_free_rx_buffer(void* buffer); + +/** + * @brief free the rx buffer which allocated by wifi driver + * + * @attention1 TODO should modify the return type from bool to int + * + * @param wifi_interface_t wifi_if : wifi interface id + * @param void *buffer : the buffer to be tansmit + * @param u16_t len : the length of buffer + * + * @return True : success transmit the buffer to wifi driver + * False : failed to transmit the buffer to wifi driver + */ +bool esp_wifi_internal_tx(wifi_interface_t wifi_if, void *buffer, u16_t len); + +#ifdef __cplusplus +} +#endif + +#endif /* __ESP_WIFI_H__ */ diff --git a/components/lwip/api/sockets.c b/components/lwip/api/sockets.c index 350847b57c..47f25bb076 100755 --- a/components/lwip/api/sockets.c +++ b/components/lwip/api/sockets.c @@ -388,10 +388,8 @@ static void lwip_socket_drop_registered_memberships(int s); #endif /* LWIP_IGMP */ #ifdef LWIP_ESP8266 - -/* Since esp_wifi_tx_is_stop/system_get_free_heap_size are not an public wifi API, so extern them here*/ -extern size_t system_get_free_heap_size(void); -extern bool esp_wifi_tx_is_stop(void); +#include "esp_wifi_internal.h" +#include "esp_system.h" /* Please be notified that this flow control is just a workaround for fixing wifi Q full issue. * Under UDP/TCP pressure test, we found that the sockets may cause wifi tx queue full if the socket @@ -404,7 +402,7 @@ static inline void esp32_tx_flow_ctrl(void) { uint8_t _wait_delay = 0; - while ((system_get_free_heap_size() < HEAP_HIGHWAT) || esp_wifi_tx_is_stop()){ + while ((system_get_free_heap_size() < HEAP_HIGHWAT) || esp_wifi_internal_tx_is_stop()){ vTaskDelay(_wait_delay/portTICK_RATE_MS); if (_wait_delay < 64) _wait_delay *= 2; } diff --git a/components/lwip/core/pbuf.c b/components/lwip/core/pbuf.c index e35f8a6b7f..044d765cdb 100755 --- a/components/lwip/core/pbuf.c +++ b/components/lwip/core/pbuf.c @@ -83,6 +83,7 @@ static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; #endif #ifdef LWIP_ESP8266 +#include "esp_wifi_internal.h" #define EP_OFFSET 0 #endif @@ -764,8 +765,7 @@ pbuf_free(struct pbuf *p) } else if (type == PBUF_ROM || type == PBUF_REF) { #ifdef LWIP_ESP8266 - extern void system_pp_recycle_rx_pkt(void*); - if (type == PBUF_REF && p->eb != NULL ) system_pp_recycle_rx_pkt(p->eb); + if (type == PBUF_REF && p->eb != NULL ) esp_wifi_internal_free_rx_buffer(p->eb); #endif memp_free(MEMP_PBUF, p); diff --git a/components/lwip/include/lwip/port/netif/wlanif.h b/components/lwip/include/lwip/port/netif/wlanif.h index 7eb303eab4..c6f7831b3d 100755 --- a/components/lwip/include/lwip/port/netif/wlanif.h +++ b/components/lwip/include/lwip/port/netif/wlanif.h @@ -8,6 +8,8 @@ #include "esp_wifi.h" +#include "esp_wifi_internal.h" + #include "lwip/err.h" #ifdef __cplusplus @@ -18,8 +20,6 @@ err_t wlanif_init(struct netif *netif); void wlanif_input(struct netif *netif, void *buffer, u16_t len, void* eb); -bool ieee80211_output(wifi_interface_t wifi_if, void *buffer, u16_t len); - wifi_interface_t wifi_get_interface(void *dev); void netif_reg_addr_change_cb(void* cb); diff --git a/components/lwip/port/netif/wlanif.c b/components/lwip/port/netif/wlanif.c index 9832c41aff..0b4fe70bad 100755 --- a/components/lwip/port/netif/wlanif.c +++ b/components/lwip/port/netif/wlanif.c @@ -150,12 +150,12 @@ low_level_output(struct netif *netif, struct pbuf *p) } } - ieee80211_output(wifi_if, q->payload, pbuf_x_len); + esp_wifi_internal_tx(wifi_if, q->payload, pbuf_x_len); return ERR_OK; #else for(q = p; q != NULL; q = q->next) { - ieee80211_output(wifi_if, q->payload, q->len); + esp_wifi_internal_tx(wifi_if, q->payload, q->len); } #endif From 48301909eba52562f60ad5a1aa8657a9d42709ba Mon Sep 17 00:00:00 2001 From: liuzhifu Date: Wed, 26 Oct 2016 13:53:00 +0800 Subject: [PATCH 139/343] components/esp32: update wifi lib 6ce01d76: rename some wifi internal APIs aa4d2aa9: last rx buffer is reserved for mgmt frame bb0ff4a8: tw7775 fix assert when rx auth frame before create bss --- components/esp32/lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp32/lib b/components/esp32/lib index a1e5f8b953..d3920845c9 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit a1e5f8b953c7934677ba7a6ed0a6dd2da0e6bd0f +Subproject commit d3920845c9501f6ebae178186c3f63a80fab1ed1 From a90217e201a2340ddfb3b5adc2c29c777b8bfd82 Mon Sep 17 00:00:00 2001 From: liuzhifu Date: Wed, 26 Oct 2016 14:09:54 +0800 Subject: [PATCH 140/343] components esp32/lwip: modify code according to review comments 1. Modify comments for esp_wifi_internal_tx 2. Fix delay time error in esp32_tx_flow_ctrl which is found in code review, modify _wait_delay init value from 0 to 1 --- components/esp32/include/esp_wifi_internal.h | 2 +- components/lwip/api/sockets.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/esp32/include/esp_wifi_internal.h b/components/esp32/include/esp_wifi_internal.h index 5100010e52..217d5f6d1f 100644 --- a/components/esp32/include/esp_wifi_internal.h +++ b/components/esp32/include/esp_wifi_internal.h @@ -60,7 +60,7 @@ bool esp_wifi_internal_tx_is_stop(void); void esp_wifi_internal_free_rx_buffer(void* buffer); /** - * @brief free the rx buffer which allocated by wifi driver + * @brief transmit the buffer via wifi driver * * @attention1 TODO should modify the return type from bool to int * diff --git a/components/lwip/api/sockets.c b/components/lwip/api/sockets.c index 47f25bb076..487bec8e8e 100755 --- a/components/lwip/api/sockets.c +++ b/components/lwip/api/sockets.c @@ -400,7 +400,7 @@ static void lwip_socket_drop_registered_memberships(int s); */ static inline void esp32_tx_flow_ctrl(void) { - uint8_t _wait_delay = 0; + uint8_t _wait_delay = 1; while ((system_get_free_heap_size() < HEAP_HIGHWAT) || esp_wifi_internal_tx_is_stop()){ vTaskDelay(_wait_delay/portTICK_RATE_MS); From 9546ad5b5ebaef3230c73b6fc248f1dbad1138d0 Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Wed, 26 Oct 2016 14:54:50 +0800 Subject: [PATCH 141/343] Move write key and stage action select constants into headers --- components/esp32/include/soc/rtc_cntl_reg.h | 3 ++- components/esp32/include/soc/timer_group_reg.h | 10 +++++++++- components/esp32/int_wdt.c | 16 ++++++++-------- components/esp32/panic.c | 10 +++++----- components/esp32/task_wdt.c | 16 ++++++++-------- 5 files changed, 32 insertions(+), 23 deletions(-) diff --git a/components/esp32/include/soc/rtc_cntl_reg.h b/components/esp32/include/soc/rtc_cntl_reg.h index 24e0f1403c..bb4e2afced 100644 --- a/components/esp32/include/soc/rtc_cntl_reg.h +++ b/components/esp32/include/soc/rtc_cntl_reg.h @@ -14,7 +14,8 @@ #ifndef _SOC_RTC_CNTL_REG_H_ #define _SOC_RTC_CNTL_REG_H_ -#define WDT_WRITE_KEY 0x50D83AA1 +/* The value that needs to be written to RTC_CNTL_WDT_WKEY to write-enable the wdt registers */ +#define RTC_CNTL_WDT_WKEY_VALUE 0x50D83AA1 #include "soc.h" diff --git a/components/esp32/include/soc/timer_group_reg.h b/components/esp32/include/soc/timer_group_reg.h index 0d67cab517..2db2a7e3f1 100644 --- a/components/esp32/include/soc/timer_group_reg.h +++ b/components/esp32/include/soc/timer_group_reg.h @@ -15,7 +15,15 @@ #define __TIMG_REG_H__ #include "soc.h" -#define WDT_WRITE_KEY 0x50D83AA1 +/* The value that needs to be written to TIMG_WDT_WKEY to write-enable the wdt registers */ +#define TIMG_WDT_WKEY_VALUE 0x50D83AA1 + +/* Possible values for TIMG_WDT_STGx */ +#define TIMG_WDT_STG_SEL_OFF 0 +#define TIMG_WDT_STG_SEL_INT 1 +#define TIMG_WDT_STG_SEL_RESET_CPU 2 +#define TIMG_WDT_STG_SEL_RESET_SYSTEM 3 + #define REG_TIMG_BASE(i) (DR_REG_TIMERGROUP0_BASE + i*0x1000) #define TIMG_T0CONFIG_REG(i) (REG_TIMG_BASE(i) + 0x0000) diff --git a/components/esp32/int_wdt.c b/components/esp32/int_wdt.c index 5f123ee368..93a4d9fe62 100644 --- a/components/esp32/int_wdt.c +++ b/components/esp32/int_wdt.c @@ -36,13 +36,13 @@ void esp_int_wdt_init() { - TIMERG1.wdt_wprotect=WDT_WRITE_KEY; - TIMERG1.wdt_config0.sys_reset_length=7; //3.2uS - TIMERG1.wdt_config0.cpu_reset_length=7; //3.2uS + TIMERG1.wdt_wprotect=TIMG_WDT_WKEY_VALUE; + TIMERG1.wdt_config0.sys_reset_length=7; //3.2uS + TIMERG1.wdt_config0.cpu_reset_length=7; //3.2uS TIMERG1.wdt_config0.level_int_en=1; - TIMERG1.wdt_config0.stg0=1; //1st stage timeout: interrupt - TIMERG1.wdt_config0.stg1=3; //2nd stage timeout: reset system - TIMERG1.wdt_config1.clk_prescale=80*500; //Prescaler: wdt counts in ticks of 0.5mS + TIMERG1.wdt_config0.stg0=TIMG_WDT_STG_SEL_INT; //1st stage timeout: interrupt + TIMERG1.wdt_config0.stg1=TIMG_WDT_STG_SEL_RESET_SYSTEM; //2nd stage timeout: reset system + TIMERG1.wdt_config1.clk_prescale=80*500; //Prescaler: wdt counts in ticks of 0.5mS //The timer configs initially are set to 5 seconds, to make sure the CPU can start up. The tick hook sets //it to their actual value. TIMERG1.wdt_config2=10000; @@ -72,7 +72,7 @@ void vApplicationTickHook(void) { } else { //Only feed wdt if app cpu also ticked. if (int_wdt_app_cpu_ticked) { - TIMERG1.wdt_wprotect=WDT_WRITE_KEY; + TIMERG1.wdt_wprotect=TIMG_WDT_WKEY_VALUE; TIMERG1.wdt_config2=CONFIG_INT_WDT_TIMEOUT_MS*2; //Set timeout before interrupt TIMERG1.wdt_config3=CONFIG_INT_WDT_TIMEOUT_MS*4; //Set timeout before reset TIMERG1.wdt_feed=1; @@ -84,7 +84,7 @@ void vApplicationTickHook(void) { #else void vApplicationTickHook(void) { if (xPortGetCoreID()!=0) return; - TIMERG1.wdt_wprotect=WDT_WRITE_KEY; + TIMERG1.wdt_wprotect=TIMG_WDT_WKEY_VALUE; TIMERG1.wdt_config2=CONFIG_INT_WDT_TIMEOUT_MS*2; //Set timeout before interrupt TIMERG1.wdt_config3=CONFIG_INT_WDT_TIMEOUT_MS*4; //Set timeout before reset TIMERG1.wdt_feed=1; diff --git a/components/esp32/panic.c b/components/esp32/panic.c index 758d581d09..274364008b 100644 --- a/components/esp32/panic.c +++ b/components/esp32/panic.c @@ -203,17 +203,17 @@ all watchdogs except the timer group 0 watchdog, and it reconfigures that to res one second. */ static void reconfigureAllWdts() { - TIMERG0.wdt_wprotect=WDT_WRITE_KEY; + TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE; TIMERG0.wdt_feed=1; TIMERG0.wdt_config0.sys_reset_length=7; //3.2uS TIMERG0.wdt_config0.cpu_reset_length=7; //3.2uS - TIMERG0.wdt_config0.stg0=3; //1st stage timeout: reset system + TIMERG0.wdt_config0.stg0=TIMG_WDT_STG_SEL_RESET_SYSTEM; //1st stage timeout: reset system TIMERG0.wdt_config1.clk_prescale=80*500; //Prescaler: wdt counts in ticks of 0.5mS TIMERG0.wdt_config2=2000; //1 second before reset TIMERG0.wdt_config0.en=1; TIMERG0.wdt_wprotect=0; //Disable wdt 1 - TIMERG1.wdt_wprotect=WDT_WRITE_KEY; + TIMERG1.wdt_wprotect=TIMG_WDT_WKEY_VALUE; TIMERG1.wdt_config0.en=0; TIMERG1.wdt_wprotect=0; } @@ -222,10 +222,10 @@ static void reconfigureAllWdts() { This disables all the watchdogs for when we call the gdbstub. */ static void disableAllWdts() { - TIMERG0.wdt_wprotect=WDT_WRITE_KEY; + TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE; TIMERG0.wdt_config0.en=0; TIMERG0.wdt_wprotect=0; - TIMERG1.wdt_wprotect=WDT_WRITE_KEY; + TIMERG1.wdt_wprotect=TIMG_WDT_WKEY_VALUE; TIMERG1.wdt_config0.en=0; TIMERG0.wdt_wprotect=0; } diff --git a/components/esp32/task_wdt.c b/components/esp32/task_wdt.c index 24d3977b18..bec1cadaa7 100644 --- a/components/esp32/task_wdt.c +++ b/components/esp32/task_wdt.c @@ -49,7 +49,7 @@ static void IRAM_ATTR task_wdt_isr(void *arg) { wdt_task_t *wdttask; const char *cpu; //Feed the watchdog so we do not reset - TIMERG0.wdt_wprotect=WDT_WRITE_KEY; + TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE; TIMERG0.wdt_feed=1; TIMERG0.wdt_wprotect=0; //Ack interrupt @@ -107,7 +107,7 @@ void esp_task_wdt_feed() { } if (do_feed_wdt) { //All tasks have checked in; time to feed the hw watchdog. - TIMERG0.wdt_wprotect=WDT_WRITE_KEY; + TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE; TIMERG0.wdt_feed=1; TIMERG0.wdt_wprotect=0; //Reset fed_watchdog status @@ -141,13 +141,13 @@ void esp_task_wdt_delete() { } void esp_task_wdt_init() { - TIMERG0.wdt_wprotect=WDT_WRITE_KEY; - TIMERG0.wdt_config0.sys_reset_length=7; //3.2uS - TIMERG0.wdt_config0.cpu_reset_length=7; //3.2uS + TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE; + TIMERG0.wdt_config0.sys_reset_length=7; //3.2uS + TIMERG0.wdt_config0.cpu_reset_length=7; //3.2uS TIMERG0.wdt_config0.level_int_en=1; - TIMERG0.wdt_config0.stg0=1; //1st stage timeout: interrupt - TIMERG0.wdt_config0.stg1=3; //2nd stage timeout: reset system - TIMERG0.wdt_config1.clk_prescale=80*500; //Prescaler: wdt counts in ticks of 0.5mS + TIMERG0.wdt_config0.stg0=TIMG_WDT_STG_SEL_INT; //1st stage timeout: interrupt + TIMERG0.wdt_config0.stg1=TIMG_WDT_STG_SEL_RESET_SYSTEM; //2nd stage timeout: reset system + TIMERG0.wdt_config1.clk_prescale=80*500; //Prescaler: wdt counts in ticks of 0.5mS TIMERG0.wdt_config2=CONFIG_TASK_WDT_TIMEOUT_S*2000; //Set timeout before interrupt TIMERG0.wdt_config3=CONFIG_TASK_WDT_TIMEOUT_S*4000; //Set timeout before reset TIMERG0.wdt_config0.en=1; From 3cca62dfa46bc0888b45e7a848657f0387e386dc Mon Sep 17 00:00:00 2001 From: liuzhifu Date: Wed, 26 Oct 2016 18:16:40 +0800 Subject: [PATCH 142/343] esp32/tcpip_adapter: refractor for some wifi APIs 1. Modify esp_wifi_get_station_list to esp_wifi_ap_get_sta_list 2. Modify tcpip_adapter_get_station_list to tcpip_adapter_get_sta_list 3. Remove esp_wifi_free_station_list 4. Remove tcpip_adapter_free_station_list 5. Modify related data struct accordingly --- components/esp32/include/esp_wifi.h | 7 ++-- components/esp32/include/esp_wifi_types.h | 13 ++++-- .../tcpip_adapter/include/tcpip_adapter.h | 28 +++++-------- components/tcpip_adapter/tcpip_adapter_lwip.c | 42 ++++--------------- 4 files changed, 29 insertions(+), 61 deletions(-) diff --git a/components/esp32/include/esp_wifi.h b/components/esp32/include/esp_wifi.h index 12378f3346..3898bfec79 100644 --- a/components/esp32/include/esp_wifi.h +++ b/components/esp32/include/esp_wifi.h @@ -198,7 +198,7 @@ esp_err_t esp_wifi_clear_fast_connect(void); * @return ESP_OK : succeed * @return others : fail */ -esp_err_t esp_wifi_kick_station(uint16_t aid); +esp_err_t esp_wifi_kick_sta(uint16_t aid); /** * @brief Scan all available APs. @@ -471,14 +471,13 @@ esp_err_t esp_wifi_get_config(wifi_interface_t ifx, wifi_config_t *conf); * * @attention SSC only API * - * @param struct station_info **station : station list + * @param wifi_sta_list_t *sta: sta list * * @return ESP_OK : succeed * @return others : fail */ -esp_err_t esp_wifi_get_station_list(struct station_info **station); +esp_err_t esp_wifi_ap_get_sta_list(wifi_sta_list_t *sta); -esp_err_t esp_wifi_free_station_list(void); /** * @brief Set the WiFi API configuration storage type diff --git a/components/esp32/include/esp_wifi_types.h b/components/esp32/include/esp_wifi_types.h index b3474769e8..a607ad9e94 100644 --- a/components/esp32/include/esp_wifi_types.h +++ b/components/esp32/include/esp_wifi_types.h @@ -150,10 +150,15 @@ typedef union { wifi_sta_config_t sta; /**< configuration of STA */ } wifi_config_t; -struct station_info { - STAILQ_ENTRY(station_info) next; - uint8_t bssid[6]; -}; +typedef struct { + uint8_t mac[6]; /**< mac address of sta that associated with ESP32 soft-AP */ +}wifi_sta_info_t; + +#define ESP_WIFI_MAX_CONN_NUM 8 /**< max number of sta the eSP32 soft-AP can connect */ +typedef struct { + wifi_sta_info_t sta[ESP_WIFI_MAX_CONN_NUM+2]; /**< sta list */ + uint8_t num; /**< number of sta that associated with ESP32 soft-AP */ +}wifi_sta_list_t; typedef enum { WIFI_STORAGE_FLASH, /**< all configuration will strore in both memory and flash */ diff --git a/components/tcpip_adapter/include/tcpip_adapter.h b/components/tcpip_adapter/include/tcpip_adapter.h index 5b0fc4c627..bbcf33727d 100644 --- a/components/tcpip_adapter/include/tcpip_adapter.h +++ b/components/tcpip_adapter/include/tcpip_adapter.h @@ -67,11 +67,15 @@ typedef struct { typedef dhcps_lease_t tcpip_adapter_dhcps_lease_t; #if CONFIG_DHCP_STA_LIST -struct station_list { - STAILQ_ENTRY(station_list) next; +typedef struct { uint8_t mac[6]; ip4_addr_t ip; -}; +}tcpip_adapter_sta_info_t; + +typedef struct { + tcpip_adapter_sta_info_t sta[ESP_WIFI_MAX_CONN_NUM+2]; + uint8_t num; +}tcpip_adapter_sta_list_t; #endif #endif @@ -359,26 +363,14 @@ wifi_interface_t tcpip_adapter_get_wifi_if(void *dev); /** * @brief Get the station information list * - * @note This function should be called in AP mode and dhcp server started, and the list should - * be by using tcpip_adapter_free_sta_list. - * - * @param[in] sta_info: station information - * @param[out] sta_list: station information list + * @param[in] wifi_sta_list_t *wifi_sta_list: sta list info + * @param[out] tcpip_adapter_sta_list_t *tcpip_sta_list: sta list info * * @return ESP_OK * ESP_ERR_TCPIP_ADAPTER_NO_MEM * ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS */ -esp_err_t tcpip_adapter_get_sta_list(struct station_info *sta_info, struct station_list **sta_list); - -/** - * @brief Free the station information list's memory - * - * @param sta_list: station information list - * - * @return ESP_OK - */ -esp_err_t tcpip_adapter_free_sta_list(struct station_list *sta_list); +esp_err_t tcpip_adapter_get_sta_list(wifi_sta_list_t *wifi_sta_list, tcpip_adapter_sta_list_t *tcpip_sta_list); #ifdef __cplusplus } diff --git a/components/tcpip_adapter/tcpip_adapter_lwip.c b/components/tcpip_adapter/tcpip_adapter_lwip.c index 12cf05f95f..677368008d 100644 --- a/components/tcpip_adapter/tcpip_adapter_lwip.c +++ b/components/tcpip_adapter/tcpip_adapter_lwip.c @@ -590,45 +590,17 @@ wifi_interface_t tcpip_adapter_get_wifi_if(void *dev) return WIFI_IF_MAX; } -esp_err_t tcpip_adapter_get_sta_list(struct station_info *sta_info, struct station_list **sta_list) +esp_err_t tcpip_adapter_get_sta_list(wifi_sta_list_t *wifi_sta_list, tcpip_adapter_sta_list_t *tcpip_sta_list) { - struct station_info *info = sta_info; - struct station_list *list; - STAILQ_HEAD(, station_list) list_head; + int i; - if (sta_list == NULL) + if ((wifi_sta_list == NULL) || (tcpip_sta_list == NULL)) return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; - STAILQ_INIT(&list_head); - - while (info != NULL) { - list = (struct station_list *)malloc(sizeof(struct station_list)); - memset(list, 0, sizeof (struct station_list)); - - if (list == NULL) { - return ESP_ERR_TCPIP_ADAPTER_NO_MEM; - } - - memcpy(list->mac, info->bssid, 6); - dhcp_search_ip_on_mac(list->mac, &list->ip); - STAILQ_INSERT_TAIL(&list_head, list, next); - - info = STAILQ_NEXT(info, next); - } - - *sta_list = STAILQ_FIRST(&list_head); - - return ESP_OK; -} - -esp_err_t tcpip_adapter_free_sta_list(struct station_list *sta_list) -{ - struct station_list *list = sta_list; - - while (sta_list != NULL) { - list = sta_list; - sta_list = STAILQ_NEXT(sta_list, next); - free(list); + memset(tcpip_sta_list, 0, sizeof(tcpip_adapter_sta_list_t)); + for (i=0; inum; i++){ + memcpy(tcpip_sta_list->sta[i].mac, wifi_sta_list->sta[i].mac, 6); + dhcp_search_ip_on_mac(tcpip_sta_list->sta[i].mac, &tcpip_sta_list->sta[i].ip); } return ESP_OK; From 345cf333a89b2e1f9d5383e5b66b6b923afb20b1 Mon Sep 17 00:00:00 2001 From: liuzhifu Date: Wed, 26 Oct 2016 18:18:58 +0800 Subject: [PATCH 143/343] components/esp32: udpate wifi lib 1. cc5a5e29 - refractor for some wifi APIs 2. 8d787147 - move soft wdt to idf --- components/esp32/lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp32/lib b/components/esp32/lib index d3920845c9..0ee0776b53 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit d3920845c9501f6ebae178186c3f63a80fab1ed1 +Subproject commit 0ee0776b539db3e42a06a5b1ff8e4ea102f8630b From 750d6faf512184803bd9016ea612b4ecf99e7bc8 Mon Sep 17 00:00:00 2001 From: liuzhifu Date: Wed, 26 Oct 2016 20:02:39 +0800 Subject: [PATCH 144/343] esp32/tcpip_adapter: rework according to review comments 1. Modify sta to station in comments 2. Modify esp_wifi_get_ap_num to esp_wifi_scan_get_ap_num 3. Modify esp_wifi_get_ap_list to esp_wifi_scan_get_ap_records --- components/esp32/include/esp_wifi.h | 10 +++++----- components/esp32/include/esp_wifi_types.h | 8 ++++---- components/esp32/lib | 2 +- components/tcpip_adapter/include/tcpip_adapter.h | 4 ++-- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/components/esp32/include/esp_wifi.h b/components/esp32/include/esp_wifi.h index 3898bfec79..6fc9d896ac 100644 --- a/components/esp32/include/esp_wifi.h +++ b/components/esp32/include/esp_wifi.h @@ -235,19 +235,19 @@ esp_err_t esp_wifi_scan_stop(void); * @return ESP_OK : succeed * @return others : fail */ -esp_err_t esp_wifi_get_ap_num(uint16_t *number); +esp_err_t esp_wifi_scan_get_ap_num(uint16_t *number); /** * @brief Get AP list found in last scan * - * @param uint16_t *number : as input param, it stores max AP number ap_list can hold, as output param, it store + * @param uint16_t *number : as input param, it stores max AP number ap_records can hold, as output param, it store the actual AP number this API returns - * @param wifi_ap_list_t *ap_list : a list to hold the found APs + * @param wifi_ap_record_t *ap_records: an wifi_ap_record_t array to hold the found APs * * @return ESP_OK : succeed * @return others : fail */ -esp_err_t esp_wifi_get_ap_list(uint16_t *number, wifi_ap_list_t *ap_list); +esp_err_t esp_wifi_scan_get_ap_records(uint16_t *number, wifi_ap_record_t *ap_records); /** * @brief Set current power save type @@ -471,7 +471,7 @@ esp_err_t esp_wifi_get_config(wifi_interface_t ifx, wifi_config_t *conf); * * @attention SSC only API * - * @param wifi_sta_list_t *sta: sta list + * @param wifi_sta_list_t *sta: station list * * @return ESP_OK : succeed * @return others : fail diff --git a/components/esp32/include/esp_wifi_types.h b/components/esp32/include/esp_wifi_types.h index a607ad9e94..0ea719a65b 100644 --- a/components/esp32/include/esp_wifi_types.h +++ b/components/esp32/include/esp_wifi_types.h @@ -109,7 +109,7 @@ typedef struct { wifi_second_chan_t second; /**< second channel of AP */ int8_t rssi; /**< signal strength of AP */ wifi_auth_mode_t authmode; /**< authmode of AP */ -} wifi_ap_list_t; +} wifi_ap_record_t; typedef enum { WIFI_PS_NONE, /**< No power save */ @@ -154,10 +154,10 @@ typedef struct { uint8_t mac[6]; /**< mac address of sta that associated with ESP32 soft-AP */ }wifi_sta_info_t; -#define ESP_WIFI_MAX_CONN_NUM 8 /**< max number of sta the eSP32 soft-AP can connect */ +#define ESP_WIFI_MAX_CONN_NUM (8+2) /**< max number of sta the eSP32 soft-AP can connect */ typedef struct { - wifi_sta_info_t sta[ESP_WIFI_MAX_CONN_NUM+2]; /**< sta list */ - uint8_t num; /**< number of sta that associated with ESP32 soft-AP */ + wifi_sta_info_t sta[ESP_WIFI_MAX_CONN_NUM]; /**< station list */ + uint8_t num; /**< number of station that associated with ESP32 soft-AP */ }wifi_sta_list_t; typedef enum { diff --git a/components/esp32/lib b/components/esp32/lib index 0ee0776b53..02063e8d40 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit 0ee0776b539db3e42a06a5b1ff8e4ea102f8630b +Subproject commit 02063e8d40f72933622b2eafd78ce968085b0047 diff --git a/components/tcpip_adapter/include/tcpip_adapter.h b/components/tcpip_adapter/include/tcpip_adapter.h index bbcf33727d..218325320e 100644 --- a/components/tcpip_adapter/include/tcpip_adapter.h +++ b/components/tcpip_adapter/include/tcpip_adapter.h @@ -363,8 +363,8 @@ wifi_interface_t tcpip_adapter_get_wifi_if(void *dev); /** * @brief Get the station information list * - * @param[in] wifi_sta_list_t *wifi_sta_list: sta list info - * @param[out] tcpip_adapter_sta_list_t *tcpip_sta_list: sta list info + * @param[in] wifi_sta_list_t *wifi_sta_list: station list info + * @param[out] tcpip_adapter_sta_list_t *tcpip_sta_list: station list info * * @return ESP_OK * ESP_ERR_TCPIP_ADAPTER_NO_MEM From d3d9a8bc280900ffac9b61a3a1bc8532fa9aa8c6 Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Wed, 26 Oct 2016 21:09:55 +0800 Subject: [PATCH 145/343] Most code written. Interrupts still do not fire yet. --- components/esp32/crosscore_int.c | 107 +++++++++++++ components/esp32/include/esp_crosscore_int.h | 8 + .../freertos/include/freertos/portable.h | 8 + components/freertos/port.c | 8 + components/freertos/tasks.c | 147 ++++++++++++------ 5 files changed, 233 insertions(+), 45 deletions(-) create mode 100644 components/esp32/crosscore_int.c create mode 100644 components/esp32/include/esp_crosscore_int.h diff --git a/components/esp32/crosscore_int.c b/components/esp32/crosscore_int.c new file mode 100644 index 0000000000..95f2762f23 --- /dev/null +++ b/components/esp32/crosscore_int.c @@ -0,0 +1,107 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include +#include + +#include "esp_attr.h" +#include "esp_err.h" +#include "esp_intr.h" + +#include "rom/ets_sys.h" +#include "rom/uart.h" + +#include "soc/cpu.h" +#include "soc/dport_reg.h" +#include "soc/io_mux_reg.h" +#include "soc/rtc_cntl_reg.h" + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/semphr.h" +#include "freertos/queue.h" +#include "freertos/portmacro.h" + + +#define REASON_YIELD (1<<0) + +static portMUX_TYPE reasonSpinlock = portMUX_INITIALIZER_UNLOCKED; +static volatile uint32_t reason[ portNUM_PROCESSORS ]; + + +/* +ToDo: There is a small chance the CPU already has yielded when this ISR is serviced. In that case, it's running the intended task but +the ISR will cause it to switch _away_ from it. portYIELD_FROM_ISR will probably just schedule the task again, but have to check that. +*/ +static void esp_crosscore_isr(void *arg) { + volatile uint32_t myReasonVal; +#if 0 + //A pointer to the correct reason array item is passed to this ISR. + volatile uint32_t *myReason=arg; +#else + //Does not work yet, the interrupt code needs work to understand two separate interrupt and argument + //tables... + volatile uint32_t *myReason=&reason[xPortGetCoreID()]; +#endif + //Clear the interrupt first. + if (xPortGetCoreID()==0) { + WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_0_REG, 0); + } else { + WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_0_REG, 1); + } + //Grab the reason and clear it. + portENTER_CRITICAL(&reasonSpinlock); + myReasonVal=*myReason; + *myReason=0; + portEXIT_CRITICAL(&reasonSpinlock); + + //Check what we need to do. + if (myReasonVal&REASON_YIELD) { + portYIELD_FROM_ISR(); + } + + ets_printf("recv yield\n"); +} + +//Initialize the crosscore interrupt on this core. Call this once +//on each active core. +void esp_crosscore_int_init() { + portENTER_CRITICAL(&reasonSpinlock); + reason[xPortGetCoreID()]=0; + portEXIT_CRITICAL(&reasonSpinlock); + ESP_INTR_DISABLE(ETS_FROM_CPU_INUM); + if (xPortGetCoreID()==0) { + intr_matrix_set(xPortGetCoreID(), ETS_FROM_CPU_INTR0_SOURCE, ETS_FROM_CPU_INUM); + } else { + intr_matrix_set(xPortGetCoreID(), ETS_FROM_CPU_INTR1_SOURCE, ETS_FROM_CPU_INUM); + } + xt_set_interrupt_handler(ETS_FROM_CPU_INUM, esp_crosscore_isr, (void*)&reason[xPortGetCoreID()]); + ESP_INTR_ENABLE(ETS_FROM_CPU_INUM); + +} + +void esp_crosscore_int_send_yield(int coreId) { + ets_printf("send yield\n"); + assert(coreIduxPriority ] ), &( ( pxTCB )->xGenericListItem ) ) /*-----------------------------------------------------------*/ + +#define tskCAN_RUN_HERE( cpuid ) ( cpuid==xPortGetCoreID() || cpuid==tskNO_AFFINITY ) + /* * Several functions take an TaskHandle_t parameter that can optionally be NULL, * where NULL is used to indicate that the handle of the currently executing @@ -581,6 +584,35 @@ static void prvResetNextTaskUnblockTime( void ); /*-----------------------------------------------------------*/ +/* + * This routine tries to send an interrupt to another core if needed to make it execute a task + * of higher priority. We try to figure out if needed first by inspecting the pxTCB of the + * other CPU first. Specifically for Xtensa, we can do this because pxTCB is an atomic pointer. It + * is possible that it is inaccurate because the other CPU just did a task switch, but in that case + * at most a superfluous interrupt is generated. +*/ +static void taskYIELD_OTHER_CORE( BaseType_t xCoreID, UBaseType_t uxPriority ) +{ + BaseType_t i; + if (xCoreID != tskNO_AFFINITY) { + if ( pxCurrentTCB[ xCoreID ]->uxPriority < uxPriority ) { + vPortYieldOtherCore( xCoreID ); + } + } + else + { + /* The task has no affinity. See if we can find a CPU to put it on.*/ + for (i=0; iuxPriority < uxPriority) + { + vPortYieldOtherCore( i ); + break; + } + } + } +} + + BaseType_t xTaskGenericCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask, StackType_t * const puxStackBuffer, const MemoryRegion_t * const xRegions, const BaseType_t xCoreID) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ { BaseType_t xReturn; @@ -753,7 +785,10 @@ BaseType_t i; the other processor will keep running the task it's working on, and only switch to the newer task on a timer interrupt. */ //No mux here, uxPriority is mostly atomic and there's not really any harm if this check misfires. - if( pxCurrentTCB[ xPortGetCoreID() ]->uxPriority < uxPriority ) + if( xCoreID != xPortGetCoreID() ) { + taskYIELD_OTHER_CORE(xCoreID, uxPriority); + } + else if( pxCurrentTCB[ xPortGetCoreID() ]->uxPriority < uxPriority ) { taskYIELD_IF_USING_PREEMPTION(); } @@ -834,7 +869,7 @@ BaseType_t i; after which it is not possible to yield away from this task - hence xYieldPending is used to latch that a context switch is required. */ - portPRE_TASK_DELETE_HOOK( pxTCB, &xYieldPending ); + portPRE_TASK_DELETE_HOOK( pxTCB, &xYieldPending[xPortGetCoreID()] ); portYIELD_WITHIN_API(); } else @@ -1188,10 +1223,14 @@ BaseType_t i; /* The priority of a task other than the currently running task is being raised. Is the priority being raised above that of the running task? */ - if( uxNewPriority >= pxCurrentTCB[ xPortGetCoreID() ]->uxPriority ) + if ( tskCAN_RUN_HERE(pxTCB->xCoreID) && uxNewPriority >= pxCurrentTCB[ xPortGetCoreID() ]->uxPriority ) { xYieldRequired = pdTRUE; } + else if ( pxTCB->xCoreID != xPortGetCoreID() ) + { + taskYIELD_OTHER_CORE( pxTCB->xCoreID, uxNewPriority ); + } else { mtCOVERAGE_TEST_MARKER(); @@ -1470,13 +1509,17 @@ BaseType_t i; prvAddTaskToReadyList( pxTCB ); /* We may have just resumed a higher priority task. */ - if( pxTCB->uxPriority >= pxCurrentTCB[ xPortGetCoreID() ]->uxPriority ) + if( tskCAN_RUN_HERE(pxTCB->xCoreID) && pxTCB->uxPriority >= pxCurrentTCB[ xPortGetCoreID() ]->uxPriority ) { /* This yield may not cause the task just resumed to run, but will leave the lists in the correct state for the next yield. */ taskYIELD_IF_USING_PREEMPTION_MUX(&xTaskQueueMutex); } + else if( pxTCB->xCoreID != xPortGetCoreID() ) + { + taskYIELD_OTHER_CORE( pxTCB->xCoreID, pxTCB->uxPriority ); + } else { mtCOVERAGE_TEST_MARKER(); @@ -1521,7 +1564,14 @@ BaseType_t i; { /* Ready lists can be accessed so move the task from the suspended list to the ready list directly. */ - if( pxTCB->uxPriority >= pxCurrentTCB[ xPortGetCoreID() ]->uxPriority ) + ( void ) uxListRemove( &( pxTCB->xGenericListItem ) ); + prvAddTaskToReadyList( pxTCB ); + + if ( pxTCB->xCoreID == xPortGetCoreID() ) + { + taskYIELD_OTHER_CORE( pxTCB->xCoreID, pxTCB->uxPriority); + } + else if( pxTCB->uxPriority >= pxCurrentTCB[ xPortGetCoreID() ]->uxPriority ) { xYieldRequired = pdTRUE; } @@ -1529,9 +1579,6 @@ BaseType_t i; { mtCOVERAGE_TEST_MARKER(); } - - ( void ) uxListRemove( &( pxTCB->xGenericListItem ) ); - prvAddTaskToReadyList( pxTCB ); } else { @@ -1732,11 +1779,16 @@ BaseType_t xAlreadyYielded = pdFALSE; /* If the moved task has a priority higher than the current task then a yield must be performed. */ - if( pxTCB->uxPriority >= pxCurrentTCB[ xPortGetCoreID() ]->uxPriority ) + if ( tskCAN_RUN_HERE(pxTCB->xCoreID) && pxTCB->uxPriority >= pxCurrentTCB[ xPortGetCoreID() ]->uxPriority ) { - xYieldPending = pdTRUE; + /* We can schedule the awoken task on this CPU. */ + xYieldPending[xPortGetCoreID()] = pdTRUE; break; } + else if ( pxTCB->xCoreID != xPortGetCoreID() ) + { + taskYIELD_OTHER_CORE( pxTCB->xCoreID, pxTCB->uxPriority ); + } else { mtCOVERAGE_TEST_MARKER(); @@ -1753,7 +1805,7 @@ BaseType_t xAlreadyYielded = pdFALSE; { if( xTaskIncrementTick() != pdFALSE ) { - xYieldPending = pdTRUE; + xYieldPending[ xPortGetCoreID() ] = pdTRUE; } else { @@ -1767,7 +1819,7 @@ BaseType_t xAlreadyYielded = pdFALSE; mtCOVERAGE_TEST_MARKER(); } - if( xYieldPending == pdTRUE ) + if( xYieldPending[ xPortGetCoreID() ] == pdTRUE ) { #if( configUSE_PREEMPTION != 0 ) { @@ -2135,7 +2187,7 @@ BaseType_t xSwitchRequired = pdFALSE; #if ( configUSE_PREEMPTION == 1 ) { - if( xYieldPending != pdFALSE ) + if( xYieldPending [ xPortGetCoreID() ] != pdFALSE ) { xSwitchRequired = pdTRUE; } @@ -2251,11 +2303,11 @@ void vTaskSwitchContext( void ) { /* The scheduler is currently suspended - do not allow a context switch. */ - xYieldPending = pdTRUE; + xYieldPending[ xPortGetCoreID() ] = pdTRUE; } else { - xYieldPending = pdFALSE; + xYieldPending[ xPortGetCoreID() ] = pdFALSE; traceTASK_SWITCHED_OUT(); #if ( configGENERATE_RUN_TIME_STATS == 1 ) @@ -2610,16 +2662,16 @@ BaseType_t xReturn; taskEXIT_CRITICAL(&xTaskQueueMutex); } - if( pxUnblockedTCB->uxPriority > pxCurrentTCB[ xPortGetCoreID() ]->uxPriority ) + if ( tskCAN_RUN_HERE(pxUnblockedTCB->xCoreID) && pxUnblockedTCB->uxPriority >= pxCurrentTCB[ xPortGetCoreID() ]->uxPriority ) { - /* Return true if the task removed from the event list has a higher - priority than the calling task. This allows the calling task to know if - it should force a context switch now. */ + /* We can schedule the awoken task on this CPU. */ + xYieldPending[xPortGetCoreID()] = pdTRUE; xReturn = pdTRUE; - - /* Mark that a yield is pending in case the user is not using the - "xHigherPriorityTaskWoken" parameter to an ISR safe FreeRTOS function. */ - xYieldPending = pdTRUE; + } + else if ( pxUnblockedTCB->xCoreID != xPortGetCoreID() ) + { + taskYIELD_OTHER_CORE( pxUnblockedTCB->xCoreID, pxUnblockedTCB->uxPriority ); + xReturn = pdFALSE; } else { @@ -2670,17 +2722,16 @@ BaseType_t xReturn; ( void ) uxListRemove( &( pxUnblockedTCB->xGenericListItem ) ); prvAddTaskToReadyList( pxUnblockedTCB ); - if( pxUnblockedTCB->uxPriority > pxCurrentTCB[ xPortGetCoreID() ]->uxPriority ) + if ( tskCAN_RUN_HERE(pxUnblockedTCB->xCoreID) && pxUnblockedTCB->uxPriority >= pxCurrentTCB[ xPortGetCoreID() ]->uxPriority ) { - /* Return true if the task removed from the event list has - a higher priority than the calling task. This allows - the calling task to know if it should force a context - switch now. */ + /* We can schedule the awoken task on this CPU. */ + xYieldPending[xPortGetCoreID()] = pdTRUE; xReturn = pdTRUE; - - /* Mark that a yield is pending in case the user is not using the - "xHigherPriorityTaskWoken" parameter to an ISR safe FreeRTOS function. */ - xYieldPending = pdTRUE; + } + else if ( pxUnblockedTCB->xCoreID != xPortGetCoreID() ) + { + taskYIELD_OTHER_CORE( pxUnblockedTCB->xCoreID, pxUnblockedTCB->uxPriority ); + xReturn = pdFALSE; } else { @@ -2751,7 +2802,7 @@ BaseType_t xReturn; void vTaskMissedYield( void ) { - xYieldPending = pdTRUE; + xYieldPending[ xPortGetCoreID() ] = pdTRUE; } /*-----------------------------------------------------------*/ @@ -2921,7 +2972,7 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters ) /* A task was made ready while the scheduler was suspended. */ eReturn = eAbortSleep; } - else if( xYieldPending != pdFALSE ) + else if( xYieldPending[ xPortGetCoreID() ] != pdFALSE ) { /* A yield was pended while the scheduler was suspended. */ eReturn = eAbortSleep; @@ -3597,12 +3648,6 @@ TCB_t *pxTCB; #endif /* ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) */ /*-----------------------------------------------------------*/ -/* -ToDo: Mutexes haven't been tested or adapted to multicore at all. - -In fact, nothing below this line has/is. -*/ - #if ( configUSE_MUTEXES == 1 ) void vTaskPriorityInherit( TaskHandle_t const pxMutexHolder ) @@ -4434,12 +4479,16 @@ TickType_t uxReturn; /* The task should not have been on an event list. */ configASSERT( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL ); - if( pxTCB->uxPriority > pxCurrentTCB[ xPortGetCoreID() ]->uxPriority ) + if( tskCAN_RUN_HERE(pxTCB->xCoreID) && pxTCB->uxPriority > pxCurrentTCB[ xPortGetCoreID() ]->uxPriority ) { /* The notified task has a priority above the currently executing task so a yield is required. */ portYIELD_WITHIN_API(); } + else if ( pxTCB->xCoreID != xPortGetCoreID() ) + { + taskYIELD_OTHER_CORE(pxTCB->xCoreID, pxTCB->uxPriority); + } else { mtCOVERAGE_TEST_MARKER(); @@ -4530,7 +4579,7 @@ TickType_t uxReturn; vListInsertEnd( &( xPendingReadyList ), &( pxTCB->xEventListItem ) ); } - if( pxTCB->uxPriority > pxCurrentTCB[ xPortGetCoreID() ]->uxPriority ) + if( tskCAN_RUN_HERE(pxTCB->xCoreID) && pxTCB->uxPriority > pxCurrentTCB[ xPortGetCoreID() ]->uxPriority ) { /* The notified task has a priority above the currently executing task so a yield is required. */ @@ -4539,6 +4588,10 @@ TickType_t uxReturn; *pxHigherPriorityTaskWoken = pdTRUE; } } + else if ( pxTCB->xCoreID != xPortGetCoreID() ) + { + taskYIELD_OTHER_CORE( pxTCB->xCoreID, pxTCB->uxPriority ); + } else { mtCOVERAGE_TEST_MARKER(); @@ -4593,8 +4646,8 @@ TickType_t uxReturn; this task pending until the scheduler is resumed. */ vListInsertEnd( &( xPendingReadyList ), &( pxTCB->xEventListItem ) ); } - - if( pxTCB->uxPriority > pxCurrentTCB[ xPortGetCoreID() ]->uxPriority ) + + if( tskCAN_RUN_HERE(pxTCB->xCoreID) && pxTCB->uxPriority > pxCurrentTCB[ xPortGetCoreID() ]->uxPriority ) { /* The notified task has a priority above the currently executing task so a yield is required. */ @@ -4603,6 +4656,10 @@ TickType_t uxReturn; *pxHigherPriorityTaskWoken = pdTRUE; } } + else if ( pxTCB->xCoreID != xPortGetCoreID() ) + { + taskYIELD_OTHER_CORE( pxTCB->xCoreID, pxTCB->uxPriority ); + } else { mtCOVERAGE_TEST_MARKER(); From df1c2f0da5e9b1a00622e5eb5f81d2ab772967c2 Mon Sep 17 00:00:00 2001 From: liuzhifu Date: Wed, 26 Oct 2016 21:50:15 +0800 Subject: [PATCH 146/343] components/esp32: refractor according to review comments modify esp_wifi_kick_sta to esp_wifi_deauth_sta --- components/esp32/include/esp_wifi.h | 6 +++--- components/esp32/lib | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/components/esp32/include/esp_wifi.h b/components/esp32/include/esp_wifi.h index 6fc9d896ac..7cfff6ee01 100644 --- a/components/esp32/include/esp_wifi.h +++ b/components/esp32/include/esp_wifi.h @@ -191,14 +191,14 @@ esp_err_t esp_wifi_disconnect(void); esp_err_t esp_wifi_clear_fast_connect(void); /** - * @brief Kick the all station or associated id equals to aid + * @brief deauthenticate all stations or associated id equals to aid * - * @param uint16_t aid : when aid is 0, kick all stations, otherwise kick station whose associated id is aid + * @param uint16_t aid : when aid is 0, deauthenticate all stations, otherwise deauthenticate station whose associated id is aid * * @return ESP_OK : succeed * @return others : fail */ -esp_err_t esp_wifi_kick_sta(uint16_t aid); +esp_err_t esp_wifi_deauth_sta(uint16_t aid); /** * @brief Scan all available APs. diff --git a/components/esp32/lib b/components/esp32/lib index 02063e8d40..b9561aa5db 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit 02063e8d40f72933622b2eafd78ce968085b0047 +Subproject commit b9561aa5db15443d11f8bb5aefdfc5da540d8f2d From 6d54fb004d3ab2c85ac80184a5f1f2ae9a513639 Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Thu, 27 Oct 2016 09:15:43 +0800 Subject: [PATCH 147/343] Change inline to static inline functions. Ref Github issue 62. --- components/freertos/include/freertos/portable.h | 2 +- components/freertos/include/freertos/portmacro.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/freertos/include/freertos/portable.h b/components/freertos/include/freertos/portable.h index a3d39bd5a2..f3474d49ea 100644 --- a/components/freertos/include/freertos/portable.h +++ b/components/freertos/include/freertos/portable.h @@ -192,7 +192,7 @@ void vPortEndScheduler( void ) PRIVILEGED_FUNCTION; #endif /* Multi-core: get current core ID */ -inline uint32_t xPortGetCoreID() { +static inline uint32_t xPortGetCoreID() { int id; asm volatile( "rsr.prid %0\n" diff --git a/components/freertos/include/freertos/portmacro.h b/components/freertos/include/freertos/portmacro.h index 5e2386d721..f20a4a1e26 100644 --- a/components/freertos/include/freertos/portmacro.h +++ b/components/freertos/include/freertos/portmacro.h @@ -234,7 +234,7 @@ static inline unsigned portENTER_CRITICAL_NESTED() { unsigned state = XTOS_SET_I * *bitwise inverse* of the old mem if the mem wasn't written. This doesn't seem to happen on the * ESP32, though. (Would show up directly if it did because the magic wouldn't match.) */ -inline void uxPortCompareSet(volatile uint32_t *addr, uint32_t compare, uint32_t *set) { +static inline void uxPortCompareSet(volatile uint32_t *addr, uint32_t compare, uint32_t *set) { __asm__ __volatile__( "WSR %2,SCOMPARE1 \n" "ISYNC \n" From e0f49c2221de4face091f8a98085e395f6c0cd4f Mon Sep 17 00:00:00 2001 From: Liu Zhi Fu Date: Thu, 27 Oct 2016 10:42:01 +0800 Subject: [PATCH 148/343] esp32: add esp_wifi_sta_get_ap_info The customers need to get information about AP that associated with ESP32 station, these information includes RSSI, channel number etc, so add this new API --- components/esp32/include/esp_wifi.h | 13 ++++++++++++- components/esp32/lib | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/components/esp32/include/esp_wifi.h b/components/esp32/include/esp_wifi.h index 7cfff6ee01..80ced5dc61 100644 --- a/components/esp32/include/esp_wifi.h +++ b/components/esp32/include/esp_wifi.h @@ -242,13 +242,24 @@ esp_err_t esp_wifi_scan_get_ap_num(uint16_t *number); * * @param uint16_t *number : as input param, it stores max AP number ap_records can hold, as output param, it store the actual AP number this API returns - * @param wifi_ap_record_t *ap_records: an wifi_ap_record_t array to hold the found APs + * @param wifi_ap_record_t *ap_records: wifi_ap_record_t array to hold the found APs * * @return ESP_OK : succeed * @return others : fail */ esp_err_t esp_wifi_scan_get_ap_records(uint16_t *number, wifi_ap_record_t *ap_records); + +/** + * @brief Get information of AP associated with ESP32 station + * + * @param wifi_ap_record_t *ap_info: the wifi_ap_record_t to hold station assocated AP + * + * @return ESP_OK : succeed + * @return others : fail + */ +esp_err_t esp_wifi_sta_get_ap_info(wifi_ap_record_t *ap_info); + /** * @brief Set current power save type * diff --git a/components/esp32/lib b/components/esp32/lib index b9561aa5db..774f6073de 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit b9561aa5db15443d11f8bb5aefdfc5da540d8f2d +Subproject commit 774f6073dee1b01da5f420c5d7513b3d88cd5729 From ff6b8addd90bc0da34fb83b914ea74d779b93089 Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Thu, 27 Oct 2016 11:17:24 +0800 Subject: [PATCH 149/343] Fix panic config ifdefs, un-stall app cpu on boot so it restarts after panic --- components/esp32/cpu_start.c | 4 ++++ components/esp32/panic.c | 10 ++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/components/esp32/cpu_start.c b/components/esp32/cpu_start.c index 37205dcd9a..a649764ab5 100644 --- a/components/esp32/cpu_start.c +++ b/components/esp32/cpu_start.c @@ -102,6 +102,10 @@ void IRAM_ATTR call_start_cpu0() #if !CONFIG_FREERTOS_UNICORE ESP_EARLY_LOGI(TAG, "Starting app cpu, entry point is %p", call_start_cpu1); + //Un-stall the app cpu; the panic handler may have stalled it. + CLEAR_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, RTC_CNTL_SW_STALL_APPCPU_C1_M); + CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_STALL_APPCPU_C0_M); + //Enable clock gating and reset the app cpu. SET_PERI_REG_MASK(DPORT_APPCPU_CTRL_B_REG, DPORT_APPCPU_CLKGATE_EN); CLEAR_PERI_REG_MASK(DPORT_APPCPU_CTRL_C_REG, DPORT_APPCPU_RUNSTALL); SET_PERI_REG_MASK(DPORT_APPCPU_CTRL_A_REG, DPORT_APPCPU_RESETTING); diff --git a/components/esp32/panic.c b/components/esp32/panic.c index 274364008b..c806dace2a 100644 --- a/components/esp32/panic.c +++ b/components/esp32/panic.c @@ -38,7 +38,7 @@ task switching / interrupt code runs into an unrecoverable error. The default ta overflow handler also is in here. */ -#if !CONFIG_FREERTOS_PANIC_SILENT_REBOOT +#if !CONFIG_ESP32_PANIC_SILENT_REBOOT //printf may be broken, so we fix our own printing fns... inline static void panicPutchar(char c) { while (((READ_PERI_REG(UART_STATUS_REG(0))>>UART_TXFIFO_CNT_S)&UART_TXFIFO_CNT)>=126) ; @@ -123,7 +123,7 @@ static void haltOtherCore() { //Returns true when a debugger is attached using JTAG. static int inOCDMode() { -#if CONFIG_FREERTOS_DEBUG_OCDAWARE +#if CONFIG_ESP32_DEBUG_OCDAWARE int dcr; int reg=0x10200C; //DSRSET register asm("rer %0,%1":"=r"(dcr):"r"(reg)); @@ -218,6 +218,7 @@ static void reconfigureAllWdts() { TIMERG1.wdt_wprotect=0; } +#if CONFIG_ESP32_PANIC_GDBSTUB || CONFIG_ESP32_PANIC_PRINT_HALT /* This disables all the watchdogs for when we call the gdbstub. */ @@ -230,6 +231,7 @@ static void disableAllWdts() { TIMERG0.wdt_wprotect=0; } +#endif /* We arrive here after a panic or unhandled exception, when no OCD is detected. Dump the registers to the @@ -259,11 +261,11 @@ void commonErrorHandler(XtExcFrame *frame) { } panicPutStr("\r\n"); } -#if CONFIG_FREERTOS_PANIC_GDBSTUB +#if CONFIG_ESP32_PANIC_GDBSTUB disableAllWdts(); panicPutStr("Entering gdb stub now.\r\n"); esp_gdbstub_panic_handler(frame); -#elif CONFIG_FREERTOS_PANIC_PRINT_REBOOT || CONFIG_FREERTOS_PANIC_SILENT_REBOOT +#elif CONFIG_ESP32_PANIC_PRINT_REBOOT || CONFIG_ESP32_PANIC_SILENT_REBOOT panicPutStr("Rebooting...\r\n"); for (x=0; x<100; x++) ets_delay_us(1000); software_reset(); From c6477ff10d983aa8dcb152be2bc673352d5bd69c Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Thu, 27 Oct 2016 12:37:19 +0800 Subject: [PATCH 150/343] Fix int clear, actually call int init code --- components/esp32/cpu_start.c | 3 +++ components/esp32/crosscore_int.c | 4 ++-- components/esp32/lib | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/components/esp32/cpu_start.c b/components/esp32/cpu_start.c index 5c7a411c8e..0c94f39e30 100644 --- a/components/esp32/cpu_start.c +++ b/components/esp32/cpu_start.c @@ -41,6 +41,7 @@ #include "esp_event.h" #include "esp_spi_flash.h" #include "esp_ipc.h" +#include "esp_crosscore_int.h" #include "esp_log.h" #include "trax.h" @@ -146,6 +147,7 @@ void start_cpu0_default(void) uart_div_modify(0, (APB_CLK_FREQ << 4) / 115200); ets_setup_syscalls(); do_global_ctors(); + esp_crosscore_int_init(); esp_ipc_init(); spi_flash_init(); xTaskCreatePinnedToCore(&main_task, "main", @@ -165,6 +167,7 @@ void start_cpu1_default(void) while (port_xSchedulerRunning[0] == 0) { ; } + esp_crosscore_int_init(); ESP_LOGI(TAG, "Starting scheduler on APP CPU."); xPortStartScheduler(); } diff --git a/components/esp32/crosscore_int.c b/components/esp32/crosscore_int.c index 95f2762f23..a98b13583c 100644 --- a/components/esp32/crosscore_int.c +++ b/components/esp32/crosscore_int.c @@ -57,7 +57,7 @@ static void esp_crosscore_isr(void *arg) { if (xPortGetCoreID()==0) { WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_0_REG, 0); } else { - WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_0_REG, 1); + WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_1_REG, 0); } //Grab the reason and clear it. portENTER_CRITICAL(&reasonSpinlock); @@ -77,6 +77,7 @@ static void esp_crosscore_isr(void *arg) { //on each active core. void esp_crosscore_int_init() { portENTER_CRITICAL(&reasonSpinlock); + ets_printf("init cpu %d\n", xPortGetCoreID()); reason[xPortGetCoreID()]=0; portEXIT_CRITICAL(&reasonSpinlock); ESP_INTR_DISABLE(ETS_FROM_CPU_INUM); @@ -87,7 +88,6 @@ void esp_crosscore_int_init() { } xt_set_interrupt_handler(ETS_FROM_CPU_INUM, esp_crosscore_isr, (void*)&reason[xPortGetCoreID()]); ESP_INTR_ENABLE(ETS_FROM_CPU_INUM); - } void esp_crosscore_int_send_yield(int coreId) { diff --git a/components/esp32/lib b/components/esp32/lib index a1e5f8b953..b9561aa5db 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit a1e5f8b953c7934677ba7a6ed0a6dd2da0e6bd0f +Subproject commit b9561aa5db15443d11f8bb5aefdfc5da540d8f2d From 329ad14b8c79ac1ae0e30850909b2ef1f12b7621 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Thu, 27 Oct 2016 12:37:34 +0800 Subject: [PATCH 151/343] esp32: update libs for changes in FreeRTOS header files --- components/esp32/lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp32/lib b/components/esp32/lib index aac7d416a7..12b3435fc0 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit aac7d416a702215f2501a6237caf034ec7e8e80a +Subproject commit 12b3435fc0cd04efc249d52d71efb1cdecda50f8 From 6e6e51426f2a5b2837d4bd9e81e54340aea226ee Mon Sep 17 00:00:00 2001 From: Liu Zhi Fu Date: Thu, 27 Oct 2016 14:11:01 +0800 Subject: [PATCH 152/343] lwip: refractor for lwip 1. All espressif specific code are prefix with ESP_ 2. Define all ESP_ options in lwipopts.h 3. Remove useless code added in 8266 --- components/lwip/api/api_lib.c | 21 +---- components/lwip/api/api_msg.c | 22 +---- components/lwip/api/netbuf.c | 5 -- components/lwip/api/netdb.c | 5 -- components/lwip/api/sockets.c | 86 +++++++------------ components/lwip/api/tcpip.c | 20 ++--- components/lwip/apps/dhcpserver.c | 6 +- components/lwip/core/dns.c | 8 +- components/lwip/core/init.c | 4 +- components/lwip/core/ipv4/autoip.c | 5 -- components/lwip/core/ipv4/dhcp.c | 10 +-- components/lwip/core/ipv4/icmp.c | 5 -- components/lwip/core/ipv4/igmp.c | 5 -- components/lwip/core/ipv4/ip4.c | 9 +- components/lwip/core/ipv4/ip4_addr.c | 14 +-- components/lwip/core/ipv4/ip_frag.c | 5 -- components/lwip/core/ipv6/icmp6.c | 4 - components/lwip/core/ipv6/ip6.c | 4 - components/lwip/core/ipv6/ip6_frag.c | 5 -- components/lwip/core/ipv6/mld6.c | 5 -- components/lwip/core/ipv6/nd6.c | 5 -- components/lwip/core/mem.c | 4 - components/lwip/core/memp.c | 4 - components/lwip/core/netif.c | 13 +-- components/lwip/core/pbuf.c | 55 ++---------- components/lwip/core/raw.c | 4 - components/lwip/core/stats.c | 4 - components/lwip/core/tcp.c | 61 +------------ components/lwip/core/tcp_in.c | 19 ---- components/lwip/core/tcp_out.c | 4 - components/lwip/core/timers.c | 17 +--- components/lwip/core/udp.c | 5 -- components/lwip/include/lwip/lwip/api.h | 4 - components/lwip/include/lwip/lwip/dhcp.h | 2 +- components/lwip/include/lwip/lwip/dns.h | 2 +- components/lwip/include/lwip/lwip/err.h | 2 +- components/lwip/include/lwip/lwip/mem.h | 37 -------- components/lwip/include/lwip/lwip/netif.h | 6 +- components/lwip/include/lwip/lwip/opt.h | 4 +- components/lwip/include/lwip/lwip/pbuf.h | 2 +- .../lwip/include/lwip/lwip/priv/api_msg.h | 6 +- components/lwip/include/lwip/lwip/sockets.h | 4 +- components/lwip/include/lwip/port/lwipopts.h | 33 ++++++- components/lwip/netif/etharp.c | 4 - components/lwip/port/freertos/sys_arch.c | 44 +++++----- components/lwip/port/netif/wlanif.c | 24 ++---- 46 files changed, 142 insertions(+), 475 deletions(-) diff --git a/components/lwip/api/api_lib.c b/components/lwip/api/api_lib.c index c38c760811..ecebf4f813 100755 --- a/components/lwip/api/api_lib.c +++ b/components/lwip/api/api_lib.c @@ -55,11 +55,6 @@ #include -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; -#endif - - #define API_MSG_VAR_REF(name) API_VAR_REF(name) #define API_MSG_VAR_DECLARE(name) API_VAR_DECLARE(struct api_msg, name) #define API_MSG_VAR_ALLOC(name) API_VAR_ALLOC(struct api_msg, MEMP_API_MSG, name) @@ -178,8 +173,8 @@ netconn_delete(struct netconn *conn) return err; } -#if !LWIP_THREAD_SAFE - LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("netconn_delete - free conn\n")); +#if !ESP_THREAD_SAFE + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("netconn_delete - free conn\n")); netconn_free(conn); #endif @@ -502,7 +497,7 @@ netconn_recv_data(struct netconn *conn, void **new_buf) #endif /* LWIP_TCP && (LWIP_UDP || LWIP_RAW) */ #if (LWIP_UDP || LWIP_RAW) { -#if LWIP_THREAD_SAFE +#if ESP_THREAD_SAFE if (buf == NULL){ API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0); return ERR_CLSD; @@ -710,17 +705,7 @@ netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size, } dontblock = netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK); -#ifdef LWIP_ESP8266 - -#ifdef FOR_XIAOMI - if (dontblock && bytes_written) { -#else - if (dontblock && !bytes_written) { -#endif - -#else if (dontblock && !bytes_written) { -#endif /* This implies netconn_write() cannot be used for non-blocking send, since it has no way to return the number of bytes written. */ return ERR_VAL; diff --git a/components/lwip/api/api_msg.c b/components/lwip/api/api_msg.c index 9cac2e0e90..d504bfb877 100755 --- a/components/lwip/api/api_msg.c +++ b/components/lwip/api/api_msg.c @@ -55,10 +55,6 @@ #include -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; -#endif - /* netconns are polled once per second (e.g. continue write on memory error) */ #define NETCONN_TCP_POLL_INTERVAL 2 @@ -1216,16 +1212,7 @@ lwip_netconn_do_connect(void *m) if (msg->conn->state == NETCONN_CONNECT) { msg->err = ERR_ALREADY; } else if (msg->conn->state != NETCONN_NONE) { - -#ifdef LWIP_ESP8266 - if( msg->conn->pcb.tcp->state == ESTABLISHED ) msg->err = ERR_ISCONN; - else - msg->err = ERR_ALREADY; -#else - msg->err = ERR_ISCONN; -#endif - } else { setup_tcp(msg->conn); msg->err = tcp_connect(msg->conn->pcb.tcp, API_EXPR_REF(msg->msg.bc.ipaddr), @@ -1646,14 +1633,7 @@ lwip_netconn_do_write(void *m) if (lwip_netconn_do_writemore(msg->conn, 0) != ERR_OK) { LWIP_ASSERT("state!", msg->conn->state == NETCONN_WRITE); UNLOCK_TCPIP_CORE(); - -#ifdef LWIP_ESP8266 -//#if 0 - sys_arch_sem_wait( LWIP_API_MSG_SND_SEM(msg), 0); -#else - sys_arch_sem_wait(LWIP_API_MSG_SEM(msg), 0); -#endif - + sys_arch_sem_wait(LWIP_API_MSG_SEM(msg), 0); LOCK_TCPIP_CORE(); LWIP_ASSERT("state!", msg->conn->state != NETCONN_WRITE); } diff --git a/components/lwip/api/netbuf.c b/components/lwip/api/netbuf.c index 6c6dc69ccd..9ab76a4638 100755 --- a/components/lwip/api/netbuf.c +++ b/components/lwip/api/netbuf.c @@ -45,11 +45,6 @@ #include -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; -#endif - - /** * Create (allocate) and initialize a new netbuf. * The netbuf doesn't yet contain a packet buffer! diff --git a/components/lwip/api/netdb.c b/components/lwip/api/netdb.c index 8fd3f41861..65510f55e9 100755 --- a/components/lwip/api/netdb.c +++ b/components/lwip/api/netdb.c @@ -47,11 +47,6 @@ #include #include -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; -#endif - - /** helper struct for gethostbyname_r to access the char* buffer */ struct gethostbyname_r_helper { ip_addr_t *addr_list[2]; diff --git a/components/lwip/api/sockets.c b/components/lwip/api/sockets.c index 1cc5fbf7b5..455d007ea7 100755 --- a/components/lwip/api/sockets.c +++ b/components/lwip/api/sockets.c @@ -61,11 +61,6 @@ #include -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; -#endif - - /* If the netconn API is not required publicly, then we include the necessary files here to get the implementation */ #if !LWIP_NETCONN @@ -216,7 +211,7 @@ struct lwip_sock { /** last error that occurred on this socket (in fact, all our errnos fit into an u8_t) */ u8_t err; -#if LWIP_THREAD_SAFE +#if ESP_THREAD_SAFE /* lock is used to protect state/ref field, however this lock is not a perfect lock, e.g * taskA and taskB can access sock X, then taskA freed sock X, before taskB detect * this, taskC reuse sock X, then when taskB try to access sock X, problem may happen. @@ -239,7 +234,7 @@ struct lwip_sock { SELWAIT_T select_waiting; }; -#if LWIP_THREAD_SAFE +#if ESP_THREAD_SAFE #define LWIP_SOCK_OPEN 0 #define LWIP_SOCK_CLOSING 1 @@ -247,25 +242,25 @@ struct lwip_sock { #define LWIP_SOCK_LOCK(sock) \ do{\ - /*LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("l\n"));*/\ + /*LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("l\n"));*/\ sys_mutex_lock(&sock->lock);\ - /*LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("l ok\n"));*/\ + /*LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("l ok\n"));*/\ }while(0) #define LWIP_SOCK_UNLOCK(sock) \ do{\ sys_mutex_unlock(&sock->lock);\ - /*LWIP_DEBUGF(THREAD_SAFE_DEBUG1, ("unl\n"));*/\ + /*LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG1, ("unl\n"));*/\ }while(0) #define LWIP_FREE_SOCK(sock) \ do{\ if(sock->conn && NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP){\ - LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("LWIP_FREE_SOCK:free tcp sock\n"));\ + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("LWIP_FREE_SOCK:free tcp sock\n"));\ free_socket(sock, 1);\ } else {\ - LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("LWIP_FREE_SOCK:free non-tcp sock\n"));\ + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("LWIP_FREE_SOCK:free non-tcp sock\n"));\ free_socket(sock, 0);\ }\ }while(0) @@ -273,7 +268,7 @@ do{\ #define LWIP_SET_CLOSE_FLAG() \ do{\ LWIP_SOCK_LOCK(__sock);\ - LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("mark sock closing\n"));\ + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("mark sock closing\n"));\ __sock->state = LWIP_SOCK_CLOSING;\ LWIP_SOCK_UNLOCK(__sock);\ }while(0) @@ -291,7 +286,7 @@ do{\ LWIP_SOCK_LOCK(__sock);\ __sock->ref ++;\ if (__sock->state != LWIP_SOCK_OPEN) {\ - LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("LWIP_API_LOCK:soc is %d, return\n", __sock->state));\ + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("LWIP_API_LOCK:soc is %d, return\n", __sock->state));\ __sock->ref --;\ LWIP_SOCK_UNLOCK(__sock);\ return -1;\ @@ -306,12 +301,12 @@ do{\ __sock->ref --;\ if (__sock->state == LWIP_SOCK_CLOSING) {\ if (__sock->ref == 0){\ - LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("LWIP_API_UNLOCK:ref 0, free __sock\n"));\ + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("LWIP_API_UNLOCK:ref 0, free __sock\n"));\ LWIP_FREE_SOCK(__sock);\ LWIP_SOCK_UNLOCK(__sock);\ return __ret;\ }\ - LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("LWIP_API_UNLOCK: soc state is closing, return\n"));\ + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("LWIP_API_UNLOCK: soc state is closing, return\n"));\ LWIP_SOCK_UNLOCK(__sock);\ return __ret;\ }\ @@ -387,7 +382,7 @@ static void lwip_socket_unregister_membership(int s, const ip4_addr_t *if_addr, static void lwip_socket_drop_registered_memberships(int s); #endif /* LWIP_IGMP */ -#ifdef LWIP_ESP8266 +#if ESP_LWIP #include "esp_wifi_internal.h" #include "esp_system.h" @@ -414,7 +409,7 @@ static inline void esp32_tx_flow_ctrl(void) /** The global array of available sockets */ static struct lwip_sock sockets[NUM_SOCKETS]; -#if LWIP_THREAD_SAFE +#if ESP_THREAD_SAFE static bool sockets_init_flag = false; #endif /** The global list of tasks waiting for select */ @@ -425,13 +420,7 @@ static volatile int select_cb_ctr; /** Table to quickly map an lwIP error (err_t) to a socket error * by using -err as an index */ -#ifdef LWIP_ESP8266 -//TO_DO -//static const int err_to_errno_table[] ICACHE_RODATA_ATTR STORE_ATTR = { static const int err_to_errno_table[] = { -#else -static const int err_to_errno_table[] = { -#endif 0, /* ERR_OK 0 No error, everything OK. */ ENOMEM, /* ERR_MEM -1 Out of memory error. */ ENOBUFS, /* ERR_BUF -2 Buffer error. */ @@ -442,7 +431,7 @@ static const int err_to_errno_table[] = { EWOULDBLOCK, /* ERR_WOULDBLOCK -7 Operation would block. */ EADDRINUSE, /* ERR_USE -8 Address in use. */ -#ifdef LWIP_ESP8266 +#if ESP_LWIP EALREADY, /* ERR_ALREADY -9 Already connected. */ EISCONN, /* ERR_ISCONN -10 Conn already established */ ECONNABORTED, /* ERR_ABRT -11 Connection aborted. */ @@ -583,7 +572,7 @@ alloc_socket(struct netconn *newconn, int accepted) int i; SYS_ARCH_DECL_PROTECT(lev); -#if LWIP_THREAD_SAFE +#if ESP_THREAD_SAFE bool found = false; int oldest = -1; @@ -639,16 +628,16 @@ alloc_socket(struct netconn *newconn, int accepted) if (!sockets[oldest].lock){ /* one time init and never free */ if (sys_mutex_new(&sockets[oldest].lock) != ERR_OK){ - LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("new sock lock fail\n")); + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("new sock lock fail\n")); return -1; } } - LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("alloc_socket: alloc %d ok\n", oldest)); + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("alloc_socket: alloc %d ok\n", oldest)); return oldest + LWIP_SOCKET_OFFSET; } - LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("alloc_socket: failed\n")); + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("alloc_socket: failed\n")); #else @@ -693,12 +682,12 @@ free_socket(struct lwip_sock *sock, int is_tcp) void *lastdata; SYS_ARCH_DECL_PROTECT(lev); - LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("free_sockset:free socket s=%p is_tcp=%d\n", sock, is_tcp)); + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("free_sockset:free socket s=%p is_tcp=%d\n", sock, is_tcp)); lastdata = sock->lastdata; sock->lastdata = NULL; sock->lastoffset = 0; sock->err = 0; -#if LWIP_THREAD_SAFE +#if ESP_THREAD_SAFE if (sock->conn){ netconn_free(sock->conn); } @@ -716,10 +705,10 @@ free_socket(struct lwip_sock *sock, int is_tcp) if (lastdata != NULL) { if (is_tcp) { - LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("free_sockset:free lastdata pbuf=%p\n", lastdata)); + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("free_sockset:free lastdata pbuf=%p\n", lastdata)); pbuf_free((struct pbuf *)lastdata); } else { - LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("free_sockset:free lastdata, netbuf=%p\n", lastdata)); + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("free_sockset:free lastdata, netbuf=%p\n", lastdata)); netbuf_delete((struct netbuf *)lastdata); } } @@ -872,19 +861,19 @@ lwip_close(int s) int is_tcp = 0; err_t err; - LWIP_DEBUGF(SOCKETS_DEBUG|THREAD_SAFE_DEBUG, ("lwip_close: (%d)\n", s)); + LWIP_DEBUGF(SOCKETS_DEBUG|ESP_THREAD_SAFE_DEBUG, ("lwip_close: (%d)\n", s)); sock = get_socket(s); if (!sock) { - LWIP_DEBUGF(SOCKETS_DEBUG|THREAD_SAFE_DEBUG, ("lwip_close: sock is null, return -1\n")); + LWIP_DEBUGF(SOCKETS_DEBUG|ESP_THREAD_SAFE_DEBUG, ("lwip_close: sock is null, return -1\n")); return -1; } if (sock->conn != NULL) { is_tcp = NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP; - LWIP_DEBUGF(SOCKETS_DEBUG|THREAD_SAFE_DEBUG, ("lwip_close: is_tcp=%d\n", is_tcp)); + LWIP_DEBUGF(SOCKETS_DEBUG|ESP_THREAD_SAFE_DEBUG, ("lwip_close: is_tcp=%d\n", is_tcp)); } else { - LWIP_DEBUGF(SOCKETS_DEBUG|THREAD_SAFE_DEBUG, ("conn is null\n")); + LWIP_DEBUGF(SOCKETS_DEBUG|ESP_THREAD_SAFE_DEBUG, ("conn is null\n")); LWIP_ASSERT("lwip_close: sock->lastdata == NULL", sock->lastdata == NULL); } @@ -895,12 +884,12 @@ lwip_close(int s) err = netconn_delete(sock->conn); if (err != ERR_OK) { - LWIP_DEBUGF(SOCKETS_DEBUG|THREAD_SAFE_DEBUG, ("netconn_delete fail, ret=%d\n", err)); + LWIP_DEBUGF(SOCKETS_DEBUG|ESP_THREAD_SAFE_DEBUG, ("netconn_delete fail, ret=%d\n", err)); sock_set_errno(sock, err_to_errno(err)); return -1; } -#if !LWIP_THREAD_SAFE +#if !ESP_THREAD_SAFE free_socket(sock, is_tcp); #endif @@ -1130,22 +1119,13 @@ lwip_recvfrom(int s, void *mem, size_t len, int flags, ip_addr_debug_print(SOCKETS_DEBUG, fromaddr); LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F" len=%d\n", port, off)); -#ifdef LWIP_ESP8266 if (from && fromlen) -#else - -#if SOCKETS_DEBUG - if (from && fromlen) -#endif /* SOCKETS_DEBUG */ - -#endif { if (*fromlen > saddr.sa.sa_len) { *fromlen = saddr.sa.sa_len; } MEMCPY(from, &saddr, *fromlen); - -#ifdef LWIP_ESP8266 +#if ESP_LWIP } else { /*fix the code for setting the UDP PROTO's remote infomation by liuh at 2014.8.27*/ if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_UDP){ @@ -1437,7 +1417,7 @@ lwip_sendto(int s, const void *data, size_t size, int flags, SOCKADDR_TO_IPADDR_PORT(to, &buf.addr, remote_port); } else { -#ifdef LWIP_ESP8266 +#if ESP_LWIP /*fix the code for getting the UDP proto's remote information by liuh at 2014.8.27*/ if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_UDP){ if(NETCONNTYPE_ISIPV6(netconn_type(sock->conn))) { @@ -1453,7 +1433,7 @@ lwip_sendto(int s, const void *data, size_t size, int flags, #endif remote_port = 0; ip_addr_set_any(NETCONNTYPE_ISIPV6(netconn_type(sock->conn)), &buf.addr); -#ifdef LWIP_ESP8266 +#if ESP_LWIP } #endif @@ -1986,7 +1966,7 @@ again: int lwip_shutdown(int s, int how) { -#ifndef LWIP_ESP8266 +#if ! ESP_LWIP struct lwip_sock *sock; err_t err; @@ -3126,7 +3106,7 @@ static void lwip_socket_drop_registered_memberships(int s) } #endif /* LWIP_IGMP */ -#if LWIP_THREAD_SAFE +#if ESP_THREAD_SAFE int lwip_sendto_r(int s, const void *data, size_t size, int flags, diff --git a/components/lwip/api/tcpip.c b/components/lwip/api/tcpip.c index 9df3c38a1d..0ad60721e4 100755 --- a/components/lwip/api/tcpip.c +++ b/components/lwip/api/tcpip.c @@ -50,18 +50,13 @@ #include "lwip/pbuf.h" #include "netif/etharp.h" -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; -#endif - - #define TCPIP_MSG_VAR_REF(name) API_VAR_REF(name) #define TCPIP_MSG_VAR_DECLARE(name) API_VAR_DECLARE(struct tcpip_msg, name) #define TCPIP_MSG_VAR_ALLOC(name) API_VAR_ALLOC(struct tcpip_msg, MEMP_TCPIP_MSG_API, name) #define TCPIP_MSG_VAR_FREE(name) API_VAR_FREE(MEMP_TCPIP_MSG_API, name) /* global variables */ -#ifdef PERF +#if ESP_PERF uint32_t g_rx_post_mbox_fail_cnt = 0; #endif static tcpip_init_done_fn tcpip_init_done; @@ -144,13 +139,11 @@ tcpip_thread(void *arg) case TCPIP_MSG_INPKT: LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: PACKET %p\n", (void *)msg)); -#ifdef LWIP_ESP8266 -//#if 0 +#if ESP_LWIP if(msg->msg.inp.p != NULL && msg->msg.inp.netif != NULL) { #endif msg->msg.inp.input_fn(msg->msg.inp.p, msg->msg.inp.netif); -#ifdef LWIP_ESP8266 -//#if 0 +#if ESP_LWIP } #endif @@ -230,7 +223,7 @@ tcpip_inpkt(struct pbuf *p, struct netif *inp, netif_input_fn input_fn) msg->msg.inp.netif = inp; msg->msg.inp.input_fn = input_fn; if (sys_mbox_trypost(&mbox, msg) != ERR_OK) { -#ifdef PERF +#if ESP_PERF g_rx_post_mbox_fail_cnt ++; #endif memp_free(MEMP_TCPIP_MSG_INPKT, msg); @@ -503,7 +496,7 @@ tcpip_init(tcpip_init_done_fn initfunc, void *arg) #endif /* LWIP_TCPIP_CORE_LOCKING */ -#ifdef LWIP_ESP8266 +#if ESP_LWIP sys_thread_t xLwipTaskHandle = sys_thread_new(TCPIP_THREAD_NAME , tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO); @@ -548,8 +541,7 @@ pbuf_free_callback(struct pbuf *p) * @return ERR_OK if callback could be enqueued, an err_t if not */ -#ifdef LWIP_ESP8266 -//#if 0 +#if ESP_LWIP static void mem_free_local(void *arg) { mem_free(arg); diff --git a/components/lwip/apps/dhcpserver.c b/components/lwip/apps/dhcpserver.c index 4cdef4123d..22443e8cde 100644 --- a/components/lwip/apps/dhcpserver.c +++ b/components/lwip/apps/dhcpserver.c @@ -24,7 +24,7 @@ #include "apps/dhcpserver.h" -#ifdef LWIP_ESP8266 +#if ESP_DHCP #define BOOTP_BROADCAST 0x8000 @@ -71,10 +71,6 @@ #define DHCPS_STATE_IDLE 5 #define DHCPS_STATE_RELEASE 6 -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; -#endif - //////////////////////////////////////////////////////////////////////////////////// static const u32_t magic_cookie = 0x63538263; diff --git a/components/lwip/core/dns.c b/components/lwip/core/dns.c index da8ac95b8d..8f0ac5cc81 100755 --- a/components/lwip/core/dns.c +++ b/components/lwip/core/dns.c @@ -85,10 +85,6 @@ #include -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; -#endif - /** Random generator function to create random TXIDs and source ports for queries */ #ifndef DNS_RAND_TXID #if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_XID) != 0) @@ -1091,7 +1087,7 @@ dns_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u8_t dns_err; /* This entry is now completed. */ -#ifndef LWIP_ESP8266 +#if ! ESP_DNS entry->state = DNS_STATE_DONE; #endif dns_err = hdr.flags2 & DNS_FLAG2_ERR_MASK; @@ -1105,7 +1101,7 @@ dns_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, if (((hdr.flags1 & DNS_FLAG1_RESPONSE) == 0) || (dns_err != 0) || (nquestions != 1)) { LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": error in flags\n", entry->name)); /* call callback to indicate error, clean up memory and return */ -#ifndef LWIP_ESP8266 +#if ! ESP_DNS goto responseerr; } #else diff --git a/components/lwip/core/init.c b/components/lwip/core/init.c index f974aedaf8..774e9a2beb 100755 --- a/components/lwip/core/init.c +++ b/components/lwip/core/init.c @@ -61,7 +61,7 @@ #include "lwip/api.h" #include "netif/ppp/ppp_impl.h" -#ifndef PERF +#if ! ESP_PERF /* Compile-time sanity checks for configuration errors. * These can be done independently of LWIP_DEBUG, without penalty. */ @@ -313,7 +313,7 @@ #error "lwip_sanity_check: WARNING: PBUF_POOL_BUFSIZE does not provide enough space for protocol headers. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." #endif -#ifndef LWIP_ESP8266 +#if ! ESP_LWIP #if !MEMP_MEM_MALLOC && (TCP_WND > (PBUF_POOL_SIZE * (PBUF_POOL_BUFSIZE - (PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN)))) #error "lwip_sanity_check: WARNING: TCP_WND is larger than space provided by PBUF_POOL_SIZE * (PBUF_POOL_BUFSIZE - protocol headers). If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." #endif diff --git a/components/lwip/core/ipv4/autoip.c b/components/lwip/core/ipv4/autoip.c index 391e8eeaed..19b1928368 100755 --- a/components/lwip/core/ipv4/autoip.c +++ b/components/lwip/core/ipv4/autoip.c @@ -76,11 +76,6 @@ #include #include -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; -#endif - - /* 169.254.0.0 */ #define AUTOIP_NET 0xA9FE0000 /* 169.254.1.0 */ diff --git a/components/lwip/core/ipv4/dhcp.c b/components/lwip/core/ipv4/dhcp.c index 1f3758fa91..33d13fb326 100755 --- a/components/lwip/core/ipv4/dhcp.c +++ b/components/lwip/core/ipv4/dhcp.c @@ -82,10 +82,6 @@ #include -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; -#endif - /** DHCP_CREATE_RAND_XID: if this is set to 1, the xid is created using * LWIP_RAND() (this overrides DHCP_GLOBAL_XID) */ @@ -146,7 +142,7 @@ static u8_t dhcp_discover_select_options[] = { DHCP_OPTION_BROADCAST, DHCP_OPTION_DNS_SERVER -#ifdef LWIP_ESP8266 +#if ESP_DHCP /**add options for support more router by liuHan**/ , DHCP_OPTION_DOMAIN_NAME, DHCP_OPTION_NB_TINS, @@ -454,7 +450,7 @@ dhcp_fine_tmr(void) /* only act on DHCP configured interfaces */ if (netif->dhcp != NULL) { -//#ifdef LWIP_ESP8266 +//#if ESP_DHCP /*add DHCP retries processing by LiuHan*/ #if 0 if (DHCP_MAXRTX != 0) { @@ -997,7 +993,7 @@ dhcp_discover(struct netif *netif) dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif)); -#ifdef LWIP_ESP8266 +#if ESP_DHCP #if LWIP_NETIF_HOSTNAME dhcp_option_hostname(dhcp, netif); #endif /* LWIP_NETIF_HOSTNAME */ diff --git a/components/lwip/core/ipv4/icmp.c b/components/lwip/core/ipv4/icmp.c index c492ed75fe..9202bb650c 100755 --- a/components/lwip/core/ipv4/icmp.c +++ b/components/lwip/core/ipv4/icmp.c @@ -51,11 +51,6 @@ #include -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; -#endif - - /** Small optimization: set to 0 if incoming PBUF_POOL pbuf always can be * used to modify and send a response packet (and to 1 if this is not the case, * e.g. when link header is stripped of when receiving) */ diff --git a/components/lwip/core/ipv4/igmp.c b/components/lwip/core/ipv4/igmp.c index d75fe15fd0..03f3ae384b 100755 --- a/components/lwip/core/ipv4/igmp.c +++ b/components/lwip/core/ipv4/igmp.c @@ -92,11 +92,6 @@ Steve Reynolds #include "string.h" -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; -#endif - - /* * IGMP constants */ diff --git a/components/lwip/core/ipv4/ip4.c b/components/lwip/core/ipv4/ip4.c index 5f1e77a5e7..1d581d4d85 100755 --- a/components/lwip/core/ipv4/ip4.c +++ b/components/lwip/core/ipv4/ip4.c @@ -59,11 +59,6 @@ #include -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; -#endif - - /** Set this to 0 in the rare case of wanting to call an extra function to * generate the IP checksum (in contrast to calculating it on-the-fly). */ #ifndef LWIP_INLINE_IP_CHKSUM @@ -150,7 +145,7 @@ ip4_route_src(const ip4_addr_t *dest, const ip4_addr_t *src) struct netif * ip4_route(const ip4_addr_t *dest) { -#ifdef LWIP_ESP8266 +#if ESP_LWIP struct netif *non_default_netif = NULL; #endif struct netif *netif; @@ -183,7 +178,7 @@ ip4_route(const ip4_addr_t *dest) } } -#ifdef LWIP_ESP8266 +#if ESP_LWIP if (non_default_netif && !ip4_addr_isbroadcast(dest, non_default_netif)){ return non_default_netif; } diff --git a/components/lwip/core/ipv4/ip4_addr.c b/components/lwip/core/ipv4/ip4_addr.c index 3053cf087e..0501b84e5f 100755 --- a/components/lwip/core/ipv4/ip4_addr.c +++ b/components/lwip/core/ipv4/ip4_addr.c @@ -45,17 +45,8 @@ /* used by IP_ADDR_ANY and IP_ADDR_BROADCAST in ip_addr.h */ -#ifdef LWIP_ESP8266 -//TO_DO -//const ip_addr_t ip_addr_any ICACHE_RODATA_ATTR STORE_ATTR = IPADDR4_INIT(IPADDR_ANY); -//const ip_addr_t ip_addr_broadcast ICACHE_RODATA_ATTR STORE_ATTR = IPADDR4_INIT(IPADDR_BROADCAST); const ip_addr_t ip_addr_any = IPADDR4_INIT(IPADDR_ANY); const ip_addr_t ip_addr_broadcast = IPADDR4_INIT(IPADDR_BROADCAST); -#else -const ip_addr_t ip_addr_any = IPADDR4_INIT(IPADDR_ANY); -const ip_addr_t ip_addr_broadcast = IPADDR4_INIT(IPADDR_BROADCAST); -#endif - /** * Determine if an address is a broadcast address on a network interface @@ -170,7 +161,7 @@ ip4addr_aton(const char *cp, ip4_addr_t *addr) u32_t parts[4]; u32_t *pp = parts; -#ifdef LWIP_ESP8266 +#if ESP_LWIP //#if 0 char ch; unsigned long cutoff; @@ -199,8 +190,7 @@ ip4addr_aton(const char *cp, ip4_addr_t *addr) } } -#ifdef LWIP_ESP8266 -//#if 0 +#if ESP_IP4_ATON cutoff =(unsigned long)0xffffffff / (unsigned long)base; cutlim =(unsigned long)0xffffffff % (unsigned long)base; for (;;) { diff --git a/components/lwip/core/ipv4/ip_frag.c b/components/lwip/core/ipv4/ip_frag.c index 1e6b053e6f..a647433506 100755 --- a/components/lwip/core/ipv4/ip_frag.c +++ b/components/lwip/core/ipv4/ip_frag.c @@ -51,11 +51,6 @@ #include -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; -#endif - - #if IP_REASSEMBLY /** * The IP reassembly code currently has the following limitations: diff --git a/components/lwip/core/ipv6/icmp6.c b/components/lwip/core/ipv6/icmp6.c index 0a17da33e1..013983bde1 100755 --- a/components/lwip/core/ipv6/icmp6.c +++ b/components/lwip/core/ipv6/icmp6.c @@ -56,10 +56,6 @@ #include -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; -#endif - #ifndef LWIP_ICMP6_DATASIZE #define LWIP_ICMP6_DATASIZE 8 #endif diff --git a/components/lwip/core/ipv6/ip6.c b/components/lwip/core/ipv6/ip6.c index 056d33355f..380bc290cd 100755 --- a/components/lwip/core/ipv6/ip6.c +++ b/components/lwip/core/ipv6/ip6.c @@ -59,10 +59,6 @@ #include "lwip/debug.h" #include "lwip/stats.h" -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; -#endif - /** * Finds the appropriate network interface for a given IPv6 address. It tries to select * a netif following a sequence of heuristics: diff --git a/components/lwip/core/ipv6/ip6_frag.c b/components/lwip/core/ipv6/ip6_frag.c index 0792c2e1be..c9e13cd208 100755 --- a/components/lwip/core/ipv6/ip6_frag.c +++ b/components/lwip/core/ipv6/ip6_frag.c @@ -52,11 +52,6 @@ #include -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; -#endif - - #if LWIP_IPV6 && LWIP_IPV6_REASS /* don't build if not configured for use in lwipopts.h */ diff --git a/components/lwip/core/ipv6/mld6.c b/components/lwip/core/ipv6/mld6.c index 6a2d55c549..489c5063a7 100755 --- a/components/lwip/core/ipv6/mld6.c +++ b/components/lwip/core/ipv6/mld6.c @@ -59,11 +59,6 @@ #include -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; -#endif - - /* * MLD constants */ diff --git a/components/lwip/core/ipv6/nd6.c b/components/lwip/core/ipv6/nd6.c index 39e7bfed03..36f8f78c35 100755 --- a/components/lwip/core/ipv6/nd6.c +++ b/components/lwip/core/ipv6/nd6.c @@ -60,11 +60,6 @@ #include -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; -#endif - - /* Router tables. */ struct nd6_neighbor_cache_entry neighbor_cache[LWIP_ND6_NUM_NEIGHBORS]; struct nd6_destination_cache_entry destination_cache[LWIP_ND6_NUM_DESTINATIONS]; diff --git a/components/lwip/core/mem.c b/components/lwip/core/mem.c index 42df6daeba..9ca9e3c4fc 100755 --- a/components/lwip/core/mem.c +++ b/components/lwip/core/mem.c @@ -65,10 +65,6 @@ #include -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; -#endif - #if MEM_USE_POOLS #if MEMP_MEM_MALLOC diff --git a/components/lwip/core/memp.c b/components/lwip/core/memp.c index a5169abc81..7895533652 100755 --- a/components/lwip/core/memp.c +++ b/components/lwip/core/memp.c @@ -70,10 +70,6 @@ #include -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; -#endif - #define LWIP_MEMPOOL(name,num,size,desc) LWIP_MEMPOOL_DECLARE(name,num,size,desc) #include "lwip/priv/memp_std.h" diff --git a/components/lwip/core/netif.c b/components/lwip/core/netif.c index 33e030412a..5c308a957c 100755 --- a/components/lwip/core/netif.c +++ b/components/lwip/core/netif.c @@ -81,10 +81,6 @@ #define NETIF_LINK_CALLBACK(n) #endif /* LWIP_NETIF_LINK_CALLBACK */ -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; -#endif - struct netif *netif_list; struct netif *netif_default; @@ -220,7 +216,7 @@ netif_add(struct netif *netif, /* netif not under DHCP control by default */ netif->dhcp = NULL; -#ifdef LWIP_ESP8266 +#if ESP_DHCP netif->dhcps_pcb = NULL; #endif @@ -233,8 +229,7 @@ netif_add(struct netif *netif, #endif /* LWIP_AUTOIP */ #if LWIP_IPV6_AUTOCONFIG -#ifdef LWIP_ESP8266 -//#if 0 +#if ESP_IPV6_AUTOCONFIG netif->ip6_autoconfig_enabled = 1; #else /* IPv6 address autoconfiguration not enabled by default */ @@ -973,7 +968,7 @@ netif_create_ip6_linklocal_address(struct netif *netif, u8_t from_mac_48bit) } } -#ifdef LWIP_ESP8266 +#if ESP_LWIP ip6_addr_set( ip_2_ip6(&netif->link_local_addr), ip_2_ip6(&netif->ip6_addr[0]) ); #endif @@ -1028,7 +1023,7 @@ netif_add_ip6_address(struct netif *netif, const ip6_addr_t *ip6addr, s8_t *chos } -#ifdef LWIP_ESP8266 +#if ESP_LWIP void netif_create_ip4_linklocal_address(struct netif * netif) { diff --git a/components/lwip/core/pbuf.c b/components/lwip/core/pbuf.c index 044d765cdb..29e24ef2b4 100755 --- a/components/lwip/core/pbuf.c +++ b/components/lwip/core/pbuf.c @@ -78,13 +78,8 @@ #include -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; -#endif - -#ifdef LWIP_ESP8266 +#if ESP_LWIP #include "esp_wifi_internal.h" -#define EP_OFFSET 0 #endif #define SIZEOF_STRUCT_PBUF LWIP_MEM_ALIGN_SIZE(sizeof(struct pbuf)) @@ -208,12 +203,7 @@ struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type) { struct pbuf *p, *q, *r; - -#ifdef LWIP_ESP8266 - u16_t offset = 0; -#else - u16_t offset; -#endif + u16_t offset = 0; s32_t rem_len; /* remaining length */ LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc(length=%"U16_F")\n", length)); @@ -224,48 +214,16 @@ pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type) /* add room for transport (often TCP) layer header */ offset = PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN; -#ifdef LWIP_ESP8266 //TO_DO - offset += EP_OFFSET; -#endif - break; case PBUF_IP: /* add room for IP layer header */ offset = PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN; -#ifdef LWIP_ESP8266 //TO_DO - offset += EP_OFFSET; -#endif - break; case PBUF_LINK: /* add room for link layer header */ offset = PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN; -#ifdef LWIP_ESP8266 //TO_DO - /* - * 1. LINK_HLEN 14Byte will be remove in WLAN layer - * 2. IEEE80211_HDR_MAX_LEN needs 40 bytes. - * 3. encryption needs exra 4 bytes ahead of actual data payload, and require - * DAddr and SAddr to be 4-byte aligned. - * 4. TRANSPORT and IP are all 20, 4 bytes aligned, nice... - * 5. LCC add 6 bytes more, We don't consider WAPI yet... - * 6. define LWIP_MEM_ALIGN to be 4 Byte aligned, pbuf struct is 16B, Only thing may be - * matter is ether_hdr is not 4B aligned. - * - * So, we need extra (40 + 4 - 14) = 30 and it's happen to be 4-Byte aligned - * - * 1. lwip - * | empty 30B | eth_hdr (14B) | payload ...| - * total: 44B ahead payload - * 2. net80211 - * | max 80211 hdr, 32B | ccmp/tkip iv (8B) | sec rsv(4B) | payload ...| - * total: 40B ahead sec_rsv and 44B ahead payload - * - */ - offset += EP_OFFSET; //remove LINK hdr in wlan -#endif - break; case PBUF_RAW_TX: /* add room for encapsulating link layer headers (e.g. 802.11) */ @@ -274,10 +232,6 @@ pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type) case PBUF_RAW: offset = 0; -#ifdef LWIP_ESP8266 //TO_DO - offset += EP_OFFSET; -#endif - break; default: LWIP_ASSERT("pbuf_alloc: bad pbuf layer", 0); @@ -396,9 +350,10 @@ pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type) /* set flags */ p->flags = 0; -#ifdef LWIP_ESP8266 +#if ESP_LWIP p->eb = NULL; #endif + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc(length=%"U16_F") == %p\n", length, (void *)p)); return p; } @@ -764,7 +719,7 @@ pbuf_free(struct pbuf *p) /* is this a ROM or RAM referencing pbuf? */ } else if (type == PBUF_ROM || type == PBUF_REF) { -#ifdef LWIP_ESP8266 +#if ESP_LWIP if (type == PBUF_REF && p->eb != NULL ) esp_wifi_internal_free_rx_buffer(p->eb); #endif diff --git a/components/lwip/core/raw.c b/components/lwip/core/raw.c index 72a58d381d..82ce4e3a73 100755 --- a/components/lwip/core/raw.c +++ b/components/lwip/core/raw.c @@ -54,10 +54,6 @@ #include -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; -#endif - /** The list of RAW PCBs */ static struct raw_pcb *raw_pcbs; diff --git a/components/lwip/core/stats.c b/components/lwip/core/stats.c index 77ac3c675e..b47ab0b7fa 100755 --- a/components/lwip/core/stats.c +++ b/components/lwip/core/stats.c @@ -47,10 +47,6 @@ #include -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; -#endif - struct stats_ lwip_stats; #if defined(LWIP_DEBUG) || LWIP_STATS_DISPLAY diff --git a/components/lwip/core/tcp.c b/components/lwip/core/tcp.c index e7ea561031..87ddf5f1a7 100755 --- a/components/lwip/core/tcp.c +++ b/components/lwip/core/tcp.c @@ -57,10 +57,6 @@ #include -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; -#endif - #ifndef TCP_LOCAL_PORT_RANGE_START /* From http://www.iana.org/assignments/port-numbers: "The Dynamic and/or Private Ports are those from 49152 through 65535" */ @@ -77,14 +73,7 @@ static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; #define TCP_KEEP_INTVL(pcb) TCP_KEEPINTVL_DEFAULT #endif /* LWIP_TCP_KEEPALIVE */ -#ifdef LWIP_ESP8266 -//TO_DO -//char tcp_state_str[12]; -//const char tcp_state_str_rodata[][12] ICACHE_RODATA_ATTR STORE_ATTR = { const char * const tcp_state_str[] = { -#else -const char * const tcp_state_str[] = { -#endif "CLOSED", "LISTEN", "SYN_SENT", @@ -100,27 +89,14 @@ const char * const tcp_state_str[] = { /* last local TCP port */ -#ifdef LWIP_ESP8266 static s16_t tcp_port = TCP_LOCAL_PORT_RANGE_START; -#else -static u16_t tcp_port = TCP_LOCAL_PORT_RANGE_START; -#endif /* Incremented every coarse grained timer shot (typically every 500 ms). */ u32_t tcp_ticks; -#ifdef LWIP_ESP8266 -//TO_DO -//const u8_t tcp_backoff[13] ICACHE_RODATA_ATTR STORE_ATTR ={ 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7}; -//const u8_t tcp_persist_backoff[7] ICACHE_RODATA_ATTR STORE_ATTR = { 3, 6, 12, 24, 48, 96, 120 }; - -const u8_t tcp_backoff[13] = { 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7}; -const u8_t tcp_persist_backoff[7] = { 3, 6, 12, 24, 48, 96, 120 }; -#else const u8_t tcp_backoff[13] = { 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7}; /* Times per slowtmr hits */ const u8_t tcp_persist_backoff[7] = { 3, 6, 12, 24, 48, 96, 120 }; -#endif /* The TCP PCB lists. */ @@ -136,19 +112,9 @@ struct tcp_pcb *tcp_active_pcbs; struct tcp_pcb *tcp_tw_pcbs; /** An array with all (non-temporary) PCB lists, mainly used for smaller code size */ -#ifdef LWIP_ESP8266 -//TO_DO -//struct tcp_pcb ** const tcp_pcb_lists[] ICACHE_RODATA_ATTR STORE_ATTR = {&tcp_listen_pcbs.pcbs, &tcp_bound_pcbs, - // &tcp_active_pcbs, &tcp_tw_pcbs}; struct tcp_pcb ** const tcp_pcb_lists[] = {&tcp_listen_pcbs.pcbs, &tcp_bound_pcbs, &tcp_active_pcbs, &tcp_tw_pcbs}; -#else -struct tcp_pcb ** const tcp_pcb_lists[] = {&tcp_listen_pcbs.pcbs, &tcp_bound_pcbs, - &tcp_active_pcbs, &tcp_tw_pcbs}; -#endif - - u8_t tcp_active_pcbs_changed; /** Timer counter to handle calling slow-timer from tcp_tmr() */ @@ -720,7 +686,7 @@ tcp_new_port(void) again: -#ifdef LWIP_ESP8266 +#if ESP_RANDOM_TCP_PORT tcp_port = system_get_time(); if (tcp_port < 0) tcp_port = LWIP_RAND() - tcp_port; @@ -915,13 +881,7 @@ tcp_slowtmr_start: /* If snd_wnd is zero, use persist timer to send 1 byte probes * instead of using the standard retransmission mechanism. */ -#ifdef LWIP_ESP8266 -//NEED TO DO - //u8_t backoff_cnt = system_get_data_of_array_8(tcp_persist_backoff, pcb->persist_backoff-1); u8_t backoff_cnt = tcp_persist_backoff[pcb->persist_backoff-1]; -#else - u8_t backoff_cnt = tcp_persist_backoff[pcb->persist_backoff-1]; -#endif if (pcb->persist_cnt < backoff_cnt) { pcb->persist_cnt++; @@ -949,15 +909,7 @@ tcp_slowtmr_start: /* Double retransmission time-out unless we are trying to * connect to somebody (i.e., we are in SYN_SENT). */ if (pcb->state != SYN_SENT) { - -#ifdef LWIP_ESP8266 -//TO_DO -// pcb->rto = ((pcb->sa >> 3) + pcb->sv) << system_get_data_of_array_8(tcp_backoff, pcb->nrtx); pcb->rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[pcb->nrtx]; -#else - pcb->rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[pcb->nrtx]; -#endif - } /* Reset the retransmission timer. */ @@ -1436,7 +1388,7 @@ tcp_kill_timewait(void) } } -#ifdef LWIP_ESP8266 +#if ESP_LWIP /** * Kills the oldest connection that is in FIN_WAIT_2 state. * Called from tcp_alloc() if no more connections are available. @@ -1502,7 +1454,7 @@ tcp_alloc(u8_t prio) struct tcp_pcb *pcb; u32_t iss; -#ifdef LWIP_ESP8266 +#if ESP_LWIP /*Kills the oldest connection that is in TIME_WAIT state.*/ u8_t time_wait_num = 0; for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { @@ -2015,14 +1967,7 @@ void tcp_netif_ipv4_addr_changed(const ip4_addr_t* old_addr, const ip4_addr_t* n const char* tcp_debug_state_str(enum tcp_state s) { -#ifdef LWIP_ESP8266 -//TO_DO - //system_get_string_from_flash(tcp_state_str_rodata[s], tcp_state_str, 12); - //return tcp_state_str; return tcp_state_str[s]; -#else - return tcp_state_str[s]; -#endif } #if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG diff --git a/components/lwip/core/tcp_in.c b/components/lwip/core/tcp_in.c index 90ebf17232..f3284233e7 100755 --- a/components/lwip/core/tcp_in.c +++ b/components/lwip/core/tcp_in.c @@ -60,11 +60,6 @@ #include "lwip/nd6.h" #endif /* LWIP_ND6_TCP_REACHABILITY_HINTS */ -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; -#endif - - /** Initial CWND calculation as defined RFC 2581 */ #define LWIP_TCP_CALC_INITIAL_CWND(mss) LWIP_MIN((4U * (mss)), LWIP_MAX((2U * (mss)), 4380U)); /** Initial slow start threshold value: we use the full window */ @@ -329,20 +324,6 @@ tcp_input(struct pbuf *p, struct netif *inp) if (pcb != NULL) { - -#ifdef LWIP_ESP8266 -//No Need Any more -/* - extern char RxNodeNum(void); - if(RxNodeNum() <= 2) - { -extern void pbuf_free_ooseq(void); - pbuf_free_ooseq(); - } -*/ -#endif - - /* The incoming segment belongs to a connection. */ #if TCP_INPUT_DEBUG tcp_debug_print_state(pcb->state); diff --git a/components/lwip/core/tcp_out.c b/components/lwip/core/tcp_out.c index 5f10befae8..f189623f5c 100755 --- a/components/lwip/core/tcp_out.c +++ b/components/lwip/core/tcp_out.c @@ -59,10 +59,6 @@ #include -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; -#endif - /* Define some copy-macros for checksum-on-copy so that the code looks nicer by preventing too many ifdef's. */ #if TCP_CHECKSUM_ON_COPY diff --git a/components/lwip/core/timers.c b/components/lwip/core/timers.c index 0a361474eb..ef47b2e187 100755 --- a/components/lwip/core/timers.c +++ b/components/lwip/core/timers.c @@ -62,11 +62,6 @@ #include "lwip/sys.h" #include "lwip/pbuf.h" -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; -#endif - - /** The one and only timeout list */ static struct sys_timeo *next_timeout; #if NO_SYS @@ -162,7 +157,7 @@ dhcp_timer_coarse(void *arg) LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: dhcp_coarse_tmr()\n")); dhcp_coarse_tmr(); -#ifdef LWIP_ESP8266 +#if ESP_DHCP extern void dhcps_coarse_tmr(void); dhcps_coarse_tmr(); #endif @@ -294,12 +289,6 @@ void sys_timeouts_init(void) #endif /* LWIP_ARP */ #if LWIP_DHCP -#ifdef LWIP_ESP8266 - // DHCP_MAXRTX = 0; -#endif - - - sys_timeout(DHCP_COARSE_TIMER_MSECS, dhcp_timer_coarse, NULL); sys_timeout(DHCP_FINE_TIMER_MSECS, dhcp_timer_fine, NULL); #endif /* LWIP_DHCP */ @@ -346,7 +335,7 @@ void sys_timeout_debug(u32_t msecs, sys_timeout_handler handler, void *arg, const char* handler_name) #else /* LWIP_DEBUG_TIMERNAMES */ -#ifdef LWIP_ESP8266 +#if ESP_LIGHT_SLEEP u32_t LwipTimOutLim = 0; // For light sleep. time out. limit is 3000ms #endif @@ -379,7 +368,7 @@ sys_timeout(u32_t msecs, sys_timeout_handler handler, void *arg) timeout->h = handler; timeout->arg = arg; -#ifdef LWIP_ESP8266 +#if ESP_LIGHT_SLEEP if(msecs < LwipTimOutLim) msecs = LwipTimOutLim; #endif diff --git a/components/lwip/core/udp.c b/components/lwip/core/udp.c index e44ab7e73d..37ae2c1796 100755 --- a/components/lwip/core/udp.c +++ b/components/lwip/core/udp.c @@ -67,11 +67,6 @@ #include -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; -#endif - - #ifndef UDP_LOCAL_PORT_RANGE_START /* From http://www.iana.org/assignments/port-numbers: "The Dynamic and/or Private Ports are those from 49152 through 65535" */ diff --git a/components/lwip/include/lwip/lwip/api.h b/components/lwip/include/lwip/lwip/api.h index 985eb76d4a..5b6a21ecf3 100755 --- a/components/lwip/include/lwip/lwip/api.h +++ b/components/lwip/include/lwip/lwip/api.h @@ -185,10 +185,6 @@ struct netconn { /** sem that is used to synchronously execute functions in the core context */ sys_sem_t op_completed; -#ifdef LWIP_ESP8266 - sys_sem_t snd_op_completed; //only for snd semphore -#endif - #endif /** mbox where received packets are stored until they are fetched diff --git a/components/lwip/include/lwip/lwip/dhcp.h b/components/lwip/include/lwip/lwip/dhcp.h index 2d8926eca6..76ce1543ff 100755 --- a/components/lwip/include/lwip/lwip/dhcp.h +++ b/components/lwip/include/lwip/lwip/dhcp.h @@ -249,7 +249,7 @@ void dhcp_fine_tmr(void); #define DHCP_OPTION_NTP 42 #define DHCP_OPTION_END 255 -#ifdef LWIP_ESP8266 +#if ESP_LWIP /**add options for support more router by liuHan**/ #define DHCP_OPTION_DOMAIN_NAME 15 #define DHCP_OPTION_PRD 31 diff --git a/components/lwip/include/lwip/lwip/dns.h b/components/lwip/include/lwip/lwip/dns.h index 1ceed0d883..5ef12e56c2 100755 --- a/components/lwip/include/lwip/lwip/dns.h +++ b/components/lwip/include/lwip/lwip/dns.h @@ -36,7 +36,7 @@ #include "lwip/opt.h" -#ifdef LWIP_ESP8266 +#if ESP_DNS #include "lwip/err.h" #endif diff --git a/components/lwip/include/lwip/lwip/err.h b/components/lwip/include/lwip/lwip/err.h index 26fb91db9b..a766ee186d 100755 --- a/components/lwip/include/lwip/lwip/err.h +++ b/components/lwip/include/lwip/lwip/err.h @@ -60,7 +60,7 @@ typedef s8_t err_t; #define ERR_USE -8 /* Address in use. */ -#ifdef LWIP_ESP8266 +#if ESP_LWIP #define ERR_ALREADY -9 /* Already connected. */ #define ERR_ISCONN -10 /* Conn already established.*/ #define ERR_IS_FATAL(e) ((e) < ERR_ISCONN) diff --git a/components/lwip/include/lwip/lwip/mem.h b/components/lwip/include/lwip/lwip/mem.h index ca76f66322..a90d07256b 100755 --- a/components/lwip/include/lwip/lwip/mem.h +++ b/components/lwip/include/lwip/lwip/mem.h @@ -51,8 +51,6 @@ typedef size_t mem_size_t; * allow these defines to be overridden. */ -#ifndef MEMLEAK_DEBUG - #ifndef mem_free #define mem_free free #endif @@ -63,41 +61,6 @@ typedef size_t mem_size_t; #define mem_calloc calloc #endif -/* DYC_NEED_TO_DO_LATER -#ifndef mem_realloc -#define mem_realloc -#endif -#ifndef mem_zalloc -#define mem_zalloc -#endif -*/ - -#else -/* -#ifndef mem_free -#define mem_free(s) \ - do{\ - const char *file = mem_debug_file;\ - vPortFree(s, file, __LINE__);\ - }while(0) -#endif -#ifndef mem_malloc -#define mem_malloc(s) ({const char *file = mem_debug_file; pvPortMalloc(s, file, __LINE__);}) -#endif -#ifndef mem_calloc -#define mem_calloc(s) ({const char *file = mem_debug_file; pvPortCalloc(s, file, __LINE__);}) -#endif -#ifndef mem_realloc -#define mem_realloc(p, s) ({const char *file = mem_debug_file; pvPortRealloc(p, s, file, __LINE__);}) -#endif -#ifndef mem_zalloc -#define mem_zalloc(s) ({const char *file = mem_debug_file; pvPortZalloc(s, file, __LINE__);}) -#endif -*/ -#endif - - - /* Since there is no C library allocation function to shrink memory without moving it, define this to nothing. */ #ifndef mem_trim diff --git a/components/lwip/include/lwip/lwip/netif.h b/components/lwip/include/lwip/lwip/netif.h index 99066a5a1f..666f77eb96 100755 --- a/components/lwip/include/lwip/lwip/netif.h +++ b/components/lwip/include/lwip/lwip/netif.h @@ -177,7 +177,7 @@ typedef err_t (*netif_mld_mac_filter_fn)(struct netif *netif, #endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ -#ifdef LWIP_ESP8266 +#if ESP_DHCP /*add DHCP event processing by LiuHan*/ typedef void (*dhcp_event_fn)(void); #endif @@ -190,7 +190,7 @@ struct netif { /** pointer to next in linked list */ struct netif *next; -#ifdef LWIP_ESP8266 +#if ESP_LWIP //ip_addr_t is changed by marco IPV4, IPV6 ip_addr_t link_local_addr; #endif @@ -248,7 +248,7 @@ struct netif { /** the DHCP client state information for this netif */ struct dhcp *dhcp; -#ifdef LWIP_ESP8266 +#if ESP_LWIP struct udp_pcb *dhcps_pcb; dhcp_event_fn dhcp_event; #endif diff --git a/components/lwip/include/lwip/lwip/opt.h b/components/lwip/include/lwip/lwip/opt.h index c286712e0d..51d340e00b 100755 --- a/components/lwip/include/lwip/lwip/opt.h +++ b/components/lwip/include/lwip/lwip/opt.h @@ -3008,8 +3008,8 @@ #define LWIP_PERF 0 #endif -#ifndef THREAD_SAFE_DEBUG -#define THREAD_SAFE_DEBUG 0 +#ifndef ESP_THREAD_SAFE_DEBUG +#define ESP_THREAD_SAFE_DEBUG 0 #endif #endif /* LWIP_HDR_OPT_H */ diff --git a/components/lwip/include/lwip/lwip/pbuf.h b/components/lwip/include/lwip/lwip/pbuf.h index aaf5e294af..1834c4e04c 100755 --- a/components/lwip/include/lwip/lwip/pbuf.h +++ b/components/lwip/include/lwip/lwip/pbuf.h @@ -137,7 +137,7 @@ struct pbuf { */ u16_t ref; -#ifdef LWIP_ESP8266 +#if ESP_LWIP void *eb; #endif }; diff --git a/components/lwip/include/lwip/lwip/priv/api_msg.h b/components/lwip/include/lwip/lwip/priv/api_msg.h index 329fa0de30..02d191a53c 100755 --- a/components/lwip/include/lwip/lwip/priv/api_msg.h +++ b/components/lwip/include/lwip/lwip/priv/api_msg.h @@ -187,7 +187,7 @@ struct dns_api_msg { #endif /* LWIP_DNS */ #if LWIP_NETCONN_SEM_PER_THREAD -#ifdef LWIP_ESP8266 +#if ESP_THREAD_SAFE #define LWIP_NETCONN_THREAD_SEM_GET() sys_thread_sem_get() #define LWIP_NETCONN_THREAD_SEM_ALLOC() sys_thread_sem_init() #define LWIP_NETCONN_THREAD_SEM_FREE() sys_thread_sem_deinit() @@ -222,10 +222,6 @@ struct dns_api_msg { #define TCPIP_APIMSG(m,f,e) do { (m)->function = f; (e) = tcpip_apimsg(m); } while(0) #define TCPIP_APIMSG_ACK(m) do { NETCONN_SET_SAFE_ERR((m)->conn, (m)->err); sys_sem_signal(LWIP_API_MSG_SEM(m)); } while(0) -#ifdef LWIP_ESP8266 -#define TCPIP_APIMSG_ACK_SND(m) do { NETCONN_SET_SAFE_ERR((m)->conn, (m)->err); sys_sem_signal(LWIP_API_MSG_SND_SEM(m)); } while(0) -#endif - #endif /* LWIP_TCPIP_CORE_LOCKING */ void lwip_netconn_do_newconn (void *m); diff --git a/components/lwip/include/lwip/lwip/sockets.h b/components/lwip/include/lwip/lwip/sockets.h index fc2b7e2d12..d9622ea03d 100755 --- a/components/lwip/include/lwip/lwip/sockets.h +++ b/components/lwip/include/lwip/lwip/sockets.h @@ -509,7 +509,7 @@ int lwip_fcntl(int s, int cmd, int val); #if LWIP_COMPAT_SOCKETS #if LWIP_COMPAT_SOCKETS != 2 -#if LWIP_THREAD_SAFE +#if ESP_THREAD_SAFE int lwip_accept_r(int s, struct sockaddr *addr, socklen_t *addrlen); int lwip_bind_r(int s, const struct sockaddr *name, socklen_t namelen); @@ -594,7 +594,7 @@ int lwip_fcntl_r(int s, int cmd, int val); #define fcntl(s,cmd,val) lwip_fcntl(s,cmd,val) #define ioctl(s,cmd,argp) lwip_ioctl(s,cmd,argp) #endif /* LWIP_POSIX_SOCKETS_IO_NAMES */ -#endif /* LWIP_THREAD_SAFE */ +#endif /* ESP_THREAD_SAFE */ #endif /* LWIP_COMPAT_SOCKETS != 2 */ diff --git a/components/lwip/include/lwip/port/lwipopts.h b/components/lwip/include/lwip/port/lwipopts.h index 5667e2d20b..75f349280a 100755 --- a/components/lwip/include/lwip/port/lwipopts.h +++ b/components/lwip/include/lwip/port/lwipopts.h @@ -37,7 +37,6 @@ #include "sdkconfig.h" /* Enable all Espressif-only options */ -#define LWIP_ESP8266 /* ----------------------------------------------- @@ -510,14 +509,42 @@ extern unsigned char misc_prof_get_tcp_snd_buf(void); */ #define TCPIP_DEBUG LWIP_DBG_OFF +/* Enable all Espressif-only options */ + +#define ESP_LWIP 1 +#define ESP_PER_SOC_TCP_WND 1 +#define ESP_THREAD_SAFE 1 +#define ESP_THREAD_SAFE_DEBUG LWIP_DBG_OFF +#define ESP_DHCP 1 +#define ESP_DNS 1 +#define ESP_IPV6_AUTOCONFIG 1 +#define ESP_PERF 0 +#define ESP_RANDOM_TCP_PORT 1 +#define ESP_IP4_ATON 1 +#define ESP_LIGHT_SLEEP 1 + + +#if ESP_PER_SOC_TCP_WND +#define TCP_WND_DEFAULT (4*TCP_MSS) +#define TCP_SND_BUF_DEFAULT (2*TCP_MSS) +#define TCP_WND(pcb) (pcb->per_soc_tcp_wnd) +#define TCP_SND_BUF(pcb) (pcb->per_soc_tcp_snd_buf) +#else +#if ESP_PERF +extern unsigned char misc_prof_get_tcpw(void); +extern unsigned char misc_prof_get_tcp_snd_buf(void); +#define TCP_WND(pcb) (misc_prof_get_tcpw()*TCP_MSS) +#define TCP_SND_BUF(pcb) (misc_prof_get_tcp_snd_buf()*TCP_MSS) +#endif +#endif + /** * DHCP_DEBUG: Enable debugging in dhcp.c. */ #define DHCP_DEBUG LWIP_DBG_OFF #define LWIP_DEBUG 0 #define TCP_DEBUG LWIP_DBG_OFF -#define THREAD_SAFE_DEBUG LWIP_DBG_OFF -#define LWIP_THREAD_SAFE 1 +#define ESP_THREAD_SAFE_DEBUG LWIP_DBG_OFF #define CHECKSUM_CHECK_UDP 0 #define CHECKSUM_CHECK_IP 0 diff --git a/components/lwip/netif/etharp.c b/components/lwip/netif/etharp.c index 5891c5cfd6..776e949f75 100755 --- a/components/lwip/netif/etharp.c +++ b/components/lwip/netif/etharp.c @@ -55,10 +55,6 @@ #include -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; -#endif - #if LWIP_IPV4 && LWIP_ARP /* don't build if not configured for use in lwipopts.h */ /** Re-request a used ARP entry 1 minute before it would expire to prevent diff --git a/components/lwip/port/freertos/sys_arch.c b/components/lwip/port/freertos/sys_arch.c index 74a4a996a8..15ba3011d9 100755 --- a/components/lwip/port/freertos/sys_arch.c +++ b/components/lwip/port/freertos/sys_arch.c @@ -56,7 +56,7 @@ sys_mutex_new(sys_mutex_t *pxMutex) xReturn = ERR_OK; } - LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("sys_mutex_new: m=%p\n", *pxMutex)); + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("sys_mutex_new: m=%p\n", *pxMutex)); return xReturn; } @@ -89,7 +89,7 @@ sys_mutex_unlock(sys_mutex_t *pxMutex) void sys_mutex_free(sys_mutex_t *pxMutex) { - LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("sys_mutex_free: m=%p\n", *pxMutex)); + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("sys_mutex_free: m=%p\n", *pxMutex)); vQueueDelete(*pxMutex); } #endif @@ -192,20 +192,20 @@ sys_mbox_new(sys_mbox_t *mbox, int size) { *mbox = malloc(sizeof(struct sys_mbox_s)); if (*mbox == NULL){ - LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("fail to new *mbox\n")); + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("fail to new *mbox\n")); return ERR_MEM; } (*mbox)->os_mbox = xQueueCreate(size, sizeof(void *)); if ((*mbox)->os_mbox == NULL) { - LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("fail to new *mbox->os_mbox\n")); + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("fail to new *mbox->os_mbox\n")); free(*mbox); return ERR_MEM; } if (sys_mutex_new(&((*mbox)->lock)) != ERR_OK){ - LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("fail to new *mbox->lock\n")); + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("fail to new *mbox->lock\n")); vQueueDelete((*mbox)->os_mbox); free(*mbox); return ERR_MEM; @@ -213,7 +213,7 @@ sys_mbox_new(sys_mbox_t *mbox, int size) (*mbox)->alive = true; - LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("new *mbox ok mbox=%p os_mbox=%p mbox_lock=%p\n", *mbox, (*mbox)->os_mbox, (*mbox)->lock)); + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("new *mbox ok mbox=%p os_mbox=%p mbox_lock=%p\n", *mbox, (*mbox)->os_mbox, (*mbox)->lock)); return ERR_OK; } @@ -234,7 +234,7 @@ sys_mbox_trypost(sys_mbox_t *mbox, void *msg) if (xQueueSend((*mbox)->os_mbox, &msg, (portTickType)0) == pdPASS) { xReturn = ERR_OK; } else { - LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("trypost mbox=%p fail\n", (*mbox)->os_mbox)); + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("trypost mbox=%p fail\n", (*mbox)->os_mbox)); xReturn = ERR_MEM; } @@ -271,7 +271,7 @@ sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) if (*mbox == NULL){ *msg = NULL; - LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("sys_arch_mbox_fetch: null mbox\n")); + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("sys_arch_mbox_fetch: null mbox\n")); return -1; } @@ -294,14 +294,14 @@ sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) } else { // block forever for a message. while (1){ - LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("sys_arch_mbox_fetch: fetch mbox=%p os_mbox=%p lock=%p\n", mbox, (*mbox)->os_mbox, (*mbox)->lock)); + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("sys_arch_mbox_fetch: fetch mbox=%p os_mbox=%p lock=%p\n", mbox, (*mbox)->os_mbox, (*mbox)->lock)); if (pdTRUE == xQueueReceive((*mbox)->os_mbox, &(*msg), portMAX_DELAY)){ - LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("sys_arch_mbox_fetch:mbox rx msg=%p\n", (*msg))); + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("sys_arch_mbox_fetch:mbox rx msg=%p\n", (*msg))); break; } if ((*mbox)->alive == false){ - LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("sys_arch_mbox_fetch:mbox not alive\n")); + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("sys_arch_mbox_fetch:mbox not alive\n")); *msg = NULL; break; } @@ -356,24 +356,24 @@ sys_mbox_free(sys_mbox_t *mbox) uint16_t count = 0; bool post_null = true; - LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("sys_mbox_free: set alive false\n")); + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("sys_mbox_free: set alive false\n")); (*mbox)->alive = false; while ( count++ < MAX_POLL_CNT ){ //ESP32_WORKAROUND - LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("sys_mbox_free:try lock=%d\n", count)); + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("sys_mbox_free:try lock=%d\n", count)); if (!sys_mutex_trylock( &(*mbox)->lock )){ - LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("sys_mbox_free:get lock ok %d\n", count)); + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("sys_mbox_free:get lock ok %d\n", count)); sys_mutex_unlock( &(*mbox)->lock ); break; } if (post_null){ - LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("sys_mbox_free: post null to mbox\n")); + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("sys_mbox_free: post null to mbox\n")); if (sys_mbox_trypost( mbox, NULL) != ERR_OK){ - LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("sys_mbox_free: post null mbox fail\n")); + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("sys_mbox_free: post null mbox fail\n")); } else { post_null = false; - LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("sys_mbox_free: post null mbox ok\n")); + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("sys_mbox_free: post null mbox ok\n")); } } @@ -383,7 +383,7 @@ sys_mbox_free(sys_mbox_t *mbox) sys_delay_ms(PER_POLL_DELAY); } - LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("sys_mbox_free:free mbox\n")); + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("sys_mbox_free:free mbox\n")); if (uxQueueMessagesWaiting((*mbox)->os_mbox)) { xQueueReset((*mbox)->os_mbox); @@ -491,7 +491,7 @@ sys_sem_t* sys_thread_sem_get(void) if (!sem){ sem = sys_thread_sem_init(); } - LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("sem_get s=%p\n", sem)); + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("sem_get s=%p\n", sem)); return sem; } @@ -500,12 +500,12 @@ static void sys_thread_tls_free(int index, void* data) sys_sem_t *sem = (sys_sem_t*)(data); if (sem && *sem){ - LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("sem del, i=%d sem=%p\n", index, *sem)); + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("sem del, i=%d sem=%p\n", index, *sem)); vSemaphoreDelete(*sem); } if (sem){ - LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("sem pointer del, i=%d sem_p=%p\n", index, sem)); + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("sem pointer del, i=%d sem_p=%p\n", index, sem)); free(sem); } } @@ -526,7 +526,7 @@ sys_sem_t* sys_thread_sem_init(void) return 0; } - LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("sem init sem_p=%p sem=%p cb=%p\n", sem, *sem, sys_thread_tls_free)); + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("sem init sem_p=%p sem=%p cb=%p\n", sem, *sem, sys_thread_tls_free)); vTaskSetThreadLocalStoragePointerAndDelCallback(xTaskGetCurrentTaskHandle(), SYS_TLS_INDEX, sem, (TlsDeleteCallbackFunction_t)sys_thread_tls_free); return sem; diff --git a/components/lwip/port/netif/wlanif.c b/components/lwip/port/netif/wlanif.c index 0b4fe70bad..548bb7f970 100755 --- a/components/lwip/port/netif/wlanif.c +++ b/components/lwip/port/netif/wlanif.c @@ -56,16 +56,8 @@ #define IFNAME0 'e' #define IFNAME1 'n' -#ifdef LWIP_ESP8266 -//TO_DO -//char *hostname; -//bool default_hostname = 1; - static char hostname[16]; -#else -static char hostname[16]; -#endif -#ifdef PERF +#if ESP_PERF uint32_t g_rx_alloc_pbuf_fail_cnt = 0; #endif @@ -95,7 +87,7 @@ low_level_init(struct netif *netif) /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */ netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; -#ifdef LWIP_ESP8266 +#if ESP_LWIP #if LWIP_IGMP @@ -133,7 +125,7 @@ low_level_output(struct netif *netif, struct pbuf *p) return ERR_IF; } -#ifdef LWIP_ESP8266 +#if ESP_LWIP q = p; u16_t pbuf_x_len = 0; pbuf_x_len = q->len; @@ -172,7 +164,7 @@ low_level_output(struct netif *netif, struct pbuf *p) * @param netif the lwip network interface structure for this ethernetif */ void -#ifdef LWIP_ESP8266 +#if ESP_LWIP wlanif_input(struct netif *netif, void *buffer, u16_t len, void* eb) #else wlanif_input(struct netif *netif, void *buffer, uint16 len) @@ -180,17 +172,17 @@ wlanif_input(struct netif *netif, void *buffer, uint16 len) { struct pbuf *p; -#ifdef LWIP_ESP8266 +#if ESP_LWIP if(buffer== NULL) goto _exit; if(netif == NULL) goto _exit; #endif -#ifdef LWIP_ESP8266 +#if ESP_LWIP p = pbuf_alloc(PBUF_RAW, len, PBUF_REF); if (p == NULL){ -#ifdef PERF +#if ESP_PERF g_rx_alloc_pbuf_fail_cnt++; #endif return; @@ -236,7 +228,7 @@ wlanif_init(struct netif *netif) #if LWIP_NETIF_HOSTNAME /* Initialize interface hostname */ -#ifdef LWIP_ESP8266 +#if ESP_LWIP //TO_DO /* if ((struct netif *)wifi_get_netif(STATION_IF) == netif) { From 3371083c1611fb7a5b0f389739599146af51047c Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Thu, 27 Oct 2016 16:07:47 +0800 Subject: [PATCH 153/343] Add checks for tasks woken up on other CPUs where needed, make xYieldPending and xPendingReadyList per-processor, add configurable ISR stack size to Kconfig, in general fix the entire wake-up-task-on-other-cpu-by-interrupt implementation --- components/esp32/crosscore_int.c | 90 +++++++++---------- components/esp32/include/esp_crosscore_int.h | 27 ++++++ components/freertos/Kconfig | 9 ++ .../include/freertos/FreeRTOSConfig.h | 2 +- components/freertos/tasks.c | 70 ++++++++------- 5 files changed, 117 insertions(+), 81 deletions(-) diff --git a/components/esp32/crosscore_int.c b/components/esp32/crosscore_int.c index a98b13583c..56fe6fe9a7 100644 --- a/components/esp32/crosscore_int.c +++ b/components/esp32/crosscore_int.c @@ -44,64 +44,60 @@ ToDo: There is a small chance the CPU already has yielded when this ISR is servi the ISR will cause it to switch _away_ from it. portYIELD_FROM_ISR will probably just schedule the task again, but have to check that. */ static void esp_crosscore_isr(void *arg) { - volatile uint32_t myReasonVal; + volatile uint32_t myReasonVal; #if 0 - //A pointer to the correct reason array item is passed to this ISR. - volatile uint32_t *myReason=arg; + //A pointer to the correct reason array item is passed to this ISR. + volatile uint32_t *myReason=arg; #else - //Does not work yet, the interrupt code needs work to understand two separate interrupt and argument - //tables... - volatile uint32_t *myReason=&reason[xPortGetCoreID()]; + //Does not work yet, the interrupt code needs work to understand two separate interrupt and argument + //tables... + volatile uint32_t *myReason=&reason[xPortGetCoreID()]; #endif - //Clear the interrupt first. - if (xPortGetCoreID()==0) { - WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_0_REG, 0); - } else { - WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_1_REG, 0); - } - //Grab the reason and clear it. - portENTER_CRITICAL(&reasonSpinlock); - myReasonVal=*myReason; - *myReason=0; - portEXIT_CRITICAL(&reasonSpinlock); + //Clear the interrupt first. + if (xPortGetCoreID()==0) { + WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_0_REG, 0); + } else { + WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_1_REG, 0); + } + //Grab the reason and clear it. + portENTER_CRITICAL(&reasonSpinlock); + myReasonVal=*myReason; + *myReason=0; + portEXIT_CRITICAL(&reasonSpinlock); - //Check what we need to do. - if (myReasonVal&REASON_YIELD) { - portYIELD_FROM_ISR(); - } - - ets_printf("recv yield\n"); + //Check what we need to do. + if (myReasonVal&REASON_YIELD) { + portYIELD_FROM_ISR(); + } } //Initialize the crosscore interrupt on this core. Call this once //on each active core. void esp_crosscore_int_init() { - portENTER_CRITICAL(&reasonSpinlock); - ets_printf("init cpu %d\n", xPortGetCoreID()); - reason[xPortGetCoreID()]=0; - portEXIT_CRITICAL(&reasonSpinlock); - ESP_INTR_DISABLE(ETS_FROM_CPU_INUM); - if (xPortGetCoreID()==0) { - intr_matrix_set(xPortGetCoreID(), ETS_FROM_CPU_INTR0_SOURCE, ETS_FROM_CPU_INUM); - } else { - intr_matrix_set(xPortGetCoreID(), ETS_FROM_CPU_INTR1_SOURCE, ETS_FROM_CPU_INUM); - } - xt_set_interrupt_handler(ETS_FROM_CPU_INUM, esp_crosscore_isr, (void*)&reason[xPortGetCoreID()]); - ESP_INTR_ENABLE(ETS_FROM_CPU_INUM); + portENTER_CRITICAL(&reasonSpinlock); + reason[xPortGetCoreID()]=0; + portEXIT_CRITICAL(&reasonSpinlock); + ESP_INTR_DISABLE(ETS_FROM_CPU_INUM); + if (xPortGetCoreID()==0) { + intr_matrix_set(xPortGetCoreID(), ETS_FROM_CPU_INTR0_SOURCE, ETS_FROM_CPU_INUM); + } else { + intr_matrix_set(xPortGetCoreID(), ETS_FROM_CPU_INTR1_SOURCE, ETS_FROM_CPU_INUM); + } + xt_set_interrupt_handler(ETS_FROM_CPU_INUM, esp_crosscore_isr, (void*)&reason[xPortGetCoreID()]); + ESP_INTR_ENABLE(ETS_FROM_CPU_INUM); } void esp_crosscore_int_send_yield(int coreId) { - ets_printf("send yield\n"); - assert(coreIduxPriority < uxPriority ) + No mux here, uxPriority is mostly atomic and there's not really any harm if this check misfires. + */ + if( tskCAN_RUN_HERE( xCoreID ) && pxCurrentTCB[ xPortGetCoreID() ]->uxPriority < uxPriority ) { taskYIELD_IF_USING_PREEMPTION(); } + else if( xCoreID != xPortGetCoreID() ) { + taskYIELD_OTHER_CORE(xCoreID, uxPriority); + } else { mtCOVERAGE_TEST_MARKER(); @@ -1452,7 +1450,7 @@ BaseType_t i; if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ) != pdFALSE ) { /* Has the task already been resumed from within an ISR? */ - if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) == pdFALSE ) + if( listIS_CONTAINED_WITHIN( &xPendingReadyList[ xPortGetCoreID() ], &( pxTCB->xEventListItem ) ) == pdFALSE ) { /* Is it in the suspended list because it is in the Suspended state, or because is is blocked with no timeout? */ @@ -1544,7 +1542,6 @@ BaseType_t i; #if ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) -/* ToDo: Make this multicore-compatible. */ BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume ) { BaseType_t xYieldRequired = pdFALSE; @@ -1567,14 +1564,14 @@ BaseType_t i; ( void ) uxListRemove( &( pxTCB->xGenericListItem ) ); prvAddTaskToReadyList( pxTCB ); - if ( pxTCB->xCoreID == xPortGetCoreID() ) - { - taskYIELD_OTHER_CORE( pxTCB->xCoreID, pxTCB->uxPriority); - } - else if( pxTCB->uxPriority >= pxCurrentTCB[ xPortGetCoreID() ]->uxPriority ) + if( tskCAN_RUN_HERE( pxTCB->xCoreID ) && pxTCB->uxPriority >= pxCurrentTCB[ xPortGetCoreID() ]->uxPriority ) { xYieldRequired = pdTRUE; } + else if ( pxTCB->xCoreID != xPortGetCoreID() ) + { + taskYIELD_OTHER_CORE( pxTCB->xCoreID, pxTCB->uxPriority); + } else { mtCOVERAGE_TEST_MARKER(); @@ -1585,7 +1582,7 @@ BaseType_t i; /* The delayed or ready lists cannot be accessed so the task is held in the pending ready list until the scheduler is unsuspended. */ - vListInsertEnd( &( xPendingReadyList ), &( pxTCB->xEventListItem ) ); + vListInsertEnd( &( xPendingReadyList[ xPortGetCoreID() ] ), &( pxTCB->xEventListItem ) ); } } else @@ -1770,9 +1767,9 @@ BaseType_t xAlreadyYielded = pdFALSE; { /* Move any readied tasks from the pending list into the appropriate ready list. */ - while( listLIST_IS_EMPTY( &xPendingReadyList ) == pdFALSE ) + while( listLIST_IS_EMPTY( &xPendingReadyList[ xPortGetCoreID() ] ) == pdFALSE ) { - pxTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( ( &xPendingReadyList ) ); + pxTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( ( &xPendingReadyList[ xPortGetCoreID() ] ) ); ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); ( void ) uxListRemove( &( pxTCB->xGenericListItem ) ); prvAddTaskToReadyList( pxTCB ); @@ -1785,10 +1782,6 @@ BaseType_t xAlreadyYielded = pdFALSE; xYieldPending[xPortGetCoreID()] = pdTRUE; break; } - else if ( pxTCB->xCoreID != xPortGetCoreID() ) - { - taskYIELD_OTHER_CORE( pxTCB->xCoreID, pxTCB->uxPriority ); - } else { mtCOVERAGE_TEST_MARKER(); @@ -2658,15 +2651,20 @@ BaseType_t xReturn; /* The delayed and ready lists cannot be accessed, so hold this task pending until the scheduler is resumed. */ taskENTER_CRITICAL(&xTaskQueueMutex); - vListInsertEnd( &( xPendingReadyList ), &( pxUnblockedTCB->xEventListItem ) ); + vListInsertEnd( &( xPendingReadyList[ xPortGetCoreID() ] ), &( pxUnblockedTCB->xEventListItem ) ); taskEXIT_CRITICAL(&xTaskQueueMutex); } if ( tskCAN_RUN_HERE(pxUnblockedTCB->xCoreID) && pxUnblockedTCB->uxPriority >= pxCurrentTCB[ xPortGetCoreID() ]->uxPriority ) { - /* We can schedule the awoken task on this CPU. */ - xYieldPending[xPortGetCoreID()] = pdTRUE; + /* Return true if the task removed from the event list has a higher + priority than the calling task. This allows the calling task to know if + it should force a context switch now. */ xReturn = pdTRUE; + + /* Mark that a yield is pending in case the user is not using the + "xHigherPriorityTaskWoken" parameter to an ISR safe FreeRTOS function. */ + xYieldPending[ xPortGetCoreID() ] = pdTRUE; } else if ( pxUnblockedTCB->xCoreID != xPortGetCoreID() ) { @@ -2724,9 +2722,15 @@ BaseType_t xReturn; if ( tskCAN_RUN_HERE(pxUnblockedTCB->xCoreID) && pxUnblockedTCB->uxPriority >= pxCurrentTCB[ xPortGetCoreID() ]->uxPriority ) { - /* We can schedule the awoken task on this CPU. */ - xYieldPending[xPortGetCoreID()] = pdTRUE; + /* Return true if the task removed from the event list has + a higher priority than the calling task. This allows + the calling task to know if it should force a context + switch now. */ xReturn = pdTRUE; + + /* Mark that a yield is pending in case the user is not using the + "xHigherPriorityTaskWoken" parameter to an ISR safe FreeRTOS function. */ + xYieldPending[ xPortGetCoreID() ] = pdTRUE; } else if ( pxUnblockedTCB->xCoreID != xPortGetCoreID() ) { @@ -2967,7 +2971,7 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters ) eSleepModeStatus eReturn = eStandardSleep; taskENTER_CRITICAL(&xTaskQueueMutex); - if( listCURRENT_LIST_LENGTH( &xPendingReadyList ) != 0 ) + if( listCURRENT_LIST_LENGTH( &xPendingReadyList[ xPortGetCoreID() ] ) != 0 ) { /* A task was made ready while the scheduler was suspended. */ eReturn = eAbortSleep; @@ -3210,7 +3214,7 @@ UBaseType_t uxPriority; vListInitialise( &xDelayedTaskList1 ); vListInitialise( &xDelayedTaskList2 ); - vListInitialise( &xPendingReadyList ); + vListInitialise( &xPendingReadyList[ xPortGetCoreID() ] ); #if ( INCLUDE_vTaskDelete == 1 ) { @@ -4576,7 +4580,7 @@ TickType_t uxReturn; { /* The delayed and ready lists cannot be accessed, so hold this task pending until the scheduler is resumed. */ - vListInsertEnd( &( xPendingReadyList ), &( pxTCB->xEventListItem ) ); + vListInsertEnd( &( xPendingReadyList[ xPortGetCoreID() ] ), &( pxTCB->xEventListItem ) ); } if( tskCAN_RUN_HERE(pxTCB->xCoreID) && pxTCB->uxPriority > pxCurrentTCB[ xPortGetCoreID() ]->uxPriority ) @@ -4644,7 +4648,7 @@ TickType_t uxReturn; { /* The delayed and ready lists cannot be accessed, so hold this task pending until the scheduler is resumed. */ - vListInsertEnd( &( xPendingReadyList ), &( pxTCB->xEventListItem ) ); + vListInsertEnd( &( xPendingReadyList[ xPortGetCoreID() ] ), &( pxTCB->xEventListItem ) ); } if( tskCAN_RUN_HERE(pxTCB->xCoreID) && pxTCB->uxPriority > pxCurrentTCB[ xPortGetCoreID() ]->uxPriority ) From 68f39c1ed90bc948ad46af74869d26f5bef9806c Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Thu, 27 Oct 2016 16:50:28 +0800 Subject: [PATCH 154/343] Only init crosscore when FreeRTOS runs in multicore mode, add warnings that cross_int calls are private. --- components/esp32/cpu_start.c | 2 ++ components/esp32/crosscore_int.c | 4 ++-- components/esp32/include/esp_crosscore_int.h | 7 +++++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/components/esp32/cpu_start.c b/components/esp32/cpu_start.c index 0c94f39e30..bfc751d453 100644 --- a/components/esp32/cpu_start.c +++ b/components/esp32/cpu_start.c @@ -147,7 +147,9 @@ void start_cpu0_default(void) uart_div_modify(0, (APB_CLK_FREQ << 4) / 115200); ets_setup_syscalls(); do_global_ctors(); +#if !CONFIG_FREERTOS_UNICORE esp_crosscore_int_init(); +#endif esp_ipc_init(); spi_flash_init(); xTaskCreatePinnedToCore(&main_task, "main", diff --git a/components/esp32/crosscore_int.c b/components/esp32/crosscore_int.c index 56fe6fe9a7..78287d405e 100644 --- a/components/esp32/crosscore_int.c +++ b/components/esp32/crosscore_int.c @@ -49,8 +49,8 @@ static void esp_crosscore_isr(void *arg) { //A pointer to the correct reason array item is passed to this ISR. volatile uint32_t *myReason=arg; #else - //Does not work yet, the interrupt code needs work to understand two separate interrupt and argument - //tables... + //The previous line does not work yet, the interrupt code needs work to understand two separate interrupt and argument + //tables... this is a valid but slightly less optimal replacement. volatile uint32_t *myReason=&reason[xPortGetCoreID()]; #endif //Clear the interrupt first. diff --git a/components/esp32/include/esp_crosscore_int.h b/components/esp32/include/esp_crosscore_int.h index ca5f3901ee..0e4b2b8385 100644 --- a/components/esp32/include/esp_crosscore_int.h +++ b/components/esp32/include/esp_crosscore_int.h @@ -19,6 +19,10 @@ * Initialize the crosscore interrupt system for this CPU. * This needs to be called once on every CPU that is used * by FreeRTOS. + * + * If multicore FreeRTOS support is enabled, this will be + * called automatically by the startup code and should not + * be called manually. */ void esp_crosscore_int_init(); @@ -28,6 +32,9 @@ void esp_crosscore_int_init(); * currently running task in favour of a higher-priority task * that presumably just woke up. * + * This is used internally by FreeRTOS in multicore mode + * and should not be called by the user. + * * @param coreID Core that should do the yielding */ void esp_crosscore_int_send_yield(int coreId); From 401f6e47134417708a4654cac150f15e0c70819a Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 25 Oct 2016 21:02:39 +0800 Subject: [PATCH 155/343] vfs: initial version of virtual filesystem API --- components/vfs/README.rst | 2 + components/vfs/component.mk | 1 + components/vfs/include/esp_vfs.h | 157 +++++++++++++++++ components/vfs/vfs.c | 285 +++++++++++++++++++++++++++++++ 4 files changed, 445 insertions(+) create mode 100644 components/vfs/README.rst create mode 100755 components/vfs/component.mk create mode 100644 components/vfs/include/esp_vfs.h create mode 100644 components/vfs/vfs.c diff --git a/components/vfs/README.rst b/components/vfs/README.rst new file mode 100644 index 0000000000..b32e22ccf8 --- /dev/null +++ b/components/vfs/README.rst @@ -0,0 +1,2 @@ +Virtual filesystem (VFS) is a driver which can perform operations on file-like objects. This can be a real filesystem (FAT, SPIFFS, etc.), or a device driver which exposes file-like interface. + \ No newline at end of file diff --git a/components/vfs/component.mk b/components/vfs/component.mk new file mode 100755 index 0000000000..fccf88db8a --- /dev/null +++ b/components/vfs/component.mk @@ -0,0 +1 @@ +include $(IDF_PATH)/make/component_common.mk diff --git a/components/vfs/include/esp_vfs.h b/components/vfs/include/esp_vfs.h new file mode 100644 index 0000000000..0d1c3d1479 --- /dev/null +++ b/components/vfs/include/esp_vfs.h @@ -0,0 +1,157 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef __ESP_VFS_H__ +#define __ESP_VFS_H__ + +#include +#include +#include "esp_err.h" +#include +#include +#include +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Maximum length of path prefix (not including zero terminator) + */ +#define ESP_VFS_PATH_MAX 15 + +/** + * Default value of flags member in esp_vfs_t structure. + */ +#define ESP_VFS_FLAG_DEFAULT 0 + +/** + * Flag which indicates that FS needs extra context pointer in syscalls. + */ +#define ESP_VFS_FLAG_CONTEXT_PTR 1 + +/** + * @brief VFS definition structure + * + * This structure should be filled with pointers to corresponding + * FS driver functions. + * + * If the FS implementation has an option to use certain offset for + * all file descriptors, this value should be passed into fd_offset + * field. Otherwise VFS component will translate all FDs to start + * at zero offset. + * + * Some FS implementations expect some state (e.g. pointer to some structure) + * to be passed in as a first argument. For these implementations, + * populate the members of this structure which have _p suffix, set + * flags member to ESP_VFS_FLAG_CONTEXT_PTR and provide the context pointer + * to esp_vfs_register function. + * If the implementation doesn't use this extra argument, populate the + * members without _p suffix and set flags memeber to ESP_VFS_FLAG_DEFAULT. + * + * If the FS driver doesn't provide some of the functions, set corresponding + * members to NULL. + */ +typedef struct +{ + int fd_offset; + int flags; + union { + size_t (*write_p)(void* p, int fd, const void * data, size_t size); + size_t (*write)(int fd, const void * data, size_t size); + }; + union { + _off_t (*lseek_p)(void* p, int fd, _off_t size, int mode); + _off_t (*lseek)(int fd, _off_t size, int mode); + }; + union { + ssize_t (*read_p)(void* ctx, int fd, void * dst, size_t size); + ssize_t (*read)(int fd, void * dst, size_t size); + }; + union { + int (*open_p)(void* ctx, const char * path, int flags, int mode); + int (*open)(const char * path, int flags, int mode); + }; + union { + int (*close_p)(void* ctx, int fd); + int (*close)(int fd); + }; + union { + int (*fstat_p)(void* ctx, int fd, struct stat * st); + int (*fstat)(int fd, struct stat * st); + }; + union { + int (*stat_p)(void* ctx, const char * path, struct stat * st); + int (*stat)(const char * path, struct stat * st); + }; + union { + int (*link_p)(void* ctx, const char* n1, const char* n2); + int (*link)(const char* n1, const char* n2); + }; + union { + int (*unlink_p)(void* ctx, const char *path); + int (*unlink)(const char *path); + }; + union { + int (*rename_p)(void* ctx, const char *src, const char *dst); + int (*rename)(const char *src, const char *dst); + }; +} esp_vfs_t; + + +/** + * Register a virtual filesystem for given path prefix. + * + * @param base_path file path prefix associated with the filesystem. + * Must be a zero-terminated C string, up to ESP_VFS_PATH_MAX + * characters long, and at least 2 characters long. + * Name must start with a "/" and must not end with "/". + * For example, "/data" or "/dev/spi" are valid. + * These VFSes would then be called to handle file paths such as + * "/data/myfile.txt" or "/dev/spi/0". + * @param vfs Pointer to esp_vfs_t, a structure which maps syscalls to + * the filesystem driver functions. VFS component doesn't + * assume ownership of this pointer. + * @param ctx If vfs->flags has ESP_VFS_FLAG_CONTEXT_PTR set, a pointer + * which should be passed to VFS functions. Otherwise, NULL. + * + * @return ESP_OK if successful, ESP_ERR_NO_MEM if too many VFSes are + * registered. + */ +esp_err_t esp_vfs_register(const char* base_path, const esp_vfs_t* vfs, void* ctx); + + +/** + * These functions are to be used in newlib syscall table. They will be called by + * newlib when it needs to use any of the syscalls. + */ + +ssize_t esp_vfs_write(struct _reent *r, int fd, const void * data, size_t size); +_off_t esp_vfs_lseek(struct _reent *r, int fd, _off_t size, int mode); +ssize_t esp_vfs_read(struct _reent *r, int fd, void * dst, size_t size); +int esp_vfs_open(struct _reent *r, const char * path, int flags, int mode); +int esp_vfs_close(struct _reent *r, int fd); +int esp_vfs_fstat(struct _reent *r, int fd, struct stat * st); +int esp_vfs_stat(struct _reent *r, const char * path, struct stat * st); +int esp_vfs_link(struct _reent *r, const char* n1, const char* n2); +int esp_vfs_unlink(struct _reent *r, const char *path); +int esp_vfs_rename(struct _reent *r, const char *src, const char *dst); + + + +#ifdef __cplusplus +} // extern "C" +#endif + + +#endif //__ESP_VFS_H__ diff --git a/components/vfs/vfs.c b/components/vfs/vfs.c new file mode 100644 index 0000000000..afc7149bad --- /dev/null +++ b/components/vfs/vfs.c @@ -0,0 +1,285 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include +#include "esp_vfs.h" +#include "esp_log.h" + +/* + * File descriptors visible by the applications are composed of two parts. + * Lower CONFIG_MAX_FD_BITS bits are used for the actual file descriptor. + * Next (16 - CONFIG_MAX_FD_BITS - 1) bits are used to identify the VFS this + * descriptor corresponds to. + * Highest bit is zero. + * We can only use 16 bits because newlib stores file descriptor as short int. + */ + +#ifndef CONFIG_MAX_FD_BITS +#define CONFIG_MAX_FD_BITS 12 +#endif + +#define MAX_VFS_ID_BITS (16 - CONFIG_MAX_FD_BITS - 1) +// mask of actual file descriptor (e.g. 0x00000fff) +#define VFS_FD_MASK ((1 << CONFIG_MAX_FD_BITS) - 1) +// max number of VFS entries +#define VFS_MAX_COUNT ((1 << MAX_VFS_ID_BITS) - 1) +// mask of VFS id (e.g. 0x00007000) +#define VFS_INDEX_MASK (VFS_MAX_COUNT << CONFIG_MAX_FD_BITS) +#define VFS_INDEX_S CONFIG_MAX_FD_BITS + +typedef struct vfs_entry_ { + esp_vfs_t vfs; // contains pointers to VFS functions + char path_prefix[ESP_VFS_PATH_MAX]; // path prefix mapped to this VFS + size_t path_prefix_len; // micro-optimization to avoid doing extra strlen + void* ctx; // optional pointer which can be passed to VFS + int offset; // index of this structure in s_vfs array +} vfs_entry_t; + +static vfs_entry_t* s_vfs[VFS_MAX_COUNT] = { 0 }; +static size_t s_vfs_count = 0; + +esp_err_t esp_vfs_register(const char* base_path, const esp_vfs_t* vfs, void* ctx) +{ + if (s_vfs_count >= VFS_MAX_COUNT) { + return ESP_ERR_NO_MEM; + } + size_t len = strlen(base_path); + if (len < 2 || len > ESP_VFS_PATH_MAX) { + return ESP_ERR_INVALID_ARG; + } + if (base_path[0] != '/' || base_path[len - 1] == '/') { + return ESP_ERR_INVALID_ARG; + } + vfs_entry_t *entry = (vfs_entry_t*) malloc(sizeof(vfs_entry_t)); + if (entry == NULL) { + return ESP_ERR_NO_MEM; + } + strcpy(entry->path_prefix, base_path); // we have already verified argument length + memcpy(&entry->vfs, vfs, sizeof(esp_vfs_t)); + entry->path_prefix_len = len; + entry->ctx = ctx; + entry->offset = s_vfs_count; + s_vfs[s_vfs_count] = entry; + ++s_vfs_count; + return ESP_OK; +} + +static const vfs_entry_t* get_vfs_for_fd(int fd) +{ + int index = ((fd & VFS_INDEX_MASK) >> VFS_INDEX_S); + if (index >= s_vfs_count) { + return NULL; + } + return s_vfs[index]; +} + +static int translate_fd(const vfs_entry_t* vfs, int fd) +{ + return (fd & VFS_FD_MASK) + vfs->vfs.fd_offset; +} + +static const char* translate_path(const vfs_entry_t* vfs, const char* src_path) +{ + assert(strncmp(src_path, vfs->path_prefix, vfs->path_prefix_len) == 0); + return src_path + vfs->path_prefix_len; +} + +static const vfs_entry_t* get_vfs_for_path(const char* path) +{ + size_t len = strlen(path); + for (size_t i = 0; i < s_vfs_count; ++i) { + const vfs_entry_t* vfs = s_vfs[i]; + if (len < vfs->path_prefix_len + 1) { // +1 is for the trailing slash after base path + continue; + } + if (memcmp(path, vfs->path_prefix, vfs->path_prefix_len) != 0) { // match prefix + continue; + } + if (path[vfs->path_prefix_len] != '/') { // don't match "/data" prefix for "/data1/foo.txt" + continue; + } + return vfs; + } + return NULL; +} + +/* + * Using huge multi-line macros is never nice, but in this case + * the only alternative is to repeat this chunk of code (with different function names) + * for each syscall being implemented. Given that this define is contained within a single + * file, this looks like a good tradeoff. + * + * First we check if syscall is implemented by VFS (corresponding member is not NULL), + * then call the right flavor of the method (e.g. open or open_p) depending on + * ESP_VFS_FLAG_CONTEXT_PTR flag. If ESP_VFS_FLAG_CONTEXT_PTR is set, context is passed + * in as first argument and _p variant is used for the call. + * It is enough to check just one of them for NULL, as both variants are part of a union. + */ +#define CHECK_AND_CALL(ret, r, pvfs, func, ...) \ + if (pvfs->vfs.func == NULL) { \ + __errno_r(r) = ENOSYS; \ + return -1; \ + } \ + if (pvfs->vfs.flags & ESP_VFS_FLAG_CONTEXT_PTR) { \ + ret = (*pvfs->vfs.func ## _p)(pvfs->ctx, __VA_ARGS__); \ + } else { \ + ret = (*pvfs->vfs.func)(__VA_ARGS__);\ + } + + +int esp_vfs_open(struct _reent *r, const char * path, int flags, int mode) +{ + const vfs_entry_t* vfs = get_vfs_for_path(path); + if (vfs == NULL) { + __errno_r(r) = ENOENT; + return -1; + } + const char* path_within_vfs = translate_path(vfs, path); + int ret; + CHECK_AND_CALL(ret, r, vfs, open, path_within_vfs, flags, mode); + return ret - vfs->vfs.fd_offset + (vfs->offset << VFS_INDEX_S); +} + +ssize_t esp_vfs_write(struct _reent *r, int fd, const void * data, size_t size) +{ + const vfs_entry_t* vfs = get_vfs_for_fd(fd); + if (vfs == NULL) { + __errno_r(r) = EBADF; + return -1; + } + int local_fd = translate_fd(vfs, fd); + int ret; + CHECK_AND_CALL(ret, r, vfs, write, local_fd, data, size); + return ret; +} + +_off_t esp_vfs_lseek(struct _reent *r, int fd, _off_t size, int mode) +{ + const vfs_entry_t* vfs = get_vfs_for_fd(fd); + if (vfs == NULL) { + __errno_r(r) = EBADF; + return -1; + } + int local_fd = translate_fd(vfs, fd); + int ret; + CHECK_AND_CALL(ret, r, vfs, lseek, local_fd, size, mode); + return ret; +} + +ssize_t esp_vfs_read(struct _reent *r, int fd, void * dst, size_t size) +{ + const vfs_entry_t* vfs = get_vfs_for_fd(fd); + if (vfs == NULL) { + __errno_r(r) = EBADF; + return -1; + } + int local_fd = translate_fd(vfs, fd); + int ret; + CHECK_AND_CALL(ret, r, vfs, read, local_fd, dst, size); + return ret; +} + + +int esp_vfs_close(struct _reent *r, int fd) +{ + const vfs_entry_t* vfs = get_vfs_for_fd(fd); + if (vfs == NULL) { + __errno_r(r) = EBADF; + return -1; + } + int local_fd = translate_fd(vfs, fd); + int ret; + CHECK_AND_CALL(ret, r, vfs, close, local_fd); + return ret; +} + +int esp_vfs_fstat(struct _reent *r, int fd, struct stat * st) +{ + const vfs_entry_t* vfs = get_vfs_for_fd(fd); + if (vfs == NULL) { + __errno_r(r) = EBADF; + return -1; + } + int local_fd = translate_fd(vfs, fd); + int ret; + CHECK_AND_CALL(ret, r, vfs, fstat, local_fd, st); + return ret; +} + +int esp_vfs_stat(struct _reent *r, const char * path, struct stat * st) +{ + const vfs_entry_t* vfs = get_vfs_for_path(path); + if (vfs == NULL) { + __errno_r(r) = ENOENT; + return -1; + } + const char* path_within_vfs = translate_path(vfs, path); + int ret; + CHECK_AND_CALL(ret, r, vfs, stat, path_within_vfs, st); + return ret; +} + +int esp_vfs_link(struct _reent *r, const char* n1, const char* n2) +{ + const vfs_entry_t* vfs = get_vfs_for_path(n1); + if (vfs == NULL) { + __errno_r(r) = ENOENT; + return -1; + } + const vfs_entry_t* vfs2 = get_vfs_for_path(n2); + if (vfs != vfs2) { + __errno_r(r) = EXDEV; + return -1; + } + const char* path1_within_vfs = translate_path(vfs, n1); + const char* path2_within_vfs = translate_path(vfs, n2); + int ret; + CHECK_AND_CALL(ret, r, vfs, link, path1_within_vfs, path2_within_vfs); + return ret; +} + +int esp_vfs_unlink(struct _reent *r, const char *path) +{ + const vfs_entry_t* vfs = get_vfs_for_path(path); + if (vfs == NULL) { + __errno_r(r) = ENOENT; + return -1; + } + const char* path_within_vfs = translate_path(vfs, path); + int ret; + CHECK_AND_CALL(ret, r, vfs, unlink, path_within_vfs); + return ret; +} + +int esp_vfs_rename(struct _reent *r, const char *src, const char *dst) +{ + const vfs_entry_t* vfs = get_vfs_for_path(src); + if (vfs == NULL) { + __errno_r(r) = ENOENT; + return -1; + } + const vfs_entry_t* vfs_dst = get_vfs_for_path(dst); + if (vfs != vfs_dst) { + __errno_r(r) = EXDEV; + return -1; + } + const char* src_within_vfs = translate_path(vfs, src); + const char* dst_within_vfs = translate_path(vfs, dst); + int ret; + CHECK_AND_CALL(ret, r, vfs, rename, src_within_vfs, dst_within_vfs); + return ret; +} From 587360363c121d266b66271b10a60831b6ff9d40 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 25 Oct 2016 22:01:50 +0800 Subject: [PATCH 156/343] vfs: add UART device This should be integrated with UART driver once everything is merged --- components/vfs/include/esp_vfs_dev.h | 28 ++++++++ components/vfs/vfs_uart.c | 95 ++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 components/vfs/include/esp_vfs_dev.h create mode 100644 components/vfs/vfs_uart.c diff --git a/components/vfs/include/esp_vfs_dev.h b/components/vfs/include/esp_vfs_dev.h new file mode 100644 index 0000000000..6eb63d852c --- /dev/null +++ b/components/vfs/include/esp_vfs_dev.h @@ -0,0 +1,28 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef __ESP_VFS_H__ +#define __ESP_VFS_H__ + +#include "esp_vfs.h" + +/** + * @brief add /dev/uart virtual filesystem driver + * + * This function is called from startup code to enable serial output + */ +void esp_vfs_dev_uart_register(); + + +#endif //__ESP_VFS_H__ diff --git a/components/vfs/vfs_uart.c b/components/vfs/vfs_uart.c new file mode 100644 index 0000000000..179c5e2585 --- /dev/null +++ b/components/vfs/vfs_uart.c @@ -0,0 +1,95 @@ +#include +#include "esp_vfs.h" +#include "esp_attr.h" +#include "sys/errno.h" +#include "sys/lock.h" +#include "soc/uart_struct.h" + +static uart_dev_t* s_uarts[3] = {&UART0, &UART1, &UART2}; + +static int IRAM_ATTR uart_open(const char * path, int flags, int mode) +{ + // this is fairly primitive, we should check if file is opened read only, + // and error out if write is requested + if (strcmp(path, "/0") == 0) { + return 0; + } else if (strcmp(path, "/1") == 0) { + return 1; + } else if (strcmp(path, "/2") == 0) { + return 2; + } + errno = ENOENT; + return -1; +} + +static void IRAM_ATTR uart_tx_char(uart_dev_t* uart, int c) +{ + while (uart->status.txfifo_cnt >= 127) { + ; + } + uart->fifo.rw_byte = c; +} + + +static size_t IRAM_ATTR uart_write(int fd, const void * data, size_t size) +{ + assert(fd >=0 && fd < 3); + const char *data_c = (const char *)data; + uart_dev_t* uart = s_uarts[fd]; + static _lock_t stdout_lock; /* lazily initialised */ + /* Even though newlib does stream locking on stdout, we need + a dedicated stdout UART lock... + + This is because each task has its own _reent structure with + unique FILEs for stdin/stdout/stderr, so these are + per-thread (lazily initialised by __sinit the first time a + stdio function is used, see findfp.c:235. + + It seems like overkill to allocate a FILE-per-task and lock + a thread-local stream, but I see no easy way to fix this + (pre-__sinit_, tasks have "fake" FILEs ie __sf_fake_stdout + which aren't fully valid.) + */ + _lock_acquire_recursive(&stdout_lock); + for (size_t i = 0; i < size; i++) { +#if CONFIG_NEWLIB_STDOUT_ADDCR + if (data_c[i]=='\n') { + uart_tx_char(uart, '\r'); + } +#endif + uart_tx_char(uart, data_c[i]); + } + _lock_release_recursive(&stdout_lock); + return size; +} + +static int IRAM_ATTR uart_fstat(int fd, struct stat * st) +{ + assert(fd >=0 && fd < 3); + st->st_mode = S_IFCHR; + return 0; +} + +static int IRAM_ATTR uart_close(int fd) +{ + assert(fd >=0 && fd < 3); + return 0; +} + +void esp_vfs_dev_uart_register() +{ + esp_vfs_t vfs = { + .fd_offset = 0, + .flags = ESP_VFS_FLAG_DEFAULT, + .write = &uart_write, + .open = &uart_open, + .fstat = &uart_fstat, + .close = &uart_close, + .read = NULL, // TODO: implement reading from UART + .stat = NULL, + .link = NULL, + .unlink = NULL, + .rename = NULL + }; + ESP_ERROR_CHECK(esp_vfs_register("/dev/uart", &vfs, NULL)); +} From b3b8334d546fbcdb57629fc07b1cbaa67b65958e Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 25 Oct 2016 22:12:07 +0800 Subject: [PATCH 157/343] vfs and newlib: small fixes - spaces->tabs in tasks.c - update vfs_uart.c to use per-UART locks - add license to vfs_uart.c - allocate separate streams for stdout, stdin, stderr, so that they can be independently reassigned - fix build system test failure --- components/esp32/cpu_start.c | 4 +- components/esp32/include/soc/cpu.h | 3 + components/newlib/component.mk | 7 +- .../{esp32/syscalls.c => newlib/locks.c} | 258 +----------------- .../newlib/platform_include/esp_newlib.h | 27 ++ components/newlib/syscall_table.c | 91 ++++++ components/newlib/syscalls.c | 105 +++++++ components/newlib/time.c | 35 +++ 8 files changed, 269 insertions(+), 261 deletions(-) rename components/{esp32/syscalls.c => newlib/locks.c} (54%) create mode 100644 components/newlib/platform_include/esp_newlib.h create mode 100644 components/newlib/syscall_table.c create mode 100644 components/newlib/syscalls.c create mode 100644 components/newlib/time.c diff --git a/components/esp32/cpu_start.c b/components/esp32/cpu_start.c index a649764ab5..cbac54d7c3 100644 --- a/components/esp32/cpu_start.c +++ b/components/esp32/cpu_start.c @@ -42,7 +42,7 @@ #include "esp_spi_flash.h" #include "esp_ipc.h" #include "esp_log.h" - +#include "esp_newlib.h" #include "esp_brownout.h" #include "esp_int_wdt.h" #include "esp_task_wdt.h" @@ -160,7 +160,7 @@ void start_cpu0_default(void) #if CONFIG_TASK_WDT esp_task_wdt_init(); #endif - ets_setup_syscalls(); + esp_setup_syscalls(); do_global_ctors(); esp_ipc_init(); spi_flash_init(); diff --git a/components/esp32/include/soc/cpu.h b/components/esp32/include/soc/cpu.h index c74ba317c8..ee2907493e 100644 --- a/components/esp32/include/soc/cpu.h +++ b/components/esp32/include/soc/cpu.h @@ -15,6 +15,9 @@ #ifndef _SOC_CPU_H #define _SOC_CPU_H +#include +#include +#include #include "xtensa/corebits.h" /* C macros for xtensa special register read/write/exchange */ diff --git a/components/newlib/component.mk b/components/newlib/component.mk index 7c8c74debe..3731b5ef0e 100644 --- a/components/newlib/component.mk +++ b/components/newlib/component.mk @@ -1,8 +1,5 @@ -COMPONENT_ADD_LDFLAGS := $(abspath lib/libc.a) $(abspath lib/libm.a) +COMPONENT_ADD_LDFLAGS := $(abspath lib/libc.a) $(abspath lib/libm.a) -lnewlib - -define COMPONENT_BUILDRECIPE - #Nothing to do; this does not generate a library. -endef +COMPONENT_ADD_INCLUDEDIRS := include platform_include include $(IDF_PATH)/make/component_common.mk diff --git a/components/esp32/syscalls.c b/components/newlib/locks.c similarity index 54% rename from components/esp32/syscalls.c rename to components/newlib/locks.c index 052605ee3e..21b974a1f1 100644 --- a/components/esp32/syscalls.c +++ b/components/newlib/locks.c @@ -3,7 +3,7 @@ // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software @@ -11,181 +11,17 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. -#include -#include -#include -#include -#include -#include -#include + +#include #include +#include #include "esp_attr.h" -#include "rom/libc_stubs.h" -#include "rom/uart.h" #include "soc/cpu.h" #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" #include "freertos/portmacro.h" #include "freertos/task.h" -void abort() { - do - { - __asm__ ("break 0,0"); - *((int*) 0) = 0; - } while(true); -} - -void* _malloc_r(struct _reent *r, size_t size) { - return pvPortMalloc(size); -} - -void _free_r(struct _reent *r, void* ptr) { - return vPortFree(ptr); -} - -void* _realloc_r(struct _reent *r, void* ptr, size_t size) { - void* new_chunk; - if (size == 0) { - if (ptr) { - vPortFree(ptr); - } - return NULL; - } - - new_chunk = pvPortMalloc(size); - if (new_chunk && ptr) { - memcpy(new_chunk, ptr, size); - vPortFree(ptr); - } - // realloc behaviour: don't free original chunk if alloc failed - return new_chunk; -} - -void* _calloc_r(struct _reent *r, size_t count, size_t size) { - void* result = pvPortMalloc(count * size); - if (result) - { - memset(result, 0, count * size); - } - return result; -} - -int _system_r(struct _reent *r, const char *str) { - abort(); - return 0; -} - -int _rename_r(struct _reent *r, const char *src, const char *dst) { - abort(); - return 0; -} - -clock_t _times_r(struct _reent *r, struct tms *ptms) { - abort(); - return 0; -} - -// TODO: read time from RTC -int _gettimeofday_r(struct _reent *r, struct timeval *tv, void *tz) { - abort(); - return 0; -} - -void _raise_r(struct _reent *r) { - abort(); -} - -int _unlink_r(struct _reent *r, const char *path) { - abort(); - return 0; -} - -int _link_r(struct _reent *r, const char* n1, const char* n2) { - abort(); - return 0; -} - -int _stat_r(struct _reent *r, const char * path, struct stat * st) { - return 0; -} - -int _fstat_r(struct _reent *r, int fd, struct stat * st) { - st->st_mode = S_IFCHR; - return 0; -} - -void* _sbrk_r(struct _reent *r, ptrdiff_t sz) { - abort(); - return 0; -} - -int _getpid_r(struct _reent *r) { - abort(); - return 0; -} - -int _kill_r(struct _reent *r, int pid, int sig) { - abort(); - return 0; -} - -void _exit_r(struct _reent *r, int e) { - abort(); -} - -int _close_r(struct _reent *r, int fd) { - return 0; -} - -int _open_r(struct _reent *r, const char * path, int flags, int mode) { - return 0; -} - -void _exit(int __status) { - abort(); -} - -ssize_t _write_r(struct _reent *r, int fd, const void * data, size_t size) { - const char *data_c = (const char *)data; - if (fd == STDOUT_FILENO) { - static _lock_t stdout_lock; /* lazily initialised */ - /* Even though newlib does stream locking on stdout, we need - a dedicated stdout UART lock... - - This is because each task has its own _reent structure with - unique FILEs for stdin/stdout/stderr, so these are - per-thread (lazily initialised by __sinit the first time a - stdio function is used, see findfp.c:235. - - It seems like overkill to allocate a FILE-per-task and lock - a thread-local stream, but I see no easy way to fix this - (pre-__sinit_, tasks have "fake" FILEs ie __sf_fake_stdout - which aren't fully valid.) - */ - _lock_acquire_recursive(&stdout_lock); - for (size_t i = 0; i < size; i++) { -#if CONFIG_NEWLIB_STDOUT_ADDCR - if (data_c[i]=='\n') { - uart_tx_one_char('\r'); - } -#endif - uart_tx_one_char(data_c[i]); - } - _lock_release_recursive(&stdout_lock); - } - return size; -} - -_off_t _lseek_r(struct _reent *r, int fd, _off_t size, int mode) { - return 0; -} - -// TODO: implement reading from UART -ssize_t _read_r(struct _reent *r, int fd, void * dst, size_t size) { - return 0; -} - /* Notes on our newlib lock implementation: * * - Use FreeRTOS mutex semaphores as locks. @@ -369,89 +205,3 @@ void IRAM_ATTR _lock_release(_lock_t *lock) { void IRAM_ATTR _lock_release_recursive(_lock_t *lock) { lock_release_generic(lock, queueQUEUE_TYPE_RECURSIVE_MUTEX); } - -// This function is not part on newlib API, it is defined in libc/stdio/local.h -// It is called as part of _reclaim_reent via a pointer in __cleanup member -// of struct _reent. -// This function doesn't call _fclose_r for _stdin, _stdout, _stderr members -// of struct reent. Not doing so causes a memory leak each time a task is -// terminated. We replace __cleanup member with _extra_cleanup_r (below) to work -// around this. -extern void _cleanup_r(struct _reent* r); - -void _extra_cleanup_r(struct _reent* r) -{ - _cleanup_r(r); - _fclose_r(r, r->_stdout); - _fclose_r(r, r->_stderr); - _fclose_r(r, r->_stdin); -} - -static struct _reent s_reent; - -/* - General ToDo that the Xtensa newlib support code did but we do not: Close every open fd a running task had when the task - is killed. Do we want that too? - JD -*/ - -extern int _printf_float(struct _reent *rptr, - void *pdata, - FILE * fp, - int (*pfunc) (struct _reent *, FILE *, _CONST char *, size_t len), - va_list * ap); - - -extern int _scanf_float(struct _reent *rptr, - void *pdata, - FILE *fp, - va_list *ap); - - -static struct syscall_stub_table s_stub_table = { - .__getreent = &__getreent, - ._malloc_r = &_malloc_r, - ._free_r = &_free_r, - ._realloc_r = &_realloc_r, - ._calloc_r = &_calloc_r, - ._abort = &abort, - ._system_r = &_system_r, - ._rename_r = &_rename_r, - ._times_r = &_times_r, - ._gettimeofday_r = &_gettimeofday_r, - ._raise_r = &_raise_r, - ._unlink_r = &_unlink_r, - ._link_r = &_link_r, - ._stat_r = &_stat_r, - ._fstat_r = &_fstat_r, - ._sbrk_r = &_sbrk_r, - ._getpid_r = &_getpid_r, - ._kill_r = &_kill_r, - ._exit_r = &_exit_r, - ._close_r = &_close_r, - ._open_r = &_open_r, - ._write_r = (int (*)(struct _reent *r, int, const void *, int)) &_write_r, - ._lseek_r = (int (*)(struct _reent *r, int, int, int)) &_lseek_r, - ._read_r = (int (*)(struct _reent *r, int, void *, int)) &_read_r, - ._lock_init = &_lock_init, - ._lock_init_recursive = &_lock_init_recursive, - ._lock_close = &_lock_close, - ._lock_close_recursive = &_lock_close, - ._lock_acquire = &_lock_acquire, - ._lock_acquire_recursive = &_lock_acquire_recursive, - ._lock_try_acquire = &_lock_try_acquire, - ._lock_try_acquire_recursive = &_lock_try_acquire_recursive, - ._lock_release = &_lock_release, - ._lock_release_recursive = &_lock_release_recursive, - ._printf_float = &_printf_float, - ._scanf_float = &_scanf_float, -}; - -void ets_setup_syscalls() { - syscall_table_ptr_pro = &s_stub_table; - syscall_table_ptr_app = &s_stub_table; - _GLOBAL_REENT = &s_reent; - environ = malloc(sizeof(char*)); - environ[0] = NULL; -} - - diff --git a/components/newlib/platform_include/esp_newlib.h b/components/newlib/platform_include/esp_newlib.h new file mode 100644 index 0000000000..74d0cc5e5e --- /dev/null +++ b/components/newlib/platform_include/esp_newlib.h @@ -0,0 +1,27 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef __ESP_NEWLIB_H__ +#define __ESP_NEWLIB_H__ + +/** + * Function which sets up syscall table used by newlib functions in ROM. + * + * Called from the startup code, not intended to be called from application + * code. + */ +void esp_setup_syscalls(); + + +#endif //__ESP_NEWLIB_H__ diff --git a/components/newlib/syscall_table.c b/components/newlib/syscall_table.c new file mode 100644 index 0000000000..b6414af554 --- /dev/null +++ b/components/newlib/syscall_table.c @@ -0,0 +1,91 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "rom/libc_stubs.h" +#include "esp_vfs.h" + +static struct _reent s_reent; + +extern int _printf_float(struct _reent *rptr, + void *pdata, + FILE * fp, + int (*pfunc) (struct _reent *, FILE *, _CONST char *, size_t len), + va_list * ap); + + +extern int _scanf_float(struct _reent *rptr, + void *pdata, + FILE *fp, + va_list *ap); + + +static struct syscall_stub_table s_stub_table = { + .__getreent = &__getreent, + ._malloc_r = &_malloc_r, + ._free_r = &_free_r, + ._realloc_r = &_realloc_r, + ._calloc_r = &_calloc_r, + ._abort = &abort, + ._system_r = &_system_r, + ._rename_r = &esp_vfs_rename, + ._times_r = &_times_r, + ._gettimeofday_r = &_gettimeofday_r, + ._raise_r = (void (*)(struct _reent *r)) &_raise_r, + ._unlink_r = &esp_vfs_unlink, + ._link_r = &esp_vfs_link, + ._stat_r = &esp_vfs_stat, + ._fstat_r = &esp_vfs_fstat, + ._sbrk_r = &_sbrk_r, + ._getpid_r = &_getpid_r, + ._kill_r = &_kill_r, + ._exit_r = NULL, // never called in ROM + ._close_r = &esp_vfs_close, + ._open_r = &esp_vfs_open, + ._write_r = (int (*)(struct _reent *r, int, const void *, int)) &esp_vfs_write, + ._lseek_r = (int (*)(struct _reent *r, int, int, int)) &esp_vfs_lseek, + ._read_r = (int (*)(struct _reent *r, int, void *, int)) &esp_vfs_read, + ._lock_init = &_lock_init, + ._lock_init_recursive = &_lock_init_recursive, + ._lock_close = &_lock_close, + ._lock_close_recursive = &_lock_close, + ._lock_acquire = &_lock_acquire, + ._lock_acquire_recursive = &_lock_acquire_recursive, + ._lock_try_acquire = &_lock_try_acquire, + ._lock_try_acquire_recursive = &_lock_try_acquire_recursive, + ._lock_release = &_lock_release, + ._lock_release_recursive = &_lock_release_recursive, + ._printf_float = &_printf_float, + ._scanf_float = &_scanf_float, +}; + +void esp_setup_syscalls() +{ + syscall_table_ptr_pro = &s_stub_table; + syscall_table_ptr_app = &s_stub_table; + _GLOBAL_REENT = &s_reent; + environ = malloc(sizeof(char*)); + environ[0] = NULL; +} + + diff --git a/components/newlib/syscalls.c b/components/newlib/syscalls.c new file mode 100644 index 0000000000..4d70a39a8d --- /dev/null +++ b/components/newlib/syscalls.c @@ -0,0 +1,105 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include +#include +#include +#include +#include "esp_attr.h" +#include "freertos/FreeRTOS.h" + +void IRAM_ATTR abort() +{ + do + { + __asm__ ("break 0,0"); + *((int*) 0) = 0; + } while(true); +} + +void* IRAM_ATTR _malloc_r(struct _reent *r, size_t size) +{ + return pvPortMalloc(size); +} + +void IRAM_ATTR _free_r(struct _reent *r, void* ptr) +{ + return vPortFree(ptr); +} + +void* IRAM_ATTR _realloc_r(struct _reent *r, void* ptr, size_t size) +{ + void* new_chunk; + if (size == 0) { + if (ptr) { + vPortFree(ptr); + } + return NULL; + } + + new_chunk = pvPortMalloc(size); + if (new_chunk && ptr) { + memcpy(new_chunk, ptr, size); + vPortFree(ptr); + } + // realloc behaviour: don't free original chunk if alloc failed + return new_chunk; +} + +void* IRAM_ATTR _calloc_r(struct _reent *r, size_t count, size_t size) +{ + void* result = pvPortMalloc(count * size); + if (result) + { + memset(result, 0, count * size); + } + return result; +} + +int _system_r(struct _reent *r, const char *str) +{ + __errno_r(r) = ENOSYS; + return -1; +} + +void _raise_r(struct _reent *r) +{ + abort(); +} + +void* _sbrk_r(struct _reent *r, ptrdiff_t sz) +{ + abort(); +} + +int _getpid_r(struct _reent *r) +{ + __errno_r(r) = ENOSYS; + return -1; +} + +int _kill_r(struct _reent *r, int pid, int sig) +{ + __errno_r(r) = ENOSYS; + return -1; +} + +void _exit(int __status) +{ + abort(); +} + diff --git a/components/newlib/time.c b/components/newlib/time.c new file mode 100644 index 0000000000..cb2efb4e19 --- /dev/null +++ b/components/newlib/time.c @@ -0,0 +1,35 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include +#include +#include +#include "esp_attr.h" + + +clock_t _times_r(struct _reent *r, struct tms *ptms) +{ + __errno_r(r) = ENOSYS; + return (clock_t) -1; +} + +// TODO: read time from RTC +int _gettimeofday_r(struct _reent *r, struct timeval *tv, void *tz) +{ + __errno_r(r) = ENOSYS; + return (clock_t) -1; +} From 0c130ecf19a8c1fe9803dba75148028965898f8b Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 25 Oct 2016 22:16:08 +0800 Subject: [PATCH 158/343] vfs: code review fixes - fix typo in readme - remove unneeded extern declaration - fix header guard macro - tabs->spaces in syscalls.c (+1 squashed commit) - fix minor typos --- components/esp32/cpu_start.c | 6 +++ components/freertos/tasks.c | 8 ++-- .../newlib/platform_include/esp_newlib.h | 10 +++++ components/newlib/reent_init.c | 45 +++++++++++++++++++ 4 files changed, 64 insertions(+), 5 deletions(-) create mode 100644 components/newlib/reent_init.c diff --git a/components/esp32/cpu_start.c b/components/esp32/cpu_start.c index cbac54d7c3..769bd3eaf3 100644 --- a/components/esp32/cpu_start.c +++ b/components/esp32/cpu_start.c @@ -42,6 +42,7 @@ #include "esp_spi_flash.h" #include "esp_ipc.h" #include "esp_log.h" +#include "esp_vfs_dev.h" #include "esp_newlib.h" #include "esp_brownout.h" #include "esp_int_wdt.h" @@ -161,6 +162,11 @@ void start_cpu0_default(void) esp_task_wdt_init(); #endif esp_setup_syscalls(); + esp_vfs_dev_uart_register(); + esp_reent_init(_GLOBAL_REENT); + _GLOBAL_REENT->_stdout = fopen("/dev/uart/0", "w"); // use fdopen here? + _GLOBAL_REENT->_stderr = _GLOBAL_REENT->_stdout; + _GLOBAL_REENT->_stdin = _GLOBAL_REENT->_stdout; do_global_ctors(); esp_ipc_init(); spi_flash_init(); diff --git a/components/freertos/tasks.c b/components/freertos/tasks.c index 9f004002c5..6a7eb50347 100644 --- a/components/freertos/tasks.c +++ b/components/freertos/tasks.c @@ -77,6 +77,7 @@ task.h is included from an application file. */ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE #include "rom/ets_sys.h" +#include "esp_newlib.h" /* FreeRTOS includes. */ #include "FreeRTOS.h" @@ -962,8 +963,8 @@ UBaseType_t x; #if ( configUSE_NEWLIB_REENTRANT == 1 ) { - /* Initialise this task's Newlib reent structure. */ - _REENT_INIT_PTR( ( &( pxNewTCB->xNewLib_reent ) ) ); + /* Initialise this task's Newlib reent structure. */ + esp_reent_init(&pxNewTCB->xNewLib_reent); } #endif @@ -3643,8 +3644,6 @@ BaseType_t xTaskGetAffinity( TaskHandle_t xTask ) #if ( INCLUDE_vTaskDelete == 1 ) - // TODO: move this to newlib component and provide a header file - extern void _extra_cleanup_r(struct _reent* r); static void prvDeleteTCB( TCB_t *pxTCB ) { @@ -3657,7 +3656,6 @@ BaseType_t xTaskGetAffinity( TaskHandle_t xTask ) to the task to free any memory allocated at the application level. */ #if ( configUSE_NEWLIB_REENTRANT == 1 ) { - pxTCB->xNewLib_reent.__cleanup = &_extra_cleanup_r; _reclaim_reent( &( pxTCB->xNewLib_reent ) ); } #endif /* configUSE_NEWLIB_REENTRANT */ diff --git a/components/newlib/platform_include/esp_newlib.h b/components/newlib/platform_include/esp_newlib.h index 74d0cc5e5e..468f2ae34f 100644 --- a/components/newlib/platform_include/esp_newlib.h +++ b/components/newlib/platform_include/esp_newlib.h @@ -15,6 +15,16 @@ #ifndef __ESP_NEWLIB_H__ #define __ESP_NEWLIB_H__ +#include + +/** + * Replacement for newlib's _REENT_INIT_PTR and __sinit. + * + * Called from startup code and FreeRTOS, not intended to be called from + * application code. + */ +void esp_reent_init(struct _reent* r); + /** * Function which sets up syscall table used by newlib functions in ROM. * diff --git a/components/newlib/reent_init.c b/components/newlib/reent_init.c new file mode 100644 index 0000000000..5c29e898c6 --- /dev/null +++ b/components/newlib/reent_init.c @@ -0,0 +1,45 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include "esp_attr.h" + +/* This function is not part on newlib API, it is defined in libc/stdio/local.h + * There is no nice way to get __cleanup member populated while avoiding __sinit, + * so extern declaration is used here. + */ +extern void _cleanup_r(struct _reent* r); + +/** + * This is the replacement for newlib's _REENT_INIT_PTR and __sinit. + * The problem with __sinit is that it allocates three FILE structures + * (stdin, stdout, stderr). Having individual standard streams for each task + * is a bit too much on a small embedded system. So we point streams + * to the streams of the global struct _reent, which are initialized in + * startup code. + */ +void IRAM_ATTR esp_reent_init(struct _reent* r) +{ + memset(r, 0, sizeof(*r)); + r->_stdout = _GLOBAL_REENT->_stdout; + r->_stderr = _GLOBAL_REENT->_stderr; + r->_stdin = _GLOBAL_REENT->_stdin; + r->__cleanup = &_cleanup_r; + r->__sdidinit = 1; + r->__sglue._next = NULL; + r->__sglue._niobs = 0; + r->__sglue._iobs = NULL; + r->_current_locale = "C"; +} From 7e201c55276649df496baed44a003fa9d958de60 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Wed, 26 Oct 2016 14:05:56 +0800 Subject: [PATCH 159/343] vfs and newlib: small fixes - spaces->tabs in tasks.c - update vfs_uart.c to use per-UART locks - add license to vfs_uart.c - allocate separate streams for stdout, stdin, stderr, so that they can be independently reassigned - fix build system test failure - use posix off_t instead of newlib internal _off_t --- components/esp32/cpu_start.c | 7 +++--- components/vfs/include/esp_vfs.h | 6 ++--- components/vfs/vfs.c | 2 +- components/vfs/vfs_uart.c | 38 ++++++++++++++++++-------------- make/test_build_system.sh | 4 ++-- 5 files changed, 32 insertions(+), 25 deletions(-) diff --git a/components/esp32/cpu_start.c b/components/esp32/cpu_start.c index 769bd3eaf3..6998140aff 100644 --- a/components/esp32/cpu_start.c +++ b/components/esp32/cpu_start.c @@ -164,9 +164,10 @@ void start_cpu0_default(void) esp_setup_syscalls(); esp_vfs_dev_uart_register(); esp_reent_init(_GLOBAL_REENT); - _GLOBAL_REENT->_stdout = fopen("/dev/uart/0", "w"); // use fdopen here? - _GLOBAL_REENT->_stderr = _GLOBAL_REENT->_stdout; - _GLOBAL_REENT->_stdin = _GLOBAL_REENT->_stdout; + const char* default_uart_dev = "/dev/uart/0"; + _GLOBAL_REENT->_stdout = fopen(default_uart_dev, "w"); + _GLOBAL_REENT->_stderr = fopen(default_uart_dev, "w"); + _GLOBAL_REENT->_stdin = fopen(default_uart_dev, "r"); do_global_ctors(); esp_ipc_init(); spi_flash_init(); diff --git a/components/vfs/include/esp_vfs.h b/components/vfs/include/esp_vfs.h index 0d1c3d1479..2d9e52c5af 100644 --- a/components/vfs/include/esp_vfs.h +++ b/components/vfs/include/esp_vfs.h @@ -71,8 +71,8 @@ typedef struct size_t (*write)(int fd, const void * data, size_t size); }; union { - _off_t (*lseek_p)(void* p, int fd, _off_t size, int mode); - _off_t (*lseek)(int fd, _off_t size, int mode); + off_t (*lseek_p)(void* p, int fd, off_t size, int mode); + off_t (*lseek)(int fd, off_t size, int mode); }; union { ssize_t (*read_p)(void* ctx, int fd, void * dst, size_t size); @@ -137,7 +137,7 @@ esp_err_t esp_vfs_register(const char* base_path, const esp_vfs_t* vfs, void* ct */ ssize_t esp_vfs_write(struct _reent *r, int fd, const void * data, size_t size); -_off_t esp_vfs_lseek(struct _reent *r, int fd, _off_t size, int mode); +off_t esp_vfs_lseek(struct _reent *r, int fd, off_t size, int mode); ssize_t esp_vfs_read(struct _reent *r, int fd, void * dst, size_t size); int esp_vfs_open(struct _reent *r, const char * path, int flags, int mode); int esp_vfs_close(struct _reent *r, int fd); diff --git a/components/vfs/vfs.c b/components/vfs/vfs.c index afc7149bad..bf26968ff7 100644 --- a/components/vfs/vfs.c +++ b/components/vfs/vfs.c @@ -167,7 +167,7 @@ ssize_t esp_vfs_write(struct _reent *r, int fd, const void * data, size_t size) return ret; } -_off_t esp_vfs_lseek(struct _reent *r, int fd, _off_t size, int mode) +off_t esp_vfs_lseek(struct _reent *r, int fd, off_t size, int mode) { const vfs_entry_t* vfs = get_vfs_for_fd(fd); if (vfs == NULL) { diff --git a/components/vfs/vfs_uart.c b/components/vfs/vfs_uart.c index 179c5e2585..6b6fad8e4b 100644 --- a/components/vfs/vfs_uart.c +++ b/components/vfs/vfs_uart.c @@ -1,3 +1,17 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #include #include "esp_vfs.h" #include "esp_attr.h" @@ -6,6 +20,7 @@ #include "soc/uart_struct.h" static uart_dev_t* s_uarts[3] = {&UART0, &UART1, &UART2}; +static _lock_t s_uart_locks[3]; // per-UART locks, lazily initialized static int IRAM_ATTR uart_open(const char * path, int flags, int mode) { @@ -36,21 +51,12 @@ static size_t IRAM_ATTR uart_write(int fd, const void * data, size_t size) assert(fd >=0 && fd < 3); const char *data_c = (const char *)data; uart_dev_t* uart = s_uarts[fd]; - static _lock_t stdout_lock; /* lazily initialised */ - /* Even though newlib does stream locking on stdout, we need - a dedicated stdout UART lock... - - This is because each task has its own _reent structure with - unique FILEs for stdin/stdout/stderr, so these are - per-thread (lazily initialised by __sinit the first time a - stdio function is used, see findfp.c:235. - - It seems like overkill to allocate a FILE-per-task and lock - a thread-local stream, but I see no easy way to fix this - (pre-__sinit_, tasks have "fake" FILEs ie __sf_fake_stdout - which aren't fully valid.) - */ - _lock_acquire_recursive(&stdout_lock); + /* + * Even though newlib does stream locking on each individual stream, we need + * a dedicated UART lock if two streams (stdout and stderr) point to the + * same UART. + */ + _lock_acquire_recursive(&s_uart_locks[fd]); for (size_t i = 0; i < size; i++) { #if CONFIG_NEWLIB_STDOUT_ADDCR if (data_c[i]=='\n') { @@ -59,7 +65,7 @@ static size_t IRAM_ATTR uart_write(int fd, const void * data, size_t size) #endif uart_tx_char(uart, data_c[i]); } - _lock_release_recursive(&stdout_lock); + _lock_release_recursive(&s_uart_locks[fd]); return size; } diff --git a/make/test_build_system.sh b/make/test_build_system.sh index 7c8cbc1f1e..d08ae6c8a2 100755 --- a/make/test_build_system.sh +++ b/make/test_build_system.sh @@ -59,9 +59,9 @@ function run_tests() print_status "Updating component source file rebuilds component" # touch a file & do a build take_build_snapshot - touch ${IDF_PATH}/components/esp32/syscalls.c + touch ${IDF_PATH}/components/esp32/cpu_start.c make || failure "Failed to partial build" - assert_rebuilt ${APP_BINS} esp32/libesp32.a esp32/syscalls.o + assert_rebuilt ${APP_BINS} esp32/libesp32.a esp32/cpu_start.o assert_not_rebuilt lwip/liblwip.a freertos/libfreertos.a ${BOOTLOADER_BINS} partitions_singleapp.bin print_status "Bootloader source file rebuilds bootloader" From da56e7625503773dba62d58c93c18fbd879cce76 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Wed, 26 Oct 2016 16:47:26 +0800 Subject: [PATCH 160/343] vfs: add readme file --- components/vfs/README.rst | 125 +++++++++++++++++++++++++++++++++++++- components/vfs/vfs_uart.c | 1 + 2 files changed, 124 insertions(+), 2 deletions(-) diff --git a/components/vfs/README.rst b/components/vfs/README.rst index b32e22ccf8..21b687e78e 100644 --- a/components/vfs/README.rst +++ b/components/vfs/README.rst @@ -1,2 +1,123 @@ -Virtual filesystem (VFS) is a driver which can perform operations on file-like objects. This can be a real filesystem (FAT, SPIFFS, etc.), or a device driver which exposes file-like interface. - \ No newline at end of file +Virtual filesystem component +============================ + +Overview +-------- + +Virtual filesystem (VFS) component provides a unified interface for drivers which can perform operations on file-like objects. This can be a real filesystems (FAT, SPIFFS, etc.), or device drivers which exposes file-like interface. + +This component allows C library functions, such as fopen and fprintf, to work with FS drivers. At high level, each FS driver is associated with some path prefix. When one of C library functions needs to open a file, VFS component searches for the FS driver associated with the file's path, and forwards the call to that driver. VFS also forwards read, write, and other calls for the given file to the same FS driver. + +For example, one can register a FAT filesystem driver with ``/fat`` prefix, and call ``fopen("/fat/file.txt", "w")``. VFS component will the call ``open`` function of FAT driver and pass ``/file.txt`` argument to it (and appropriate mode flags). All subsequent calls to C library functions for the returned ``FILE*`` stream will also be forwarded to the FAT driver. + +FS registration +--------------- + +To register an FS driver, application needs to define in instance of esp_vfs_t structure and populate it with function pointers to FS APIs:: + + esp_vfs_t myfs = { + .fd_offset = 0, + .flags = ESP_VFS_FLAG_DEFAULT, + .write = &myfs_write, + .open = &myfs_open, + .fstat = &myfs_fstat, + .close = &myfs_close, + .read = &myfs_read, + .lseek = NULL, + .stat = NULL, + .link = NULL, + .unlink = NULL, + .rename = NULL + }; + + ESP_ERROR_CHECK(esp_vfs_register("/data", &myfs, NULL)); + +Depending on the way FS driver declares it's APIs, either ``read``, ``write``, etc., or ``read_p``, ``write_p``, etc. should be used. + +Case 1: API functions are declared without an extra context pointer (FS driver is a singleton):: + + size_t myfs_write(int fd, const void * data, size_t size); + + // In definition of esp_vfs_t: + .flags = ESP_VFS_FLAG_DEFAULT, + .write = &myfs_write, + // ... other member initialized + + // When registering FS, context pointer (third argument) is NULL: + ESP_ERROR_CHECK(esp_vfs_register("/data", &myfs, NULL)); + +Case 2: API functions are declared with an extra context pointer (FS driver supports multiple instances):: + + size_t myfs_write(myfs_t* fs, int fd, const void * data, size_t size); + + // In definition of esp_vfs_t: + .flags = ESP_VFS_FLAG_CONTEXT_PTR, + .write_p = &myfs_write, + // ... other member initialized + + // When registering FS, pass the FS context pointer into the third argument + // (hypothetical myfs_mount function is used for illustrative purposes) + myfs_t* myfs_inst1 = myfs_mount(partition1->offset, parition1->size); + ESP_ERROR_CHECK(esp_vfs_register("/data1", &myfs, myfs_inst1)); + + // Can register another instance: + myfs_t* myfs_inst2 = myfs_mount(partition2->offset, parition2->size); + ESP_ERROR_CHECK(esp_vfs_register("/data2", &myfs, myfs_inst2)); + +Paths +----- + +Each registered FS has a path prefix associated with it. This prefix may be considered a "mount point" of this partition. + +Registering mount points which have another mount point as a prefix is not supported and results in undefined behavior. For instance, the following is correct and supported: + +- FS 1 on /data/fs1 +- FS 2 on /data/fs2 + +This **will not work** as expected: + +- FS 1 on /data +- FS 2 on /data/fs2 + +When opening files, FS driver will only be given relative path to files. If the ``myfs`` driver is registered with ``/data`` as prefix, and application calls ``fopen("/data/config.json", ...)``, VFS component will call ``myfs_open("/config.json", ...)``. + +VFS doesn't impose a limit on total file path length, but it does limit FS path prefix to ``ESP_VFS_PATH_MAX`` characters. Individual FS drivers may have their own filename length limitations. + + +File descriptors +---------------- + +It is suggested that filesystem drivers should use small positive integers as file descriptors. VFS component assumes that ``CONFIG_MAX_FD_BITS`` bits (12 by default) are sufficient to represent a file descriptor. + +If filesystem is configured with an option to offset all file descriptors by a constant value, such value should be passed to ``fd_offset`` field of ``esp_vfs_t`` structure. VFS component will then remove this offset when working with FDs of that specific FS, bringing them into the range of small positive integers. + +While file descriptors returned by VFS component to newlib library are rarely seen by the application, the following details may be useful for debugging purposes. File descriptors returned by VFS component are composed of two parts: FS driver ID, and the actual file descriptor. Because newlib stores file descriptors as 16-bit integers, VFS component is also limited by 16 bits to store both parts. + +Lower ``CONFIG_MAX_FD_BITS`` bits are used to store zero-based file descriptor. If FS driver has a non-zero ``fd_offset`` field, this ``fd_offset`` is subtracted FDs obtained from the FS ``open`` call, and the result is stored in the lower bits of the FD. Higher bits are used to save the index of FS in the internal table of registered filesystems. + +When VFS component receives a call from newlib which has a file descriptor, this file descriptor is translated back to the FS-specific file descriptor. First, higher bits of FD are used to identify the FS. Then ``fd_offset`` field of the FS is added to the lower ``CONFIG_MAX_FD_BITS`` bits of the fd, and resulting FD is passed to the FS driver. + +:: + + FD as seen by newlib FD as seen by FS driver + +-----+ + +-------+---------------+ | | +------------------------+ + | FS id | Zero—based FD | +---------------> sum +----> | + +---+---+------+--------+ | | | +------------------------+ + | | | +--^--+ + | +--------------+ | + | | + | +-------------+ | + | | Table of | | + | | registered | | + | | filesystems | | + | +-------------+ +-------------+ | + +-------> entry +----> esp_vfs_t | | + index +-------------+ | structure | | + | | | | | + | | | + fd_offset +---+ + +-------------+ | | + +-------------+ + + + diff --git a/components/vfs/vfs_uart.c b/components/vfs/vfs_uart.c index 6b6fad8e4b..bfccad8963 100644 --- a/components/vfs/vfs_uart.c +++ b/components/vfs/vfs_uart.c @@ -92,6 +92,7 @@ void esp_vfs_dev_uart_register() .fstat = &uart_fstat, .close = &uart_close, .read = NULL, // TODO: implement reading from UART + .lseek = NULL, .stat = NULL, .link = NULL, .unlink = NULL, From 6f1d3ce4a7c782f8001574b96e37fc781f6f09c4 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Thu, 27 Oct 2016 11:47:41 +0800 Subject: [PATCH 161/343] vfs: code review fixes - fix typo in readme - remove unneeded extern declaration - fix header guard macro - tabs->spaces in syscalls.c - spaces->tabs in tasks.c --- components/esp32/cpu_start.c | 1 - components/freertos/tasks.c | 4 ++-- components/newlib/syscalls.c | 32 ++++++++++++++-------------- components/newlib/time.c | 2 +- components/vfs/README.rst | 19 +++++++++++------ components/vfs/include/esp_vfs_dev.h | 6 +++--- 6 files changed, 34 insertions(+), 30 deletions(-) diff --git a/components/esp32/cpu_start.c b/components/esp32/cpu_start.c index 6998140aff..12189ccf66 100644 --- a/components/esp32/cpu_start.c +++ b/components/esp32/cpu_start.c @@ -60,7 +60,6 @@ static bool app_cpu_started = false; static void do_global_ctors(void); static void main_task(void* args); -extern void ets_setup_syscalls(void); extern void app_main(void); extern int _bss_start; diff --git a/components/freertos/tasks.c b/components/freertos/tasks.c index 6a7eb50347..64cc3a65df 100644 --- a/components/freertos/tasks.c +++ b/components/freertos/tasks.c @@ -963,8 +963,8 @@ UBaseType_t x; #if ( configUSE_NEWLIB_REENTRANT == 1 ) { - /* Initialise this task's Newlib reent structure. */ - esp_reent_init(&pxNewTCB->xNewLib_reent); + /* Initialise this task's Newlib reent structure. */ + esp_reent_init(&pxNewTCB->xNewLib_reent); } #endif diff --git a/components/newlib/syscalls.c b/components/newlib/syscalls.c index 4d70a39a8d..3b2fbf62ca 100644 --- a/components/newlib/syscalls.c +++ b/components/newlib/syscalls.c @@ -38,26 +38,26 @@ void* IRAM_ATTR _malloc_r(struct _reent *r, size_t size) void IRAM_ATTR _free_r(struct _reent *r, void* ptr) { - return vPortFree(ptr); + vPortFree(ptr); } void* IRAM_ATTR _realloc_r(struct _reent *r, void* ptr, size_t size) { - void* new_chunk; - if (size == 0) { - if (ptr) { - vPortFree(ptr); - } - return NULL; - } + void* new_chunk; + if (size == 0) { + if (ptr) { + vPortFree(ptr); + } + return NULL; + } - new_chunk = pvPortMalloc(size); - if (new_chunk && ptr) { - memcpy(new_chunk, ptr, size); - vPortFree(ptr); - } - // realloc behaviour: don't free original chunk if alloc failed - return new_chunk; + new_chunk = pvPortMalloc(size); + if (new_chunk && ptr) { + memcpy(new_chunk, ptr, size); + vPortFree(ptr); + } + // realloc behaviour: don't free original chunk if alloc failed + return new_chunk; } void* IRAM_ATTR _calloc_r(struct _reent *r, size_t count, size_t size) @@ -65,7 +65,7 @@ void* IRAM_ATTR _calloc_r(struct _reent *r, size_t count, size_t size) void* result = pvPortMalloc(count * size); if (result) { - memset(result, 0, count * size); + memset(result, 0, count * size); } return result; } diff --git a/components/newlib/time.c b/components/newlib/time.c index cb2efb4e19..021b295451 100644 --- a/components/newlib/time.c +++ b/components/newlib/time.c @@ -31,5 +31,5 @@ clock_t _times_r(struct _reent *r, struct tms *ptms) int _gettimeofday_r(struct _reent *r, struct timeval *tv, void *tz) { __errno_r(r) = ENOSYS; - return (clock_t) -1; + return -1; } diff --git a/components/vfs/README.rst b/components/vfs/README.rst index 21b687e78e..c58161c900 100644 --- a/components/vfs/README.rst +++ b/components/vfs/README.rst @@ -8,7 +8,7 @@ Virtual filesystem (VFS) component provides a unified interface for drivers whic This component allows C library functions, such as fopen and fprintf, to work with FS drivers. At high level, each FS driver is associated with some path prefix. When one of C library functions needs to open a file, VFS component searches for the FS driver associated with the file's path, and forwards the call to that driver. VFS also forwards read, write, and other calls for the given file to the same FS driver. -For example, one can register a FAT filesystem driver with ``/fat`` prefix, and call ``fopen("/fat/file.txt", "w")``. VFS component will the call ``open`` function of FAT driver and pass ``/file.txt`` argument to it (and appropriate mode flags). All subsequent calls to C library functions for the returned ``FILE*`` stream will also be forwarded to the FAT driver. +For example, one can register a FAT filesystem driver with ``/fat`` prefix, and call ``fopen("/fat/file.txt", "w")``. VFS component will then call ``open`` function of FAT driver and pass ``/file.txt`` argument to it (and appropriate mode flags). All subsequent calls to C library functions for the returned ``FILE*`` stream will also be forwarded to the FAT driver. FS registration --------------- @@ -32,7 +32,7 @@ To register an FS driver, application needs to define in instance of esp_vfs_t s ESP_ERROR_CHECK(esp_vfs_register("/data", &myfs, NULL)); -Depending on the way FS driver declares it's APIs, either ``read``, ``write``, etc., or ``read_p``, ``write_p``, etc. should be used. +Depending on the way FS driver declares its APIs, either ``read``, ``write``, etc., or ``read_p``, ``write_p``, etc. should be used. Case 1: API functions are declared without an extra context pointer (FS driver is a singleton):: @@ -41,7 +41,7 @@ Case 1: API functions are declared without an extra context pointer (FS driver i // In definition of esp_vfs_t: .flags = ESP_VFS_FLAG_DEFAULT, .write = &myfs_write, - // ... other member initialized + // ... other members initialized // When registering FS, context pointer (third argument) is NULL: ESP_ERROR_CHECK(esp_vfs_register("/data", &myfs, NULL)); @@ -53,15 +53,15 @@ Case 2: API functions are declared with an extra context pointer (FS driver supp // In definition of esp_vfs_t: .flags = ESP_VFS_FLAG_CONTEXT_PTR, .write_p = &myfs_write, - // ... other member initialized + // ... other members initialized // When registering FS, pass the FS context pointer into the third argument // (hypothetical myfs_mount function is used for illustrative purposes) - myfs_t* myfs_inst1 = myfs_mount(partition1->offset, parition1->size); + myfs_t* myfs_inst1 = myfs_mount(partition1->offset, partition1->size); ESP_ERROR_CHECK(esp_vfs_register("/data1", &myfs, myfs_inst1)); // Can register another instance: - myfs_t* myfs_inst2 = myfs_mount(partition2->offset, parition2->size); + myfs_t* myfs_inst2 = myfs_mount(partition2->offset, partition2->size); ESP_ERROR_CHECK(esp_vfs_register("/data2", &myfs, myfs_inst2)); Paths @@ -79,7 +79,12 @@ This **will not work** as expected: - FS 1 on /data - FS 2 on /data/fs2 -When opening files, FS driver will only be given relative path to files. If the ``myfs`` driver is registered with ``/data`` as prefix, and application calls ``fopen("/data/config.json", ...)``, VFS component will call ``myfs_open("/config.json", ...)``. +When opening files, FS driver will only be given relative path to files. For example: + +- ``myfs`` driver is registered with ``/data`` as path prefix +- and application calls ``fopen("/data/config.json", ...)`` +- then VFS component will call ``myfs_open("/config.json", ...)``. +- ``myfs`` driver will open ``/config.json`` file VFS doesn't impose a limit on total file path length, but it does limit FS path prefix to ``ESP_VFS_PATH_MAX`` characters. Individual FS drivers may have their own filename length limitations. diff --git a/components/vfs/include/esp_vfs_dev.h b/components/vfs/include/esp_vfs_dev.h index 6eb63d852c..bb2579ee0a 100644 --- a/components/vfs/include/esp_vfs_dev.h +++ b/components/vfs/include/esp_vfs_dev.h @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef __ESP_VFS_H__ -#define __ESP_VFS_H__ +#ifndef __ESP_VFS_DEV_H__ +#define __ESP_VFS_DEV_H__ #include "esp_vfs.h" @@ -25,4 +25,4 @@ void esp_vfs_dev_uart_register(); -#endif //__ESP_VFS_H__ +#endif //__ESP_VFS_DEV_H__ From f6f23141b35dd3fbcf7fe4522766e732ea92df61 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Thu, 8 Sep 2016 19:18:03 +0800 Subject: [PATCH 162/343] components/spi_flash: add high level partition api header TW6701 --- components/spi_flash/include/esp_partition.h | 211 +++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 components/spi_flash/include/esp_partition.h diff --git a/components/spi_flash/include/esp_partition.h b/components/spi_flash/include/esp_partition.h new file mode 100644 index 0000000000..fd1223da51 --- /dev/null +++ b/components/spi_flash/include/esp_partition.h @@ -0,0 +1,211 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef __ESP_PARTITION_H__ +#define __ESP_PARTITION_H__ + +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +enum esp_partition_type_t { + PT_APP_MASK = 0x0000, + PT_APP_FACTORY = PT_APP_MASK | 0x00, + PT_APP_OTA_MIN = PT_APP_MASK | 0x10, + PT_APP_OTA_0 = PT_APP_OTA_MIN + 0, + PT_APP_OTA_1 = PT_APP_OTA_MIN + 1, + PT_APP_OTA_2 = PT_APP_OTA_MIN + 2, + PT_APP_OTA_3 = PT_APP_OTA_MIN + 3, + PT_APP_OTA_4 = PT_APP_OTA_MIN + 4, + PT_APP_OTA_5 = PT_APP_OTA_MIN + 5, + PT_APP_OTA_6 = PT_APP_OTA_MIN + 6, + PT_APP_OTA_7 = PT_APP_OTA_MIN + 7, + PT_APP_OTA_8 = PT_APP_OTA_MIN + 8, + PT_APP_OTA_9 = PT_APP_OTA_MIN + 9, + PT_APP_OTA_10 = PT_APP_OTA_MIN + 10, + PT_APP_OTA_11 = PT_APP_OTA_MIN + 11, + PT_APP_OTA_12 = PT_APP_OTA_MIN + 12, + PT_APP_OTA_13 = PT_APP_OTA_MIN + 13, + PT_APP_OTA_14 = PT_APP_OTA_MIN + 14, + PT_APP_OTA_15 = PT_APP_OTA_MIN + 15, + PT_APP_OTA_MAX = PT_APP_MASK | 0x1f, + PT_APP_TEST = PT_APP_MASK | 0x20, + PT_APP_ANY = PT_APP_MASK | 0xff, + + PT_DATA_MASK = 0x0100, + PT_DATA_OTA = PT_DATA_MASK | 0x00, + PT_DATA_RF = PT_DATA_MASK | 0x01, + PT_DATA_WIFI = PT_DATA_MASK | 0x02, + PT_DATA_ANY = PT_DATA_MASK | 0xff, + + PT_FILESYSTEM_MASK = 0x0200, + PT_FILESYSTEM_ESPHTTPD = 0x0200, + PT_FILESYSTEM_FAT = 0x0201, + PT_FILESYSTEM_SPIFFS = 0x0202, + PT_FILESYSTEM_ANY = 0x20ff, + + PT_END = 0xffff +}; + +#define PT_APP_OTA(i) ((esp_partition_type_t)(PT_APP_OTA_MIN + ((i) & 0xf))) + + +typedef struct esp_partition_iterator_opaque_t* esp_partition_iterator_t; + +/** + * @brief Find partition based on one or more parameters + * + * @param type Partition type, one of esp_partition_type_t values + * To find all app partitions or all filesystem partitions, + * use PT_APP_ANY or PT_FILESYSTEM_ANY, respectively. + * @param label (optional) Partition label. Set this value if looking + * for partition with a specific name. Pass NULL otherwise. + * + * @return iterator which can be used to enumerate all the partitions found, + * or NULL if no partitions were found. + * Iterator obtained through this function has to be released + * using esp_partition_iterator_release when not used any more. + */ +esp_partition_iterator_t esp_partition_find(esp_partition_type_t type, const char* label); + + +/** + * @brief Move partition iterator to the next partition found + * + * Any pointers obtained using esp_partition_label function for this iterator + * will be invalid after this call. + * + * @param iterator Iterator obtained using esp_partition_find. Must be non-NULL. + * + * @return iterator pointing to the next partition found, or NULL if no more + * partitions were found. + * + */ +esp_partition_iterator_t esp_partition_next(esp_partition_iterator_t iterator); + +/** + * @brief Get partition type + * + * @param iterator Iterator obtained using esp_partition_find. Must be non-NULL. + * + * @return esp_partition_type_t value for partition pointed to by the iterator. + */ +esp_partition_type_t esp_partition_type(esp_partition_iterator_t iterator); + +/** + * @brief Get partition size + * + * @param iterator Iterator obtained using esp_partition_find. Must be non-NULL. + * + * @return partition size, in bytes + */ +uint32_t esp_partition_size(esp_partition_iterator_t iterator); + +/** + * @brief Get partition address + * + * @param iterator Iterator obtained using esp_partition_find. Must be non-NULL. + * + * @return flash address of partition start + */ +uint32_t esp_partition_address(esp_partition_iterator_t iterator); + +/** + * @brief Get partition label + * + * @param iterator Iterator obtained using esp_partition_find. Must be non-NULL. + * + * @return pointer to a zero-terminated string with partition label. + * The pointer is valid until the call to esp_partition_next or + * esp_partition_iterator_release for the given iterator. + */ +const char* esp_partition_label(esp_partition_iterator_t iterator); + +/** + * @brief Read data from the partition + * + * @param iterator Iterator obtained using esp_partition_find. Must be non-NULL. + * @param src_offset Address of the data to be read, relative to the + * beginning of the partition. + * @param dst Pointer to the buffer where data should be stored. + * Must be non-NULL and at least 'size' bytes long. + * @param size Size of data to be read, in bytes. + * + * @return ESP_OK, if data was read successfully; + * ESP_INVALID_ARG, if iterator or src are NULL; + * ESP_INVALID_SIZE, if read would go out of bounds of the partition; + * or one of error codes from lower-level flash driver. + */ +esp_err_t esp_partition_read(esp_partition_iterator_t iterator, + uint32_t src_offset, uint8_t* dst, uint32_t size); + +/** + * @brief Write data to the partition + * + * @param iterator Iterator obtained using esp_partition_find. Must be non-NULL. + * @param src Pointer to the source buffer. Must be non-NULL and + * at least 'size' bytes long. + * @param dst_offset Address where the data should be written, relative to the + * beginning of the partition. + * @param size Size of data to be written, in bytes. + * + * @note Prior to writing to flash memory, make sure it has been erased with + * esp_partition_erase_range call. + * + * @return ESP_OK, if data was written successfully; + * ESP_INVALID_ARG, if iterator or dst are NULL; + * ESP_INVALID_SIZE, if write would go out of bounds of the partition; + * or one of error codes from lower-level flash driver. + */ +esp_err_t esp_partition_write(esp_partition_iterator_t iterator, + const uint8_t* src, uint32_t dst_offset, uint32_t size); + +/** + * @brief Erase part of the partition + * + * @param iterator Iterator obtained using esp_partition_find. Must be non-NULL. + * @param start_addr Address where erase operation should start. Must be aligned + * to 4 kilobytes. + * @param size Size of the range which should be erased, in bytes. + * Must be divisible by 4 kilobytes. + * + * @return ESP_OK, if the range was erased successfully; + * ESP_INVALID_ARG, if iterator or dst are NULL; + * ESP_INVALID_SIZE, if erase would go out of bounds of the partition; + * or one of error codes from lower-level flash driver. + */ +esp_err_t esp_partition_erase_range(esp_partition_iterator_t iterator, + uint32_t start_addr, uint32_t size); + + +/** + * @brief Release partition iterator + * + * Any pointers obtained using esp_partition_label function will be invalid + * after this call. + * + * @param iterator Iterator obtained using esp_partition_find. Must be non-NULL. + * + */ +void esp_partition_iterator_release(esp_partition_iterator_t iterator); + + +#ifdef __cplusplus +} +#endif + + +#endif /* __ESP_PARTITION_H__ */ From 628bde2080a9b99023e3214a8d55aae5962d9eeb Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Wed, 19 Oct 2016 17:05:37 +0800 Subject: [PATCH 163/343] bootloader: move useful structures to esp32 component --- .../bootloader/src/main/bootloader_config.h | 80 +---------- .../bootloader/src/main/bootloader_start.c | 124 ++++++++---------- .../bootloader/src/main/flash_encrypt.c | 2 +- .../esp32/include/esp_flash_data_types.h | 102 ++++++++++++++ 4 files changed, 162 insertions(+), 146 deletions(-) create mode 100644 components/esp32/include/esp_flash_data_types.h diff --git a/components/bootloader/src/main/bootloader_config.h b/components/bootloader/src/main/bootloader_config.h index f99a1c94e5..8a837693c2 100644 --- a/components/bootloader/src/main/bootloader_config.h +++ b/components/bootloader/src/main/bootloader_config.h @@ -20,12 +20,13 @@ extern "C" { #endif + +#include "esp_flash_data_types.h" + #define BOOT_VERSION "V0.1" #define SPI_SEC_SIZE 0x1000 #define MEM_CACHE(offset) (uint8_t *)(0x3f400000 + (offset)) #define CACHE_READ_32(offset) ((uint32_t *)(0x3f400000 + (offset))) -#define PARTITION_ADD 0x4000 -#define PARTITION_MAGIC 0x50AA #define IROM_LOW 0x400D0000 #define IROM_HIGH 0x40400000 #define DROM_LOW 0x3F400000 @@ -35,73 +36,6 @@ extern "C" #define RTC_DATA_LOW 0x50000000 #define RTC_DATA_HIGH 0x50002000 -/*spi mode,saved in third byte in flash */ -enum { - SPI_MODE_QIO, - SPI_MODE_QOUT, - SPI_MODE_DIO, - SPI_MODE_DOUT, - SPI_MODE_FAST_READ, - SPI_MODE_SLOW_READ -}; -/* spi speed*/ -enum { - SPI_SPEED_40M, - SPI_SPEED_26M, - SPI_SPEED_20M, - SPI_SPEED_80M = 0xF -}; -/*supported flash sizes*/ -enum { - SPI_SIZE_1MB = 0, - SPI_SIZE_2MB, - SPI_SIZE_4MB, - SPI_SIZE_8MB, - SPI_SIZE_16MB, - SPI_SIZE_MAX -}; - - -struct flash_hdr { - char magic; - char blocks; - char spi_mode; /* flag of flash read mode in unpackage and usage in future */ - char spi_speed: 4; /* low bit */ - char spi_size: 4; - unsigned int entry_addr; - uint8_t encrypt_flag; /* encrypt flag */ - uint8_t secury_boot_flag; /* secury boot flag */ - char extra_header[14]; /* ESP32 additional header, unused by second bootloader */ -}; - -/* each header of flash bin block */ -struct block_hdr { - unsigned int load_addr; - unsigned int data_len; -}; - -/* OTA selection structure (two copies in the OTA data partition.) - - Size of 32 bytes is friendly to flash encryption */ -typedef struct { - uint32_t ota_seq; - uint8_t seq_label[24]; - uint32_t crc; /* CRC32 of ota_seq field only */ -} ota_select; - -typedef struct { - uint32_t offset; - uint32_t size; -} partition_pos_t; - -typedef struct { - uint16_t magic; - uint8_t type; /* partition Type */ - uint8_t subtype; /* part_subtype */ - partition_pos_t pos; - uint8_t label[16]; /* label for the partition */ - uint8_t reserved[4]; /* reserved */ -} partition_info_t; #define PART_TYPE_APP 0x00 #define PART_SUBTYPE_FACTORY 0x00 @@ -120,10 +54,10 @@ typedef struct { #define SPI_ERROR_LOG "spi flash error" typedef struct { - partition_pos_t ota_info; - partition_pos_t factory; - partition_pos_t test; - partition_pos_t ota[16]; + esp_partition_pos_t ota_info; + esp_partition_pos_t factory; + esp_partition_pos_t test; + esp_partition_pos_t ota[16]; uint32_t app_count; uint32_t selected_subtype; } bootloader_state_t; diff --git a/components/bootloader/src/main/bootloader_start.c b/components/bootloader/src/main/bootloader_start.c index e87f579f42..5b1e152070 100644 --- a/components/bootloader/src/main/bootloader_start.c +++ b/components/bootloader/src/main/bootloader_start.c @@ -3,7 +3,7 @@ // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software @@ -49,8 +49,8 @@ flash cache is down and the app CPU is in reset. We do have a stack, so we can d extern void Cache_Flush(int); void bootloader_main(); -void unpack_load_app(const partition_pos_t *app_node); -void print_flash_info(struct flash_hdr* pfhdr); +void unpack_load_app(const esp_partition_pos_t *app_node); +void print_flash_info(const esp_image_header_t* pfhdr); void IRAM_ATTR set_cache_and_start_app(uint32_t drom_addr, uint32_t drom_load_addr, uint32_t drom_size, @@ -58,7 +58,7 @@ void IRAM_ATTR set_cache_and_start_app(uint32_t drom_addr, uint32_t irom_load_addr, uint32_t irom_size, uint32_t entry_addr); -static void update_flash_config(struct flash_hdr* pfhdr); +static void update_flash_config(const esp_image_header_t* pfhdr); void IRAM_ATTR call_start_cpu0() @@ -154,7 +154,7 @@ void boot_cache_redirect( uint32_t pos, size_t size ) */ bool load_partition_table(bootloader_state_t* bs, uint32_t addr) { - partition_info_t partition; + esp_partition_info_t partition; uint32_t end = addr + 0x1000; int index = 0; char *partition_usage; @@ -168,7 +168,7 @@ bool load_partition_table(bootloader_state_t* bs, uint32_t addr) ESP_LOGD(TAG, "type=%x subtype=%x", partition.type, partition.subtype); partition_usage = "unknown"; - if (partition.magic == PARTITION_MAGIC) { /* valid partition definition */ + if (partition.magic == ESP_PARTITION_MAGIC) { /* valid partition definition */ switch(partition.type) { case PART_TYPE_APP: /* app partition */ switch(partition.subtype) { @@ -231,12 +231,12 @@ bool load_partition_table(bootloader_state_t* bs, uint32_t addr) return true; } -static uint32_t ota_select_crc(const ota_select *s) +static uint32_t ota_select_crc(const esp_ota_select_entry_t *s) { return crc32_le(UINT32_MAX, (uint8_t*)&s->ota_seq, 4); } -static bool ota_select_valid(const ota_select *s) +static bool ota_select_valid(const esp_ota_select_entry_t *s) { return s->ota_seq != UINT32_MAX && s->crc == ota_select_crc(s); } @@ -252,10 +252,10 @@ void bootloader_main() { ESP_LOGI(TAG, "Espressif ESP32 2nd stage bootloader v. %s", BOOT_VERSION); - struct flash_hdr fhdr; + esp_image_header_t fhdr; bootloader_state_t bs; SpiFlashOpResult spiRet1,spiRet2; - ota_select sa,sb; + esp_ota_select_entry_t sa,sb; memset(&bs, 0, sizeof(bs)); ESP_LOGI(TAG, "compile time " __TIME__ ); @@ -266,18 +266,18 @@ void bootloader_main() /*register first sector in drom0 page 0 */ boot_cache_redirect( 0, 0x5000 ); - memcpy((unsigned int *) &fhdr, MEM_CACHE(0x1000), sizeof(struct flash_hdr) ); + memcpy((unsigned int *) &fhdr, MEM_CACHE(0x1000), sizeof(esp_image_header_t) ); print_flash_info(&fhdr); update_flash_config(&fhdr); - if (!load_partition_table(&bs, PARTITION_ADD)) { + if (!load_partition_table(&bs, ESP_PARTITION_TABLE_ADDR)) { ESP_LOGE(TAG, "load partition table error!"); return; } - partition_pos_t load_part_pos; + esp_partition_pos_t load_part_pos; if (bs.ota_info.offset != 0) { // check if partition table has OTA info partition //ESP_LOGE("OTA info sector handling is not implemented"); @@ -293,14 +293,14 @@ void bootloader_main() sb.crc = ota_select_crc(&sb); Cache_Read_Disable(0); - spiRet1 = SPIEraseSector(bs.ota_info.offset/0x1000); - spiRet2 = SPIEraseSector(bs.ota_info.offset/0x1000+1); + spiRet1 = SPIEraseSector(bs.ota_info.offset/0x1000); + spiRet2 = SPIEraseSector(bs.ota_info.offset/0x1000+1); if (spiRet1 != SPI_FLASH_RESULT_OK || spiRet2 != SPI_FLASH_RESULT_OK ) { ESP_LOGE(TAG, SPI_ERROR_LOG); return; } - spiRet1 = SPIWrite(bs.ota_info.offset,(uint32_t *)&sa,sizeof(ota_select)); - spiRet2 = SPIWrite(bs.ota_info.offset + 0x1000,(uint32_t *)&sb,sizeof(ota_select)); + spiRet1 = SPIWrite(bs.ota_info.offset,(uint32_t *)&sa,sizeof(esp_ota_select_entry_t)); + spiRet2 = SPIWrite(bs.ota_info.offset + 0x1000,(uint32_t *)&sb,sizeof(esp_ota_select_entry_t)); if (spiRet1 != SPI_FLASH_RESULT_OK || spiRet2 != SPI_FLASH_RESULT_OK ) { ESP_LOGE(TAG, SPI_ERROR_LOG); return; @@ -329,7 +329,7 @@ void bootloader_main() } ESP_LOGI(TAG, "Loading app partition at offset %08x", load_part_pos); - if(fhdr.secury_boot_flag == 0x01) { + if(fhdr.secure_boot_flag == 0x01) { /* protect the 2nd_boot */ if(false == secure_boot()){ ESP_LOGE(TAG, "secure boot failed"); @@ -350,12 +350,12 @@ void bootloader_main() } -void unpack_load_app(const partition_pos_t* partition) +void unpack_load_app(const esp_partition_pos_t* partition) { boot_cache_redirect(partition->offset, partition->size); uint32_t pos = 0; - struct flash_hdr image_header; + esp_image_header_t image_header; memcpy(&image_header, MEM_CACHE(pos), sizeof(image_header)); pos += sizeof(image_header); @@ -379,7 +379,7 @@ void unpack_load_app(const partition_pos_t* partition) for (uint32_t section_index = 0; section_index < image_header.blocks; ++section_index) { - struct block_hdr section_header = {0}; + esp_image_section_header_t section_header = {0}; memcpy(§ion_header, MEM_CACHE(pos), sizeof(section_header)); pos += sizeof(section_header); @@ -485,23 +485,23 @@ void IRAM_ATTR set_cache_and_start_app( (*entry)(); } -static void update_flash_config(struct flash_hdr* pfhdr) +static void update_flash_config(const esp_image_header_t* pfhdr) { uint32_t size; switch(pfhdr->spi_size) { - case SPI_SIZE_1MB: + case ESP_IMAGE_FLASH_SIZE_1MB: size = 1; break; - case SPI_SIZE_2MB: + case ESP_IMAGE_FLASH_SIZE_2MB: size = 2; break; - case SPI_SIZE_4MB: + case ESP_IMAGE_FLASH_SIZE_4MB: size = 4; break; - case SPI_SIZE_8MB: + case ESP_IMAGE_FLASH_SIZE_8MB: size = 8; break; - case SPI_SIZE_16MB: + case ESP_IMAGE_FLASH_SIZE_16MB: size = 16; break; default: @@ -516,66 +516,53 @@ static void update_flash_config(struct flash_hdr* pfhdr) Cache_Read_Enable( 0 ); } -void print_flash_info(struct flash_hdr* pfhdr) +void print_flash_info(const esp_image_header_t* phdr) { #if (BOOT_LOG_LEVEL >= BOOT_LOG_LEVEL_NOTICE) - struct flash_hdr fhdr = *pfhdr; - - ESP_LOGD(TAG, "magic %02x", fhdr.magic ); - ESP_LOGD(TAG, "blocks %02x", fhdr.blocks ); - ESP_LOGD(TAG, "spi_mode %02x", fhdr.spi_mode ); - ESP_LOGD(TAG, "spi_speed %02x", fhdr.spi_speed ); - ESP_LOGD(TAG, "spi_size %02x", fhdr.spi_size ); + ESP_LOGD(TAG, "magic %02x", phdr->magic ); + ESP_LOGD(TAG, "blocks %02x", phdr->blocks ); + ESP_LOGD(TAG, "spi_mode %02x", phdr->spi_mode ); + ESP_LOGD(TAG, "spi_speed %02x", phdr->spi_speed ); + ESP_LOGD(TAG, "spi_size %02x", phdr->spi_size ); const char* str; - switch ( fhdr.spi_speed ) { - case SPI_SPEED_40M: + switch ( phdr->spi_speed ) { + case ESP_IMAGE_SPI_SPEED_40M: str = "40MHz"; break; - - case SPI_SPEED_26M: + case ESP_IMAGE_SPI_SPEED_26M: str = "26.7MHz"; break; - - case SPI_SPEED_20M: + case ESP_IMAGE_SPI_SPEED_20M: str = "20MHz"; break; - - case SPI_SPEED_80M: + case ESP_IMAGE_SPI_SPEED_80M: str = "80MHz"; break; - default: str = "20MHz"; break; } ESP_LOGI(TAG, "SPI Speed : %s", str ); - - - switch ( fhdr.spi_mode ) { - case SPI_MODE_QIO: + switch ( phdr->spi_mode ) { + case ESP_IMAGE_SPI_MODE_QIO: str = "QIO"; break; - - case SPI_MODE_QOUT: + case ESP_IMAGE_SPI_MODE_QOUT: str = "QOUT"; break; - - case SPI_MODE_DIO: + case ESP_IMAGE_SPI_MODE_DIO: str = "DIO"; break; - - case SPI_MODE_DOUT: + case ESP_IMAGE_SPI_MODE_DOUT: str = "DOUT"; break; - - case SPI_MODE_FAST_READ: + case ESP_IMAGE_SPI_MODE_FAST_READ: str = "FAST READ"; break; - - case SPI_MODE_SLOW_READ: + case ESP_IMAGE_SPI_MODE_SLOW_READ: str = "SLOW READ"; break; default: @@ -584,31 +571,24 @@ void print_flash_info(struct flash_hdr* pfhdr) } ESP_LOGI(TAG, "SPI Mode : %s", str ); - - - switch ( fhdr.spi_size ) { - case SPI_SIZE_1MB: + switch ( phdr->spi_size ) { + case ESP_IMAGE_FLASH_SIZE_1MB: str = "1MB"; break; - - case SPI_SIZE_2MB: + case ESP_IMAGE_FLASH_SIZE_2MB: str = "2MB"; break; - - case SPI_SIZE_4MB: + case ESP_IMAGE_FLASH_SIZE_4MB: str = "4MB"; break; - - case SPI_SIZE_8MB: + case ESP_IMAGE_FLASH_SIZE_8MB: str = "8MB"; break; - - case SPI_SIZE_16MB: + case ESP_IMAGE_FLASH_SIZE_16MB: str = "16MB"; break; - default: - str = "1MB"; + str = "2MB"; break; } ESP_LOGI(TAG, "SPI Flash Size : %s", str ); diff --git a/components/bootloader/src/main/flash_encrypt.c b/components/bootloader/src/main/flash_encrypt.c index 26e66aa039..2fb57a987d 100644 --- a/components/bootloader/src/main/flash_encrypt.c +++ b/components/bootloader/src/main/flash_encrypt.c @@ -128,7 +128,7 @@ bool flash_encrypt(bootloader_state_t *bs) return false; } /* encrypt partition table */ - if (false == flash_encrypt_write(PARTITION_ADD, SPI_SEC_SIZE)) { + if (false == flash_encrypt_write(ESP_PARTITION_TABLE_ADDR, SPI_SEC_SIZE)) { ESP_LOGE(TAG, "encrypt partition table error"); return false; } diff --git a/components/esp32/include/esp_flash_data_types.h b/components/esp32/include/esp_flash_data_types.h new file mode 100644 index 0000000000..b16ee59f57 --- /dev/null +++ b/components/esp32/include/esp_flash_data_types.h @@ -0,0 +1,102 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#ifndef __ESP_BIN_TYPES_H__ +#define __ESP_BIN_TYPES_H__ + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define ESP_PARTITION_TABLE_ADDR 0x4000 +#define ESP_PARTITION_MAGIC 0x50AA + +/*spi mode,saved in third byte in flash */ +typedef enum { + ESP_IMAGE_SPI_MODE_QIO, + ESP_IMAGE_SPI_MODE_QOUT, + ESP_IMAGE_SPI_MODE_DIO, + ESP_IMAGE_SPI_MODE_DOUT, + ESP_IMAGE_SPI_MODE_FAST_READ, + ESP_IMAGE_SPI_MODE_SLOW_READ +} esp_image_spi_mode_t; + +/* spi speed*/ +enum { + ESP_IMAGE_SPI_SPEED_40M, + ESP_IMAGE_SPI_SPEED_26M, + ESP_IMAGE_SPI_SPEED_20M, + ESP_IMAGE_SPI_SPEED_80M = 0xF +} esp_image_spi_freq_t; + +/*supported flash sizes*/ +typedef enum { + ESP_IMAGE_FLASH_SIZE_1MB = 0, + ESP_IMAGE_FLASH_SIZE_2MB, + ESP_IMAGE_FLASH_SIZE_4MB, + ESP_IMAGE_FLASH_SIZE_8MB, + ESP_IMAGE_FLASH_SIZE_16MB, + ESP_IMAGE_FLASH_SIZE_MAX +} esp_image_flash_size_t; + +typedef struct { + char magic; + char blocks; + char spi_mode; /* flag of flash read mode in unpackage and usage in future */ + char spi_speed: 4; /* low bit */ + char spi_size: 4; + unsigned int entry_addr; + uint8_t encrypt_flag; /* encrypt flag */ + uint8_t secure_boot_flag; /* secure boot flag */ + char extra_header[14]; /* ESP32 additional header, unused by second bootloader */ +} esp_image_header_t; + +/* each header of flash bin block */ +typedef struct { + unsigned int load_addr; + unsigned int data_len; +} esp_image_section_header_t; + + +/* OTA selection structure (two copies in the OTA data partition.) + Size of 32 bytes is friendly to flash encryption */ +typedef struct { + uint32_t ota_seq; + uint8_t seq_label[24]; + uint32_t crc; /* CRC32 of ota_seq field only */ +} esp_ota_select_entry_t; + + +typedef struct { + uint32_t offset; + uint32_t size; +} esp_partition_pos_t; + +typedef struct { + uint16_t magic; + uint8_t type; /* partition Type */ + uint8_t subtype; /* part_subtype */ + esp_partition_pos_t pos; + uint8_t label[16]; /* label for the partition */ + uint8_t reserved[4]; /* reserved */ +} esp_partition_info_t; + + +#ifdef __cplusplus +} +#endif + +#endif //__ESP_BIN_TYPES_H__ From 54ca573ce465b4a12cad9cc804c6c80063dcab35 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Wed, 19 Oct 2016 17:08:05 +0800 Subject: [PATCH 164/343] spi_flash: move cache operations into separate file --- components/spi_flash/README.rst | 33 +++ .../{esp_spi_flash.c => cache_utils.c} | 201 ++++-------------- components/spi_flash/cache_utils.h | 44 ++++ components/spi_flash/flash_ops.c | 158 ++++++++++++++ 4 files changed, 274 insertions(+), 162 deletions(-) create mode 100644 components/spi_flash/README.rst rename components/spi_flash/{esp_spi_flash.c => cache_utils.c} (53%) create mode 100644 components/spi_flash/cache_utils.h create mode 100644 components/spi_flash/flash_ops.c diff --git a/components/spi_flash/README.rst b/components/spi_flash/README.rst new file mode 100644 index 0000000000..22f98cf02d --- /dev/null +++ b/components/spi_flash/README.rst @@ -0,0 +1,33 @@ +Driver for SPI flash read/write/erase operations +================================================ + +Implementation notes +-------------------- + +In order to perform some flash operations, we need to make sure both CPUs +are not running any code from flash for the duration of the flash operation. +In a single-core setup this is easy: we disable interrupts/scheduler and do +the flash operation. In the dual-core setup this is slightly more complicated. +We need to make sure that the other CPU doesn't run any code from flash. + + +When SPI flash API is called on CPU A (can be PRO or APP), we start +spi_flash_op_block_func function on CPU B using esp_ipc_call API. This API +wakes up high priority task on CPU B and tells it to execute given function, +in this case spi_flash_op_block_func. This function disables cache on CPU B and +signals that cache is disabled by setting s_flash_op_can_start flag. +Then the task on CPU A disables cache as well, and proceeds to execute flash +operation. + +While flash operation is running, interrupts can still run on CPU B. +We assume that all interrupt code is placed into RAM. + +Once flash operation is complete, function on CPU A sets another flag, +s_flash_op_complete, to let the task on CPU B know that it can re-enable +cache and release the CPU. Then the function on CPU A re-enables the cache on +CPU A as well and returns control to the calling code. + +Additionally, all API functions are protected with a mutex (s_flash_op_mutex). + +In a single core environment (CONFIG_FREERTOS_UNICORE enabled), we simply +disable both caches, no inter-CPU communication takes place. diff --git a/components/spi_flash/esp_spi_flash.c b/components/spi_flash/cache_utils.c similarity index 53% rename from components/spi_flash/esp_spi_flash.c rename to components/spi_flash/cache_utils.c index d702f3b815..6ae47bdb3e 100644 --- a/components/spi_flash/esp_spi_flash.c +++ b/components/spi_flash/cache_utils.c @@ -3,7 +3,7 @@ // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software @@ -30,39 +30,7 @@ #include "esp_spi_flash.h" #include "esp_log.h" -/* - Driver for SPI flash read/write/erase operations - In order to perform some flash operations, we need to make sure both CPUs - are not running any code from flash for the duration of the flash operation. - In a single-core setup this is easy: we disable interrupts/scheduler and do - the flash operation. In the dual-core setup this is slightly more complicated. - We need to make sure that the other CPU doesn't run any code from flash. - - - When SPI flash API is called on CPU A (can be PRO or APP), we start - spi_flash_op_block_func function on CPU B using esp_ipc_call API. This API - wakes up high priority task on CPU B and tells it to execute given function, - in this case spi_flash_op_block_func. This function disables cache on CPU B and - signals that cache is disabled by setting s_flash_op_can_start flag. - Then the task on CPU A disables cache as well, and proceeds to execute flash - operation. - - While flash operation is running, interrupts can still run on CPU B. - We assume that all interrupt code is placed into RAM. - - Once flash operation is complete, function on CPU A sets another flag, - s_flash_op_complete, to let the task on CPU B know that it can re-enable - cache and release the CPU. Then the function on CPU A re-enables the cache on - CPU A as well and returns control to the calling code. - - Additionally, all API functions are protected with a mutex (s_flash_op_mutex). - - In a single core environment (CONFIG_FREERTOS_UNICORE enabled), we simply - disable both caches, no inter-CPU communication takes place. -*/ - -static esp_err_t spi_flash_translate_rc(SpiFlashOpResult rc); static void IRAM_ATTR spi_flash_disable_cache(uint32_t cpuid, uint32_t* saved_state); static void IRAM_ATTR spi_flash_restore_cache(uint32_t cpuid, uint32_t saved_state); @@ -72,25 +40,23 @@ static uint32_t s_flash_op_cache_state[2]; static SemaphoreHandle_t s_flash_op_mutex; static bool s_flash_op_can_start = false; static bool s_flash_op_complete = false; -#endif //CONFIG_FREERTOS_UNICORE -#if CONFIG_SPI_FLASH_ENABLE_COUNTERS -static const char* TAG = "spi_flash"; -static spi_flash_counters_t s_flash_stats; +void spi_flash_init_lock() +{ + s_flash_op_mutex = xSemaphoreCreateMutex(); +} -#define COUNTER_START() uint32_t ts_begin = xthal_get_ccount() -#define COUNTER_STOP(counter) do{ s_flash_stats.counter.count++; s_flash_stats.counter.time += (xthal_get_ccount() - ts_begin) / (XT_CLOCK_FREQ / 1000000); } while(0) -#define COUNTER_ADD_BYTES(counter, size) do { s_flash_stats.counter.bytes += size; } while (0) -#else -#define COUNTER_START() -#define COUNTER_STOP(counter) -#define COUNTER_ADD_BYTES(counter, size) +void spi_flash_op_lock() +{ + xSemaphoreTake(s_flash_op_mutex, portMAX_DELAY); +} -#endif //CONFIG_SPI_FLASH_ENABLE_COUNTERS +void spi_flash_op_unlock() +{ + xSemaphoreGive(s_flash_op_mutex); +} -#ifndef CONFIG_FREERTOS_UNICORE - -static void IRAM_ATTR spi_flash_op_block_func(void* arg) +void IRAM_ATTR spi_flash_op_block_func(void* arg) { // Disable scheduler on this CPU vTaskSuspendAll(); @@ -108,19 +74,9 @@ static void IRAM_ATTR spi_flash_op_block_func(void* arg) xTaskResumeAll(); } -void spi_flash_init() +void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu() { - s_flash_op_mutex = xSemaphoreCreateMutex(); - -#if CONFIG_SPI_FLASH_ENABLE_COUNTERS - spi_flash_reset_counters(); -#endif -} - -static void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu() -{ - // Take the API lock - xSemaphoreTake(s_flash_op_mutex, portMAX_DELAY); + spi_flash_op_lock(); const uint32_t cpuid = xPortGetCoreID(); const uint32_t other_cpuid = (cpuid == 0) ? 1 : 0; @@ -152,7 +108,7 @@ static void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu() spi_flash_disable_cache(cpuid, &s_flash_op_cache_state[cpuid]); } -static void IRAM_ATTR spi_flash_enable_interrupts_caches_and_other_cpu() +void IRAM_ATTR spi_flash_enable_interrupts_caches_and_other_cpu() { const uint32_t cpuid = xPortGetCoreID(); const uint32_t other_cpuid = (cpuid == 0) ? 1 : 0; @@ -173,98 +129,45 @@ static void IRAM_ATTR spi_flash_enable_interrupts_caches_and_other_cpu() xTaskResumeAll(); } // Release API lock - xSemaphoreGive(s_flash_op_mutex); + spi_flash_op_unlock(); } -#else // CONFIG_FREERTOS_UNICORE +#else // CONFIG_FREERTOS_UNICORE -void spi_flash_init() +void spi_flash_init_lock() { -#if CONFIG_SPI_FLASH_ENABLE_COUNTERS - spi_flash_reset_counters(); -#endif } -static void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu() +void spi_flash_op_lock() { vTaskSuspendAll(); +} + +void spi_flash_op_unlock() +{ + xTaskResumeAll(); +} + + +void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu() +{ + spi_flash_op_lock(); spi_flash_disable_cache(0, &s_flash_op_cache_state[0]); } -static void IRAM_ATTR spi_flash_enable_interrupts_caches_and_other_cpu() +void IRAM_ATTR spi_flash_enable_interrupts_caches_and_other_cpu() { spi_flash_restore_cache(0, s_flash_op_cache_state[0]); - xTaskResumeAll(); + spi_flash_op_unlock(); } #endif // CONFIG_FREERTOS_UNICORE - -SpiFlashOpResult IRAM_ATTR spi_flash_unlock() -{ - static bool unlocked = false; - if (!unlocked) { - SpiFlashOpResult rc = SPIUnlock(); - if (rc != SPI_FLASH_RESULT_OK) { - return rc; - } - unlocked = true; - } - return SPI_FLASH_RESULT_OK; -} - -esp_err_t IRAM_ATTR spi_flash_erase_sector(uint16_t sec) -{ - COUNTER_START(); - spi_flash_disable_interrupts_caches_and_other_cpu(); - SpiFlashOpResult rc; - rc = spi_flash_unlock(); - if (rc == SPI_FLASH_RESULT_OK) { - rc = SPIEraseSector(sec); - } - spi_flash_enable_interrupts_caches_and_other_cpu(); - COUNTER_STOP(erase); - return spi_flash_translate_rc(rc); -} - -esp_err_t IRAM_ATTR spi_flash_write(uint32_t dest_addr, const uint32_t *src, uint32_t size) -{ - COUNTER_START(); - spi_flash_disable_interrupts_caches_and_other_cpu(); - SpiFlashOpResult rc; - rc = spi_flash_unlock(); - if (rc == SPI_FLASH_RESULT_OK) { - rc = SPIWrite(dest_addr, src, (int32_t) size); - COUNTER_ADD_BYTES(write, size); - } - spi_flash_enable_interrupts_caches_and_other_cpu(); - COUNTER_STOP(write); - return spi_flash_translate_rc(rc); -} - -esp_err_t IRAM_ATTR spi_flash_read(uint32_t src_addr, uint32_t *dest, uint32_t size) -{ - COUNTER_START(); - spi_flash_disable_interrupts_caches_and_other_cpu(); - SpiFlashOpResult rc = SPIRead(src_addr, dest, (int32_t) size); - COUNTER_ADD_BYTES(read, size); - spi_flash_enable_interrupts_caches_and_other_cpu(); - COUNTER_STOP(read); - return spi_flash_translate_rc(rc); -} - -static esp_err_t spi_flash_translate_rc(SpiFlashOpResult rc) -{ - switch (rc) { - case SPI_FLASH_RESULT_OK: - return ESP_OK; - case SPI_FLASH_RESULT_TIMEOUT: - return ESP_ERR_FLASH_OP_TIMEOUT; - case SPI_FLASH_RESULT_ERR: - default: - return ESP_ERR_FLASH_OP_FAIL; - } -} +/** + * The following two functions are replacements for Cache_Read_Disable and Cache_Read_Enable + * function in ROM. They are used to work around a bug where Cache_Read_Disable requires a call to + * Cache_Flush before Cache_Read_Enable, even if cached data was not modified. + */ static const uint32_t cache_mask = DPORT_APP_CACHE_MASK_OPSDRAM | DPORT_APP_CACHE_MASK_DROM0 | DPORT_APP_CACHE_MASK_DRAM1 | DPORT_APP_CACHE_MASK_IROM0 | @@ -300,29 +203,3 @@ static void IRAM_ATTR spi_flash_restore_cache(uint32_t cpuid, uint32_t saved_sta } } -#if CONFIG_SPI_FLASH_ENABLE_COUNTERS - -static inline void dump_counter(spi_flash_counter_t* counter, const char* name) -{ - ESP_LOGI(TAG, "%s count=%8d time=%8dms bytes=%8d\n", name, - counter->count, counter->time, counter->bytes); -} - -const spi_flash_counters_t* spi_flash_get_counters() -{ - return &s_flash_stats; -} - -void spi_flash_reset_counters() -{ - memset(&s_flash_stats, 0, sizeof(s_flash_stats)); -} - -void spi_flash_dump_counters() -{ - dump_counter(&s_flash_stats.read, "read "); - dump_counter(&s_flash_stats.write, "write"); - dump_counter(&s_flash_stats.erase, "erase"); -} - -#endif //CONFIG_SPI_FLASH_ENABLE_COUNTERS diff --git a/components/spi_flash/cache_utils.h b/components/spi_flash/cache_utils.h new file mode 100644 index 0000000000..899a31c651 --- /dev/null +++ b/components/spi_flash/cache_utils.h @@ -0,0 +1,44 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ESP_SPI_FLASH_CACHE_UTILS_H +#define ESP_SPI_FLASH_CACHE_UTILS_H + +/** + * This header file contains declarations of cache manipulation functions + * used both in flash_ops.c and flash_mmap.c. + * + * These functions are considered internal and are not designed to be called from applications. + */ + +// Init mutex protecting access to spi_flash_* APIs +void spi_flash_init_lock(); + +// Take mutex protecting access to spi_flash_* APIs +void spi_flash_op_lock(); + +// Release said mutex +void spi_flash_op_unlock(); + +// Suspend the scheduler on both CPUs, disable cache. +// Contrary to its name this doesn't do anything with interrupts, yet. +// Interrupt disabling capability will be added once we implement +// interrupt allocation API. +void spi_flash_disable_interrupts_caches_and_other_cpu(); + +// Enable cache, enable interrupts (to be added in future), resume scheduler +void spi_flash_enable_interrupts_caches_and_other_cpu(); + + +#endif //ESP_SPI_FLASH_CACHE_UTILS_H diff --git a/components/spi_flash/flash_ops.c b/components/spi_flash/flash_ops.c new file mode 100644 index 0000000000..99e8ef77f2 --- /dev/null +++ b/components/spi_flash/flash_ops.c @@ -0,0 +1,158 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include "sdkconfig.h" +#include "esp_ipc.h" +#include "esp_attr.h" +#include "esp_spi_flash.h" +#include "esp_log.h" +#include "cache_utils.h" + +#if CONFIG_SPI_FLASH_ENABLE_COUNTERS +static const char* TAG = "spi_flash"; +static spi_flash_counters_t s_flash_stats; + +#define COUNTER_START() uint32_t ts_begin = xthal_get_ccount() +#define COUNTER_STOP(counter) \ + do{ \ + s_flash_stats.counter.count++; \ + s_flash_stats.counter.time += (xthal_get_ccount() - ts_begin) / (XT_CLOCK_FREQ / 1000000); \\ + } while(0) + +#define COUNTER_ADD_BYTES(counter, size) \ + do { \ + s_flash_stats.counter.bytes += size; \ + } while (0) + +#else +#define COUNTER_START() +#define COUNTER_STOP(counter) +#define COUNTER_ADD_BYTES(counter, size) + +#endif //CONFIG_SPI_FLASH_ENABLE_COUNTERS + +static esp_err_t spi_flash_translate_rc(SpiFlashOpResult rc); + +void spi_flash_init() +{ + spi_flash_init_lock(); +#if CONFIG_SPI_FLASH_ENABLE_COUNTERS + spi_flash_reset_counters(); +#endif +} + +SpiFlashOpResult IRAM_ATTR spi_flash_unlock() +{ + static bool unlocked = false; + if (!unlocked) { + SpiFlashOpResult rc = SPIUnlock(); + if (rc != SPI_FLASH_RESULT_OK) { + return rc; + } + unlocked = true; + } + return SPI_FLASH_RESULT_OK; +} + +esp_err_t IRAM_ATTR spi_flash_erase_sector(uint16_t sec) +{ + COUNTER_START(); + spi_flash_disable_interrupts_caches_and_other_cpu(); + SpiFlashOpResult rc; + rc = spi_flash_unlock(); + if (rc == SPI_FLASH_RESULT_OK) { + rc = SPIEraseSector(sec); + } + spi_flash_enable_interrupts_caches_and_other_cpu(); + COUNTER_STOP(erase); + return spi_flash_translate_rc(rc); +} + +esp_err_t IRAM_ATTR spi_flash_write(uint32_t dest_addr, const uint32_t *src, uint32_t size) +{ + COUNTER_START(); + spi_flash_disable_interrupts_caches_and_other_cpu(); + SpiFlashOpResult rc; + rc = spi_flash_unlock(); + if (rc == SPI_FLASH_RESULT_OK) { + rc = SPIWrite(dest_addr, src, (int32_t) size); + COUNTER_ADD_BYTES(write, size); + } + spi_flash_enable_interrupts_caches_and_other_cpu(); + COUNTER_STOP(write); + return spi_flash_translate_rc(rc); +} + +esp_err_t IRAM_ATTR spi_flash_read(uint32_t src_addr, uint32_t *dest, uint32_t size) +{ + COUNTER_START(); + spi_flash_disable_interrupts_caches_and_other_cpu(); + SpiFlashOpResult rc = SPIRead(src_addr, dest, (int32_t) size); + COUNTER_ADD_BYTES(read, size); + spi_flash_enable_interrupts_caches_and_other_cpu(); + COUNTER_STOP(read); + return spi_flash_translate_rc(rc); +} + +static esp_err_t spi_flash_translate_rc(SpiFlashOpResult rc) +{ + switch (rc) { + case SPI_FLASH_RESULT_OK: + return ESP_OK; + case SPI_FLASH_RESULT_TIMEOUT: + return ESP_ERR_FLASH_OP_TIMEOUT; + case SPI_FLASH_RESULT_ERR: + default: + return ESP_ERR_FLASH_OP_FAIL; + } +} + +#if CONFIG_SPI_FLASH_ENABLE_COUNTERS + +static inline void dump_counter(spi_flash_counter_t* counter, const char* name) +{ + ESP_LOGI(TAG, "%s count=%8d time=%8dms bytes=%8d\n", name, + counter->count, counter->time, counter->bytes); +} + +const spi_flash_counters_t* spi_flash_get_counters() +{ + return &s_flash_stats; +} + +void spi_flash_reset_counters() +{ + memset(&s_flash_stats, 0, sizeof(s_flash_stats)); +} + +void spi_flash_dump_counters() +{ + dump_counter(&s_flash_stats.read, "read "); + dump_counter(&s_flash_stats.write, "write"); + dump_counter(&s_flash_stats.erase, "erase"); +} + +#endif //CONFIG_SPI_FLASH_ENABLE_COUNTERS From 42068c3b36cb4b5898ea0f9b353057dd85af33ab Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Wed, 19 Oct 2016 17:17:24 +0800 Subject: [PATCH 165/343] spi_flash: implement mmap/munmap --- components/esp32/include/esp_err.h | 2 + components/esp32/include/soc/dport_reg.h | 5 + components/spi_flash/flash_mmap.c | 211 +++++++++++++++++++ components/spi_flash/include/esp_spi_flash.h | 57 +++++ 4 files changed, 275 insertions(+) create mode 100644 components/spi_flash/flash_mmap.c diff --git a/components/esp32/include/esp_err.h b/components/esp32/include/esp_err.h index 4f013f91ab..af9d2ec33a 100644 --- a/components/esp32/include/esp_err.h +++ b/components/esp32/include/esp_err.h @@ -31,6 +31,8 @@ typedef int32_t esp_err_t; #define ESP_ERR_NO_MEM 0x101 #define ESP_ERR_INVALID_ARG 0x102 #define ESP_ERR_INVALID_STATE 0x103 +#define ESP_ERR_INVALID_SIZE 0x104 +#define ESP_ERR_NOT_FOUND 0x105 /** * Macro which can be used to check the error code, diff --git a/components/esp32/include/soc/dport_reg.h b/components/esp32/include/soc/dport_reg.h index d65d9edbce..0c43c08740 100644 --- a/components/esp32/include/soc/dport_reg.h +++ b/components/esp32/include/soc/dport_reg.h @@ -3830,6 +3830,11 @@ #define DPORT_DATE_S 0 #define DPORT_DPORT_DATE_VERSION 0x1605190 +/* Flash MMU table for PRO CPU */ +#define DPORT_PRO_FLASH_MMU_TABLE ((volatile uint32_t*) 0x3FF10000) + +/* Flash MMU table for APP CPU */ +#define DPORT_APP_FLASH_MMU_TABLE ((volatile uint32_t*) 0x3FF12000) diff --git a/components/spi_flash/flash_mmap.c b/components/spi_flash/flash_mmap.c new file mode 100644 index 0000000000..8636a2605e --- /dev/null +++ b/components/spi_flash/flash_mmap.c @@ -0,0 +1,211 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include "sdkconfig.h" +#include "esp_ipc.h" +#include "esp_attr.h" +#include "esp_spi_flash.h" +#include "esp_log.h" +#include "cache_utils.h" + +#ifndef NDEBUG +// Enable built-in checks in queue.h in debug builds +#define INVARIANTS +#endif +#include "rom/queue.h" + +#define REGIONS_COUNT 4 +#define PAGES_PER_REGION 64 +#define FLASH_PAGE_SIZE 0x10000 +#define INVALID_ENTRY_VAL 0x100 +#define VADDR0_START_ADDR 0x3F400000 +#define VADDR1_START_ADDR 0x40000000 +#define VADDR1_FIRST_USABLE_ADDR 0x400D0000 +#define PRO_IRAM0_FIRST_USABLE_PAGE ((VADDR1_FIRST_USABLE_ADDR - VADDR1_START_ADDR) / FLASH_PAGE_SIZE + 64) + + +typedef struct mmap_entry_{ + uint32_t handle; + int page; + int count; + LIST_ENTRY(mmap_entry_) entries; +} mmap_entry_t; + + +static LIST_HEAD(mmap_entries_head, mmap_entry_) s_mmap_entries_head = + LIST_HEAD_INITIALIZER(s_mmap_entries_head); +static uint8_t s_mmap_page_refcnt[REGIONS_COUNT * PAGES_PER_REGION] = {0}; +static uint32_t s_mmap_last_handle = 0; + + +static void IRAM_ATTR spi_flash_mmap_init() +{ + for (int i = 0; i < REGIONS_COUNT * PAGES_PER_REGION; ++i) { + uint32_t entry_pro = DPORT_PRO_FLASH_MMU_TABLE[i]; + uint32_t entry_app = DPORT_APP_FLASH_MMU_TABLE[i]; + if (entry_pro != entry_app) { + // clean up entries used by boot loader + entry_pro = 0; + DPORT_PRO_FLASH_MMU_TABLE[i] = 0; + } + if ((entry_pro & 0x100) == 0 && (i == 0 || i == PRO_IRAM0_FIRST_USABLE_PAGE || entry_pro != 0)) { + s_mmap_page_refcnt[i] = 1; + } + } +} + +esp_err_t IRAM_ATTR spi_flash_mmap(uint32_t src_addr, size_t size, spi_flash_mmap_memory_t memory, + const void** out_ptr, spi_flash_mmap_handle_t* out_handle) +{ + esp_err_t ret; + mmap_entry_t* new_entry = (mmap_entry_t*) malloc(sizeof(mmap_entry_t)); + if (new_entry == 0) { + return ESP_ERR_NO_MEM; + } + if (src_addr & 0xffff) { + return ESP_ERR_INVALID_ARG; + } + spi_flash_disable_interrupts_caches_and_other_cpu(); + if (s_mmap_page_refcnt[0] == 0) { + spi_flash_mmap_init(); + } + // figure out the memory region where we should look for pages + int region_begin; // first page to check + int region_size; // number of pages to check + uint32_t region_addr; // base address of memory region + if (memory == SPI_FLASH_MMAP_DATA) { + // Vaddr0 + region_begin = 0; + region_size = 64; + region_addr = VADDR0_START_ADDR; + } else { + // only part of VAddr1 is usable, so adjust for that + region_begin = VADDR1_FIRST_USABLE_ADDR; + region_size = 3 * 64 - region_begin; + region_addr = VADDR1_FIRST_USABLE_ADDR; + } + // region which should be mapped + int phys_page = src_addr / FLASH_PAGE_SIZE; + int page_count = (size + FLASH_PAGE_SIZE - 1) / FLASH_PAGE_SIZE; + // The following part searches for a range of MMU entries which can be used. + // Algorithm is essentially naïve strstr algorithm, except that unused MMU + // entries are treated as wildcards. + int start; + int end = region_begin + region_size - page_count; + for (start = region_begin; start < end; ++start) { + int page = phys_page; + int pos; + for (pos = start; pos < start + page_count; ++pos, ++page) { + int table_val = (int) DPORT_PRO_FLASH_MMU_TABLE[pos]; + uint8_t refcnt = s_mmap_page_refcnt[pos]; + if (refcnt != 0 && table_val != page) { + break; + } + } + // whole mapping range matched, bail out + if (pos - start == page_count) { + break; + } + } + // checked all the region(s) and haven't found anything? + if (start == end) { + *out_handle = 0; + *out_ptr = NULL; + ret = ESP_ERR_NO_MEM; + } else { + // set up mapping using pages [start, start + page_count) + uint32_t entry_val = (uint32_t) phys_page; + for (int i = start; i != start + page_count; ++i, ++entry_val) { + // sanity check: we won't reconfigure entries with non-zero reference count + assert(s_mmap_page_refcnt[i] == 0 || + (DPORT_PRO_FLASH_MMU_TABLE[i] == entry_val && + DPORT_APP_FLASH_MMU_TABLE[i] == entry_val)); + if (s_mmap_page_refcnt[i] == 0) { + DPORT_PRO_FLASH_MMU_TABLE[i] = entry_val; + DPORT_APP_FLASH_MMU_TABLE[i] = entry_val; + } + ++s_mmap_page_refcnt[i]; + } + + LIST_INSERT_HEAD(&s_mmap_entries_head, new_entry, entries); + new_entry->page = start; + new_entry->count = page_count; + new_entry->handle = ++s_mmap_last_handle; + *out_handle = new_entry->handle; + *out_ptr = (void*) (region_addr + start * FLASH_PAGE_SIZE); + ret = ESP_OK; + } + spi_flash_enable_interrupts_caches_and_other_cpu(); + if (*out_ptr == NULL) { + free(new_entry); + } + return ret; +} + +void IRAM_ATTR spi_flash_munmap(spi_flash_mmap_handle_t handle) +{ + spi_flash_disable_interrupts_caches_and_other_cpu(); + mmap_entry_t* it; + // look for handle in linked list + for (it = LIST_FIRST(&s_mmap_entries_head); it != NULL; it = LIST_NEXT(it, entries)) { + if (it->handle == handle) { + // for each page, decrement reference counter + // if reference count is zero, disable MMU table entry to + // facilitate debugging of use-after-free conditions + for (int i = it->page; i < it->page + it->count; ++i) { + assert(s_mmap_page_refcnt[i] > 0); + if (--s_mmap_page_refcnt[i] == 0) { + DPORT_PRO_FLASH_MMU_TABLE[i] = INVALID_ENTRY_VAL; + DPORT_APP_FLASH_MMU_TABLE[i] = INVALID_ENTRY_VAL; + } + } + LIST_REMOVE(it, entries); + break; + } + } + spi_flash_enable_interrupts_caches_and_other_cpu(); + if (it == NULL) { + assert(0 && "invalid handle, or handle already unmapped"); + } + free(it); +} + +void spi_flash_mmap_dump() +{ + if (s_mmap_page_refcnt[0] == 0) { + spi_flash_mmap_init(); + } + mmap_entry_t* it; + for (it = LIST_FIRST(&s_mmap_entries_head); it != NULL; it = LIST_NEXT(it, entries)) { + printf("handle=%d page=%d count=%d\n", it->handle, it->page, it->count); + } + for (int i = 0; i < REGIONS_COUNT * PAGES_PER_REGION; ++i) { + if (s_mmap_page_refcnt[i] != 0) { + printf("page %d: refcnt=%d paddr=%d\n", + i, (int) s_mmap_page_refcnt[i], DPORT_PRO_FLASH_MMU_TABLE[i]); + } + } +} diff --git a/components/spi_flash/include/esp_spi_flash.h b/components/spi_flash/include/esp_spi_flash.h index 6d635880eb..597e41857c 100644 --- a/components/spi_flash/include/esp_spi_flash.h +++ b/components/spi_flash/include/esp_spi_flash.h @@ -70,6 +70,63 @@ esp_err_t spi_flash_write(uint32_t des_addr, const uint32_t *src_addr, uint32_t esp_err_t spi_flash_read(uint32_t src_addr, uint32_t *des_addr, uint32_t size); +/** + * @brief Enumeration which specifies memory space requested in an mmap call + */ +typedef enum { + SPI_FLASH_MMAP_DATA, /**< map to data memory (Vaddr0), allows byte-aligned access, 4 MB total */ + SPI_FLASH_MMAP_INST, /**< map to instruction memory (Vaddr1-3), allows only 4-byte-aligned access, 11 MB total */ +} spi_flash_mmap_memory_t; + +/** + * @brief Opaque handle for memory region obtained from spi_flash_mmap. + */ +typedef uint32_t spi_flash_mmap_handle_t; + +/** + * @brief Map region of flash memory into data or instruction address space + * + * This function allocates sufficient number of 64k MMU pages and configures + * them to map request region of flash memory into data address space or into + * instruction address space. It may reuse MMU pages which already provide + * required mapping. As with any allocator, there is possibility of fragmentation + * of address space if mmap/munmap are heavily used. To troubleshoot issues with + * page allocation, use spi_flash_mmap_dump function. + * + * @param src_addr Physical address in flash where requested region starts. + * This address *must* be aligned to 64kB boundary. + * @param size Size of region which has to be mapped. This size will be rounded + * up to a 64k boundary. + * @param memory Memory space where the region should be mapped + * @param out_ptr Output, pointer to the mapped memory region + * @param out_handle Output, handle which should be used for spi_flash_munmap call + * + * @return ESP_OK on success, ESP_ERR_NO_MEM if pages can not be allocated + */ +esp_err_t spi_flash_mmap(uint32_t src_addr, size_t size, spi_flash_mmap_memory_t memory, + const void** out_ptr, spi_flash_mmap_handle_t* out_handle); + +/** + * @brief Release region previously obtained using spi_flash_mmap + * + * @note Calling this function will not necessarily unmap memory region. + * Region will only be unmapped when there are no other handles which + * reference this region. In case of partially overlapping regions + * it is possible that memory will be unmapped partially. + * + * @param handle Handle obtained from spi_flash_mmap + */ +void spi_flash_munmap(spi_flash_mmap_handle_t handle); + +/** + * @brief Display information about mapped regions + * + * This function lists handles obtained using spi_flash_mmap, along with range + * of pages allocated to each handle. It also lists all non-zero entries of + * MMU table and corresponding reference counts. + */ +void spi_flash_mmap_dump(); + #if CONFIG_SPI_FLASH_ENABLE_COUNTERS /** From 999e6d4e8f9035f8de54410a8e037ec7ada3e917 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Wed, 19 Oct 2016 17:19:02 +0800 Subject: [PATCH 166/343] freertos: move panic handler data to DRAM Fixes https://ezredmine.espressif.com/issues/7817 --- components/esp32/ld/esp32.common.ld | 1 + 1 file changed, 1 insertion(+) diff --git a/components/esp32/ld/esp32.common.ld b/components/esp32/ld/esp32.common.ld index a3c6367840..2226e98825 100644 --- a/components/esp32/ld/esp32.common.ld +++ b/components/esp32/ld/esp32.common.ld @@ -92,6 +92,7 @@ SECTIONS KEEP(*(.gnu.linkonce.s2.*)) KEEP(*(.jcr)) *(.dram1 .dram1.*) + *libfreertos.a:panic.o(.rodata .rodata.*) _data_end = ABSOLUTE(.); . = ALIGN(4); _heap_start = ABSOLUTE(.); From 079d9ea018729c95a9aea0ac759f40849cb13f5e Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Wed, 19 Oct 2016 18:04:25 +0800 Subject: [PATCH 167/343] spi_flash: implement partition API --- components/spi_flash/include/esp_partition.h | 156 ++++++++----- components/spi_flash/partition.c | 221 +++++++++++++++++++ 2 files changed, 326 insertions(+), 51 deletions(-) create mode 100644 components/spi_flash/partition.c diff --git a/components/spi_flash/include/esp_partition.h b/components/spi_flash/include/esp_partition.h index fd1223da51..6bdba149f1 100644 --- a/components/spi_flash/include/esp_partition.h +++ b/components/spi_flash/include/esp_partition.h @@ -15,62 +15,73 @@ #ifndef __ESP_PARTITION_H__ #define __ESP_PARTITION_H__ +#include +#include #include "esp_err.h" #ifdef __cplusplus extern "C" { #endif -enum esp_partition_type_t { - PT_APP_MASK = 0x0000, - PT_APP_FACTORY = PT_APP_MASK | 0x00, - PT_APP_OTA_MIN = PT_APP_MASK | 0x10, - PT_APP_OTA_0 = PT_APP_OTA_MIN + 0, - PT_APP_OTA_1 = PT_APP_OTA_MIN + 1, - PT_APP_OTA_2 = PT_APP_OTA_MIN + 2, - PT_APP_OTA_3 = PT_APP_OTA_MIN + 3, - PT_APP_OTA_4 = PT_APP_OTA_MIN + 4, - PT_APP_OTA_5 = PT_APP_OTA_MIN + 5, - PT_APP_OTA_6 = PT_APP_OTA_MIN + 6, - PT_APP_OTA_7 = PT_APP_OTA_MIN + 7, - PT_APP_OTA_8 = PT_APP_OTA_MIN + 8, - PT_APP_OTA_9 = PT_APP_OTA_MIN + 9, - PT_APP_OTA_10 = PT_APP_OTA_MIN + 10, - PT_APP_OTA_11 = PT_APP_OTA_MIN + 11, - PT_APP_OTA_12 = PT_APP_OTA_MIN + 12, - PT_APP_OTA_13 = PT_APP_OTA_MIN + 13, - PT_APP_OTA_14 = PT_APP_OTA_MIN + 14, - PT_APP_OTA_15 = PT_APP_OTA_MIN + 15, - PT_APP_OTA_MAX = PT_APP_MASK | 0x1f, - PT_APP_TEST = PT_APP_MASK | 0x20, - PT_APP_ANY = PT_APP_MASK | 0xff, +typedef enum { + ESP_PARTITION_APP_MASK = 0x0000, + ESP_PARTITION_APP_FACTORY = ESP_PARTITION_APP_MASK | 0x00, + ESP_PARTITION_APP_OTA_MIN = ESP_PARTITION_APP_MASK | 0x10, + ESP_PARTITION_APP_OTA_0 = ESP_PARTITION_APP_OTA_MIN + 0, + ESP_PARTITION_APP_OTA_1 = ESP_PARTITION_APP_OTA_MIN + 1, + ESP_PARTITION_APP_OTA_2 = ESP_PARTITION_APP_OTA_MIN + 2, + ESP_PARTITION_APP_OTA_3 = ESP_PARTITION_APP_OTA_MIN + 3, + ESP_PARTITION_APP_OTA_4 = ESP_PARTITION_APP_OTA_MIN + 4, + ESP_PARTITION_APP_OTA_5 = ESP_PARTITION_APP_OTA_MIN + 5, + ESP_PARTITION_APP_OTA_6 = ESP_PARTITION_APP_OTA_MIN + 6, + ESP_PARTITION_APP_OTA_7 = ESP_PARTITION_APP_OTA_MIN + 7, + ESP_PARTITION_APP_OTA_8 = ESP_PARTITION_APP_OTA_MIN + 8, + ESP_PARTITION_APP_OTA_9 = ESP_PARTITION_APP_OTA_MIN + 9, + ESP_PARTITION_APP_OTA_10 = ESP_PARTITION_APP_OTA_MIN + 10, + ESP_PARTITION_APP_OTA_11 = ESP_PARTITION_APP_OTA_MIN + 11, + ESP_PARTITION_APP_OTA_12 = ESP_PARTITION_APP_OTA_MIN + 12, + ESP_PARTITION_APP_OTA_13 = ESP_PARTITION_APP_OTA_MIN + 13, + ESP_PARTITION_APP_OTA_14 = ESP_PARTITION_APP_OTA_MIN + 14, + ESP_PARTITION_APP_OTA_15 = ESP_PARTITION_APP_OTA_MIN + 15, + ESP_PARTITION_APP_OTA_MAX = ESP_PARTITION_APP_MASK | 0x1f, + ESP_PARTITION_APP_TEST = ESP_PARTITION_APP_MASK | 0x20, + ESP_PARTITION_APP_ANY = ESP_PARTITION_APP_MASK | 0xff, - PT_DATA_MASK = 0x0100, - PT_DATA_OTA = PT_DATA_MASK | 0x00, - PT_DATA_RF = PT_DATA_MASK | 0x01, - PT_DATA_WIFI = PT_DATA_MASK | 0x02, - PT_DATA_ANY = PT_DATA_MASK | 0xff, + ESP_PARTITION_DATA_MASK = 0x0100, + ESP_PARTITION_DATA_OTA = ESP_PARTITION_DATA_MASK | 0x00, + ESP_PARTITION_DATA_RF = ESP_PARTITION_DATA_MASK | 0x01, + ESP_PARTITION_DATA_WIFI = ESP_PARTITION_DATA_MASK | 0x02, + ESP_PARTITION_DATA_ANY = ESP_PARTITION_DATA_MASK | 0xff, - PT_FILESYSTEM_MASK = 0x0200, - PT_FILESYSTEM_ESPHTTPD = 0x0200, - PT_FILESYSTEM_FAT = 0x0201, - PT_FILESYSTEM_SPIFFS = 0x0202, - PT_FILESYSTEM_ANY = 0x20ff, + ESP_PARTITION_FILESYSTEM_MASK = 0x0200, + ESP_PARTITION_FILESYSTEM_ESPHTTPD = 0x0200, + ESP_PARTITION_FILESYSTEM_FAT = 0x0201, + ESP_PARTITION_FILESYSTEM_SPIFFS = 0x0202, + ESP_PARTITION_FILESYSTEM_ANY = 0x20ff, - PT_END = 0xffff -}; + ESP_PARTITION_END = 0xffff +} esp_partition_type_t; -#define PT_APP_OTA(i) ((esp_partition_type_t)(PT_APP_OTA_MIN + ((i) & 0xf))) +#define ESP_PARTITION_APP_OTA(i) ((esp_partition_type_t)(ESP_PARTITION_APP_OTA_MIN + ((i) & 0xf))) -typedef struct esp_partition_iterator_opaque_t* esp_partition_iterator_t; +typedef struct esp_partition_iterator_opaque_* esp_partition_iterator_t; + +typedef struct { + esp_partition_type_t type; + uint32_t address; + uint32_t size; + char label[17]; + bool encrypted; +} esp_partition_t; /** * @brief Find partition based on one or more parameters * * @param type Partition type, one of esp_partition_type_t values * To find all app partitions or all filesystem partitions, - * use PT_APP_ANY or PT_FILESYSTEM_ANY, respectively. + * use ESP_PARTITION_APP_ANY or ESP_PARTITION_FILESYSTEM_ANY, + * respectively. * @param label (optional) Partition label. Set this value if looking * for partition with a specific name. Pass NULL otherwise. * @@ -81,24 +92,47 @@ typedef struct esp_partition_iterator_opaque_t* esp_partition_iterator_t; */ esp_partition_iterator_t esp_partition_find(esp_partition_type_t type, const char* label); +/** + * @brief Find first partition based on one or more parameters + * + * @param type Partition type, one of esp_partition_type_t values + * To find all app partitions or all filesystem partitions, + * use ESP_PARTITION_APP_ANY or ESP_PARTITION_FILESYSTEM_ANY, + * respectively. + * @param label (optional) Partition label. Set this value if looking + * for partition with a specific name. Pass NULL otherwise. + * + * @return pointer to esp_partition_t structure, or NULL if no parition is found. + * This pointer is valid for the lifetime of the application. + */ +const esp_partition_t* esp_partition_find_first(esp_partition_type_t type, const char* label); + +/** + * @brief Get esp_partition_t structure for given partition + * + * @param iterator Iterator obtained using esp_partition_find. Must be non-NULL. + * + * @return pointer to esp_partition_t structure. This pointer is valid for the lifetime + * of the application. + */ +const esp_partition_t* esp_partition_get(esp_partition_iterator_t iterator); /** * @brief Move partition iterator to the next partition found * - * Any pointers obtained using esp_partition_label function for this iterator - * will be invalid after this call. + * Any copies of the iterator will be invalid after this call. * * @param iterator Iterator obtained using esp_partition_find. Must be non-NULL. * - * @return iterator pointing to the next partition found, or NULL if no more - * partitions were found. - * + * @return NULL if no partition was found, valid esp_partition_iterator_t otherwise. */ esp_partition_iterator_t esp_partition_next(esp_partition_iterator_t iterator); /** * @brief Get partition type * + * @note This is a helper function built around esp_partition_get. + * * @param iterator Iterator obtained using esp_partition_find. Must be non-NULL. * * @return esp_partition_type_t value for partition pointed to by the iterator. @@ -108,6 +142,8 @@ esp_partition_type_t esp_partition_type(esp_partition_iterator_t iterator); /** * @brief Get partition size * + * @note This is a helper function built around esp_partition_get. + * * @param iterator Iterator obtained using esp_partition_find. Must be non-NULL. * * @return partition size, in bytes @@ -117,6 +153,8 @@ uint32_t esp_partition_size(esp_partition_iterator_t iterator); /** * @brief Get partition address * + * @note This is a helper function built around esp_partition_get. + * * @param iterator Iterator obtained using esp_partition_find. Must be non-NULL. * * @return flash address of partition start @@ -126,11 +164,12 @@ uint32_t esp_partition_address(esp_partition_iterator_t iterator); /** * @brief Get partition label * + * @note This is a helper function built around esp_partition_get. + * * @param iterator Iterator obtained using esp_partition_find. Must be non-NULL. * * @return pointer to a zero-terminated string with partition label. - * The pointer is valid until the call to esp_partition_next or - * esp_partition_iterator_release for the given iterator. + * The pointer is valid for the lifetime of the application. */ const char* esp_partition_label(esp_partition_iterator_t iterator); @@ -145,8 +184,8 @@ const char* esp_partition_label(esp_partition_iterator_t iterator); * @param size Size of data to be read, in bytes. * * @return ESP_OK, if data was read successfully; - * ESP_INVALID_ARG, if iterator or src are NULL; - * ESP_INVALID_SIZE, if read would go out of bounds of the partition; + * ESP_ERR_INVALID_ARG, if iterator or src are NULL; + * ESP_ERR_INVALID_SIZE, if read would go out of bounds of the partition; * or one of error codes from lower-level flash driver. */ esp_err_t esp_partition_read(esp_partition_iterator_t iterator, @@ -166,8 +205,8 @@ esp_err_t esp_partition_read(esp_partition_iterator_t iterator, * esp_partition_erase_range call. * * @return ESP_OK, if data was written successfully; - * ESP_INVALID_ARG, if iterator or dst are NULL; - * ESP_INVALID_SIZE, if write would go out of bounds of the partition; + * ESP_ERR_INVALID_ARG, if iterator or dst are NULL; + * ESP_ERR_INVALID_SIZE, if write would go out of bounds of the partition; * or one of error codes from lower-level flash driver. */ esp_err_t esp_partition_write(esp_partition_iterator_t iterator, @@ -183,13 +222,28 @@ esp_err_t esp_partition_write(esp_partition_iterator_t iterator, * Must be divisible by 4 kilobytes. * * @return ESP_OK, if the range was erased successfully; - * ESP_INVALID_ARG, if iterator or dst are NULL; - * ESP_INVALID_SIZE, if erase would go out of bounds of the partition; + * ESP_ERR_INVALID_ARG, if iterator or dst are NULL; + * ESP_ERR_INVALID_SIZE, if erase would go out of bounds of the partition; * or one of error codes from lower-level flash driver. */ esp_err_t esp_partition_erase_range(esp_partition_iterator_t iterator, uint32_t start_addr, uint32_t size); +/** + * @brief Configure MMU to map partition into data memory + * + * @param iterator Iterator obtained using esp_partition_find. Must be non-NULL. + * + * @param offset Offset from the beginning of partition where mapping should start. + * Must be aligned to 64k. + * + * @param size Size of the area to be mapped. + * + * @return pointer to mapped memory, if successful + * NULL, if memory can not be mapped for any reason + */ +void* esp_partition_mmap(esp_partition_iterator_t iterator, uint32_t offset, uint32_t size); + /** * @brief Release partition iterator diff --git a/components/spi_flash/partition.c b/components/spi_flash/partition.c new file mode 100644 index 0000000000..381a1624b5 --- /dev/null +++ b/components/spi_flash/partition.c @@ -0,0 +1,221 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include +#include + +#include "esp_attr.h" +#include "esp_flash_data_types.h" +#include "esp_spi_flash.h" +#include "esp_partition.h" +#include "esp_log.h" + + +#ifndef NDEBUG +// Enable built-in checks in queue.h in debug builds +#define INVARIANTS +#endif +#include "rom/queue.h" + + +typedef struct partition_list_item_ { + esp_partition_t info; + SLIST_ENTRY(partition_list_item_) next; +} partition_list_item_t; + +typedef struct esp_partition_iterator_opaque_ { + esp_partition_type_t type; // requested type + const char* label; // requested label (can be NULL) + partition_list_item_t* next_item; // next item to iterate to + esp_partition_t* info; // pointer to info (it is redundant, but makes code more readable) +} esp_partition_iterator_opaque_t; + + +static esp_partition_iterator_opaque_t* iterator_create(esp_partition_type_t type, const char* label); +static esp_err_t load_partitions(); + + +static SLIST_HEAD(partition_list_head_, partition_list_item_) s_partition_list = + SLIST_HEAD_INITIALIZER(s_partition_list); +static _lock_t s_partition_list_lock; + + +static uint32_t get_major_type(esp_partition_type_t type) +{ + return (type >> 8) & 0xff; +} + +static uint32_t get_minor_type(esp_partition_type_t type) +{ + return type & 0xff; +} + +esp_partition_iterator_t esp_partition_find(esp_partition_type_t type, + const char* label) +{ + if (SLIST_EMPTY(&s_partition_list)) { + // only lock if list is empty (and check again after acquiring lock) + _lock_acquire(&s_partition_list_lock); + esp_err_t err = ESP_OK; + if (SLIST_EMPTY(&s_partition_list)) { + err = load_partitions(); + } + _lock_release(&s_partition_list_lock); + if (err != ESP_OK) { + return NULL; + } + } + // create an iterator pointing to the start of the list + // (next item will be the first one) + esp_partition_iterator_t it = iterator_create(type, label); + // advance iterator to the next item which matches constraints + it = esp_partition_next(it); + // if nothing found, it == NULL and iterator has been released + return it; +} + +esp_partition_iterator_t esp_partition_next(esp_partition_iterator_t it) +{ + assert(it); + // iterator reached the end of linked list? + if (it->next_item == NULL) { + return NULL; + } + uint32_t requested_major_type = get_major_type(it->type); + uint32_t requested_minor_type = get_minor_type(it->type); + _lock_acquire(&s_partition_list_lock); + for (; it->next_item != NULL; it->next_item = SLIST_NEXT(it->next_item, next)) { + esp_partition_t* p = &it->next_item->info; + uint32_t it_major_type = get_major_type(p->type); + uint32_t it_minor_type = get_minor_type(p->type); + if (requested_major_type != it_major_type) { + continue; + } + if (requested_minor_type != 0xff && requested_minor_type != it_minor_type) { + continue; + } + if (it->label != NULL && strcmp(it->label, p->label) != 0) { + continue; + } + // all constraints match, bail out + break; + } + _lock_release(&s_partition_list_lock); + if (it->next_item == NULL) { + esp_partition_iterator_release(it); + return NULL; + } + it->info = &it->next_item->info; + it->next_item = SLIST_NEXT(it->next_item, next); + return it; +} + +const esp_partition_t* esp_partition_find_first(esp_partition_type_t type, const char* label) +{ + esp_partition_iterator_t it = esp_partition_find(type, label); + if (it == NULL) { + return NULL; + } + const esp_partition_t* res = esp_partition_get(it); + esp_partition_iterator_release(it); + return res; +} + +void esp_partition_iterator_release(esp_partition_iterator_t iterator) +{ + // iterator == NULL is okay + free(iterator); +} + +const esp_partition_t* esp_partition_get(esp_partition_iterator_t iterator) +{ + assert(iterator != NULL); + return iterator->info; +} + +esp_partition_type_t esp_partition_type(esp_partition_iterator_t iterator) +{ + return esp_partition_get(iterator)->type; +} + +uint32_t esp_partition_size(esp_partition_iterator_t iterator) +{ + return esp_partition_get(iterator)->size; +} + +uint32_t esp_partition_address(esp_partition_iterator_t iterator) +{ + return esp_partition_get(iterator)->address; +} + +const char* esp_partition_label(esp_partition_iterator_t iterator) +{ + return esp_partition_get(iterator)->label; +} + +static esp_partition_iterator_opaque_t* iterator_create(esp_partition_type_t type, const char* label) +{ + esp_partition_iterator_opaque_t* it = + (esp_partition_iterator_opaque_t*) malloc(sizeof(esp_partition_iterator_opaque_t)); + it->type = type; + it->label = label; + it->next_item = SLIST_FIRST(&s_partition_list); + it->info = NULL; + return it; +} + +// Create linked list of partition_list_item_t structures. +// This function is called only once, with s_partition_list_lock taken. +static esp_err_t load_partitions() +{ + const uint32_t* ptr; + spi_flash_mmap_handle_t handle; + // map 64kB block where partition table is located + esp_err_t err = spi_flash_mmap(ESP_PARTITION_TABLE_ADDR & 0xffff0000, + SPI_FLASH_SEC_SIZE, SPI_FLASH_MMAP_DATA, (const void**) &ptr, &handle); + if (err != ESP_OK) { + return err; + } + // calculate partition address within mmap-ed region + const esp_partition_info_t* it = (const esp_partition_info_t*) + (ptr + (ESP_PARTITION_TABLE_ADDR & 0xffff) / sizeof(*ptr)); + const esp_partition_info_t* end = it + SPI_FLASH_SEC_SIZE / sizeof(*it); + // tail of the linked list of partitions + partition_list_item_t* last = NULL; + for (; it != end; ++it) { + if (it->magic != ESP_PARTITION_MAGIC) { + break; + } + // allocate new linked list item and populate it with data from partition table + partition_list_item_t* item = (partition_list_item_t*) malloc(sizeof(partition_list_item_t)); + item->info.address = it->pos.offset; + item->info.size = it->pos.size; + item->info.type = (it->type << 8) | it->subtype; + item->info.encrypted = false; + // it->label may not be zero-terminated + strncpy(item->info.label, (const char*) it->label, sizeof(it->label)); + item->info.label[sizeof(it->label)] = 0; + // add it to the list + if (last == NULL) { + SLIST_INSERT_HEAD(&s_partition_list, item, next); + } else { + SLIST_INSERT_AFTER(last, item, next); + } + } + spi_flash_munmap(handle); + return ESP_OK; +} From 2c5340d47e2a482c2fc58ae02178332775c3a699 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 21 Oct 2016 17:28:50 +0800 Subject: [PATCH 168/343] spi_flash: change argument types spi_flash_read and spi_flash_write currently have a limitation that source and destination must be word-aligned. This can be fixed by adding code paths for various unaligned scenarios, but function signatures also need to be adjusted. As a first step (since we are pre-1.0 and can still change function signatures) alignment checks are added, and pointer types are relaxed to uint8_t. Later we will add handling of unaligned operations. This change also introduces spi_flash_erase_range and spi_flash_get_chip_size functions. We probably need something like spi_flash_chip_size_detect which will detect actual chip size. This is to allow single application binary to be used on a variety of boards and modules. --- components/nvs_flash/src/nvs_page.cpp | 27 ++++--- .../nvs_flash/test/spi_flash_emulation.cpp | 10 +-- .../nvs_flash/test/spi_flash_emulation.h | 6 +- .../test/test_spi_flash_emulation.cpp | 20 ++--- components/spi_flash/flash_ops.c | 81 +++++++++++++++++-- components/spi_flash/include/esp_spi_flash.h | 50 +++++++++--- 6 files changed, 146 insertions(+), 48 deletions(-) diff --git a/components/nvs_flash/src/nvs_page.cpp b/components/nvs_flash/src/nvs_page.cpp index f4fc5430cd..9ba478e215 100644 --- a/components/nvs_flash/src/nvs_page.cpp +++ b/components/nvs_flash/src/nvs_page.cpp @@ -37,7 +37,7 @@ esp_err_t Page::load(uint32_t sectorNumber) mErasedEntryCount = 0; Header header; - auto rc = spi_flash_read(mBaseAddress, reinterpret_cast(&header), sizeof(header)); + auto rc = spi_flash_read(mBaseAddress, reinterpret_cast(&header), sizeof(header)); if (rc != ESP_OK) { mState = PageState::INVALID; return rc; @@ -48,7 +48,7 @@ esp_err_t Page::load(uint32_t sectorNumber) // reading the whole page takes ~40 times less than erasing it uint32_t line[8]; for (uint32_t i = 0; i < SPI_FLASH_SEC_SIZE; i += sizeof(line)) { - rc = spi_flash_read(mBaseAddress + i, line, sizeof(line)); + rc = spi_flash_read(mBaseAddress + i, reinterpret_cast(line), sizeof(line)); if (rc != ESP_OK) { mState = PageState::INVALID; return rc; @@ -86,7 +86,7 @@ esp_err_t Page::load(uint32_t sectorNumber) esp_err_t Page::writeEntry(const Item& item) { - auto rc = spi_flash_write(getEntryAddress(mNextFreeEntry), reinterpret_cast(&item), sizeof(item)); + auto rc = spi_flash_write(getEntryAddress(mNextFreeEntry), reinterpret_cast(&item), sizeof(item)); if (rc != ESP_OK) { mState = PageState::INVALID; return rc; @@ -114,7 +114,7 @@ esp_err_t Page::writeEntryData(const uint8_t* data, size_t size) assert(mFirstUsedEntry != INVALID_ENTRY); const uint16_t count = size / ENTRY_SIZE; - auto rc = spi_flash_write(getEntryAddress(mNextFreeEntry), reinterpret_cast(data), static_cast(size)); + auto rc = spi_flash_write(getEntryAddress(mNextFreeEntry), data, size); if (rc != ESP_OK) { mState = PageState::INVALID; return rc; @@ -396,8 +396,8 @@ esp_err_t Page::mLoadEntryTable() if (mState == PageState::ACTIVE || mState == PageState::FULL || mState == PageState::FREEING) { - auto rc = spi_flash_read(mBaseAddress + ENTRY_TABLE_OFFSET, mEntryTable.data(), - static_cast(mEntryTable.byteSize())); + auto rc = spi_flash_read(mBaseAddress + ENTRY_TABLE_OFFSET, reinterpret_cast(mEntryTable.data()), + mEntryTable.byteSize()); if (rc != ESP_OK) { mState = PageState::INVALID; return rc; @@ -435,7 +435,7 @@ esp_err_t Page::mLoadEntryTable() while (mNextFreeEntry < ENTRY_COUNT) { uint32_t entryAddress = getEntryAddress(mNextFreeEntry); uint32_t header; - auto rc = spi_flash_read(entryAddress, &header, sizeof(header)); + auto rc = spi_flash_read(entryAddress, reinterpret_cast(&header), sizeof(header)); if (rc != ESP_OK) { mState = PageState::INVALID; return rc; @@ -559,7 +559,7 @@ esp_err_t Page::initialize() header.mSeqNumber = mSeqNumber; header.mCrc32 = header.calculateCrc32(); - auto rc = spi_flash_write(mBaseAddress, reinterpret_cast(&header), sizeof(header)); + auto rc = spi_flash_write(mBaseAddress, reinterpret_cast(&header), sizeof(header)); if (rc != ESP_OK) { mState = PageState::INVALID; return rc; @@ -577,7 +577,8 @@ esp_err_t Page::alterEntryState(size_t index, EntryState state) mEntryTable.set(index, state); size_t wordToWrite = mEntryTable.getWordIndex(index); uint32_t word = mEntryTable.data()[wordToWrite]; - auto rc = spi_flash_write(mBaseAddress + ENTRY_TABLE_OFFSET + static_cast(wordToWrite) * 4, &word, 4); + auto rc = spi_flash_write(mBaseAddress + ENTRY_TABLE_OFFSET + static_cast(wordToWrite) * 4, + reinterpret_cast(&word), sizeof(word)); if (rc != ESP_OK) { mState = PageState::INVALID; return rc; @@ -600,7 +601,8 @@ esp_err_t Page::alterEntryRangeState(size_t begin, size_t end, EntryState state) } if (nextWordIndex != wordIndex) { uint32_t word = mEntryTable.data()[wordIndex]; - auto rc = spi_flash_write(mBaseAddress + ENTRY_TABLE_OFFSET + static_cast(wordIndex) * 4, &word, 4); + auto rc = spi_flash_write(mBaseAddress + ENTRY_TABLE_OFFSET + static_cast(wordIndex) * 4, + reinterpret_cast(&word), 4); if (rc != ESP_OK) { return rc; } @@ -612,7 +614,8 @@ esp_err_t Page::alterEntryRangeState(size_t begin, size_t end, EntryState state) esp_err_t Page::alterPageState(PageState state) { - auto rc = spi_flash_write(mBaseAddress, reinterpret_cast(&state), sizeof(state)); + uint32_t state_val = static_cast(state); + auto rc = spi_flash_write(mBaseAddress, reinterpret_cast(&state_val), sizeof(state)); if (rc != ESP_OK) { mState = PageState::INVALID; return rc; @@ -623,7 +626,7 @@ esp_err_t Page::alterPageState(PageState state) esp_err_t Page::readEntry(size_t index, Item& dst) const { - auto rc = spi_flash_read(getEntryAddress(index), reinterpret_cast(&dst), sizeof(dst)); + auto rc = spi_flash_read(getEntryAddress(index), reinterpret_cast(&dst), sizeof(dst)); if (rc != ESP_OK) { return rc; } diff --git a/components/nvs_flash/test/spi_flash_emulation.cpp b/components/nvs_flash/test/spi_flash_emulation.cpp index 5185bd34cb..bd14822688 100644 --- a/components/nvs_flash/test/spi_flash_emulation.cpp +++ b/components/nvs_flash/test/spi_flash_emulation.cpp @@ -22,7 +22,7 @@ void spi_flash_emulator_set(SpiFlashEmulator* e) s_emulator = e; } -esp_err_t spi_flash_erase_sector(uint16_t sec) +esp_err_t spi_flash_erase_sector(size_t sec) { if (!s_emulator) { return ESP_ERR_FLASH_OP_TIMEOUT; @@ -35,26 +35,26 @@ esp_err_t spi_flash_erase_sector(uint16_t sec) return ESP_OK; } -esp_err_t spi_flash_write(uint32_t des_addr, const uint32_t *src_addr, uint32_t size) +esp_err_t spi_flash_write(size_t des_addr, const uint8_t *src_addr, size_t size) { if (!s_emulator) { return ESP_ERR_FLASH_OP_TIMEOUT; } - if (!s_emulator->write(des_addr, src_addr, size)) { + if (!s_emulator->write(des_addr, reinterpret_cast(src_addr), size)) { return ESP_ERR_FLASH_OP_FAIL; } return ESP_OK; } -esp_err_t spi_flash_read(uint32_t src_addr, uint32_t *des_addr, uint32_t size) +esp_err_t spi_flash_read(size_t src_addr, uint8_t *des_addr, size_t size) { if (!s_emulator) { return ESP_ERR_FLASH_OP_TIMEOUT; } - if (!s_emulator->read(des_addr, src_addr, size)) { + if (!s_emulator->read(reinterpret_cast(des_addr), src_addr, size)) { return ESP_ERR_FLASH_OP_FAIL; } diff --git a/components/nvs_flash/test/spi_flash_emulation.h b/components/nvs_flash/test/spi_flash_emulation.h index d5a242b240..ba50c4f9e4 100644 --- a/components/nvs_flash/test/spi_flash_emulation.h +++ b/components/nvs_flash/test/spi_flash_emulation.h @@ -44,7 +44,7 @@ public: spi_flash_emulator_set(nullptr); } - bool read(uint32_t* dest, uint32_t srcAddr, size_t size) const + bool read(uint32_t* dest, size_t srcAddr, size_t size) const { if (srcAddr % 4 != 0 || size % 4 != 0 || @@ -60,7 +60,7 @@ public: return true; } - bool write(uint32_t dstAddr, const uint32_t* src, size_t size) + bool write(size_t dstAddr, const uint32_t* src, size_t size) { uint32_t sectorNumber = dstAddr/SPI_FLASH_SEC_SIZE; if (sectorNumber < mLowerSectorBound || sectorNumber >= mUpperSectorBound) { @@ -96,7 +96,7 @@ public: return true; } - bool erase(uint32_t sectorNumber) + bool erase(size_t sectorNumber) { size_t offset = sectorNumber * SPI_FLASH_SEC_SIZE / 4; if (offset > mData.size()) { diff --git a/components/nvs_flash/test/test_spi_flash_emulation.cpp b/components/nvs_flash/test/test_spi_flash_emulation.cpp index ea233da61b..329e721ce7 100644 --- a/components/nvs_flash/test/test_spi_flash_emulation.cpp +++ b/components/nvs_flash/test/test_spi_flash_emulation.cpp @@ -30,7 +30,7 @@ TEST_CASE("flash starts with all bytes == 0xff", "[spi_flash_emu]") uint8_t sector[SPI_FLASH_SEC_SIZE]; for (int i = 0; i < 4; ++i) { - CHECK(spi_flash_read(0, reinterpret_cast(sector), sizeof(sector)) == ESP_OK); + CHECK(spi_flash_read(0, sector, sizeof(sector)) == ESP_OK); for (auto v: sector) { CHECK(v == 0xff); } @@ -42,9 +42,9 @@ TEST_CASE("invalid writes are checked", "[spi_flash_emu]") SpiFlashEmulator emu(1); uint32_t val = 0; - CHECK(spi_flash_write(0, &val, 4) == ESP_OK); + CHECK(spi_flash_write(0, reinterpret_cast(&val), 4) == ESP_OK); val = 1; - CHECK(spi_flash_write(0, &val, 4) == ESP_ERR_FLASH_OP_FAIL); + CHECK(spi_flash_write(0, reinterpret_cast(&val), 4) == ESP_ERR_FLASH_OP_FAIL); } @@ -53,11 +53,11 @@ TEST_CASE("out of bounds writes fail", "[spi_flash_emu]") SpiFlashEmulator emu(4); uint32_t vals[8]; std::fill_n(vals, 8, 0); - CHECK(spi_flash_write(0, vals, sizeof(vals)) == ESP_OK); + CHECK(spi_flash_write(0, reinterpret_cast(vals), sizeof(vals)) == ESP_OK); - CHECK(spi_flash_write(4*4096 - sizeof(vals), vals, sizeof(vals)) == ESP_OK); + CHECK(spi_flash_write(4*4096 - sizeof(vals), reinterpret_cast(vals), sizeof(vals)) == ESP_OK); - CHECK(spi_flash_write(4*4096 - sizeof(vals) + 4, vals, sizeof(vals)) == ESP_ERR_FLASH_OP_FAIL); + CHECK(spi_flash_write(4*4096 - sizeof(vals) + 4, reinterpret_cast(vals), sizeof(vals)) == ESP_ERR_FLASH_OP_FAIL); } @@ -65,9 +65,9 @@ TEST_CASE("after erase the sector is set to 0xff", "[spi_flash_emu]") { SpiFlashEmulator emu(4); uint32_t val1 = 0xab00cd12; - CHECK(spi_flash_write(0, &val1, sizeof(val1)) == ESP_OK); + CHECK(spi_flash_write(0, reinterpret_cast(&val1), sizeof(val1)) == ESP_OK); uint32_t val2 = 0x5678efab; - CHECK(spi_flash_write(4096 - 4, &val2, sizeof(val2)) == ESP_OK); + CHECK(spi_flash_write(4096 - 4, reinterpret_cast(&val2), sizeof(val2)) == ESP_OK); CHECK(emu.words()[0] == val1); CHECK(range_empty_n(emu.words() + 1, 4096 / 4 - 2)); @@ -83,7 +83,7 @@ TEST_CASE("after erase the sector is set to 0xff", "[spi_flash_emu]") TEST_CASE("read/write/erase operation times are calculated correctly", "[spi_flash_emu]") { SpiFlashEmulator emu(1); - uint32_t data[128]; + uint8_t data[512]; spi_flash_read(0, data, 4); CHECK(emu.getTotalTime() == 7); CHECK(emu.getReadOps() == 1); @@ -141,7 +141,7 @@ TEST_CASE("read/write/erase operation times are calculated correctly", "[spi_fla CHECK(emu.getTotalTime() == 37142); } -TEST_CASE("data is randomized predicatbly", "[spi_flash_emu]") +TEST_CASE("data is randomized predictably", "[spi_flash_emu]") { SpiFlashEmulator emu1(3); emu1.randomize(0x12345678); diff --git a/components/spi_flash/flash_ops.c b/components/spi_flash/flash_ops.c index 99e8ef77f2..512f6d20d2 100644 --- a/components/spi_flash/flash_ops.c +++ b/components/spi_flash/flash_ops.c @@ -64,6 +64,11 @@ void spi_flash_init() #endif } +size_t spi_flash_get_chip_size() +{ + return g_rom_flashchip.chip_size; +} + SpiFlashOpResult IRAM_ATTR spi_flash_unlock() { static bool unlocked = false; @@ -77,28 +82,74 @@ SpiFlashOpResult IRAM_ATTR spi_flash_unlock() return SPI_FLASH_RESULT_OK; } -esp_err_t IRAM_ATTR spi_flash_erase_sector(uint16_t sec) +esp_err_t IRAM_ATTR spi_flash_erase_sector(size_t sec) { + return spi_flash_erase_range(sec * SPI_FLASH_SEC_SIZE, SPI_FLASH_SEC_SIZE); +} + +esp_err_t IRAM_ATTR spi_flash_erase_range(uint32_t start_addr, uint32_t size) +{ + if (start_addr % SPI_FLASH_SEC_SIZE != 0) { + return ESP_ERR_INVALID_ARG; + } + if (size % SPI_FLASH_SEC_SIZE != 0) { + return ESP_ERR_INVALID_SIZE; + } + if (size + start_addr > spi_flash_get_chip_size()) { + return ESP_ERR_INVALID_SIZE; + } + size_t start = start_addr / SPI_FLASH_SEC_SIZE; + size_t end = start + size / SPI_FLASH_SEC_SIZE; + const size_t sectors_per_block = 16; COUNTER_START(); spi_flash_disable_interrupts_caches_and_other_cpu(); SpiFlashOpResult rc; rc = spi_flash_unlock(); if (rc == SPI_FLASH_RESULT_OK) { - rc = SPIEraseSector(sec); + for (size_t sector = start; sector != end && rc == SPI_FLASH_RESULT_OK; ) { + if (sector % sectors_per_block == 0 && end - sector > sectors_per_block) { + rc = SPIEraseBlock(sector / sectors_per_block); + sector += sectors_per_block; + COUNTER_ADD_BYTES(erase, sectors_per_block * SPI_FLASH_SEC_SIZE); + } + else { + rc = SPIEraseSector(sector); + ++sector; + COUNTER_ADD_BYTES(erase, SPI_FLASH_SEC_SIZE); + } + } } spi_flash_enable_interrupts_caches_and_other_cpu(); COUNTER_STOP(erase); return spi_flash_translate_rc(rc); } -esp_err_t IRAM_ATTR spi_flash_write(uint32_t dest_addr, const uint32_t *src, uint32_t size) +esp_err_t IRAM_ATTR spi_flash_write(size_t dest_addr, const uint8_t *src, size_t size) { + // TODO: replace this check with code which deals with unaligned sources + if (((ptrdiff_t) src) % 4 != 0) { + return ESP_ERR_INVALID_ARG; + } + // Destination alignment is also checked in ROM code, but we can give + // better error code here + // TODO: add handling of unaligned destinations + if (dest_addr % 4 != 0) { + return ESP_ERR_INVALID_ARG; + } + if (size % 4 != 0) { + return ESP_ERR_INVALID_SIZE; + } + // Out of bound writes are checked in ROM code, but we can give better + // error code here + if (dest_addr + size > g_rom_flashchip.chip_size) { + return ESP_ERR_INVALID_SIZE; + } COUNTER_START(); spi_flash_disable_interrupts_caches_and_other_cpu(); SpiFlashOpResult rc; rc = spi_flash_unlock(); if (rc == SPI_FLASH_RESULT_OK) { - rc = SPIWrite(dest_addr, src, (int32_t) size); + rc = SPIWrite((uint32_t) dest_addr, (const uint32_t*) src, (int32_t) size); COUNTER_ADD_BYTES(write, size); } spi_flash_enable_interrupts_caches_and_other_cpu(); @@ -106,11 +157,29 @@ esp_err_t IRAM_ATTR spi_flash_write(uint32_t dest_addr, const uint32_t *src, uin return spi_flash_translate_rc(rc); } -esp_err_t IRAM_ATTR spi_flash_read(uint32_t src_addr, uint32_t *dest, uint32_t size) +esp_err_t IRAM_ATTR spi_flash_read(size_t src_addr, uint8_t *dest, size_t size) { + // TODO: replace this check with code which deals with unaligned destinations + if (((ptrdiff_t) dest) % 4 != 0) { + return ESP_ERR_INVALID_ARG; + } + // Source alignment is also checked in ROM code, but we can give + // better error code here + // TODO: add handling of unaligned destinations + if (src_addr % 4 != 0) { + return ESP_ERR_INVALID_ARG; + } + if (size % 4 != 0) { + return ESP_ERR_INVALID_SIZE; + } + // Out of bound reads are checked in ROM code, but we can give better + // error code here + if (src_addr + size > g_rom_flashchip.chip_size) { + return ESP_ERR_INVALID_SIZE; + } COUNTER_START(); spi_flash_disable_interrupts_caches_and_other_cpu(); - SpiFlashOpResult rc = SPIRead(src_addr, dest, (int32_t) size); + SpiFlashOpResult rc = SPIRead((uint32_t) src_addr, (uint32_t*) dest, (int32_t) size); COUNTER_ADD_BYTES(read, size); spi_flash_enable_interrupts_caches_and_other_cpu(); COUNTER_STOP(read); diff --git a/components/spi_flash/include/esp_spi_flash.h b/components/spi_flash/include/esp_spi_flash.h index 597e41857c..ab66a42041 100644 --- a/components/spi_flash/include/esp_spi_flash.h +++ b/components/spi_flash/include/esp_spi_flash.h @@ -38,37 +38,63 @@ extern "C" { */ void spi_flash_init(); +/** + * @brief Get flash chip size, as set in binary image header + * + * @note This value does not necessarily match real flash size. + * + * @return size of flash chip, in bytes + */ +size_t spi_flash_get_chip_size(); + /** * @brief Erase the Flash sector. * - * @param uint16 sec : Sector number, the count starts at sector 0, 4KB per sector. + * @param sector Sector number, the count starts at sector 0, 4KB per sector. * * @return esp_err_t */ -esp_err_t spi_flash_erase_sector(uint16_t sec); +esp_err_t spi_flash_erase_sector(size_t sector); + +/** + * @brief Erase a range of flash sectors + * + * @param uint32_t start_address : Address where erase operation has to start. + * Must be 4kB-aligned + * @param uint32_t size : Size of erased range, in bytes. Must be divisible by 4kB. + * + * @return esp_err_t + */ +esp_err_t spi_flash_erase_range(size_t start_addr, size_t size); + /** * @brief Write data to Flash. * - * @param uint32 des_addr : destination address in Flash. - * @param uint32 *src_addr : source address of the data. - * @param uint32 size : length of data + * @note Both des_addr and src_addr have to be 4-byte aligned. + * This is a temporary limitation which will be removed. + * + * @param des_addr destination address in Flash + * @param src_addr source address of the data + * @param size length of data, in bytes * * @return esp_err_t */ -esp_err_t spi_flash_write(uint32_t des_addr, const uint32_t *src_addr, uint32_t size); +esp_err_t spi_flash_write(size_t des_addr, const uint8_t *src_addr, size_t size); /** * @brief Read data from Flash. * - * @param uint32 src_addr : source address of the data in Flash. - * @param uint32 *des_addr : destination address. - * @param uint32 size : length of data + * @note Both des_addr and src_addr have to be 4-byte aligned. + * This is a temporary limitation which will be removed. + * + * @param src_addr source address of the data in Flash. + * @param des_addr destination address + * @param size length of data * * @return esp_err_t */ -esp_err_t spi_flash_read(uint32_t src_addr, uint32_t *des_addr, uint32_t size); - +esp_err_t spi_flash_read(size_t src_addr, uint8_t *des_addr, size_t size); /** * @brief Enumeration which specifies memory space requested in an mmap call @@ -135,7 +161,7 @@ void spi_flash_mmap_dump(); typedef struct { uint32_t count; // number of times operation was executed uint32_t time; // total time taken, in microseconds - uint32_t bytes; // total number of bytes, for read and write operations + uint32_t bytes; // total number of bytes } spi_flash_counter_t; typedef struct { From b6693225c188ab627a31bbe8e881bfa183f21c22 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 21 Oct 2016 18:44:57 +0800 Subject: [PATCH 169/343] spi_flash: implement partition API, drop trivial wrappers This implements esp_partition_read, esp_partition_write, esp_partition_erase_range, esp_partition_mmap. Also removed getters which didn't add much sugar after all. --- components/spi_flash/include/esp_partition.h | 213 +++++++++---------- components/spi_flash/include/esp_spi_flash.h | 1 + components/spi_flash/partition.c | 121 ++++++++--- 3 files changed, 186 insertions(+), 149 deletions(-) diff --git a/components/spi_flash/include/esp_partition.h b/components/spi_flash/include/esp_partition.h index 6bdba149f1..89e523f9a7 100644 --- a/components/spi_flash/include/esp_partition.h +++ b/components/spi_flash/include/esp_partition.h @@ -17,7 +17,9 @@ #include #include +#include #include "esp_err.h" +#include "esp_spi_flash.h" #ifdef __cplusplus extern "C" { @@ -128,123 +130,6 @@ const esp_partition_t* esp_partition_get(esp_partition_iterator_t iterator); */ esp_partition_iterator_t esp_partition_next(esp_partition_iterator_t iterator); -/** - * @brief Get partition type - * - * @note This is a helper function built around esp_partition_get. - * - * @param iterator Iterator obtained using esp_partition_find. Must be non-NULL. - * - * @return esp_partition_type_t value for partition pointed to by the iterator. - */ -esp_partition_type_t esp_partition_type(esp_partition_iterator_t iterator); - -/** - * @brief Get partition size - * - * @note This is a helper function built around esp_partition_get. - * - * @param iterator Iterator obtained using esp_partition_find. Must be non-NULL. - * - * @return partition size, in bytes - */ -uint32_t esp_partition_size(esp_partition_iterator_t iterator); - -/** - * @brief Get partition address - * - * @note This is a helper function built around esp_partition_get. - * - * @param iterator Iterator obtained using esp_partition_find. Must be non-NULL. - * - * @return flash address of partition start - */ -uint32_t esp_partition_address(esp_partition_iterator_t iterator); - -/** - * @brief Get partition label - * - * @note This is a helper function built around esp_partition_get. - * - * @param iterator Iterator obtained using esp_partition_find. Must be non-NULL. - * - * @return pointer to a zero-terminated string with partition label. - * The pointer is valid for the lifetime of the application. - */ -const char* esp_partition_label(esp_partition_iterator_t iterator); - -/** - * @brief Read data from the partition - * - * @param iterator Iterator obtained using esp_partition_find. Must be non-NULL. - * @param src_offset Address of the data to be read, relative to the - * beginning of the partition. - * @param dst Pointer to the buffer where data should be stored. - * Must be non-NULL and at least 'size' bytes long. - * @param size Size of data to be read, in bytes. - * - * @return ESP_OK, if data was read successfully; - * ESP_ERR_INVALID_ARG, if iterator or src are NULL; - * ESP_ERR_INVALID_SIZE, if read would go out of bounds of the partition; - * or one of error codes from lower-level flash driver. - */ -esp_err_t esp_partition_read(esp_partition_iterator_t iterator, - uint32_t src_offset, uint8_t* dst, uint32_t size); - -/** - * @brief Write data to the partition - * - * @param iterator Iterator obtained using esp_partition_find. Must be non-NULL. - * @param src Pointer to the source buffer. Must be non-NULL and - * at least 'size' bytes long. - * @param dst_offset Address where the data should be written, relative to the - * beginning of the partition. - * @param size Size of data to be written, in bytes. - * - * @note Prior to writing to flash memory, make sure it has been erased with - * esp_partition_erase_range call. - * - * @return ESP_OK, if data was written successfully; - * ESP_ERR_INVALID_ARG, if iterator or dst are NULL; - * ESP_ERR_INVALID_SIZE, if write would go out of bounds of the partition; - * or one of error codes from lower-level flash driver. - */ -esp_err_t esp_partition_write(esp_partition_iterator_t iterator, - const uint8_t* src, uint32_t dst_offset, uint32_t size); - -/** - * @brief Erase part of the partition - * - * @param iterator Iterator obtained using esp_partition_find. Must be non-NULL. - * @param start_addr Address where erase operation should start. Must be aligned - * to 4 kilobytes. - * @param size Size of the range which should be erased, in bytes. - * Must be divisible by 4 kilobytes. - * - * @return ESP_OK, if the range was erased successfully; - * ESP_ERR_INVALID_ARG, if iterator or dst are NULL; - * ESP_ERR_INVALID_SIZE, if erase would go out of bounds of the partition; - * or one of error codes from lower-level flash driver. - */ -esp_err_t esp_partition_erase_range(esp_partition_iterator_t iterator, - uint32_t start_addr, uint32_t size); - -/** - * @brief Configure MMU to map partition into data memory - * - * @param iterator Iterator obtained using esp_partition_find. Must be non-NULL. - * - * @param offset Offset from the beginning of partition where mapping should start. - * Must be aligned to 64k. - * - * @param size Size of the area to be mapped. - * - * @return pointer to mapped memory, if successful - * NULL, if memory can not be mapped for any reason - */ -void* esp_partition_mmap(esp_partition_iterator_t iterator, uint32_t offset, uint32_t size); - - /** * @brief Release partition iterator * @@ -256,6 +141,100 @@ void* esp_partition_mmap(esp_partition_iterator_t iterator, uint32_t offset, uin */ void esp_partition_iterator_release(esp_partition_iterator_t iterator); +/** + * @brief Read data from the partition + * + * @param partition Pointer to partition structure obtained using + * esp_partition_find_first or esp_partition_get. + * Must be non-NULL. + * @param dst Pointer to the buffer where data should be stored. + * Pointer must be non-NULL and buffer must be at least 'size' bytes long. + * @param src_offset Address of the data to be read, relative to the + * beginning of the partition. + * @param size Size of data to be read, in bytes. + * + * @return ESP_OK, if data was read successfully; + * ESP_ERR_INVALID_ARG, if iterator or src are NULL; + * ESP_ERR_INVALID_SIZE, if read would go out of bounds of the partition; + * or one of error codes from lower-level flash driver. + */ +esp_err_t esp_partition_read(const esp_partition_t* partition, + size_t src_offset, uint8_t* dst, size_t size); + +/** + * @brief Write data to the partition + * + * Before writing data to flash, corresponding region of flash needs to be erased. + * This can be done using esp_partition_erase_range function. + * + * @param partition Pointer to partition structure obtained using + * esp_partition_find_first or esp_partition_get. + * Must be non-NULL. + * @param dst_offset Address where the data should be written, relative to the + * beginning of the partition. + * @param src Pointer to the source buffer. Pointer must be non-NULL and + * buffer must be at least 'size' bytes long. + * @param size Size of data to be written, in bytes. + * + * @note Prior to writing to flash memory, make sure it has been erased with + * esp_partition_erase_range call. + * + * @return ESP_OK, if data was written successfully; + * ESP_ERR_INVALID_ARG, if iterator or dst are NULL; + * ESP_ERR_INVALID_SIZE, if write would go out of bounds of the partition; + * or one of error codes from lower-level flash driver. + */ +esp_err_t esp_partition_write(const esp_partition_t* partition, + size_t dst_offset, const uint8_t* src, size_t size); + +/** + * @brief Erase part of the partition + * + * @param partition Pointer to partition structure obtained using + * esp_partition_find_first or esp_partition_get. + * Must be non-NULL. + * @param start_addr Address where erase operation should start. Must be aligned + * to 4 kilobytes. + * @param size Size of the range which should be erased, in bytes. + * Must be divisible by 4 kilobytes. + * + * @return ESP_OK, if the range was erased successfully; + * ESP_ERR_INVALID_ARG, if iterator or dst are NULL; + * ESP_ERR_INVALID_SIZE, if erase would go out of bounds of the partition; + * or one of error codes from lower-level flash driver. + */ +esp_err_t esp_partition_erase_range(const esp_partition_t* partition, + uint32_t start_addr, uint32_t size); + +/** + * @brief Configure MMU to map partition into data memory + * + * Unlike spi_flash_mmap function, which requires a 64kB aligned base address, + * this function doesn't impose such a requirement. + * If offset results in a flash address which is not aligned to 64kB boundary, + * address will be rounded to the lower 64kB boundary, so that mapped region + * includes requested range. + * Pointer returned via out_ptr argument will be adjusted to point to the + * requested offset (not necessarily to the beginning of mmap-ed region). + * + * To release mapped memory, pass handle returned via out_handle argument to + * spi_flash_munmap function. + * + * @param partition Pointer to partition structure obtained using + * esp_partition_find_first or esp_partition_get. + * Must be non-NULL. + * @param offset Offset from the beginning of partition where mapping should start. + * @param size Size of the area to be mapped. + * @param memory Memory space where the region should be mapped + * @param out_ptr Output, pointer to the mapped memory region + * @param out_handle Output, handle which should be used for spi_flash_munmap call + * + * @return ESP_OK, if successful + */ +esp_err_t esp_partition_mmap(const esp_partition_t* partition, uint32_t offset, uint32_t size, + spi_flash_mmap_memory_t memory, + const void** out_ptr, spi_flash_mmap_handle_t* out_handle); + #ifdef __cplusplus } diff --git a/components/spi_flash/include/esp_spi_flash.h b/components/spi_flash/include/esp_spi_flash.h index ab66a42041..2aa92d9a5d 100644 --- a/components/spi_flash/include/esp_spi_flash.h +++ b/components/spi_flash/include/esp_spi_flash.h @@ -16,6 +16,7 @@ #define ESP_SPI_FLASH_H #include +#include #include "esp_err.h" #include "sdkconfig.h" diff --git a/components/spi_flash/partition.c b/components/spi_flash/partition.c index 381a1624b5..d138f09b5f 100644 --- a/components/spi_flash/partition.c +++ b/components/spi_flash/partition.c @@ -135,38 +135,6 @@ const esp_partition_t* esp_partition_find_first(esp_partition_type_t type, const return res; } -void esp_partition_iterator_release(esp_partition_iterator_t iterator) -{ - // iterator == NULL is okay - free(iterator); -} - -const esp_partition_t* esp_partition_get(esp_partition_iterator_t iterator) -{ - assert(iterator != NULL); - return iterator->info; -} - -esp_partition_type_t esp_partition_type(esp_partition_iterator_t iterator) -{ - return esp_partition_get(iterator)->type; -} - -uint32_t esp_partition_size(esp_partition_iterator_t iterator) -{ - return esp_partition_get(iterator)->size; -} - -uint32_t esp_partition_address(esp_partition_iterator_t iterator) -{ - return esp_partition_get(iterator)->address; -} - -const char* esp_partition_label(esp_partition_iterator_t iterator) -{ - return esp_partition_get(iterator)->label; -} - static esp_partition_iterator_opaque_t* iterator_create(esp_partition_type_t type, const char* label) { esp_partition_iterator_opaque_t* it = @@ -219,3 +187,92 @@ static esp_err_t load_partitions() spi_flash_munmap(handle); return ESP_OK; } + +void esp_partition_iterator_release(esp_partition_iterator_t iterator) +{ + // iterator == NULL is okay + free(iterator); +} + +const esp_partition_t* esp_partition_get(esp_partition_iterator_t iterator) +{ + assert(iterator != NULL); + return iterator->info; +} + +esp_err_t esp_partition_read(const esp_partition_t* partition, + size_t src_offset, uint8_t* dst, size_t size) +{ + assert(partition != NULL); + if (src_offset > partition->size) { + return ESP_ERR_INVALID_ARG; + } + if (src_offset + size > partition->size) { + return ESP_ERR_INVALID_SIZE; + } + return spi_flash_read(partition->address + src_offset, dst, size); +} + +esp_err_t esp_partition_write(const esp_partition_t* partition, + size_t dst_offset, const uint8_t* src, size_t size) +{ + assert(partition != NULL); + if (dst_offset > partition->size) { + return ESP_ERR_INVALID_ARG; + } + if (dst_offset + size > partition->size) { + return ESP_ERR_INVALID_SIZE; + } + return spi_flash_write(partition->address + dst_offset, src, size); +} + +esp_err_t esp_partition_erase_range(const esp_partition_t* partition, + size_t start_addr, size_t size) +{ + assert(partition != NULL); + if (start_addr > partition->size) { + return ESP_ERR_INVALID_ARG; + } + if (start_addr + size > partition->size) { + return ESP_ERR_INVALID_SIZE; + } + if (size % SPI_FLASH_SEC_SIZE != 0) { + return ESP_ERR_INVALID_SIZE; + } + if (start_addr % SPI_FLASH_SEC_SIZE != 0) { + return ESP_ERR_INVALID_ARG; + } + return spi_flash_erase_range(partition->address + start_addr, size); + +} + +/* + * Note: current implementation ignores the possibility of multiple regions in the same partition being + * mapped. Reference counting and address space re-use is delegated to spi_flash_mmap. + * + * If this becomes a performance issue (i.e. if we need to map multiple regions within the partition), + * we can add esp_partition_mmapv which will accept an array of offsets and sizes, and return array of + * mmaped pointers, and a single handle for all these regions. + */ +esp_err_t esp_partition_mmap(const esp_partition_t* partition, uint32_t offset, uint32_t size, + spi_flash_mmap_memory_t memory, + const void** out_ptr, spi_flash_mmap_handle_t* out_handle) +{ + assert(partition != NULL); + if (offset > partition->size) { + return ESP_ERR_INVALID_ARG; + } + if (offset + size > partition->size) { + return ESP_ERR_INVALID_SIZE; + } + size_t phys_addr = partition->address + offset; + // offset within 64kB block + size_t region_offset = phys_addr & 0xffff; + size_t mmap_addr = phys_addr & 0xffff0000; + esp_err_t rc = spi_flash_mmap(mmap_addr, size, memory, out_ptr, out_handle); + // adjust returned pointer to point to the correct offset + if (rc == ESP_OK) { + *out_ptr = (void*) (((ptrdiff_t) *out_ptr) + region_offset); + } + return rc; +} From e229ec0340ba2a921223eec51169200cc10c8329 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 21 Oct 2016 19:33:42 +0800 Subject: [PATCH 170/343] spi_flash: check physical address in mmap against flash chip size --- components/spi_flash/flash_mmap.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/components/spi_flash/flash_mmap.c b/components/spi_flash/flash_mmap.c index 8636a2605e..2165a784d1 100644 --- a/components/spi_flash/flash_mmap.c +++ b/components/spi_flash/flash_mmap.c @@ -88,6 +88,9 @@ esp_err_t IRAM_ATTR spi_flash_mmap(uint32_t src_addr, size_t size, spi_flash_mma if (src_addr & 0xffff) { return ESP_ERR_INVALID_ARG; } + if (src_addr + size > g_rom_flashchip.chip_size) { + return ESP_ERR_INVALID_ARG; + } spi_flash_disable_interrupts_caches_and_other_cpu(); if (s_mmap_page_refcnt[0] == 0) { spi_flash_mmap_init(); From e03b45eb0a9eb07eb1e78c7869af18a7faa386d5 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 25 Oct 2016 11:43:00 +0800 Subject: [PATCH 171/343] spi_flash: improve documentation --- .../esp32/include/esp_flash_data_types.h | 38 ++--- components/spi_flash/README.rst | 133 +++++++++++++++++- components/spi_flash/include/esp_spi_flash.h | 2 + 3 files changed, 152 insertions(+), 21 deletions(-) diff --git a/components/esp32/include/esp_flash_data_types.h b/components/esp32/include/esp_flash_data_types.h index b16ee59f57..4bf886c842 100644 --- a/components/esp32/include/esp_flash_data_types.h +++ b/components/esp32/include/esp_flash_data_types.h @@ -24,7 +24,7 @@ extern "C" #define ESP_PARTITION_TABLE_ADDR 0x4000 #define ESP_PARTITION_MAGIC 0x50AA -/*spi mode,saved in third byte in flash */ +/* SPI flash mode, used in esp_image_header_t */ typedef enum { ESP_IMAGE_SPI_MODE_QIO, ESP_IMAGE_SPI_MODE_QOUT, @@ -34,7 +34,7 @@ typedef enum { ESP_IMAGE_SPI_MODE_SLOW_READ } esp_image_spi_mode_t; -/* spi speed*/ +/* SPI flash clock frequency */ enum { ESP_IMAGE_SPI_SPEED_40M, ESP_IMAGE_SPI_SPEED_26M, @@ -42,7 +42,7 @@ enum { ESP_IMAGE_SPI_SPEED_80M = 0xF } esp_image_spi_freq_t; -/*supported flash sizes*/ +/* Supported SPI flash sizes */ typedef enum { ESP_IMAGE_FLASH_SIZE_1MB = 0, ESP_IMAGE_FLASH_SIZE_2MB, @@ -52,22 +52,23 @@ typedef enum { ESP_IMAGE_FLASH_SIZE_MAX } esp_image_flash_size_t; +/* Main header of binary image */ typedef struct { - char magic; - char blocks; - char spi_mode; /* flag of flash read mode in unpackage and usage in future */ - char spi_speed: 4; /* low bit */ - char spi_size: 4; - unsigned int entry_addr; + uint8_t magic; + uint8_t blocks; + uint8_t spi_mode; /* flash read mode (esp_image_spi_mode_t as uint8_t) */ + uint8_t spi_speed: 4; /* flash frequency (esp_image_spi_freq_t as uint8_t) */ + uint8_t spi_size: 4; /* flash chip size (esp_image_flash_size_t as uint8_t) */ + uint32_t entry_addr; uint8_t encrypt_flag; /* encrypt flag */ uint8_t secure_boot_flag; /* secure boot flag */ - char extra_header[14]; /* ESP32 additional header, unused by second bootloader */ + uint8_t extra_header[14]; /* ESP32 additional header, unused by second bootloader */ } esp_image_header_t; -/* each header of flash bin block */ +/* Header of binary image segment */ typedef struct { - unsigned int load_addr; - unsigned int data_len; + uint32_t load_addr; + uint32_t data_len; } esp_image_section_header_t; @@ -85,13 +86,16 @@ typedef struct { uint32_t size; } esp_partition_pos_t; +/* Structure which describes the layout of partition table entry. + * See docs/partition_tables.rst for more information about individual fields. + */ typedef struct { uint16_t magic; - uint8_t type; /* partition Type */ - uint8_t subtype; /* part_subtype */ + uint8_t type; + uint8_t subtype; esp_partition_pos_t pos; - uint8_t label[16]; /* label for the partition */ - uint8_t reserved[4]; /* reserved */ + uint8_t label[16]; + uint8_t reserved[4]; } esp_partition_info_t; diff --git a/components/spi_flash/README.rst b/components/spi_flash/README.rst index 22f98cf02d..b479c3b0e9 100644 --- a/components/spi_flash/README.rst +++ b/components/spi_flash/README.rst @@ -1,5 +1,128 @@ -Driver for SPI flash read/write/erase operations -================================================ +SPI flash related APIs +====================== + +Overview +-------- +Spi_flash component contains APIs related to reading, writing, erasing, +memory mapping data in the external SPI flash. It also has higher-level +APIs which work with partition table and partitions. + +Note that all the functionality is limited to the "main" flash chip, +i.e. the flash chip from which program runs. For ``spi_flash_*`` functions, +this is software limitation. Underlying ROM functions which work with SPI flash +do not have provisions for working with flash chips attached to SPI peripherals +other than SPI0. + +SPI flash access APIs +--------------------- + +This is the set of APIs for working with data in flash: + +- ``spi_flash_read`` used to read data from flash to RAM +- ``spi_flash_write`` used to write data from RAM to flash +- ``spi_flash_erase_sector`` used to erase individual sectors of flash +- ``spi_flash_erase_range`` used to erase range of addresses in flash +- ``spi_flash_get_chip_size`` returns flash chip size, in bytes, as configured in menuconfig + +There are some data alignment limitations which need to be considered when using +spi_flash_read/spi_flash_write functions: + +- buffer in RAM must be 4-byte aligned +- size must be 4-byte aligned +- address in flash must be 4-byte aligned + +These alignment limitations are purely software, and should be removed in future +versions. + +It is assumed that correct SPI flash chip size is set at compile time using +menuconfig. While run-time detection of SPI flash chip size is possible, it is +not implemented yet. Applications which need this (e.g. to provide one firmware +binary for different flash sizes) can do flash chip size detection and set +the correct flash chip size in ``chip_size`` member of ``g_rom_flashchip`` +structure. This size is used by ``spi_flash_*`` functions for bounds checking. + +SPI flash APIs disable instruction and data caches while reading/writing/erasing. +See implementation notes below on details how this happens. For application +this means that at some periods of time, code can not be run from flash, +and constant data can not be fetched from flash by the CPU. This is not an +issue for normal code which runs in a task, because SPI flash APIs prevent +other tasks from running while caches are disabled. This is an issue for +interrupt handlers, which can still be called while flash operation is in +progress. If the interrupt handler is not placed into IRAM, there is a +possibility that interrupt will happen at the time when caches are disabled, +which will cause an illegal instruction exception. + +To prevent this, make sure that all ISR code, and all functions called from ISR +code are placed into IRAM, or are located in ROM. Most useful C library +functions are located in ROM, so they can be called from ISR. + +To place a function into IRAM, use ``IRAM_ATTR`` attribute, e.g.:: + + #include "esp_attr.h" + + void IRAM_ATTR gpio_isr_handler(void* arg) + { + // ... + } + +When flash encryption is enabled, ``spi_flash_read`` will read data as it is +stored in flash (without decryption), and ``spi_flash_write`` will write data +in plain text. In other words, ``spi_flash_read/write`` APIs don't have +provisions to deal with encrypted data. + + +Partition table APIs +-------------------- + +ESP-IDF uses partition table to maintain information about various regions of +SPI flash memory (bootloader, various application binaries, data, filesystems). +More information about partition tables can be found in docs/partition_tables.rst. + +This component provides APIs to enumerate partitions found in the partition table +and perform operations on them. These functions are declared in ``esp_partition.h``: + +- ``esp_partition_find`` used to search partition table for entries with specific type, returns an opaque iterator +- ``esp_partition_get`` returns a structure describing the partition, for the given iterator +- ``esp_partition_next`` advances iterator to the next partition found +- ``esp_partition_iterator_release`` releases iterator returned by ``esp_partition_find`` +- ``esp_partition_find_first`` is a convenience function which returns structure describing the first partition found by esp_partition_find +- ``esp_partition_read``, ``esp_partition_write``, ``esp_partition_erase_range`` are equivalent to ``spi_flash_read``, ``spi_flash_write``, ``spi_flash_erase_range``, but operate within partition boundaries + +Most application code should use ``esp_partition_*`` APIs instead of lower level +``spi_flash_*`` APIs. Partition APIs do bounds checking and calculate correct +offsets in flash based on data stored in partition table. + +Memory mapping APIs +------------------- + +ESP32 features memory hardware which allows regions of flash memory to be mapped +into instruction and data address spaces. This mapping works only for read operations, +it is not possible to modify contents of flash memory by writing to mapped memory +region. Mapping happens in 64KB pages. Memory mapping hardware can map up to +4 megabytes of flash into data address space, and up to 16 megabytes of flash into +instruction address space. See the technical reference manual for more details +about memory mapping hardware. + +Note that some number of 64KB pages is used to map the application +itself into memory, so the actual number of available 64KB pages may be less. + +Reading data from flash using a memory mapped region is the only way to decrypt +contents of flash when flash encryption is enabled. Decryption is performed at +hardware level. + +Memory mapping APIs are declared in ``esp_spi_flash.h`` and ``esp_partition.h``: + +- ``spi_flash_mmap`` maps a region of physical flash addresses into instruction space or data space of the CPU +- ``spi_flash_munmap`` unmaps previously mapped region +- ``esp_partition_mmap`` maps part of a partition into the instruction space or data space of the CPU + +Differences between ``spi_flash_mmap`` and ``esp_partition_mmap`` are as follows: + +- ``spi_flash_mmap`` must be given a 64KB aligned physical address +- ``esp_partition_mmap`` may be given an arbitrary offset within the partition, it will adjust returned pointer to mapped memory as necessary + +Note that because memory mapping happens in 64KB blocks, it may be possible to +read data outside of the partition provided to ``esp_partition_mmap``. Implementation notes -------------------- @@ -19,8 +142,10 @@ signals that cache is disabled by setting s_flash_op_can_start flag. Then the task on CPU A disables cache as well, and proceeds to execute flash operation. -While flash operation is running, interrupts can still run on CPU B. -We assume that all interrupt code is placed into RAM. +While flash operation is running, interrupts can still run on CPUs A and B. +We assume that all interrupt code is placed into RAM. Once interrupt allocation +API is added, we should add a flag to request interrupt to be disabled for +the duration of flash operations. Once flash operation is complete, function on CPU A sets another flag, s_flash_op_complete, to let the task on CPU B know that it can re-enable diff --git a/components/spi_flash/include/esp_spi_flash.h b/components/spi_flash/include/esp_spi_flash.h index 2aa92d9a5d..16b50a7189 100644 --- a/components/spi_flash/include/esp_spi_flash.h +++ b/components/spi_flash/include/esp_spi_flash.h @@ -35,6 +35,8 @@ extern "C" { * * This function must be called exactly once, before any other * spi_flash_* functions are called. + * Currently this function is called from startup code. There is + * no need to call it from application code. * */ void spi_flash_init(); From 9f0f05d5201aeed9390f94b50f5cf65403040729 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Thu, 27 Oct 2016 00:46:33 +0800 Subject: [PATCH 172/343] spi_flash: change pointer type to void* --- components/nvs_flash/src/nvs_page.cpp | 20 +++++++++---------- .../nvs_flash/test/spi_flash_emulation.cpp | 4 ++-- .../test/test_spi_flash_emulation.cpp | 14 ++++++------- components/spi_flash/flash_ops.c | 4 ++-- components/spi_flash/include/esp_partition.h | 4 ++-- components/spi_flash/include/esp_spi_flash.h | 4 ++-- 6 files changed, 25 insertions(+), 25 deletions(-) diff --git a/components/nvs_flash/src/nvs_page.cpp b/components/nvs_flash/src/nvs_page.cpp index 9ba478e215..a5e058758a 100644 --- a/components/nvs_flash/src/nvs_page.cpp +++ b/components/nvs_flash/src/nvs_page.cpp @@ -37,7 +37,7 @@ esp_err_t Page::load(uint32_t sectorNumber) mErasedEntryCount = 0; Header header; - auto rc = spi_flash_read(mBaseAddress, reinterpret_cast(&header), sizeof(header)); + auto rc = spi_flash_read(mBaseAddress, &header, sizeof(header)); if (rc != ESP_OK) { mState = PageState::INVALID; return rc; @@ -48,7 +48,7 @@ esp_err_t Page::load(uint32_t sectorNumber) // reading the whole page takes ~40 times less than erasing it uint32_t line[8]; for (uint32_t i = 0; i < SPI_FLASH_SEC_SIZE; i += sizeof(line)) { - rc = spi_flash_read(mBaseAddress + i, reinterpret_cast(line), sizeof(line)); + rc = spi_flash_read(mBaseAddress + i, line, sizeof(line)); if (rc != ESP_OK) { mState = PageState::INVALID; return rc; @@ -86,7 +86,7 @@ esp_err_t Page::load(uint32_t sectorNumber) esp_err_t Page::writeEntry(const Item& item) { - auto rc = spi_flash_write(getEntryAddress(mNextFreeEntry), reinterpret_cast(&item), sizeof(item)); + auto rc = spi_flash_write(getEntryAddress(mNextFreeEntry), &item, sizeof(item)); if (rc != ESP_OK) { mState = PageState::INVALID; return rc; @@ -396,7 +396,7 @@ esp_err_t Page::mLoadEntryTable() if (mState == PageState::ACTIVE || mState == PageState::FULL || mState == PageState::FREEING) { - auto rc = spi_flash_read(mBaseAddress + ENTRY_TABLE_OFFSET, reinterpret_cast(mEntryTable.data()), + auto rc = spi_flash_read(mBaseAddress + ENTRY_TABLE_OFFSET, mEntryTable.data(), mEntryTable.byteSize()); if (rc != ESP_OK) { mState = PageState::INVALID; @@ -435,7 +435,7 @@ esp_err_t Page::mLoadEntryTable() while (mNextFreeEntry < ENTRY_COUNT) { uint32_t entryAddress = getEntryAddress(mNextFreeEntry); uint32_t header; - auto rc = spi_flash_read(entryAddress, reinterpret_cast(&header), sizeof(header)); + auto rc = spi_flash_read(entryAddress, &header, sizeof(header)); if (rc != ESP_OK) { mState = PageState::INVALID; return rc; @@ -559,7 +559,7 @@ esp_err_t Page::initialize() header.mSeqNumber = mSeqNumber; header.mCrc32 = header.calculateCrc32(); - auto rc = spi_flash_write(mBaseAddress, reinterpret_cast(&header), sizeof(header)); + auto rc = spi_flash_write(mBaseAddress, &header, sizeof(header)); if (rc != ESP_OK) { mState = PageState::INVALID; return rc; @@ -578,7 +578,7 @@ esp_err_t Page::alterEntryState(size_t index, EntryState state) size_t wordToWrite = mEntryTable.getWordIndex(index); uint32_t word = mEntryTable.data()[wordToWrite]; auto rc = spi_flash_write(mBaseAddress + ENTRY_TABLE_OFFSET + static_cast(wordToWrite) * 4, - reinterpret_cast(&word), sizeof(word)); + &word, sizeof(word)); if (rc != ESP_OK) { mState = PageState::INVALID; return rc; @@ -602,7 +602,7 @@ esp_err_t Page::alterEntryRangeState(size_t begin, size_t end, EntryState state) if (nextWordIndex != wordIndex) { uint32_t word = mEntryTable.data()[wordIndex]; auto rc = spi_flash_write(mBaseAddress + ENTRY_TABLE_OFFSET + static_cast(wordIndex) * 4, - reinterpret_cast(&word), 4); + &word, 4); if (rc != ESP_OK) { return rc; } @@ -615,7 +615,7 @@ esp_err_t Page::alterEntryRangeState(size_t begin, size_t end, EntryState state) esp_err_t Page::alterPageState(PageState state) { uint32_t state_val = static_cast(state); - auto rc = spi_flash_write(mBaseAddress, reinterpret_cast(&state_val), sizeof(state)); + auto rc = spi_flash_write(mBaseAddress, &state_val, sizeof(state)); if (rc != ESP_OK) { mState = PageState::INVALID; return rc; @@ -626,7 +626,7 @@ esp_err_t Page::alterPageState(PageState state) esp_err_t Page::readEntry(size_t index, Item& dst) const { - auto rc = spi_flash_read(getEntryAddress(index), reinterpret_cast(&dst), sizeof(dst)); + auto rc = spi_flash_read(getEntryAddress(index), &dst, sizeof(dst)); if (rc != ESP_OK) { return rc; } diff --git a/components/nvs_flash/test/spi_flash_emulation.cpp b/components/nvs_flash/test/spi_flash_emulation.cpp index bd14822688..914efc1452 100644 --- a/components/nvs_flash/test/spi_flash_emulation.cpp +++ b/components/nvs_flash/test/spi_flash_emulation.cpp @@ -35,7 +35,7 @@ esp_err_t spi_flash_erase_sector(size_t sec) return ESP_OK; } -esp_err_t spi_flash_write(size_t des_addr, const uint8_t *src_addr, size_t size) +esp_err_t spi_flash_write(size_t des_addr, const void *src_addr, size_t size) { if (!s_emulator) { return ESP_ERR_FLASH_OP_TIMEOUT; @@ -48,7 +48,7 @@ esp_err_t spi_flash_write(size_t des_addr, const uint8_t *src_addr, size_t size) return ESP_OK; } -esp_err_t spi_flash_read(size_t src_addr, uint8_t *des_addr, size_t size) +esp_err_t spi_flash_read(size_t src_addr, void *des_addr, size_t size) { if (!s_emulator) { return ESP_ERR_FLASH_OP_TIMEOUT; diff --git a/components/nvs_flash/test/test_spi_flash_emulation.cpp b/components/nvs_flash/test/test_spi_flash_emulation.cpp index 329e721ce7..0c77aa9669 100644 --- a/components/nvs_flash/test/test_spi_flash_emulation.cpp +++ b/components/nvs_flash/test/test_spi_flash_emulation.cpp @@ -42,9 +42,9 @@ TEST_CASE("invalid writes are checked", "[spi_flash_emu]") SpiFlashEmulator emu(1); uint32_t val = 0; - CHECK(spi_flash_write(0, reinterpret_cast(&val), 4) == ESP_OK); + CHECK(spi_flash_write(0, &val, 4) == ESP_OK); val = 1; - CHECK(spi_flash_write(0, reinterpret_cast(&val), 4) == ESP_ERR_FLASH_OP_FAIL); + CHECK(spi_flash_write(0, &val, 4) == ESP_ERR_FLASH_OP_FAIL); } @@ -53,11 +53,11 @@ TEST_CASE("out of bounds writes fail", "[spi_flash_emu]") SpiFlashEmulator emu(4); uint32_t vals[8]; std::fill_n(vals, 8, 0); - CHECK(spi_flash_write(0, reinterpret_cast(vals), sizeof(vals)) == ESP_OK); + CHECK(spi_flash_write(0, vals, sizeof(vals)) == ESP_OK); - CHECK(spi_flash_write(4*4096 - sizeof(vals), reinterpret_cast(vals), sizeof(vals)) == ESP_OK); + CHECK(spi_flash_write(4*4096 - sizeof(vals), vals, sizeof(vals)) == ESP_OK); - CHECK(spi_flash_write(4*4096 - sizeof(vals) + 4, reinterpret_cast(vals), sizeof(vals)) == ESP_ERR_FLASH_OP_FAIL); + CHECK(spi_flash_write(4*4096 - sizeof(vals) + 4, vals, sizeof(vals)) == ESP_ERR_FLASH_OP_FAIL); } @@ -65,9 +65,9 @@ TEST_CASE("after erase the sector is set to 0xff", "[spi_flash_emu]") { SpiFlashEmulator emu(4); uint32_t val1 = 0xab00cd12; - CHECK(spi_flash_write(0, reinterpret_cast(&val1), sizeof(val1)) == ESP_OK); + CHECK(spi_flash_write(0, &val1, sizeof(val1)) == ESP_OK); uint32_t val2 = 0x5678efab; - CHECK(spi_flash_write(4096 - 4, reinterpret_cast(&val2), sizeof(val2)) == ESP_OK); + CHECK(spi_flash_write(4096 - 4, &val2, sizeof(val2)) == ESP_OK); CHECK(emu.words()[0] == val1); CHECK(range_empty_n(emu.words() + 1, 4096 / 4 - 2)); diff --git a/components/spi_flash/flash_ops.c b/components/spi_flash/flash_ops.c index 512f6d20d2..ae72568aa5 100644 --- a/components/spi_flash/flash_ops.c +++ b/components/spi_flash/flash_ops.c @@ -124,7 +124,7 @@ esp_err_t IRAM_ATTR spi_flash_erase_range(uint32_t start_addr, uint32_t size) return spi_flash_translate_rc(rc); } -esp_err_t IRAM_ATTR spi_flash_write(size_t dest_addr, const uint8_t *src, size_t size) +esp_err_t IRAM_ATTR spi_flash_write(size_t dest_addr, const void *src, size_t size) { // TODO: replace this check with code which deals with unaligned sources if (((ptrdiff_t) src) % 4 != 0) { @@ -157,7 +157,7 @@ esp_err_t IRAM_ATTR spi_flash_write(size_t dest_addr, const uint8_t *src, size_t return spi_flash_translate_rc(rc); } -esp_err_t IRAM_ATTR spi_flash_read(size_t src_addr, uint8_t *dest, size_t size) +esp_err_t IRAM_ATTR spi_flash_read(size_t src_addr, void *dest, size_t size) { // TODO: replace this check with code which deals with unaligned destinations if (((ptrdiff_t) dest) % 4 != 0) { diff --git a/components/spi_flash/include/esp_partition.h b/components/spi_flash/include/esp_partition.h index 89e523f9a7..432575f194 100644 --- a/components/spi_flash/include/esp_partition.h +++ b/components/spi_flash/include/esp_partition.h @@ -159,7 +159,7 @@ void esp_partition_iterator_release(esp_partition_iterator_t iterator); * or one of error codes from lower-level flash driver. */ esp_err_t esp_partition_read(const esp_partition_t* partition, - size_t src_offset, uint8_t* dst, size_t size); + size_t src_offset, void* dst, size_t size); /** * @brief Write data to the partition @@ -185,7 +185,7 @@ esp_err_t esp_partition_read(const esp_partition_t* partition, * or one of error codes from lower-level flash driver. */ esp_err_t esp_partition_write(const esp_partition_t* partition, - size_t dst_offset, const uint8_t* src, size_t size); + size_t dst_offset, const void* src, size_t size); /** * @brief Erase part of the partition diff --git a/components/spi_flash/include/esp_spi_flash.h b/components/spi_flash/include/esp_spi_flash.h index 16b50a7189..df0a8decce 100644 --- a/components/spi_flash/include/esp_spi_flash.h +++ b/components/spi_flash/include/esp_spi_flash.h @@ -83,7 +83,7 @@ esp_err_t spi_flash_erase_range(size_t start_addr, size_t size); * * @return esp_err_t */ -esp_err_t spi_flash_write(size_t des_addr, const uint8_t *src_addr, size_t size); +esp_err_t spi_flash_write(size_t dest, const void *src, size_t size); /** * @brief Read data from Flash. @@ -97,7 +97,7 @@ esp_err_t spi_flash_write(size_t des_addr, const uint8_t *src_addr, size_t size) * * @return esp_err_t */ -esp_err_t spi_flash_read(size_t src_addr, uint8_t *des_addr, size_t size); +esp_err_t spi_flash_read(size_t src, void *dest, size_t size); /** * @brief Enumeration which specifies memory space requested in an mmap call From c581229e1d47da7b531433905896e4820ccdf54e Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Thu, 27 Oct 2016 00:48:10 +0800 Subject: [PATCH 173/343] partition API: separate type and subtype into two enums --- components/spi_flash/include/esp_partition.h | 91 ++++++++++---------- components/spi_flash/partition.c | 41 ++++----- 2 files changed, 62 insertions(+), 70 deletions(-) diff --git a/components/spi_flash/include/esp_partition.h b/components/spi_flash/include/esp_partition.h index 432575f194..e2f289eb73 100644 --- a/components/spi_flash/include/esp_partition.h +++ b/components/spi_flash/include/esp_partition.h @@ -26,51 +26,52 @@ extern "C" { #endif typedef enum { - ESP_PARTITION_APP_MASK = 0x0000, - ESP_PARTITION_APP_FACTORY = ESP_PARTITION_APP_MASK | 0x00, - ESP_PARTITION_APP_OTA_MIN = ESP_PARTITION_APP_MASK | 0x10, - ESP_PARTITION_APP_OTA_0 = ESP_PARTITION_APP_OTA_MIN + 0, - ESP_PARTITION_APP_OTA_1 = ESP_PARTITION_APP_OTA_MIN + 1, - ESP_PARTITION_APP_OTA_2 = ESP_PARTITION_APP_OTA_MIN + 2, - ESP_PARTITION_APP_OTA_3 = ESP_PARTITION_APP_OTA_MIN + 3, - ESP_PARTITION_APP_OTA_4 = ESP_PARTITION_APP_OTA_MIN + 4, - ESP_PARTITION_APP_OTA_5 = ESP_PARTITION_APP_OTA_MIN + 5, - ESP_PARTITION_APP_OTA_6 = ESP_PARTITION_APP_OTA_MIN + 6, - ESP_PARTITION_APP_OTA_7 = ESP_PARTITION_APP_OTA_MIN + 7, - ESP_PARTITION_APP_OTA_8 = ESP_PARTITION_APP_OTA_MIN + 8, - ESP_PARTITION_APP_OTA_9 = ESP_PARTITION_APP_OTA_MIN + 9, - ESP_PARTITION_APP_OTA_10 = ESP_PARTITION_APP_OTA_MIN + 10, - ESP_PARTITION_APP_OTA_11 = ESP_PARTITION_APP_OTA_MIN + 11, - ESP_PARTITION_APP_OTA_12 = ESP_PARTITION_APP_OTA_MIN + 12, - ESP_PARTITION_APP_OTA_13 = ESP_PARTITION_APP_OTA_MIN + 13, - ESP_PARTITION_APP_OTA_14 = ESP_PARTITION_APP_OTA_MIN + 14, - ESP_PARTITION_APP_OTA_15 = ESP_PARTITION_APP_OTA_MIN + 15, - ESP_PARTITION_APP_OTA_MAX = ESP_PARTITION_APP_MASK | 0x1f, - ESP_PARTITION_APP_TEST = ESP_PARTITION_APP_MASK | 0x20, - ESP_PARTITION_APP_ANY = ESP_PARTITION_APP_MASK | 0xff, - - ESP_PARTITION_DATA_MASK = 0x0100, - ESP_PARTITION_DATA_OTA = ESP_PARTITION_DATA_MASK | 0x00, - ESP_PARTITION_DATA_RF = ESP_PARTITION_DATA_MASK | 0x01, - ESP_PARTITION_DATA_WIFI = ESP_PARTITION_DATA_MASK | 0x02, - ESP_PARTITION_DATA_ANY = ESP_PARTITION_DATA_MASK | 0xff, - - ESP_PARTITION_FILESYSTEM_MASK = 0x0200, - ESP_PARTITION_FILESYSTEM_ESPHTTPD = 0x0200, - ESP_PARTITION_FILESYSTEM_FAT = 0x0201, - ESP_PARTITION_FILESYSTEM_SPIFFS = 0x0202, - ESP_PARTITION_FILESYSTEM_ANY = 0x20ff, - - ESP_PARTITION_END = 0xffff + ESP_PARTITION_TYPE_APP = 0x00, + ESP_PARTITION_TYPE_DATA = 0x01, + ESP_PARTITION_TYPE_FILESYSTEM = 0x02, } esp_partition_type_t; -#define ESP_PARTITION_APP_OTA(i) ((esp_partition_type_t)(ESP_PARTITION_APP_OTA_MIN + ((i) & 0xf))) +typedef enum { + ESP_PARTITION_SUBTYPE_APP_FACTORY = 0x00, + ESP_PARTITION_SUBTYPE_APP_OTA_MIN = 0x10, + ESP_PARTITION_SUBTYPE_APP_OTA_0 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 0, + ESP_PARTITION_SUBTYPE_APP_OTA_1 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 1, + ESP_PARTITION_SUBTYPE_APP_OTA_2 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 2, + ESP_PARTITION_SUBTYPE_APP_OTA_3 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 3, + ESP_PARTITION_SUBTYPE_APP_OTA_4 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 4, + ESP_PARTITION_SUBTYPE_APP_OTA_5 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 5, + ESP_PARTITION_SUBTYPE_APP_OTA_6 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 6, + ESP_PARTITION_SUBTYPE_APP_OTA_7 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 7, + ESP_PARTITION_SUBTYPE_APP_OTA_8 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 8, + ESP_PARTITION_SUBTYPE_APP_OTA_9 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 9, + ESP_PARTITION_SUBTYPE_APP_OTA_10 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 10, + ESP_PARTITION_SUBTYPE_APP_OTA_11 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 11, + ESP_PARTITION_SUBTYPE_APP_OTA_12 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 12, + ESP_PARTITION_SUBTYPE_APP_OTA_13 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 13, + ESP_PARTITION_SUBTYPE_APP_OTA_14 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 14, + ESP_PARTITION_SUBTYPE_APP_OTA_15 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 15, + ESP_PARTITION_SUBTYPE_APP_OTA_MAX = 15, + ESP_PARTITION_SUBTYPE_APP_TEST = 0x20, + + ESP_PARTITION_SUBTYPE_DATA_OTA = 0x00, + ESP_PARTITION_SUBTYPE_DATA_RF = 0x01, + ESP_PARTITION_SUBTYPE_DATA_NVS = 0x02, + + ESP_PARTITION_SUBTYPE_FILESYSTEM_ESPHTTPD = 0x00, + ESP_PARTITION_SUBTYPE_FILESYSTEM_FAT = 0x01, + ESP_PARTITION_SUBTYPE_FILESYSTEM_SPIFFS = 0x02, + + ESP_PARTITION_SUBTYPE_ANY = 0xff, +} esp_partition_subtype_t; + +#define ESP_PARTITION_SUBTYPE_OTA(i) ((esp_partition_subtype_t)(ESP_PARTITION_SUBTYPE_APP_OTA_MIN + ((i) & 0xf))) typedef struct esp_partition_iterator_opaque_* esp_partition_iterator_t; typedef struct { esp_partition_type_t type; + esp_partition_subtype_t subtype; uint32_t address; uint32_t size; char label[17]; @@ -81,9 +82,9 @@ typedef struct { * @brief Find partition based on one or more parameters * * @param type Partition type, one of esp_partition_type_t values - * To find all app partitions or all filesystem partitions, - * use ESP_PARTITION_APP_ANY or ESP_PARTITION_FILESYSTEM_ANY, - * respectively. + * @param subtype Partition subtype, of esp_partition_subtype_t values. + * To find all partitions of given type, use + * ESP_PARTITION_SUBTYPE_ANY. * @param label (optional) Partition label. Set this value if looking * for partition with a specific name. Pass NULL otherwise. * @@ -92,22 +93,22 @@ typedef struct { * Iterator obtained through this function has to be released * using esp_partition_iterator_release when not used any more. */ -esp_partition_iterator_t esp_partition_find(esp_partition_type_t type, const char* label); +esp_partition_iterator_t esp_partition_find(esp_partition_type_t type, esp_partition_subtype_t subtype, const char* label); /** * @brief Find first partition based on one or more parameters * * @param type Partition type, one of esp_partition_type_t values - * To find all app partitions or all filesystem partitions, - * use ESP_PARTITION_APP_ANY or ESP_PARTITION_FILESYSTEM_ANY, - * respectively. + * @param subtype Partition subtype, of esp_partition_subtype_t values. + * To find all partitions of given type, use + * ESP_PARTITION_SUBTYPE_ANY. * @param label (optional) Partition label. Set this value if looking * for partition with a specific name. Pass NULL otherwise. * * @return pointer to esp_partition_t structure, or NULL if no parition is found. * This pointer is valid for the lifetime of the application. */ -const esp_partition_t* esp_partition_find_first(esp_partition_type_t type, const char* label); +const esp_partition_t* esp_partition_find_first(esp_partition_type_t type, esp_partition_subtype_t subtype, const char* label); /** * @brief Get esp_partition_t structure for given partition diff --git a/components/spi_flash/partition.c b/components/spi_flash/partition.c index d138f09b5f..21013d96fa 100644 --- a/components/spi_flash/partition.c +++ b/components/spi_flash/partition.c @@ -39,13 +39,14 @@ typedef struct partition_list_item_ { typedef struct esp_partition_iterator_opaque_ { esp_partition_type_t type; // requested type + esp_partition_subtype_t subtype; // requested subtype const char* label; // requested label (can be NULL) partition_list_item_t* next_item; // next item to iterate to esp_partition_t* info; // pointer to info (it is redundant, but makes code more readable) } esp_partition_iterator_opaque_t; -static esp_partition_iterator_opaque_t* iterator_create(esp_partition_type_t type, const char* label); +static esp_partition_iterator_opaque_t* iterator_create(esp_partition_type_t type, esp_partition_subtype_t subtype, const char* label); static esp_err_t load_partitions(); @@ -54,18 +55,8 @@ static SLIST_HEAD(partition_list_head_, partition_list_item_) s_partition_list = static _lock_t s_partition_list_lock; -static uint32_t get_major_type(esp_partition_type_t type) -{ - return (type >> 8) & 0xff; -} - -static uint32_t get_minor_type(esp_partition_type_t type) -{ - return type & 0xff; -} - esp_partition_iterator_t esp_partition_find(esp_partition_type_t type, - const char* label) + esp_partition_subtype_t subtype, const char* label) { if (SLIST_EMPTY(&s_partition_list)) { // only lock if list is empty (and check again after acquiring lock) @@ -81,7 +72,7 @@ esp_partition_iterator_t esp_partition_find(esp_partition_type_t type, } // create an iterator pointing to the start of the list // (next item will be the first one) - esp_partition_iterator_t it = iterator_create(type, label); + esp_partition_iterator_t it = iterator_create(type, subtype, label); // advance iterator to the next item which matches constraints it = esp_partition_next(it); // if nothing found, it == NULL and iterator has been released @@ -95,17 +86,13 @@ esp_partition_iterator_t esp_partition_next(esp_partition_iterator_t it) if (it->next_item == NULL) { return NULL; } - uint32_t requested_major_type = get_major_type(it->type); - uint32_t requested_minor_type = get_minor_type(it->type); _lock_acquire(&s_partition_list_lock); for (; it->next_item != NULL; it->next_item = SLIST_NEXT(it->next_item, next)) { esp_partition_t* p = &it->next_item->info; - uint32_t it_major_type = get_major_type(p->type); - uint32_t it_minor_type = get_minor_type(p->type); - if (requested_major_type != it_major_type) { + if (it->type != p->type) { continue; } - if (requested_minor_type != 0xff && requested_minor_type != it_minor_type) { + if (it->subtype != 0xff && it->subtype != p->subtype) { continue; } if (it->label != NULL && strcmp(it->label, p->label) != 0) { @@ -124,9 +111,10 @@ esp_partition_iterator_t esp_partition_next(esp_partition_iterator_t it) return it; } -const esp_partition_t* esp_partition_find_first(esp_partition_type_t type, const char* label) +const esp_partition_t* esp_partition_find_first(esp_partition_type_t type, + esp_partition_subtype_t subtype, const char* label) { - esp_partition_iterator_t it = esp_partition_find(type, label); + esp_partition_iterator_t it = esp_partition_find(type, subtype, label); if (it == NULL) { return NULL; } @@ -135,11 +123,13 @@ const esp_partition_t* esp_partition_find_first(esp_partition_type_t type, const return res; } -static esp_partition_iterator_opaque_t* iterator_create(esp_partition_type_t type, const char* label) +static esp_partition_iterator_opaque_t* iterator_create(esp_partition_type_t type, + esp_partition_subtype_t subtype, const char* label) { esp_partition_iterator_opaque_t* it = (esp_partition_iterator_opaque_t*) malloc(sizeof(esp_partition_iterator_opaque_t)); it->type = type; + it->subtype = subtype; it->label = label; it->next_item = SLIST_FIRST(&s_partition_list); it->info = NULL; @@ -172,7 +162,8 @@ static esp_err_t load_partitions() partition_list_item_t* item = (partition_list_item_t*) malloc(sizeof(partition_list_item_t)); item->info.address = it->pos.offset; item->info.size = it->pos.size; - item->info.type = (it->type << 8) | it->subtype; + item->info.type = it->type; + item->info.subtype = it->subtype; item->info.encrypted = false; // it->label may not be zero-terminated strncpy(item->info.label, (const char*) it->label, sizeof(it->label)); @@ -201,7 +192,7 @@ const esp_partition_t* esp_partition_get(esp_partition_iterator_t iterator) } esp_err_t esp_partition_read(const esp_partition_t* partition, - size_t src_offset, uint8_t* dst, size_t size) + size_t src_offset, void* dst, size_t size) { assert(partition != NULL); if (src_offset > partition->size) { @@ -214,7 +205,7 @@ esp_err_t esp_partition_read(const esp_partition_t* partition, } esp_err_t esp_partition_write(const esp_partition_t* partition, - size_t dst_offset, const uint8_t* src, size_t size) + size_t dst_offset, const void* src, size_t size) { assert(partition != NULL); if (dst_offset > partition->size) { From dc2b5d0c96ff018ebd5b988939f44793dbed3f9d Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Thu, 27 Oct 2016 10:16:42 +0800 Subject: [PATCH 174/343] spi_flash: update comment blocks --- components/spi_flash/include/esp_partition.h | 21 +++++++++----------- components/spi_flash/include/esp_spi_flash.h | 8 ++++---- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/components/spi_flash/include/esp_partition.h b/components/spi_flash/include/esp_partition.h index e2f289eb73..ae0185dcd7 100644 --- a/components/spi_flash/include/esp_partition.h +++ b/components/spi_flash/include/esp_partition.h @@ -82,9 +82,9 @@ typedef struct { * @brief Find partition based on one or more parameters * * @param type Partition type, one of esp_partition_type_t values - * @param subtype Partition subtype, of esp_partition_subtype_t values. - * To find all partitions of given type, use - * ESP_PARTITION_SUBTYPE_ANY. + * @param subtype Partition subtype, one of esp_partition_subtype_t values. + * To find all partitions of given type, use + * ESP_PARTITION_SUBTYPE_ANY. * @param label (optional) Partition label. Set this value if looking * for partition with a specific name. Pass NULL otherwise. * @@ -99,13 +99,13 @@ esp_partition_iterator_t esp_partition_find(esp_partition_type_t type, esp_parti * @brief Find first partition based on one or more parameters * * @param type Partition type, one of esp_partition_type_t values - * @param subtype Partition subtype, of esp_partition_subtype_t values. - * To find all partitions of given type, use - * ESP_PARTITION_SUBTYPE_ANY. + * @param subtype Partition subtype, one of esp_partition_subtype_t values. + * To find all partitions of given type, use + * ESP_PARTITION_SUBTYPE_ANY. * @param label (optional) Partition label. Set this value if looking * for partition with a specific name. Pass NULL otherwise. * - * @return pointer to esp_partition_t structure, or NULL if no parition is found. + * @return pointer to esp_partition_t structure, or NULL if no partition is found. * This pointer is valid for the lifetime of the application. */ const esp_partition_t* esp_partition_find_first(esp_partition_type_t type, esp_partition_subtype_t subtype, const char* label); @@ -134,9 +134,6 @@ esp_partition_iterator_t esp_partition_next(esp_partition_iterator_t iterator); /** * @brief Release partition iterator * - * Any pointers obtained using esp_partition_label function will be invalid - * after this call. - * * @param iterator Iterator obtained using esp_partition_find. Must be non-NULL. * */ @@ -155,7 +152,7 @@ void esp_partition_iterator_release(esp_partition_iterator_t iterator); * @param size Size of data to be read, in bytes. * * @return ESP_OK, if data was read successfully; - * ESP_ERR_INVALID_ARG, if iterator or src are NULL; + * ESP_ERR_INVALID_ARG, if src_offset exceeds partition size; * ESP_ERR_INVALID_SIZE, if read would go out of bounds of the partition; * or one of error codes from lower-level flash driver. */ @@ -181,7 +178,7 @@ esp_err_t esp_partition_read(const esp_partition_t* partition, * esp_partition_erase_range call. * * @return ESP_OK, if data was written successfully; - * ESP_ERR_INVALID_ARG, if iterator or dst are NULL; + * ESP_ERR_INVALID_ARG, if dst_offset exceeds partition size; * ESP_ERR_INVALID_SIZE, if write would go out of bounds of the partition; * or one of error codes from lower-level flash driver. */ diff --git a/components/spi_flash/include/esp_spi_flash.h b/components/spi_flash/include/esp_spi_flash.h index df0a8decce..c65eaa5836 100644 --- a/components/spi_flash/include/esp_spi_flash.h +++ b/components/spi_flash/include/esp_spi_flash.h @@ -77,8 +77,8 @@ esp_err_t spi_flash_erase_range(size_t start_addr, size_t size); * @note Both des_addr and src_addr have to be 4-byte aligned. * This is a temporary limitation which will be removed. * - * @param des_addr destination address in Flash - * @param src_addr source address of the data + * @param dest destination address in Flash + * @param src pointer to the source buffer * @param size length of data, in bytes * * @return esp_err_t @@ -91,8 +91,8 @@ esp_err_t spi_flash_write(size_t dest, const void *src, size_t size); * @note Both des_addr and src_addr have to be 4-byte aligned. * This is a temporary limitation which will be removed. * - * @param src_addr source address of the data in Flash. - * @param des_addr destination address + * @param src source address of the data in Flash. + * @param dest pointer to the destination buffer * @param size length of data * * @return esp_err_t From 305b63209ecb3e7c3c6c0bf20f60d41135e7da8f Mon Sep 17 00:00:00 2001 From: Liu Zhi Fu Date: Fri, 28 Oct 2016 12:03:51 +0800 Subject: [PATCH 175/343] lwip: support max 16 sockets Since the customers need more sockets in their application, support max 16 sockets, in other words, the total socket number of UDP/TCP/RAW sockets should not exceed 16. --- components/lwip/include/lwip/port/lwipopts.h | 32 +++++++++++++++++--- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/components/lwip/include/lwip/port/lwipopts.h b/components/lwip/include/lwip/port/lwipopts.h index 75f349280a..e72279067b 100755 --- a/components/lwip/include/lwip/port/lwipopts.h +++ b/components/lwip/include/lwip/port/lwipopts.h @@ -99,13 +99,37 @@ extern unsigned long os_random(void); * MEMP_NUM_TCP_PCB: the number of simulatenously active TCP connections. * (requires the LWIP_TCP option) */ -#define MEMP_NUM_TCP_PCB 5 /** * MEMP_NUM_NETCONN: the number of struct netconns. * (only needed if you use the sequential API, like api_lib.c) */ -#define MEMP_NUM_NETCONN 10 +#define MEMP_NUM_NETCONN CONFIG_LWIP_MAX_SOCKETS + +/** + * MEMP_NUM_RAW_PCB: Number of raw connection PCBs + * (requires the LWIP_RAW option) + */ +#define MEMP_NUM_RAW_PCB 16 + +/** + * MEMP_NUM_TCP_PCB: the number of simulatenously active TCP connections. + * (requires the LWIP_TCP option) + */ +#define MEMP_NUM_TCP_PCB 16 + +/** + * MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP connections. + * (requires the LWIP_TCP option) + */ +#define MEMP_NUM_TCP_PCB_LISTEN 16 + +/** + * MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One + * per active UDP "connection". + * (requires the LWIP_UDP option) + */ +#define MEMP_NUM_UDP_PCB 16 /* -------------------------------- @@ -542,9 +566,9 @@ extern unsigned char misc_prof_get_tcp_snd_buf(void); * DHCP_DEBUG: Enable debugging in dhcp.c. */ #define DHCP_DEBUG LWIP_DBG_OFF -#define LWIP_DEBUG 0 +#define LWIP_DEBUG LWIP_DBG_OFF #define TCP_DEBUG LWIP_DBG_OFF -#define ESP_THREAD_SAFE_DEBUG LWIP_DBG_OFF +#define ESP_THREAD_SAFE_DEBUG LWIP_DBG_OFF #define CHECKSUM_CHECK_UDP 0 #define CHECKSUM_CHECK_IP 0 From 4d8ad3c87738eed231c2dec97b713c135b292524 Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Fri, 28 Oct 2016 12:05:42 +0800 Subject: [PATCH 176/343] Fix int wdt iram, fix some fallout of moving panic stuff to esp32 --- components/esp32/Kconfig | 2 +- components/esp32/int_wdt.c | 5 +++-- components/freertos/FreeRTOS-openocd.c | 2 +- components/freertos/Kconfig | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig index 9e141529be..3b50dbd2c3 100644 --- a/components/esp32/Kconfig +++ b/components/esp32/Kconfig @@ -157,7 +157,7 @@ config ULP_COPROC_RESERVE_MEM choice ESP32_PANIC prompt "Panic handler behaviour" - default FREERTOS_PANIC_PRINT_REBOOT + default ESP32_PANIC_PRINT_REBOOT help If FreeRTOS detects unexpected behaviour or an unhandled exception, the panic handler is invoked. Configure the panic handlers action here. diff --git a/components/esp32/int_wdt.c b/components/esp32/int_wdt.c index 93a4d9fe62..11de8f20d2 100644 --- a/components/esp32/int_wdt.c +++ b/components/esp32/int_wdt.c @@ -24,6 +24,7 @@ #include #include "esp_err.h" #include "esp_intr.h" +#include "esp_attr.h" #include "soc/timer_group_struct.h" #include "soc/timer_group_reg.h" @@ -66,7 +67,7 @@ void esp_int_wdt_init() { //Not static; the ISR assembly checks this. bool int_wdt_app_cpu_ticked=false; -void vApplicationTickHook(void) { +void IRAM_ATTR vApplicationTickHook(void) { if (xPortGetCoreID()!=0) { int_wdt_app_cpu_ticked=true; } else { @@ -82,7 +83,7 @@ void vApplicationTickHook(void) { } } #else -void vApplicationTickHook(void) { +void IRAM_ATTR vApplicationTickHook(void) { if (xPortGetCoreID()!=0) return; TIMERG1.wdt_wprotect=TIMG_WDT_WKEY_VALUE; TIMERG1.wdt_config2=CONFIG_INT_WDT_TIMEOUT_MS*2; //Set timeout before interrupt diff --git a/components/freertos/FreeRTOS-openocd.c b/components/freertos/FreeRTOS-openocd.c index 6177f02057..d74564495e 100644 --- a/components/freertos/FreeRTOS-openocd.c +++ b/components/freertos/FreeRTOS-openocd.c @@ -18,6 +18,6 @@ #define USED #endif -#ifdef CONFIG_FREERTOS_DEBUG_OCDAWARE +#ifdef CONFIG_ESP32_DEBUG_OCDAWARE const int USED uxTopUsedPriority = configMAX_PRIORITIES - 1; #endif \ No newline at end of file diff --git a/components/freertos/Kconfig b/components/freertos/Kconfig index 413c710d22..25d5581e80 100644 --- a/components/freertos/Kconfig +++ b/components/freertos/Kconfig @@ -121,7 +121,7 @@ endchoice config FREERTOS_BREAK_ON_SCHEDULER_START_JTAG bool "Stop program on scheduler start when JTAG/OCD is detected" - depends on FREERTOS_DEBUG_OCDAWARE + depends on ESP32_DEBUG_OCDAWARE default y help If JTAG/OCD is connected, stop execution when the scheduler is started and the first From 38ff616e4a46650869fff52441c327dfa129932c Mon Sep 17 00:00:00 2001 From: Liu Zhi Fu Date: Fri, 28 Oct 2016 12:29:26 +0800 Subject: [PATCH 177/343] lwip: add prompt when configure max sockets number in menuconfig --- components/lwip/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/lwip/Kconfig b/components/lwip/Kconfig index 715d7dd467..a957c1fdb5 100644 --- a/components/lwip/Kconfig +++ b/components/lwip/Kconfig @@ -1,7 +1,7 @@ menu "LWIP" config LWIP_MAX_SOCKETS - int "Max number of open sockets" + int "Max number of open sockets, the valid value is from 1 to 16" range 1 16 default 4 help From 9e7bc900c51dd31545222dca993e18c2964cb060 Mon Sep 17 00:00:00 2001 From: Liu Zhi Fu Date: Fri, 28 Oct 2016 13:35:06 +0800 Subject: [PATCH 178/343] lwip: rework comments according to review --- components/lwip/Kconfig | 5 +++-- components/lwip/include/lwip/port/lwipopts.h | 4 ---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/components/lwip/Kconfig b/components/lwip/Kconfig index a957c1fdb5..15c94c66ba 100644 --- a/components/lwip/Kconfig +++ b/components/lwip/Kconfig @@ -1,13 +1,14 @@ menu "LWIP" config LWIP_MAX_SOCKETS - int "Max number of open sockets, the valid value is from 1 to 16" + int "Max number of open sockets" range 1 16 default 4 help Sockets take up a certain amount of memory, and allowing fewer sockets to be open at the same time conserves memory. Specify - the maximum amount of sockets here. + the maximum amount of sockets here. The valid value is from 1 + to 16. config LWIP_THREAD_LOCAL_STORAGE_INDEX int "Index for thread-local-storage pointer for lwip" diff --git a/components/lwip/include/lwip/port/lwipopts.h b/components/lwip/include/lwip/port/lwipopts.h index e72279067b..35c2800ed3 100755 --- a/components/lwip/include/lwip/port/lwipopts.h +++ b/components/lwip/include/lwip/port/lwipopts.h @@ -95,10 +95,6 @@ extern unsigned long os_random(void); ---------- Internal Memory Pool Sizes ---------- ------------------------------------------------ */ -/** - * MEMP_NUM_TCP_PCB: the number of simulatenously active TCP connections. - * (requires the LWIP_TCP option) - */ /** * MEMP_NUM_NETCONN: the number of struct netconns. From a038a2b5335f2b330eb32748f1950add28b85947 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 28 Oct 2016 13:41:07 +0800 Subject: [PATCH 179/343] freertos: fix calling first task hook --- components/freertos/tasks.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/components/freertos/tasks.c b/components/freertos/tasks.c index 64cc3a65df..bd32f834ff 100644 --- a/components/freertos/tasks.c +++ b/components/freertos/tasks.c @@ -1018,6 +1018,11 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB, TaskFunction_t pxTaskCode if( uxCurrentNumberOfTasks == ( UBaseType_t ) 1 ) { +#if portFIRST_TASK_HOOK + if ( xPortGetCoreID() == 0 ) { + vPortFirstTaskHook(pxTaskCode); + } +#endif /* configFIRST_TASK_HOOK */ /* This is the first task to be created so do the preliminary initialisation required. We will not recover if this call fails, but we will report the failure. */ @@ -1044,12 +1049,6 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB, TaskFunction_t pxTaskCode /* Schedule if nothing is scheduled yet, or overwrite a task of lower prio. */ if ( pxCurrentTCB[i] == NULL || pxCurrentTCB[i]->uxPriority <= pxNewTCB->uxPriority ) { -#if portFIRST_TASK_HOOK - if ( i == 0) { - vPortFirstTaskHook(pxTaskCode); - } -#endif /* configFIRST_TASK_HOOK */ - pxCurrentTCB[i] = pxNewTCB; break; } From 309bd12855b15b55a3226733c9a25cd09033cb65 Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Fri, 28 Oct 2016 14:32:11 +0800 Subject: [PATCH 180/343] Re-add panic.o to IRAM/DRAM. --- components/esp32/ld/esp32.common.ld | 3 ++- components/esp32/panic.c | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/components/esp32/ld/esp32.common.ld b/components/esp32/ld/esp32.common.ld index 2226e98825..7b14b6da1f 100644 --- a/components/esp32/ld/esp32.common.ld +++ b/components/esp32/ld/esp32.common.ld @@ -47,6 +47,7 @@ SECTIONS _iram_text_start = ABSOLUTE(.); *(.iram1 .iram1.*) *libfreertos.a:(.literal .text .literal.* .text.*) + *libesp32.a:panic.o(.literal .text .literal.* .text.*) *libphy.a:(.literal .text .literal.* .text.*) *librtc.a:(.literal .text .literal.* .text.*) *libpp.a:(.literal .text .literal.* .text.*) @@ -92,7 +93,7 @@ SECTIONS KEEP(*(.gnu.linkonce.s2.*)) KEEP(*(.jcr)) *(.dram1 .dram1.*) - *libfreertos.a:panic.o(.rodata .rodata.*) + *libesp32.a:panic.o(.rodata .rodata.*) _data_end = ABSOLUTE(.); . = ALIGN(4); _heap_start = ABSOLUTE(.); diff --git a/components/esp32/panic.c b/components/esp32/panic.c index c806dace2a..c5d8aa669e 100644 --- a/components/esp32/panic.c +++ b/components/esp32/panic.c @@ -30,7 +30,7 @@ #include "esp_gdbstub.h" #include "esp_panic.h" - +#include "esp_attr.h" /* Panic handlers; these get called when an unhandled exception occurs or the assembly-level @@ -38,6 +38,10 @@ task switching / interrupt code runs into an unrecoverable error. The default ta overflow handler also is in here. */ +/* +Note: The linker script will put everything in this file in IRAM/DRAM, so it also works with flash cache disabled. +*/ + #if !CONFIG_ESP32_PANIC_SILENT_REBOOT //printf may be broken, so we fix our own printing fns... inline static void panicPutchar(char c) { From 78392bf76b3d47ba290a0d97f443e695916416f5 Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Fri, 28 Oct 2016 14:32:13 +0800 Subject: [PATCH 181/343] components/openssl: change the description 1. change the description of Makefile.projbuild 2. remove the license header in the API document 3. add private inlcuding header code in the components file --- components/openssl/Makefile.projbuild | 3 +-- components/openssl/OpenSSL-APIs.rst | 7 +------ components/openssl/component.mk | 3 ++- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/components/openssl/Makefile.projbuild b/components/openssl/Makefile.projbuild index b1d5641231..f8501f3187 100644 --- a/components/openssl/Makefile.projbuild +++ b/components/openssl/Makefile.projbuild @@ -1,3 +1,2 @@ -# Anyone compiling mbedTLS code needs the name of the -# alternative config file +# Anyone compiling openssl code needs the mbedtls library and header file diff --git a/components/openssl/OpenSSL-APIs.rst b/components/openssl/OpenSSL-APIs.rst index e7877b128c..2b606dbcf2 100644 --- a/components/openssl/OpenSSL-APIs.rst +++ b/components/openssl/OpenSSL-APIs.rst @@ -1,14 +1,9 @@ OpenSSL-APIs ------------ -All original source code in this repository is Copyright (C) 2015-2016 -Espressif Systems. This source code is licensed under the Apache -License 2.0 as described in the file LICENSE. - OpenSSL APIs not mentioned in this article are not open to public for the time, also do not have the corresponding function. -If user calls it directly, it will always return an error or may show cannot link -at compile time. +If user calls it directly, it will always return an error or may show cannot link at compile time. Chapter Introduction ==================== diff --git a/components/openssl/component.mk b/components/openssl/component.mk index 97de6975c9..2dfcc6b38d 100644 --- a/components/openssl/component.mk +++ b/components/openssl/component.mk @@ -2,7 +2,8 @@ # Component Makefile # -COMPONENT_ADD_INCLUDEDIRS := include include/internal include/platform include/oepnssl +COMPONENT_ADD_INCLUDEDIRS := include +COMPONENT_PRIV_INCLUDEDIRS := include/internal include/platform include/openssl COMPONENT_SRCDIRS := library platform From 3cd86d6bce502b41248b6fb8bccaeb1a4ee47c7d Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Fri, 28 Oct 2016 14:37:36 +0800 Subject: [PATCH 182/343] Also call tick hook on app cpu when scheduler is suspended --- components/freertos/tasks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/freertos/tasks.c b/components/freertos/tasks.c index bd32f834ff..e4b887273d 100644 --- a/components/freertos/tasks.c +++ b/components/freertos/tasks.c @@ -2308,7 +2308,7 @@ BaseType_t xSwitchRequired = pdFALSE; { /* Guard against the tick hook being called when the pended tick count is being unwound (when the scheduler is being unlocked). */ - if( uxPendedTicks == ( UBaseType_t ) 0U ) + if( ( uxSchedulerSuspended[ xPortGetCoreID() ] != ( UBaseType_t ) pdFALSE ) || uxPendedTicks == ( UBaseType_t ) 0U ) { vApplicationTickHook(); } From 0e90983c9f0aaf1caf003b92d2f0471c92a389f0 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 28 Oct 2016 16:16:12 +0800 Subject: [PATCH 183/343] vfs: fix adding CR --- components/vfs/vfs_uart.c | 1 + 1 file changed, 1 insertion(+) diff --git a/components/vfs/vfs_uart.c b/components/vfs/vfs_uart.c index bfccad8963..d9d755f9be 100644 --- a/components/vfs/vfs_uart.c +++ b/components/vfs/vfs_uart.c @@ -18,6 +18,7 @@ #include "sys/errno.h" #include "sys/lock.h" #include "soc/uart_struct.h" +#include "sdkconfig.h" static uart_dev_t* s_uarts[3] = {&UART0, &UART1, &UART2}; static _lock_t s_uart_locks[3]; // per-UART locks, lazily initialized From 5ffd6155f28eb906212238868fe242e0aeaa6da4 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 28 Oct 2016 16:17:41 +0800 Subject: [PATCH 184/343] set default interrupt watchdog timeout to 300ms 10ms is too low for openocd/gdb to work, so it's not a very useful default value. --- components/esp32/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig index 3b50dbd2c3..b5a8d2f2dd 100644 --- a/components/esp32/Kconfig +++ b/components/esp32/Kconfig @@ -206,7 +206,7 @@ config INT_WDT config INT_WDT_TIMEOUT_MS int "Interrupt watchdog timeout (ms)" depends on INT_WDT - default 10 + default 300 range 10 10000 help The timeout of the watchdog, in miliseconds. Make this higher than the FreeRTOS tick rate. From 4f2719236fc49a7f15ef636da6369c4dd52ae7c7 Mon Sep 17 00:00:00 2001 From: Liu Zhi Fu Date: Fri, 28 Oct 2016 16:53:49 +0800 Subject: [PATCH 185/343] esp32/tcpip_adapter: softap supports max 10 stations The max number of stations softap supports is modified from 8 to 10 --- components/esp32/include/esp_wifi_types.h | 4 ++-- components/esp32/lib | 2 +- components/tcpip_adapter/include/tcpip_adapter.h | 4 ++-- components/tcpip_adapter/tcpip_adapter_lwip.c | 1 + 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/components/esp32/include/esp_wifi_types.h b/components/esp32/include/esp_wifi_types.h index 0ea719a65b..3304a8a3ea 100644 --- a/components/esp32/include/esp_wifi_types.h +++ b/components/esp32/include/esp_wifi_types.h @@ -154,10 +154,10 @@ typedef struct { uint8_t mac[6]; /**< mac address of sta that associated with ESP32 soft-AP */ }wifi_sta_info_t; -#define ESP_WIFI_MAX_CONN_NUM (8+2) /**< max number of sta the eSP32 soft-AP can connect */ +#define ESP_WIFI_MAX_CONN_NUM (10) /**< max number of sta the ESP32 soft-AP can connect */ typedef struct { wifi_sta_info_t sta[ESP_WIFI_MAX_CONN_NUM]; /**< station list */ - uint8_t num; /**< number of station that associated with ESP32 soft-AP */ + int num; /**< number of station that associated with ESP32 soft-AP */ }wifi_sta_list_t; typedef enum { diff --git a/components/esp32/lib b/components/esp32/lib index 12b3435fc0..9d18fd1a8f 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit 12b3435fc0cd04efc249d52d71efb1cdecda50f8 +Subproject commit 9d18fd1a8f7610130e69f8be74ec68f6399221b1 diff --git a/components/tcpip_adapter/include/tcpip_adapter.h b/components/tcpip_adapter/include/tcpip_adapter.h index 218325320e..e847016884 100644 --- a/components/tcpip_adapter/include/tcpip_adapter.h +++ b/components/tcpip_adapter/include/tcpip_adapter.h @@ -73,8 +73,8 @@ typedef struct { }tcpip_adapter_sta_info_t; typedef struct { - tcpip_adapter_sta_info_t sta[ESP_WIFI_MAX_CONN_NUM+2]; - uint8_t num; + tcpip_adapter_sta_info_t sta[ESP_WIFI_MAX_CONN_NUM]; + int num; }tcpip_adapter_sta_list_t; #endif diff --git a/components/tcpip_adapter/tcpip_adapter_lwip.c b/components/tcpip_adapter/tcpip_adapter_lwip.c index 677368008d..9b6e9d94fa 100644 --- a/components/tcpip_adapter/tcpip_adapter_lwip.c +++ b/components/tcpip_adapter/tcpip_adapter_lwip.c @@ -598,6 +598,7 @@ esp_err_t tcpip_adapter_get_sta_list(wifi_sta_list_t *wifi_sta_list, tcpip_adapt return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; memset(tcpip_sta_list, 0, sizeof(tcpip_adapter_sta_list_t)); + tcpip_sta_list->num = wifi_sta_list->num; for (i=0; inum; i++){ memcpy(tcpip_sta_list->sta[i].mac, wifi_sta_list->sta[i].mac, 6); dhcp_search_ip_on_mac(tcpip_sta_list->sta[i].mac, &tcpip_sta_list->sta[i].ip); From 90b787636a49fd2f36c6c30e2a57c06303afb20e Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Mon, 31 Oct 2016 11:00:27 +0800 Subject: [PATCH 186/343] Remove redundant volatile keyword --- components/esp32/crosscore_int.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp32/crosscore_int.c b/components/esp32/crosscore_int.c index 78287d405e..60a45da402 100644 --- a/components/esp32/crosscore_int.c +++ b/components/esp32/crosscore_int.c @@ -44,7 +44,7 @@ ToDo: There is a small chance the CPU already has yielded when this ISR is servi the ISR will cause it to switch _away_ from it. portYIELD_FROM_ISR will probably just schedule the task again, but have to check that. */ static void esp_crosscore_isr(void *arg) { - volatile uint32_t myReasonVal; + uint32_t myReasonVal; #if 0 //A pointer to the correct reason array item is passed to this ISR. volatile uint32_t *myReason=arg; From f30887bc700aff63f88362dca8e0fb3557ada7f9 Mon Sep 17 00:00:00 2001 From: Liu Zhi Fu Date: Mon, 31 Oct 2016 11:17:33 +0800 Subject: [PATCH 187/343] modify comments according to review --- components/esp32/include/esp_wifi_types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp32/include/esp_wifi_types.h b/components/esp32/include/esp_wifi_types.h index 3304a8a3ea..fb19aa8fc3 100644 --- a/components/esp32/include/esp_wifi_types.h +++ b/components/esp32/include/esp_wifi_types.h @@ -154,7 +154,7 @@ typedef struct { uint8_t mac[6]; /**< mac address of sta that associated with ESP32 soft-AP */ }wifi_sta_info_t; -#define ESP_WIFI_MAX_CONN_NUM (10) /**< max number of sta the ESP32 soft-AP can connect */ +#define ESP_WIFI_MAX_CONN_NUM (10) /**< max number of stations which can connect to ESP32 soft-AP */ typedef struct { wifi_sta_info_t sta[ESP_WIFI_MAX_CONN_NUM]; /**< station list */ int num; /**< number of station that associated with ESP32 soft-AP */ From 41a91d7cb9540f718811c62629aaca140d87ac08 Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Mon, 31 Oct 2016 14:06:29 +0800 Subject: [PATCH 188/343] feature/openssl: change the description for docbook --- components/openssl/Makefile.projbuild | 2 -- components/openssl/OpenSSL-APIs.rst | 5 ++++- 2 files changed, 4 insertions(+), 3 deletions(-) delete mode 100644 components/openssl/Makefile.projbuild diff --git a/components/openssl/Makefile.projbuild b/components/openssl/Makefile.projbuild deleted file mode 100644 index f8501f3187..0000000000 --- a/components/openssl/Makefile.projbuild +++ /dev/null @@ -1,2 +0,0 @@ -# Anyone compiling openssl code needs the mbedtls library and header file - diff --git a/components/openssl/OpenSSL-APIs.rst b/components/openssl/OpenSSL-APIs.rst index 2b606dbcf2..39fa0ebb9b 100644 --- a/components/openssl/OpenSSL-APIs.rst +++ b/components/openssl/OpenSSL-APIs.rst @@ -1,9 +1,12 @@ OpenSSL-APIs ------------ +This directory does not contain OpenSSL itself, but the code here can be used as a wrapper for applications using the OpenSSL API. +It uses mbedSSL to do the actual work, so anyone compiling openssl code needs the mbedtls library and header file. + OpenSSL APIs not mentioned in this article are not open to public for the time, also do not have the corresponding function. -If user calls it directly, it will always return an error or may show cannot link at compile time. +If user calls it directly, it will always return an error or may show cannot link at compiling time. Chapter Introduction ==================== From 9555ce291e094b8e9e25c1b6e4a36ee8d340ca14 Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Mon, 31 Oct 2016 14:13:00 +0800 Subject: [PATCH 189/343] feature/openssl: correct wrong description --- components/openssl/OpenSSL-APIs.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/openssl/OpenSSL-APIs.rst b/components/openssl/OpenSSL-APIs.rst index 39fa0ebb9b..93e438dcf9 100644 --- a/components/openssl/OpenSSL-APIs.rst +++ b/components/openssl/OpenSSL-APIs.rst @@ -2,7 +2,7 @@ OpenSSL-APIs ------------ This directory does not contain OpenSSL itself, but the code here can be used as a wrapper for applications using the OpenSSL API. -It uses mbedSSL to do the actual work, so anyone compiling openssl code needs the mbedtls library and header file. +It uses mbedTLS to do the actual work, so anyone compiling openssl code needs the mbedtls library and header file. OpenSSL APIs not mentioned in this article are not open to public for the time, also do not have the corresponding function. From a5552b1e21b725bc17882e2b44452d194b56f97a Mon Sep 17 00:00:00 2001 From: Liu Zhi Fu Date: Mon, 31 Oct 2016 17:50:09 +0800 Subject: [PATCH 190/343] lwip: fix tcp rx abnormal issue(tw8242) In tcp_alloc(), initialize per_soc_tcp_wnd before initializing recv_wnd because recv_wnd depends on per_soc_tcp_wnd. --- components/lwip/core/tcp.c | 11 ++++++----- components/lwip/core/tcp_out.c | 4 ++-- components/lwip/include/lwip/port/lwipopts.h | 20 -------------------- 3 files changed, 8 insertions(+), 27 deletions(-) diff --git a/components/lwip/core/tcp.c b/components/lwip/core/tcp.c index 87ddf5f1a7..627df6d293 100755 --- a/components/lwip/core/tcp.c +++ b/components/lwip/core/tcp.c @@ -1532,6 +1532,12 @@ tcp_alloc(u8_t prio) } if (pcb != NULL) { memset(pcb, 0, sizeof(struct tcp_pcb)); + +#if ESP_PER_SOC_TCP_WND + pcb->per_soc_tcp_wnd = TCP_WND_DEFAULT; + pcb->per_soc_tcp_snd_buf = TCP_SND_BUF_DEFAULT; +#endif + pcb->prio = prio; pcb->snd_buf = TCP_SND_BUF_DEFAULT; pcb->snd_queuelen = 0; @@ -1575,11 +1581,6 @@ tcp_alloc(u8_t prio) #endif /* LWIP_TCP_KEEPALIVE */ pcb->keep_cnt_sent = 0; - -#if ESP_PER_SOC_TCP_WND - pcb->per_soc_tcp_wnd = TCP_WND_DEFAULT; - pcb->per_soc_tcp_snd_buf = TCP_SND_BUF_DEFAULT; -#endif } return pcb; diff --git a/components/lwip/core/tcp_out.c b/components/lwip/core/tcp_out.c index f189623f5c..35a8aa145d 100755 --- a/components/lwip/core/tcp_out.c +++ b/components/lwip/core/tcp_out.c @@ -1320,9 +1320,9 @@ tcp_rst(u32_t seqno, u32_t ackno, #endif #else #if LWIP_WND_SCALE - tcphdr->wnd = PP_HTONS(((TCP_WND >> TCP_RCV_SCALE) & 0xFFFF)); + tcphdr->wnd = PP_HTONS(((TCP_WND_DEFAULT >> TCP_RCV_SCALE) & 0xFFFF)); #else - tcphdr->wnd = PP_HTONS(TCP_WND); + tcphdr->wnd = PP_HTONS(TCP_WND_DEFAULT); #endif #endif tcphdr->chksum = 0; diff --git a/components/lwip/include/lwip/port/lwipopts.h b/components/lwip/include/lwip/port/lwipopts.h index 35c2800ed3..b8811813d1 100755 --- a/components/lwip/include/lwip/port/lwipopts.h +++ b/components/lwip/include/lwip/port/lwipopts.h @@ -240,26 +240,6 @@ extern unsigned long os_random(void); ---------- TCP options ---------- --------------------------------- */ -/** - * TCP_WND: The size of a TCP window. This must be at least - * (2 * TCP_MSS) for things to work well - */ - -#define ESP_PER_SOC_TCP_WND 1 -#if ESP_PER_SOC_TCP_WND -#define TCP_WND_DEFAULT (4*TCP_MSS) -#define TCP_SND_BUF_DEFAULT (2*TCP_MSS) - -#define TCP_WND(pcb) (pcb->per_soc_tcp_wnd) -#define TCP_SND_BUF(pcb) (pcb->per_soc_tcp_snd_buf) -#else -#ifdef PERF -extern unsigned char misc_prof_get_tcpw(void); -extern unsigned char misc_prof_get_tcp_snd_buf(void); -#define TCP_WND(pcb) (misc_prof_get_tcpw()*TCP_MSS) -#define TCP_SND_BUF(pcb) (misc_prof_get_tcp_snd_buf()*TCP_MSS) -#endif -#endif /** From 2119b9846962c2b2d961fa13c26662a2be711e19 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Mon, 31 Oct 2016 19:08:56 +0800 Subject: [PATCH 191/343] spi_flash: remove unnecessary src pointer alignment check in spi_flash_write ROM SPIWrite routine can work with unaligned sources, so this check is unnecessary. Furthermore, it breaks nvs_set_str and nvs_get_blob when data pointer is unaligned. Also fix stray backslash in COUNTER_STOP macro --- components/spi_flash/flash_ops.c | 6 +----- components/spi_flash/include/esp_spi_flash.h | 4 ++-- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/components/spi_flash/flash_ops.c b/components/spi_flash/flash_ops.c index ae72568aa5..134e1fe65b 100644 --- a/components/spi_flash/flash_ops.c +++ b/components/spi_flash/flash_ops.c @@ -39,7 +39,7 @@ static spi_flash_counters_t s_flash_stats; #define COUNTER_STOP(counter) \ do{ \ s_flash_stats.counter.count++; \ - s_flash_stats.counter.time += (xthal_get_ccount() - ts_begin) / (XT_CLOCK_FREQ / 1000000); \\ + s_flash_stats.counter.time += (xthal_get_ccount() - ts_begin) / (XT_CLOCK_FREQ / 1000000); \ } while(0) #define COUNTER_ADD_BYTES(counter, size) \ @@ -126,10 +126,6 @@ esp_err_t IRAM_ATTR spi_flash_erase_range(uint32_t start_addr, uint32_t size) esp_err_t IRAM_ATTR spi_flash_write(size_t dest_addr, const void *src, size_t size) { - // TODO: replace this check with code which deals with unaligned sources - if (((ptrdiff_t) src) % 4 != 0) { - return ESP_ERR_INVALID_ARG; - } // Destination alignment is also checked in ROM code, but we can give // better error code here // TODO: add handling of unaligned destinations diff --git a/components/spi_flash/include/esp_spi_flash.h b/components/spi_flash/include/esp_spi_flash.h index c65eaa5836..840bbc4971 100644 --- a/components/spi_flash/include/esp_spi_flash.h +++ b/components/spi_flash/include/esp_spi_flash.h @@ -74,7 +74,7 @@ esp_err_t spi_flash_erase_range(size_t start_addr, size_t size); /** * @brief Write data to Flash. * - * @note Both des_addr and src_addr have to be 4-byte aligned. + * @note Address in flash, dest, has to be 4-byte aligned. * This is a temporary limitation which will be removed. * * @param dest destination address in Flash @@ -88,7 +88,7 @@ esp_err_t spi_flash_write(size_t dest, const void *src, size_t size); /** * @brief Read data from Flash. * - * @note Both des_addr and src_addr have to be 4-byte aligned. + * @note Both src and dest have to be 4-byte aligned. * This is a temporary limitation which will be removed. * * @param src source address of the data in Flash. From 269332f473b6e3b2960f53605dbac840ecedd60d Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Mon, 31 Oct 2016 19:11:40 +0800 Subject: [PATCH 192/343] nvs_flash: use CRC-32 routine compatible with ROM version Host tests used different flavour of CRC-32, which made it impossible to load NVS partition dumps created on the chip --- components/nvs_flash/test/crc.cpp | 64 ++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 19 deletions(-) diff --git a/components/nvs_flash/test/crc.cpp b/components/nvs_flash/test/crc.cpp index 288b58a323..4cbb9be9ec 100644 --- a/components/nvs_flash/test/crc.cpp +++ b/components/nvs_flash/test/crc.cpp @@ -14,25 +14,51 @@ #include #include -extern "C" unsigned long crc32_le(unsigned long crc_in, unsigned char const* data, unsigned int length) -{ - uint32_t i; - bool bit; - uint8_t c; - uint32_t crc = (uint32_t) crc_in; +static const unsigned int crc32_le_table[256] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L, + 0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L, + 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, + 0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L, + 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, + 0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL, + 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, + 0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L, + 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, + 0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L, + 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, + 0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L, + 0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, + + 0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L, + 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, + 0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L, + 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, + 0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 0x4669be79L, + 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, + 0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL, + 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, + 0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L, + 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, + 0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL, + 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL, + 0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL +}; - while (length--) { - c = *data++; - for (i = 0x80; i > 0; i >>= 1) { - bit = crc & 0x80000000; - if (c & i) { - bit = !bit; - } - crc <<= 1; - if (bit) { - crc ^= 0x04c11db7; - } - } + + +extern "C" unsigned int crc32_le(unsigned int crc, unsigned char const * buf,unsigned int len) +{ + unsigned int i; + crc = ~crc; + for(i=0;i>8); } - return crc; + return ~crc; } + From 413f2c00f69ff6ce9777eab366280eb82cb3ac35 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Mon, 31 Oct 2016 19:17:25 +0800 Subject: [PATCH 193/343] nvs_flash: introduce write failures after each word written Previously the test bench would check failure recovery by introducing error after each write operation. This makes checks a bit more extensive (and much longer) by failing after every word written. Surprisingly, this change didn't expose any bugs. --- .../nvs_flash/test/spi_flash_emulation.h | 8 +++---- components/nvs_flash/test/test_nvs.cpp | 22 ++++++++++--------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/components/nvs_flash/test/spi_flash_emulation.h b/components/nvs_flash/test/spi_flash_emulation.h index ba50c4f9e4..4e544a39e2 100644 --- a/components/nvs_flash/test/spi_flash_emulation.h +++ b/components/nvs_flash/test/spi_flash_emulation.h @@ -74,11 +74,11 @@ public: return false; } - if (mFailCountdown != SIZE_MAX && mFailCountdown-- == 0) { - return false; - } - for (size_t i = 0; i < size / 4; ++i) { + if (mFailCountdown != SIZE_MAX && mFailCountdown-- == 0) { + return false; + } + uint32_t sv = src[i]; size_t pos = dstAddr / 4 + i; uint32_t& dv = mData[pos]; diff --git a/components/nvs_flash/test/test_nvs.cpp b/components/nvs_flash/test/test_nvs.cpp index ce552578db..223e5dea9a 100644 --- a/components/nvs_flash/test/test_nvs.cpp +++ b/components/nvs_flash/test/test_nvs.cpp @@ -894,7 +894,7 @@ TEST_CASE("test recovery from sudden poweroff", "[.][long][nvs][recovery][monkey size_t totalOps = 0; int lastPercent = -1; - for (uint32_t errDelay = 4; ; ++errDelay) { + for (uint32_t errDelay = 0; ; ++errDelay) { INFO(errDelay); emu.randomize(seed); emu.clearStats(); @@ -903,23 +903,25 @@ TEST_CASE("test recovery from sudden poweroff", "[.][long][nvs][recovery][monkey if (totalOps != 0) { int percent = errDelay * 100 / totalOps; - if (percent != lastPercent) { + if (percent > lastPercent) { printf("%d/%d (%d%%)\r\n", errDelay, static_cast(totalOps), percent); lastPercent = percent; } } - TEST_ESP_OK(nvs_flash_init_custom(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN)); nvs_handle handle; - TEST_ESP_OK(nvs_open("namespace1", NVS_READWRITE, &handle)); - size_t count = iter_count; - if(test.doRandomThings(handle, gen, count) != ESP_ERR_FLASH_OP_FAIL) { - nvs_close(handle); - break; + + if (nvs_flash_init_custom(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN) == ESP_OK) { + if (nvs_open("namespace1", NVS_READWRITE, &handle) == ESP_OK) { + if(test.doRandomThings(handle, gen, count) != ESP_ERR_FLASH_OP_FAIL) { + nvs_close(handle); + break; + } + nvs_close(handle); + } } - nvs_close(handle); TEST_ESP_OK(nvs_flash_init_custom(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN)); TEST_ESP_OK(nvs_open("namespace1", NVS_READWRITE, &handle)); @@ -929,7 +931,7 @@ TEST_CASE("test recovery from sudden poweroff", "[.][long][nvs][recovery][monkey CHECK(0); } nvs_close(handle); - totalOps = emu.getEraseOps() + emu.getWriteOps(); + totalOps = emu.getEraseOps() + emu.getWriteBytes() / 4; } } From 19f61332a9a9c5c0d585d88d2bef7475594724a2 Mon Sep 17 00:00:00 2001 From: Liu Zhi Fu Date: Mon, 31 Oct 2016 19:38:47 +0800 Subject: [PATCH 194/343] make build pass when disable per soc tcp window --- components/lwip/core/init.c | 22 ++++++++++---------- components/lwip/include/lwip/port/lwipopts.h | 5 +++-- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/components/lwip/core/init.c b/components/lwip/core/init.c index 774e9a2beb..8b2e92669a 100755 --- a/components/lwip/core/init.c +++ b/components/lwip/core/init.c @@ -135,7 +135,7 @@ //#endif #else /* LWIP_WND_SCALE */ -#if (ESP_PER_SOC_TCP_WND == 0) +#if ! ESP_PER_SOC_TCP_WND #if (LWIP_TCP && (TCP_WND > 0xffff)) #error "If you want to use TCP, TCP_WND must fit in an u16_t, so, you have to reduce it in your lwipopts.h (or enable window scaling)" #endif @@ -143,11 +143,11 @@ #endif /* LWIP_WND_SCALE */ -#if (ESP_PER_SOC_TCP_WND == 0) -#if (LWIP_TCP && (TCP_SND_QUEUELEN > 0xffff)) +#if ! ESP_PER_SOC_TCP_WND +#if (LWIP_TCP && (TCP_SND_QUEUELEN(0) > 0xffff)) #error "If you want to use TCP, TCP_SND_QUEUELEN must fit in an u16_t, so, you have to reduce it in your lwipopts.h" #endif -#if (LWIP_TCP && (TCP_SND_QUEUELEN < 2)) +#if (LWIP_TCP && (TCP_SND_QUEUELEN(0) < 2)) #error "TCP_SND_QUEUELEN must be at least 2 for no-copy TCP writes to work" #endif @@ -286,25 +286,25 @@ /* TCP sanity checks */ #if !LWIP_DISABLE_TCP_SANITY_CHECKS +#if ! ESP_PER_SOC_TCP_WND #if LWIP_TCP -#if !MEMP_MEM_MALLOC && (MEMP_NUM_TCP_SEG < TCP_SND_QUEUELEN) +#if !MEMP_MEM_MALLOC && (MEMP_NUM_TCP_SEG < TCP_SND_QUEUELEN(0)) #error "lwip_sanity_check: WARNING: MEMP_NUM_TCP_SEG should be at least as big as TCP_SND_QUEUELEN. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." #endif -#if (ESP_PER_SOC_TCP_WND == 0) -#if TCP_SND_BUF < (2 * TCP_MSS) +#if TCP_SND_BUF(0) < (2 * TCP_MSS) #error "lwip_sanity_check: WARNING: TCP_SND_BUF must be at least as much as (2 * TCP_MSS) for things to work smoothly. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." #endif -#if TCP_SND_QUEUELEN < (2 * (TCP_SND_BUF / TCP_MSS)) - #error "lwip_sanity_check: WARNING: TCP_SND_QUEUELEN must be at least as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." +#if TCP_SND_QUEUELEN(0) < (2 * (TCP_SND_BUF(0) / TCP_MSS)) + #error "lwip_sanity_check: WARNING: TCP_SND_QUEUELEN must be at least as much as (2 * TCP_SND_BUF(0)/TCP_MSS) for things to work. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." #endif -#if TCP_SNDLOWAT >= TCP_SND_BUF +#if TCP_SNDLOWAT >= TCP_SND_BUF(0) #error "lwip_sanity_check: WARNING: TCP_SNDLOWAT must be less than TCP_SND_BUF. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." #endif #if TCP_SNDLOWAT >= (0xFFFF - (4 * TCP_MSS)) #error "lwip_sanity_check: WARNING: TCP_SNDLOWAT must at least be 4*MSS below u16_t overflow!" #endif -#if TCP_SNDQUEUELOWAT >= TCP_SND_QUEUELEN +#if TCP_SNDQUEUELOWAT >= TCP_SND_QUEUELEN(0) #error "lwip_sanity_check: WARNING: TCP_SNDQUEUELOWAT must be less than TCP_SND_QUEUELEN. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." #endif #endif diff --git a/components/lwip/include/lwip/port/lwipopts.h b/components/lwip/include/lwip/port/lwipopts.h index b8811813d1..2e11bdd5ce 100755 --- a/components/lwip/include/lwip/port/lwipopts.h +++ b/components/lwip/include/lwip/port/lwipopts.h @@ -512,7 +512,7 @@ extern unsigned long os_random(void); /* Enable all Espressif-only options */ #define ESP_LWIP 1 -#define ESP_PER_SOC_TCP_WND 1 +#define ESP_PER_SOC_TCP_WND 0 #define ESP_THREAD_SAFE 1 #define ESP_THREAD_SAFE_DEBUG LWIP_DBG_OFF #define ESP_DHCP 1 @@ -524,9 +524,10 @@ extern unsigned long os_random(void); #define ESP_LIGHT_SLEEP 1 -#if ESP_PER_SOC_TCP_WND #define TCP_WND_DEFAULT (4*TCP_MSS) #define TCP_SND_BUF_DEFAULT (2*TCP_MSS) + +#if ESP_PER_SOC_TCP_WND #define TCP_WND(pcb) (pcb->per_soc_tcp_wnd) #define TCP_SND_BUF(pcb) (pcb->per_soc_tcp_snd_buf) #else From 2b722ea468ee69693d5e728101e7b4e36c66f231 Mon Sep 17 00:00:00 2001 From: Liu Zhi Fu Date: Mon, 31 Oct 2016 19:43:18 +0800 Subject: [PATCH 195/343] turn on per socket tcp window by default --- components/lwip/include/lwip/port/lwipopts.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/lwip/include/lwip/port/lwipopts.h b/components/lwip/include/lwip/port/lwipopts.h index 2e11bdd5ce..67a62b8227 100755 --- a/components/lwip/include/lwip/port/lwipopts.h +++ b/components/lwip/include/lwip/port/lwipopts.h @@ -512,7 +512,7 @@ extern unsigned long os_random(void); /* Enable all Espressif-only options */ #define ESP_LWIP 1 -#define ESP_PER_SOC_TCP_WND 0 +#define ESP_PER_SOC_TCP_WND 1 #define ESP_THREAD_SAFE 1 #define ESP_THREAD_SAFE_DEBUG LWIP_DBG_OFF #define ESP_DHCP 1 From d9cdc7de5811a450919518b5ea8d6a8edd0a960f Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Mon, 31 Oct 2016 19:48:28 +0800 Subject: [PATCH 196/343] nvs_flash: don't allow more operation to be done on page in PageState::INVALID Currently a restart is required to recover a page from invalid state. The long-term solution is to detect such a condition and recover automatically (without a restart). This will be implemented in a separate change set. --- components/nvs_flash/src/nvs_page.cpp | 26 +++++--- .../nvs_flash/test/spi_flash_emulation.h | 12 ++++ components/nvs_flash/test/test_nvs.cpp | 62 +++++++++++++++++++ 3 files changed, 93 insertions(+), 7 deletions(-) diff --git a/components/nvs_flash/src/nvs_page.cpp b/components/nvs_flash/src/nvs_page.cpp index fae1f6f1b7..a10b88c976 100644 --- a/components/nvs_flash/src/nvs_page.cpp +++ b/components/nvs_flash/src/nvs_page.cpp @@ -3,7 +3,7 @@ // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software @@ -131,8 +131,12 @@ esp_err_t Page::writeEntryData(const uint8_t* data, size_t size) esp_err_t Page::writeItem(uint8_t nsIndex, ItemType datatype, const char* key, const void* data, size_t dataSize) { Item item; - esp_err_t err; + + if (mState == PageState::INVALID) { + return ESP_ERR_NVS_INVALID_STATE; + } + if (mState == PageState::UNINITIALIZED) { err = initialize(); if (err != ESP_OK) { @@ -166,7 +170,6 @@ esp_err_t Page::writeItem(uint8_t nsIndex, ItemType datatype, const char* key, c } // write first item - size_t span = (totalSize + ENTRY_SIZE - 1) / ENTRY_SIZE; item = Item(nsIndex, datatype, span, key); mHashList.insert(item, mNextFreeEntry); @@ -215,6 +218,11 @@ esp_err_t Page::readItem(uint8_t nsIndex, ItemType datatype, const char* key, vo { size_t index = 0; Item item; + + if (mState == PageState::INVALID) { + return ESP_ERR_NVS_INVALID_STATE; + } + esp_err_t rc = findItem(nsIndex, datatype, key, index, item); if (rc != ESP_OK) { return rc; @@ -478,6 +486,8 @@ esp_err_t Page::mLoadEntryTable() mState = PageState::INVALID; return err; } + + mHashList.insert(item, i); if (item.crc32 != item.calculateCrc32()) { err = eraseEntryAndSpan(i); @@ -488,8 +498,6 @@ esp_err_t Page::mLoadEntryTable() continue; } - mHashList.insert(item, i); - if (item.datatype != ItemType::BLOB && item.datatype != ItemType::SZ) { continue; } @@ -785,8 +793,12 @@ void Page::debugDump() const Item item; readEntry(i, item); if (skip == 0) { - printf("W ns=%2u type=%2u span=%3u key=\"%s\"\n", item.nsIndex, static_cast(item.datatype), item.span, item.key); - skip = item.span - 1; + printf("W ns=%2u type=%2u span=%3u key=\"%s\" len=%d\n", item.nsIndex, static_cast(item.datatype), item.span, item.key, (item.span != 1)?((int)item.varLength.dataSize):-1); + if (item.span > 0 && item.span <= ENTRY_COUNT - i) { + skip = item.span - 1; + } else { + skip = 0; + } } else { printf("D\n"); skip--; diff --git a/components/nvs_flash/test/spi_flash_emulation.h b/components/nvs_flash/test/spi_flash_emulation.h index 4e544a39e2..14e56bab6e 100644 --- a/components/nvs_flash/test/spi_flash_emulation.h +++ b/components/nvs_flash/test/spi_flash_emulation.h @@ -141,6 +141,18 @@ public: { return reinterpret_cast(mData.data()); } + + void load(const char* filename) + { + FILE* f = fopen(filename, "rb"); + fseek(f, 0, SEEK_END); + off_t size = ftell(f); + assert(size % SPI_FLASH_SEC_SIZE == 0); + mData.resize(size); + fseek(f, 0, SEEK_SET); + auto s = fread(mData.data(), SPI_FLASH_SEC_SIZE, size / SPI_FLASH_SEC_SIZE, f); + assert(s == static_cast(size / SPI_FLASH_SEC_SIZE)); + } void clearStats() { diff --git a/components/nvs_flash/test/test_nvs.cpp b/components/nvs_flash/test/test_nvs.cpp index 223e5dea9a..b70801f848 100644 --- a/components/nvs_flash/test/test_nvs.cpp +++ b/components/nvs_flash/test/test_nvs.cpp @@ -953,6 +953,68 @@ TEST_CASE("test for memory leaks in open/set", "[leaks]") } } +TEST_CASE("duplicate items are removed", "[nvs][dupes]") +{ + SpiFlashEmulator emu(3); + { + // create one item + nvs::Page p; + p.load(0); + p.writeItem(1, "opmode", 3); + } + { + // add another one without deleting the first one + nvs::Item item(1, ItemType::U8, 1, "opmode"); + item.data[0] = 2; + item.crc32 = item.calculateCrc32(); + emu.write(3 * 32, reinterpret_cast(&item), sizeof(item)); + uint32_t mask = 0xFFFFFFFA; + emu.write(32, &mask, 4); + } + { + // load page and check that second item persists + nvs::Page p; + p.load(0); + uint8_t val; + p.readItem(1, "opmode", val); + CHECK(val == 2); + CHECK(p.getErasedEntryCount() == 1); + CHECK(p.getUsedEntryCount() == 1); + } +} + +TEST_CASE("recovery after failure to write data", "[nvs]") +{ + SpiFlashEmulator emu(3); + // TODO: remove explicit alignment + const char str[] __attribute__((aligned(4))) = "value 0123456789abcdef012345678value 0123456789abcdef012345678"; + + // make flash write fail exactly in Page::writeEntryData + emu.failAfter(17); + { + Storage storage; + TEST_ESP_OK(storage.init(0, 3)); + + TEST_ESP_ERR(storage.writeItem(1, ItemType::SZ, "key", str, strlen(str)), ESP_ERR_FLASH_OP_FAIL); + + // check that repeated operations cause an error + TEST_ESP_ERR(storage.writeItem(1, ItemType::SZ, "key", str, strlen(str)), ESP_ERR_NVS_INVALID_STATE); + + uint8_t val; + TEST_ESP_ERR(storage.readItem(1, ItemType::U8, "key", &val, sizeof(val)), ESP_ERR_NVS_NOT_FOUND); + } + { + // load page and check that data was erased + Page p; + p.load(0); + CHECK(p.getErasedEntryCount() == 3); + CHECK(p.getUsedEntryCount() == 0); + + // try to write again + TEST_ESP_OK(p.writeItem(1, ItemType::SZ, "key", str, strlen(str))); + } +} + TEST_CASE("dump all performance data", "[nvs]") { std::cout << "====================" << std::endl << "Dumping benchmarks" << std::endl; From abea6c50f15f74c43f467a1179166ad031443b0a Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Mon, 31 Oct 2016 21:10:47 +0800 Subject: [PATCH 197/343] nvs_flash: delete all duplicate entries in a page while loading Due to previous flash write bug it was possible to create multiple duplicate entries in a single page. Recovery logic detected that case and bailed out with an assert. This change adds graceful recovery from this condition. Tests included. --- components/nvs_flash/src/nvs_page.cpp | 40 +++++++++++------- components/nvs_flash/test/test_nvs.cpp | 56 ++++++++++++++++++++++---- 2 files changed, 73 insertions(+), 23 deletions(-) diff --git a/components/nvs_flash/src/nvs_page.cpp b/components/nvs_flash/src/nvs_page.cpp index a10b88c976..23cefd1aad 100644 --- a/components/nvs_flash/src/nvs_page.cpp +++ b/components/nvs_flash/src/nvs_page.cpp @@ -301,6 +301,8 @@ esp_err_t Page::eraseEntryAndSpan(size_t index) } if (item.calculateCrc32() != item.crc32) { rc = alterEntryState(index, EntryState::ERASED); + --mUsedEntryCount; + ++mErasedEntryCount; if (rc != ESP_OK) { return rc; } @@ -473,7 +475,9 @@ esp_err_t Page::mLoadEntryTable() if (end > ENTRY_COUNT) { end = ENTRY_COUNT; } - for (size_t i = 0; i < end; ++i) { + size_t span; + for (size_t i = 0; i < end; i += span) { + span = 1; if (mEntryTable.get(i) == EntryState::ERASED) { lastItemIndex = INVALID_ENTRY; continue; @@ -488,6 +492,9 @@ esp_err_t Page::mLoadEntryTable() } mHashList.insert(item, i); + + // search for potential duplicate item + size_t duplicateIndex = mHashList.find(0, item); if (item.crc32 != item.calculateCrc32()) { err = eraseEntryAndSpan(i); @@ -498,23 +505,26 @@ esp_err_t Page::mLoadEntryTable() continue; } - if (item.datatype != ItemType::BLOB && item.datatype != ItemType::SZ) { - continue; - } - - size_t span = item.span; - bool needErase = false; - for (size_t j = i; j < i + span; ++j) { - if (mEntryTable.get(j) != EntryState::WRITTEN) { - needErase = true; - lastItemIndex = INVALID_ENTRY; - break; + + if (item.datatype == ItemType::BLOB || item.datatype == ItemType::SZ) { + span = item.span; + bool needErase = false; + for (size_t j = i; j < i + span; ++j) { + if (mEntryTable.get(j) != EntryState::WRITTEN) { + needErase = true; + lastItemIndex = INVALID_ENTRY; + break; + } + } + if (needErase) { + eraseEntryAndSpan(i); + continue; } } - if (needErase) { - eraseEntryAndSpan(i); + + if (duplicateIndex < i) { + eraseEntryAndSpan(duplicateIndex); } - i += span - 1; } // check that last item is not duplicate diff --git a/components/nvs_flash/test/test_nvs.cpp b/components/nvs_flash/test/test_nvs.cpp index b70801f848..528c9df686 100644 --- a/components/nvs_flash/test/test_nvs.cpp +++ b/components/nvs_flash/test/test_nvs.cpp @@ -963,22 +963,27 @@ TEST_CASE("duplicate items are removed", "[nvs][dupes]") p.writeItem(1, "opmode", 3); } { - // add another one without deleting the first one + // add another two without deleting the first one nvs::Item item(1, ItemType::U8, 1, "opmode"); item.data[0] = 2; item.crc32 = item.calculateCrc32(); emu.write(3 * 32, reinterpret_cast(&item), sizeof(item)); - uint32_t mask = 0xFFFFFFFA; + emu.write(4 * 32, reinterpret_cast(&item), sizeof(item)); + uint32_t mask = 0xFFFFFFEA; emu.write(32, &mask, 4); } { // load page and check that second item persists - nvs::Page p; - p.load(0); + nvs::Storage s; + s.init(0, 3); uint8_t val; - p.readItem(1, "opmode", val); + ESP_ERROR_CHECK(s.readItem(1, "opmode", val)); CHECK(val == 2); - CHECK(p.getErasedEntryCount() == 1); + } + { + Page p; + p.load(0); + CHECK(p.getErasedEntryCount() == 2); CHECK(p.getUsedEntryCount() == 1); } } @@ -986,8 +991,7 @@ TEST_CASE("duplicate items are removed", "[nvs][dupes]") TEST_CASE("recovery after failure to write data", "[nvs]") { SpiFlashEmulator emu(3); - // TODO: remove explicit alignment - const char str[] __attribute__((aligned(4))) = "value 0123456789abcdef012345678value 0123456789abcdef012345678"; + const char str[] = "value 0123456789abcdef012345678value 0123456789abcdef012345678"; // make flash write fail exactly in Page::writeEntryData emu.failAfter(17); @@ -1015,6 +1019,42 @@ TEST_CASE("recovery after failure to write data", "[nvs]") } } +TEST_CASE("crc error in variable length item is handled", "[nvs]") +{ + SpiFlashEmulator emu(3); + const uint64_t before_val = 0xbef04e; + const uint64_t after_val = 0xaf7e4; + // write some data + { + Page p; + p.load(0); + TEST_ESP_OK(p.writeItem(0, "before", before_val)); + const char* str = "foobar"; + TEST_ESP_OK(p.writeItem(0, ItemType::SZ, "key", str, strlen(str))); + TEST_ESP_OK(p.writeItem(0, "after", after_val)); + } + // corrupt some data + uint32_t w; + CHECK(emu.read(&w, 32 * 3 + 8, sizeof(w))); + w &= 0xf000000f; + CHECK(emu.write(32 * 3 + 8, &w, sizeof(w))); + // load and check + { + Page p; + p.load(0); + CHECK(p.getUsedEntryCount() == 2); + CHECK(p.getErasedEntryCount() == 2); + + uint64_t val; + TEST_ESP_OK(p.readItem(0, "before", val)); + CHECK(val == before_val); + TEST_ESP_ERR(p.findItem(0, ItemType::SZ, "key"), ESP_ERR_NVS_NOT_FOUND); + TEST_ESP_OK(p.readItem(0, "after", val)); + CHECK(val == after_val); + } +} + + TEST_CASE("dump all performance data", "[nvs]") { std::cout << "====================" << std::endl << "Dumping benchmarks" << std::endl; From 92b663d9f214180486f46c5c6926f518b345083b Mon Sep 17 00:00:00 2001 From: Liu Zhi Fu Date: Mon, 31 Oct 2016 21:26:33 +0800 Subject: [PATCH 198/343] lwip: optimize tx flow control 1. Remove tx flow control for TCP 2. Remove tx flow control for UDP temporary 3. Return the error code when call esp_wifi_internal_tx() --- components/lwip/api/sockets.c | 5 +++-- components/lwip/port/netif/wlanif.c | 7 ++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/components/lwip/api/sockets.c b/components/lwip/api/sockets.c index 455d007ea7..df658578af 100755 --- a/components/lwip/api/sockets.c +++ b/components/lwip/api/sockets.c @@ -395,12 +395,15 @@ static void lwip_socket_drop_registered_memberships(int s); */ static inline void esp32_tx_flow_ctrl(void) { +//TODO we need to do flow control for UDP +#if 0 uint8_t _wait_delay = 1; while ((system_get_free_heap_size() < HEAP_HIGHWAT) || esp_wifi_internal_tx_is_stop()){ vTaskDelay(_wait_delay/portTICK_RATE_MS); if (_wait_delay < 64) _wait_delay *= 2; } +#endif } #else @@ -1208,8 +1211,6 @@ lwip_send(int s, const void *data, size_t size, int flags) #endif /* (LWIP_UDP || LWIP_RAW) */ } - esp32_tx_flow_ctrl(); - write_flags = NETCONN_COPY | ((flags & MSG_MORE) ? NETCONN_MORE : 0) | ((flags & MSG_DONTWAIT) ? NETCONN_DONTBLOCK : 0); diff --git a/components/lwip/port/netif/wlanif.c b/components/lwip/port/netif/wlanif.c index 548bb7f970..ffad69cd46 100755 --- a/components/lwip/port/netif/wlanif.c +++ b/components/lwip/port/netif/wlanif.c @@ -142,16 +142,13 @@ low_level_output(struct netif *netif, struct pbuf *p) } } - esp_wifi_internal_tx(wifi_if, q->payload, pbuf_x_len); - return ERR_OK; - + return esp_wifi_internal_tx(wifi_if, q->payload, pbuf_x_len); #else for(q = p; q != NULL; q = q->next) { esp_wifi_internal_tx(wifi_if, q->payload, q->len); } -#endif - return ERR_OK; +#endif } /** From 41514f497aa5965a7b8b238392205d11c6c8805b Mon Sep 17 00:00:00 2001 From: Krzysztof Date: Sun, 23 Oct 2016 22:12:34 +0200 Subject: [PATCH 199/343] Renamed .md to .rst --- CONTRIBUTING.md => CONTRIBUTING.rst | 15 ++++++++++----- README.md => README.rst | 29 ++++++++++++++++++++--------- 2 files changed, 30 insertions(+), 14 deletions(-) rename CONTRIBUTING.md => CONTRIBUTING.rst (91%) rename README.md => README.rst (86%) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.rst similarity index 91% rename from CONTRIBUTING.md rename to CONTRIBUTING.rst index b0af761d53..a6e759eb18 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.rst @@ -1,12 +1,15 @@ -# Contributions Guide +Contributions Guide +=================== We welcome contributions to the esp-idf project! -## How to Contribute +How to Contribute +----------------- Contributions to esp-idf - fixing bugs, adding features, adding documentation - are welcome. We accept contributions via [Github Pull Requests](https://help.github.com/articles/about-pull-requests/). -## Before Contributing +Before Contributing +------------------- Before sending us a Pull Request, please consider this list of points: @@ -24,7 +27,8 @@ Before sending us a Pull Request, please consider this list of points: * If you're unsure about any of these points, please open the Pull Request anyhow and then ask us for feedback. -## Pull Request Process +Pull Request Process +-------------------- After you open the Pull Request, there will probably be some discussion in the comments field of the request itself. @@ -32,6 +36,7 @@ Once the Pull Request is ready to merge, it will first be merged into our intern If this process passes, it will be merged onto the public github repository. -## Legal Part +Legal Part +---------- Before a contribution can be accepted, you will need to sign our [Contributor Agreement](docs/contributor-agreement.rst). You will be prompted for this automatically as part of the Pull Request process. diff --git a/README.md b/README.rst similarity index 86% rename from README.md rename to README.rst index ff645c3392..65d6167673 100644 --- a/README.md +++ b/README.rst @@ -1,6 +1,10 @@ -# Using Espressif IoT Development Framework with the ESP32 +Using Espressif IoT Development Framework with the ESP32 +======================================================== -# Setting Up ESP-IDF +|docs| + +Setting Up ESP-IDF +------------------ In the [docs](docs) directory you will find per-platform setup guides: @@ -8,23 +12,27 @@ In the [docs](docs) directory you will find per-platform setup guides: * [Mac OS Setup Guide](docs/macos-setup.rst) * [Linux Setup Guide](docs/linux-setup.rst) -# Finding A Project +Finding A Project +----------------- As well as the [esp-idf-template](https://github.com/espressif/esp-idf-template) project mentioned in the setup guide, esp-idf comes with some example projects in the [examples](examples) directory. Once you've found the project you want to work with, change to its directory and you can configure and build it: -# Configuring your project +Configuring your project +------------------------ `make menuconfig` -# Compiling your project +Compiling your project +---------------------- `make all` ... will compile app, bootloader and generate a partition table based on the config. -# Flashing your project +Flashing your project +--------------------- When `make all` finishes, it will print a command line to use esptool.py to flash the chip. However you can also do this from make by running: @@ -34,7 +42,8 @@ This will flash the entire project (app, bootloader and partition table) to a ne You don't need to run `make all` before running `make flash`, `make flash` will automatically rebuild anything which needs it. -# Compiling & Flashing Just the App +Compiling & Flashing Just the App +--------------------------------- After the initial flash, you may just want to build and flash just your app, not the bootloader and partition table: @@ -45,7 +54,8 @@ After the initial flash, you may just want to build and flash just your app, not (There's no downside to reflashing the bootloader and partition table each time, if they haven't changed.) -# The Partition Table +The Partition Table +------------------- Once you've compiled your project, the "build" directory will contain a binary file with a name like "my_app.bin". This is an ESP32 image binary that can be loaded by the bootloader. @@ -62,7 +72,8 @@ In both cases the factory app is flashed at offset 0x10000. If you `make partiti For more details about partition tables and how to create custom variations, view the `docs/partition_tables.rst` file. -# Resources +Resources +--------- * The [docs directory of the esp-idf repository](docs) contains esp-idf documentation. From ec99397c3ea057903fba8cf12e1360df0727baae Mon Sep 17 00:00:00 2001 From: Krzysztof Date: Sun, 23 Oct 2016 22:14:24 +0200 Subject: [PATCH 200/343] Initial Sphinx / ReadTheDocs.org configuration --- docs/Doxyfile | 12 ++ docs/Makefile | 177 +++++++++++++++++++++++++++ docs/_static/1.png | Bin 0 -> 11412 bytes docs/conf.py | 270 ++++++++++++++++++++++++++++++++++++++++++ docs/index.rst | 88 ++++++++++++++ docs/requirements.txt | 1 + 6 files changed, 548 insertions(+) create mode 100644 docs/Doxyfile create mode 100644 docs/Makefile create mode 100644 docs/_static/1.png create mode 100644 docs/conf.py create mode 100644 docs/index.rst create mode 100644 docs/requirements.txt diff --git a/docs/Doxyfile b/docs/Doxyfile new file mode 100644 index 0000000000..795bfa5e89 --- /dev/null +++ b/docs/Doxyfile @@ -0,0 +1,12 @@ +PROJECT_NAME = "ESP32 Programming Guide" +XML_OUTPUT = xml +GENERATE_LATEX = NO +GENERATE_MAN = NO +GENERATE_RTF = NO +CASE_SENSE_NAMES = NO +INPUT = ../components/driver/include +RECURSIVE = YES +QUIET = YES +JAVADOC_AUTOBRIEF = YES +GENERATE_HTML = NO +GENERATE_XML = YES \ No newline at end of file diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000000..c04268ff1d --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,177 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = _build + +# User-friendly check for sphinx-build +ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) +$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) +endif + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " xml to make Docutils-native XML files" + @echo " pseudoxml to make pseudoxml-XML files for display purposes" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/ReadtheDocsTemplate.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/ReadtheDocsTemplate.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/ReadtheDocsTemplate" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/ReadtheDocsTemplate" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +latexpdfja: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through platex and dvipdfmx..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." + +xml: + $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml + @echo + @echo "Build finished. The XML files are in $(BUILDDIR)/xml." + +pseudoxml: + $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml + @echo + @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." diff --git a/docs/_static/1.png b/docs/_static/1.png new file mode 100644 index 0000000000000000000000000000000000000000..4920892781f90c3db323f82033866c3f7116c073 GIT binary patch literal 11412 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 i-AuB$6Izt`{{a9CH0GJi2@$^l0000 v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +#html_extra_path = [] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'ReadtheDocsTemplatedoc' + + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { +# The paper size ('letterpaper' or 'a4paper'). +#'papersize': 'letterpaper', + +# The font size ('10pt', '11pt' or '12pt'). +#'pointsize': '10pt', + +# Additional stuff for the LaTeX preamble. +#'preamble': '', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + ('index', 'ReadtheDocsTemplate.tex', u'Read the Docs Template Documentation', + u'Read the Docs', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'readthedocstemplate', u'Read the Docs Template Documentation', + [u'Read the Docs'], 1) +] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ('index', 'ReadtheDocsTemplate', u'Read the Docs Template Documentation', + u'Read the Docs', 'ReadtheDocsTemplate', 'One line description of project.', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +#texinfo_no_detailmenu = False diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000000..f74a3acae1 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,88 @@ +.. Read the Docs Template documentation master file + +Welcome to ESP32 Programming Guide +================================== + + +Example C functions +------------------- + +.. c:function:: esp_err_t esp_wifi_get_ap_list (uint16_t *number, wifi_ap_list_t *ap_list) + +.. c:function:: esp_err_t esp_wifi_set_protocol (wifi_interface_t ifx, uint8_t protocol_bitmap) + + +Example C function integration +------------------------------ + +.. doxygenfunction:: esp_wifi_init +.. doxygenfunction:: esp_wifi_set_config + +.. doxygenfunction:: gpio_isr_register +.. doxygenfunction:: ledc_timer_set + + +Example C enum integration +-------------------------- + +.. doxygenenum:: wifi_auth_mode_t + + +Example C struct integration +---------------------------- + +.. doxygenstruct:: wifi_scan_config_t + :members: + + +Contents: + +.. About - TBA + +.. toctree:: + :caption: Toolchain Setup + :maxdepth: 1 + + windows-setup + linux-setup + macos-setup + eclipse-setup + +.. API Reference - TBA + +.. Technical Reference - TBA + +.. toctree:: + :caption: Debugging + :maxdepth: 1 + + openocd + +.. Resources - TBA + +.. toctree:: + :caption: Contribute + :maxdepth: 1 + + contributing + contributor-agreement + +.. toctree:: + :caption: Copyrights and Licenses + :maxdepth: 1 + + COPYRIGHT + +.. toctree:: + :caption: Flapping Documents + :maxdepth: 1 + + partition-tables + build_system + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`search` diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 0000000000..188f51e62d --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1 @@ +breathe \ No newline at end of file From 99fc7600888ae76252772ac544aed3a8399c1de6 Mon Sep 17 00:00:00 2001 From: Krzysztof Date: Sun, 23 Oct 2016 22:15:13 +0200 Subject: [PATCH 201/343] Link to file a folder up --- docs/contributing.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 docs/contributing.rst diff --git a/docs/contributing.rst b/docs/contributing.rst new file mode 100644 index 0000000000..3bdd7dc21a --- /dev/null +++ b/docs/contributing.rst @@ -0,0 +1 @@ +.. include:: ../CONTRIBUTING.rst \ No newline at end of file From cb70ac831f3430175cbb8f230e48ce2c8b164f28 Mon Sep 17 00:00:00 2001 From: Krzysztof Date: Sun, 23 Oct 2016 22:25:28 +0200 Subject: [PATCH 202/343] Increased buikd coverage of DoxyGen --- docs/Doxyfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Doxyfile b/docs/Doxyfile index 795bfa5e89..23f6f1a2d7 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -4,7 +4,7 @@ GENERATE_LATEX = NO GENERATE_MAN = NO GENERATE_RTF = NO CASE_SENSE_NAMES = NO -INPUT = ../components/driver/include +INPUT = ../components RECURSIVE = YES QUIET = YES JAVADOC_AUTOBRIEF = YES From 6435a71de2b9b9e5a3c731f630cf0dc8a33953ac Mon Sep 17 00:00:00 2001 From: Krzysztof Date: Sun, 23 Oct 2016 22:31:15 +0200 Subject: [PATCH 203/343] Reduced the build coverage by DoxyGen --- docs/Doxyfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Doxyfile b/docs/Doxyfile index 23f6f1a2d7..795bfa5e89 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -4,7 +4,7 @@ GENERATE_LATEX = NO GENERATE_MAN = NO GENERATE_RTF = NO CASE_SENSE_NAMES = NO -INPUT = ../components +INPUT = ../components/driver/include RECURSIVE = YES QUIET = YES JAVADOC_AUTOBRIEF = YES From 4900c63071a88883b327aedc754bcae0bcc6fd62 Mon Sep 17 00:00:00 2001 From: Krzysztof Date: Sun, 23 Oct 2016 22:59:53 +0200 Subject: [PATCH 204/343] Added ReadTheDocs.org badges --- README.rst | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 65d6167673..9711e22946 100644 --- a/README.rst +++ b/README.rst @@ -15,7 +15,9 @@ In the [docs](docs) directory you will find per-platform setup guides: Finding A Project ----------------- -As well as the [esp-idf-template](https://github.com/espressif/esp-idf-template) project mentioned in the setup guide, esp-idf comes with some example projects in the [examples](examples) directory. +As well as the esp-idf-template_ project mentioned in the setup guide, esp-idf comes with some example projects in the [examples](examples) directory. + +.. _esp-idf-template: https://github.com/espressif/esp-idf-template Once you've found the project you want to work with, change to its directory and you can configure and build it: @@ -82,3 +84,9 @@ Resources * [Check the Issues section on github](https://github.com/espressif/esp-idf/issues) if you find a bug or have a feature request. Please check existing Issues before opening a new one. * If you're interested in contributing to esp-idf, please check the [CONTRIBUTING.md](CONTRIBUTING.md) file. + + +.. |docs| image:: https://readthedocs.org/projects/docs/badge/?version=latest + :alt: Documentation Status + :scale: 100% + :target: http://esp-idf.readthedocs.io/en/latest/?badge=latest \ No newline at end of file From 6ce1af58984751a3dafc3d5111e8bbedffdf7aa3 Mon Sep 17 00:00:00 2001 From: Krzysztof Date: Mon, 24 Oct 2016 20:43:13 +0200 Subject: [PATCH 205/343] Set up of theme for local builds --- docs/conf.py | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 7c4614d458..5ba76d7f25 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -20,14 +20,16 @@ import os # documentation root, use os.path.abspath to make it absolute, like shown here. #sys.path.insert(0, os.path.abspath('.')) -# run doxygen +# -- Run DoxyGen to prepare XML for Sphinx--------------------------------- +# ref. https://github.com/rtfd/readthedocs.org/issues/388 # -# for implementation on readthedocs.org check -# https://github.com/rtfd/readthedocs.org/issues/388 +# added by krzychb, 24-Oct-2016 # + from subprocess import call call('doxygen') + # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. @@ -268,3 +270,18 @@ texinfo_documents = [ # If true, do not generate a @detailmenu in the "Top" node's menu. #texinfo_no_detailmenu = False + +# -- Use sphinx_rtd_theme for local builds -------------------------------- +# ref. https://github.com/snide/sphinx_rtd_theme#using-this-theme-locally-then-building-on-read-the-docs +# +# added by krzychb, 24-Oct-2016 +# +# on_rtd is whether we are on readthedocs.org +on_rtd = os.environ.get('READTHEDOCS', None) == 'True' + +if not on_rtd: # only import and set the theme if we're building docs locally + import sphinx_rtd_theme + html_theme = 'sphinx_rtd_theme' + html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] + +# otherwise, readthedocs.org uses their theme by default, so no need to specify it From 8ae97a285551a07046e7b80a5fb4de157fb36faf Mon Sep 17 00:00:00 2001 From: Krzysztof Date: Mon, 24 Oct 2016 20:44:57 +0200 Subject: [PATCH 206/343] Initial list of Wi-Fi API --- docs/COPYRIGHT.rst | 6 ++- docs/Doxyfile | 4 +- docs/api/esp_wifi.rst | 59 ++++++++++++++++++++++++ docs/api/example.rst | 41 +++++++++++++++++ docs/build_system.rst | 2 +- docs/contributor-agreement.rst | 2 +- docs/eclipse-setup.rst | 3 ++ docs/index.rst | 82 ++++++++++++++-------------------- docs/linux-setup.rst | 3 ++ docs/macos-setup.rst | 3 ++ docs/openocd.rst | 3 ++ docs/partition-tables.rst | 5 ++- docs/windows-setup.rst | 7 ++- 13 files changed, 162 insertions(+), 58 deletions(-) create mode 100644 docs/api/esp_wifi.rst create mode 100644 docs/api/example.rst diff --git a/docs/COPYRIGHT.rst b/docs/COPYRIGHT.rst index da5f5b204a..67b3d9bf1c 100644 --- a/docs/COPYRIGHT.rst +++ b/docs/COPYRIGHT.rst @@ -1,3 +1,6 @@ +Copyrights and Licenses +*********************** + Software Copyrights =================== @@ -87,8 +90,7 @@ developments under license policy of following terms. Copyright (C) 2011, ChaN, all right reserved. * The TJpgDec module is a free software and there is NO WARRANTY. -* No restriction on use. You can use, modify and redistribute it for -personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY. +* No restriction on use. You can use, modify and redistribute it for personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY. * Redistributions of source code must retain the above copyright notice. diff --git a/docs/Doxyfile b/docs/Doxyfile index 795bfa5e89..9c8fb81df8 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -4,9 +4,9 @@ GENERATE_LATEX = NO GENERATE_MAN = NO GENERATE_RTF = NO CASE_SENSE_NAMES = NO -INPUT = ../components/driver/include +INPUT = ../components/esp32/include/esp_wifi.h RECURSIVE = YES QUIET = YES JAVADOC_AUTOBRIEF = YES GENERATE_HTML = NO -GENERATE_XML = YES \ No newline at end of file +GENERATE_XML = YES diff --git a/docs/api/esp_wifi.rst b/docs/api/esp_wifi.rst new file mode 100644 index 0000000000..48b4db204a --- /dev/null +++ b/docs/api/esp_wifi.rst @@ -0,0 +1,59 @@ +Wi-Fi API +========= + +Macros +------ + +.. doxygendefine:: WIFI_INIT_CONFIG_DEFAULT + + +Typedefs +-------- + +.. doxygentypedef:: wifi_promiscuous_cb_t +.. doxygentypedef:: wifi_rxcb_t +.. doxygentypedef:: esp_vendor_ie_cb_t + + +Functions +--------- + +.. doxygenfunction:: esp_wifi_init +.. doxygenfunction:: esp_wifi_deinit +.. doxygenfunction:: esp_wifi_set_mode +.. doxygenfunction:: esp_wifi_get_mode +.. doxygenfunction:: esp_wifi_start +.. doxygenfunction:: esp_wifi_stop +.. doxygenfunction:: esp_wifi_connect +.. doxygenfunction:: esp_wifi_disconnect +.. doxygenfunction:: esp_wifi_clear_fast_connect +.. doxygenfunction:: esp_wifi_kick_station +.. doxygenfunction:: esp_wifi_scan_start +.. doxygenfunction:: esp_wifi_scan_stop +.. doxygenfunction:: esp_wifi_get_ap_num +.. doxygenfunction:: esp_wifi_get_ap_list +.. doxygenfunction:: esp_wifi_set_ps +.. doxygenfunction:: esp_wifi_get_ps +.. doxygenfunction:: esp_wifi_set_protocol +.. doxygenfunction:: esp_wifi_get_protocol +.. doxygenfunction:: esp_wifi_set_bandwidth +.. doxygenfunction:: esp_wifi_get_bandwidth +.. doxygenfunction:: esp_wifi_set_channel +.. doxygenfunction:: esp_wifi_get_channel +.. doxygenfunction:: esp_wifi_set_country +.. doxygenfunction:: esp_wifi_get_country +.. doxygenfunction:: esp_wifi_set_mac +.. doxygenfunction:: esp_wifi_get_mac +.. doxygenfunction:: esp_wifi_set_promiscuous_rx_cb +.. doxygenfunction:: esp_wifi_set_promiscuous +.. doxygenfunction:: esp_wifi_get_promiscuous +.. doxygenfunction:: esp_wifi_set_config +.. doxygenfunction:: esp_wifi_get_config +.. doxygenfunction:: esp_wifi_get_station_list +.. doxygenfunction:: esp_wifi_free_station_list +.. doxygenfunction:: esp_wifi_set_storage +.. doxygenfunction:: esp_wifi_reg_rxcb +.. doxygenfunction:: esp_wifi_set_auto_connect +.. doxygenfunction:: esp_wifi_get_auto_connect +.. doxygenfunction:: esp_wifi_set_vendor_ie +.. doxygenfunction:: esp_wifi_set_vendor_ie_cb diff --git a/docs/api/example.rst b/docs/api/example.rst new file mode 100644 index 0000000000..88ecb4601d --- /dev/null +++ b/docs/api/example.rst @@ -0,0 +1,41 @@ +Example Visualizations +====================== + +Function prototpe +----------------- + +.. c:function:: esp_err_t esp_wifi_get_ap_list (uint16_t *number, wifi_ap_list_t *ap_list) +.. c:function:: esp_err_t esp_wifi_set_protocol (wifi_interface_t ifx, uint8_t protocol_bitmap) + + +Function definition +------------------- + +Wi-Fi +^^^^^ +.. doxygenfunction:: esp_wifi_init +.. doxygenfunction:: esp_wifi_set_config + +GPIO +^^^^ +.. doxygenfunction:: gpio_isr_register + +Led Control +^^^^^^^^^^^ + +.. doxygenfunction:: ledc_timer_set + + +Enum definition +--------------- + +.. doxygenenum:: wifi_auth_mode_t + + +Struct definition +----------------- + +.. doxygenstruct:: wifi_scan_config_t + :members: + + diff --git a/docs/build_system.rst b/docs/build_system.rst index 4df65b1b5c..34db487e0a 100644 --- a/docs/build_system.rst +++ b/docs/build_system.rst @@ -1,5 +1,5 @@ Build System ------------- +************ This document explains the Espressif IoT Development Framework build system and the concept of "components" diff --git a/docs/contributor-agreement.rst b/docs/contributor-agreement.rst index 7c194e7728..de294740c4 100644 --- a/docs/contributor-agreement.rst +++ b/docs/contributor-agreement.rst @@ -1,5 +1,5 @@ Contributor Agreement ---------------------- +===================== Individual Contributor Non-Exclusive License Agreement ------------------------------------------------------ diff --git a/docs/eclipse-setup.rst b/docs/eclipse-setup.rst index 21d83a7f06..32d60a17a0 100644 --- a/docs/eclipse-setup.rst +++ b/docs/eclipse-setup.rst @@ -1,3 +1,6 @@ +Build and Falsh with Eclipse IDE +******************************** + Installing Eclipse IDE ====================== diff --git a/docs/index.rst b/docs/index.rst index f74a3acae1..30e981e8ef 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,54 +1,41 @@ .. Read the Docs Template documentation master file -Welcome to ESP32 Programming Guide -================================== - - -Example C functions -------------------- - -.. c:function:: esp_err_t esp_wifi_get_ap_list (uint16_t *number, wifi_ap_list_t *ap_list) - -.. c:function:: esp_err_t esp_wifi_set_protocol (wifi_interface_t ifx, uint8_t protocol_bitmap) - - -Example C function integration ------------------------------- - -.. doxygenfunction:: esp_wifi_init -.. doxygenfunction:: esp_wifi_set_config - -.. doxygenfunction:: gpio_isr_register -.. doxygenfunction:: ledc_timer_set - - -Example C enum integration --------------------------- - -.. doxygenenum:: wifi_auth_mode_t - - -Example C struct integration ----------------------------- - -.. doxygenstruct:: wifi_scan_config_t - :members: - +ESP32 Programming Guide +======================= Contents: -.. About - TBA - .. toctree:: - :caption: Toolchain Setup + :caption: Setup Toolchain :maxdepth: 1 - windows-setup - linux-setup - macos-setup - eclipse-setup + Windows + Linux + Mac OS -.. API Reference - TBA +.. Configure - TBA + +.. Connect - TBA + +.. toctree:: + :caption: Build and Flash + :maxdepth: 1 + + Eclipse IDE + +.. toctree:: + :caption: Tweak + :maxdepth: 1 + + partition-tables + build_system + +.. toctree:: + :caption: API Reference + :maxdepth: 1 + + Wi-Fi + api/example .. Technical Reference - TBA @@ -68,17 +55,14 @@ Contents: contributor-agreement .. toctree:: - :caption: Copyrights and Licenses + :caption: Legal :maxdepth: 1 COPYRIGHT -.. toctree:: - :caption: Flapping Documents - :maxdepth: 1 - - partition-tables - build_system +.. About - TBA + + Indices and tables diff --git a/docs/linux-setup.rst b/docs/linux-setup.rst index 13e1b3a9c0..cf5e78b63d 100644 --- a/docs/linux-setup.rst +++ b/docs/linux-setup.rst @@ -1,3 +1,6 @@ +Set up of Toolchain for Linux +***************************** + Step 0: Prerequisites ===================== diff --git a/docs/macos-setup.rst b/docs/macos-setup.rst index 8178a17ada..53c6fe54c8 100644 --- a/docs/macos-setup.rst +++ b/docs/macos-setup.rst @@ -1,3 +1,6 @@ +Set up of Toolchain for Mac OS +****************************** + Step 0: Prerequisites ===================== diff --git a/docs/openocd.rst b/docs/openocd.rst index 57ee93db4a..6a6f50e3f4 100644 --- a/docs/openocd.rst +++ b/docs/openocd.rst @@ -1,3 +1,6 @@ +Debugging +========= + OpenOCD setup for ESP32 ----------------------- diff --git a/docs/partition-tables.rst b/docs/partition-tables.rst index e0a39126b5..88597532d2 100644 --- a/docs/partition-tables.rst +++ b/docs/partition-tables.rst @@ -1,5 +1,8 @@ Partition Tables ----------------- +================ + +Overview +-------- A single ESP32's flash can contain multiple apps, as well as many different kinds of data (calibration data, filesystems, parameter storage, etc). For this reason a partition table is flashed to offset 0x4000 in the flash. diff --git a/docs/windows-setup.rst b/docs/windows-setup.rst index baea1ac40b..a425f5b3a0 100644 --- a/docs/windows-setup.rst +++ b/docs/windows-setup.rst @@ -1,5 +1,8 @@ -Step 1: Toolchain for Windows: Quick Steps -================================== +Set up of Toolchain for Windows +******************************* + +Step 1: Quick Steps +=================== Windows doesn't have a built-in "make" environment, so as well as installing the toolchain you will need a GNU-compatible environment. We use the MSYS2_ environment to provide. You don't need to use this environment all the time (you can use Eclipse_ or some other front-end), but it runs behind the scenes. From b6a463e94f5886bc953515e8b9a45b7c13a514a2 Mon Sep 17 00:00:00 2001 From: krzychb Date: Tue, 25 Oct 2016 12:09:05 +0200 Subject: [PATCH 207/343] Draft of GPIO API included --- docs/Doxyfile | 25 +++++++++--------- docs/api/gpio.rst | 67 +++++++++++++++++++++++++++++++++++++++++++++++ docs/index.rst | 1 + 3 files changed, 81 insertions(+), 12 deletions(-) create mode 100644 docs/api/gpio.rst diff --git a/docs/Doxyfile b/docs/Doxyfile index 9c8fb81df8..8328d44ca3 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -1,12 +1,13 @@ -PROJECT_NAME = "ESP32 Programming Guide" -XML_OUTPUT = xml -GENERATE_LATEX = NO -GENERATE_MAN = NO -GENERATE_RTF = NO -CASE_SENSE_NAMES = NO -INPUT = ../components/esp32/include/esp_wifi.h -RECURSIVE = YES -QUIET = YES -JAVADOC_AUTOBRIEF = YES -GENERATE_HTML = NO -GENERATE_XML = YES +PROJECT_NAME = "ESP32 Programming Guide" +XML_OUTPUT = xml +GENERATE_LATEX = NO +GENERATE_MAN = NO +GENERATE_RTF = NO +CASE_SENSE_NAMES = NO +INPUT = ../components/esp32/include/esp_wifi.h ../components/driver/include/driver/gpio.h ../components/esp32/include/rom/gpio.h +RECURSIVE = YES +QUIET = YES +JAVADOC_AUTOBRIEF = YES +GENERATE_HTML = NO +GENERATE_XML = YES +WARN_LOGFILE = "DoxyGenWarningLog.txt" \ No newline at end of file diff --git a/docs/api/gpio.rst b/docs/api/gpio.rst new file mode 100644 index 0000000000..11b0e4a463 --- /dev/null +++ b/docs/api/gpio.rst @@ -0,0 +1,67 @@ +GPIO API +======== + +Functions +--------- + +.. doxygenfunction:: gpio_config +.. doxygenfunction:: gpio_set_intr_type +.. doxygenfunction:: gpio_intr_enable +.. doxygenfunction:: gpio_intr_disable +.. doxygenfunction:: gpio_set_level +.. doxygenfunction:: gpio_get_level +.. doxygenfunction:: gpio_set_direction +.. doxygenfunction:: gpio_set_pull_mode +.. doxygenfunction:: gpio_wakeup_enable +.. doxygenfunction:: gpio_wakeup_disable +.. doxygenfunction:: gpio_isr_register + +*Example code:* + +Configuration of GPIO as an output + +.. code-block:: c + + gpio_config_t io_conf; + io_conf.intr_type = GPIO_INTR_DISABLE; //disable interrupt + io_conf.mode = GPIO_MODE_OUTPUT; //set as output mode + io_conf.pin_bit_mask = GPIO_SEL_18 | GPIO_SEL_19; //bit mask of the pins that you want to set,e.g.GPIO18/19 + io_conf.pull_down_en = 0; //disable pull-down mode + io_conf.pull_up_en = 0; //disable pull-up mode + gpio_config(&io_conf); //configure GPIO with the given settings + +Configuration of GPIO as an input + +.. code-block:: c + + gpio_config_t io_conf; + io_conf.intr_type = GPIO_INTR_POSEDGE; //set posedge interrupt + io_conf.mode = GPIO_MODE_INPUT; //set as input + io_conf.pin_bit_mask = GPIO_SEL_4 | GPIO_SEL_5; //bit mask of the pins that you want to set, e.g.,GPIO4/5 + io_conf.pull_down_en = 0; //disable pull-down mode + io_conf.pull_up_en = 1; //enable pull-up mode + gpio_config(&io_conf); //configure GPIO with the given settings + + +Low level ROM GPIO functions + +.. doxygenfunction:: gpio_init +.. doxygenfunction:: gpio_output_set +.. doxygenfunction:: gpio_output_set_high +.. doxygenfunction:: gpio_input_get +.. doxygenfunction:: gpio_input_get_high +.. doxygenfunction:: gpio_intr_handler_register +.. doxygenfunction:: gpio_intr_pending +.. doxygenfunction:: gpio_intr_pending_high +.. doxygenfunction:: gpio_intr_ack +.. doxygenfunction:: gpio_intr_ack_high +.. doxygenfunction:: gpio_pin_wakeup_enable +.. doxygenfunction:: gpio_pin_wakeup_disable +.. doxygenfunction:: gpio_matrix_in +.. doxygenfunction:: gpio_matrix_out +.. doxygenfunction:: gpio_pad_select_gpio +.. doxygenfunction:: gpio_pad_set_drv +.. doxygenfunction:: gpio_pad_pullup +.. doxygenfunction:: gpio_pad_pulldown +.. doxygenfunction:: gpio_pad_unhold +.. doxygenfunction:: gpio_pad_hold diff --git a/docs/index.rst b/docs/index.rst index 30e981e8ef..26b906c366 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -35,6 +35,7 @@ Contents: :maxdepth: 1 Wi-Fi + GPIO api/example .. Technical Reference - TBA From 3584fcfc7cf3a3211c476cb2d02b66360d649bce Mon Sep 17 00:00:00 2001 From: Krzysztof Date: Tue, 25 Oct 2016 21:28:21 +0200 Subject: [PATCH 208/343] Make section --- docs/index.rst | 19 ++++++------- docs/make-project.rst | 63 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 11 deletions(-) create mode 100644 docs/make-project.rst diff --git a/docs/index.rst b/docs/index.rst index 26b906c366..84f37b5600 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -21,14 +21,16 @@ Contents: :caption: Build and Flash :maxdepth: 1 + Make Eclipse IDE .. toctree:: - :caption: Tweak + :caption: Want More? :maxdepth: 1 partition-tables build_system + openocd .. toctree:: :caption: API Reference @@ -38,13 +40,10 @@ Contents: GPIO api/example -.. Technical Reference - TBA - .. toctree:: - :caption: Debugging - :maxdepth: 1 + :caption: Technical Reference - openocd + Technical Reference .. Resources - TBA @@ -63,11 +62,9 @@ Contents: .. About - TBA - - - -Indices and tables -================== + +Indices +======= * :ref:`genindex` * :ref:`search` diff --git a/docs/make-project.rst b/docs/make-project.rst new file mode 100644 index 0000000000..e72bb81dd0 --- /dev/null +++ b/docs/make-project.rst @@ -0,0 +1,63 @@ +Build and Flash with Make +========================= + +Finding a project +----------------- + +As well as the `esp-idf-template `_ project mentioned in the setup guide, esp-idf comes with some example projects on github in the `examples `_ directory. + +Once you've found the project you want to work with, change to its directory and you can configure and build it: + +Configuring your project +------------------------ + +`make menuconfig` + +Compiling your project +---------------------- + +`make all` + +... will compile app, bootloader and generate a partition table based on the config. + +Flashing your project +--------------------- + +When `make all` finishes, it will print a command line to use esptool.py to flash the chip. However you can also do this from make by running: + +`make flash` + +This will flash the entire project (app, bootloader and partition table) to a new chip. The settings for serial port flashing can be configured with `make menuconfig`. + +You don't need to run `make all` before running `make flash`, `make flash` will automatically rebuild anything which needs it. + +Compiling & Flashing Just the App +--------------------------------- + +After the initial flash, you may just want to build and flash just your app, not the bootloader and partition table: + +* `make app` - build just the app. +* `make app-flash` - flash just the app. + +`make app-flash` will automatically rebuild the app if it needs it. + +(There's no downside to reflashing the bootloader and partition table each time, if they haven't changed.) + +The Partition Table +------------------- + +Once you've compiled your project, the "build" directory will contain a binary file with a name like "my_app.bin". This is an ESP32 image binary that can be loaded by the bootloader. + +A single ESP32's flash can contain multiple apps, as well as many different kinds of data (calibration data, filesystems, parameter storage, etc). For this reason a partition table is flashed to offset 0x4000 in the flash. + +Each entry in the partition table has a name (label), type (app, data, or something else), subtype and the offset in flash where the partition is loaded. + +The simplest way to use the partition table is to `make menuconfig` and choose one of the simple predefined partition tables: + +* "Single factory app, no OTA" +* "Factory app, two OTA definitions" + +In both cases the factory app is flashed at offset 0x10000. If you `make partition_table` then it will print a summary of the partition table. + +For more details about :doc:`partition tables ` and how to create custom variations, view the :doc:`documentation `. + From 591b7caa9514ab7d2a2c03bf8b42bec490eea86f Mon Sep 17 00:00:00 2001 From: Krzysztof Date: Tue, 25 Oct 2016 21:28:42 +0200 Subject: [PATCH 209/343] Back to .md format --- CONTRIBUTING.rst | 6 +++--- README.rst => README.md | 44 +++++++++++++---------------------------- 2 files changed, 17 insertions(+), 33 deletions(-) rename README.rst => README.md (72%) diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index a6e759eb18..ed1c0b92d8 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -6,7 +6,7 @@ We welcome contributions to the esp-idf project! How to Contribute ----------------- -Contributions to esp-idf - fixing bugs, adding features, adding documentation - are welcome. We accept contributions via [Github Pull Requests](https://help.github.com/articles/about-pull-requests/). +Contributions to esp-idf - fixing bugs, adding features, adding documentation - are welcome. We accept contributions via `Github Pull Requests `_. Before Contributing ------------------- @@ -23,7 +23,7 @@ Before sending us a Pull Request, please consider this list of points: * Are comments and documentation written in clear English, with no spelling or grammar errors? -* If the contribution contains multiple commits, are they grouped together into logical changes (one major change per pull request)? Are any commits with names like "fixed typo" [squashed into previous commits](http://eli.thegreenplace.net/2014/02/19/squashing-github-pull-requests-into-a-single-commit/)? +* If the contribution contains multiple commits, are they grouped together into logical changes (one major change per pull request)? Are any commits with names like "fixed typo" `squashed into previous commits `_? * If you're unsure about any of these points, please open the Pull Request anyhow and then ask us for feedback. @@ -39,4 +39,4 @@ If this process passes, it will be merged onto the public github repository. Legal Part ---------- -Before a contribution can be accepted, you will need to sign our [Contributor Agreement](docs/contributor-agreement.rst). You will be prompted for this automatically as part of the Pull Request process. +Before a contribution can be accepted, you will need to sign our :doc:`Contributor Agreement `. You will be prompted for this automatically as part of the Pull Request process. diff --git a/README.rst b/README.md similarity index 72% rename from README.rst rename to README.md index 9711e22946..c01e314f11 100644 --- a/README.rst +++ b/README.md @@ -1,10 +1,8 @@ -Using Espressif IoT Development Framework with the ESP32 -======================================================== +# Using Espressif IoT Development Framework with the ESP32 -|docs| +[![alt text](https://readthedocs.org/projects/docs/badge/?version=latest "Documentation Status")](http://esp-idf.readthedocs.io/en/latest/?badge=latest) -Setting Up ESP-IDF ------------------- +# Setting Up ESP-IDF In the [docs](docs) directory you will find per-platform setup guides: @@ -12,29 +10,23 @@ In the [docs](docs) directory you will find per-platform setup guides: * [Mac OS Setup Guide](docs/macos-setup.rst) * [Linux Setup Guide](docs/linux-setup.rst) -Finding A Project ------------------ +# Finding A Project -As well as the esp-idf-template_ project mentioned in the setup guide, esp-idf comes with some example projects in the [examples](examples) directory. - -.. _esp-idf-template: https://github.com/espressif/esp-idf-template +As well as the [esp-idf-template](https://github.com/espressif/esp-idf-template) project mentioned in the setup guide, esp-idf comes with some example projects in the [examples](examples) directory. Once you've found the project you want to work with, change to its directory and you can configure and build it: -Configuring your project ------------------------- +# Configuring your project `make menuconfig` -Compiling your project ----------------------- +# Compiling your project `make all` ... will compile app, bootloader and generate a partition table based on the config. -Flashing your project ---------------------- +# Flashing your project When `make all` finishes, it will print a command line to use esptool.py to flash the chip. However you can also do this from make by running: @@ -44,8 +36,7 @@ This will flash the entire project (app, bootloader and partition table) to a ne You don't need to run `make all` before running `make flash`, `make flash` will automatically rebuild anything which needs it. -Compiling & Flashing Just the App ---------------------------------- +# Compiling & Flashing Just the App After the initial flash, you may just want to build and flash just your app, not the bootloader and partition table: @@ -56,8 +47,7 @@ After the initial flash, you may just want to build and flash just your app, not (There's no downside to reflashing the bootloader and partition table each time, if they haven't changed.) -The Partition Table -------------------- +# The Partition Table Once you've compiled your project, the "build" directory will contain a binary file with a name like "my_app.bin". This is an ESP32 image binary that can be loaded by the bootloader. @@ -72,21 +62,15 @@ The simplest way to use the partition table is to `make menuconfig` and choose o In both cases the factory app is flashed at offset 0x10000. If you `make partition_table` then it will print a summary of the partition table. -For more details about partition tables and how to create custom variations, view the `docs/partition_tables.rst` file. +For more details about partition tables and how to create custom variations, view the `docs/partition-tables.rst` file. -Resources ---------- +# Resources -* The [docs directory of the esp-idf repository](docs) contains esp-idf documentation. +* The [docs directory of the esp-idf repository](docs) contains source of [esp-idf](http://esp-idf.readthedocs.io/) documentation. * The [esp32.com forum](http://esp32.com/) is a place to ask questions and find community resources. * [Check the Issues section on github](https://github.com/espressif/esp-idf/issues) if you find a bug or have a feature request. Please check existing Issues before opening a new one. -* If you're interested in contributing to esp-idf, please check the [CONTRIBUTING.md](CONTRIBUTING.md) file. +* If you're interested in contributing to esp-idf, please check the [Contributions Guide](http://esp-idf.readthedocs.io/en/latest/contributing.html>). - -.. |docs| image:: https://readthedocs.org/projects/docs/badge/?version=latest - :alt: Documentation Status - :scale: 100% - :target: http://esp-idf.readthedocs.io/en/latest/?badge=latest \ No newline at end of file From adae42fd85381071a2564940f398e2fdf22fdc97 Mon Sep 17 00:00:00 2001 From: Krzysztof Date: Wed, 26 Oct 2016 21:08:36 +0200 Subject: [PATCH 210/343] API template - reflected template in other DRAFT API dcouments - DRAFT of Bluetooth API - link fixes in CONTRIBUTING.rst --- CONTRIBUTING.rst | 6 +++-- docs/Doxyfile | 26 +++++++++--------- docs/api/bt.rst | 31 ++++++++++++++++++++++ docs/api/esp_wifi.rst | 15 +++++++++++ docs/api/example.rst | 41 ----------------------------- docs/api/gpio.rst | 28 +++++++++++++++----- docs/api/template.rst | 61 +++++++++++++++++++++++++++++++++++++++++++ docs/index.rst | 7 +++-- 8 files changed, 149 insertions(+), 66 deletions(-) create mode 100644 docs/api/bt.rst delete mode 100644 docs/api/example.rst create mode 100644 docs/api/template.rst diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index ed1c0b92d8..3bf43f6dbe 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -19,7 +19,7 @@ Before sending us a Pull Request, please consider this list of points: * Is the code adequately commented for people to understand how it is structured? -* Is there documentation or examples that go with code contributions? [There are additional suggestions for writing good examples in the examples README](examples/README.md). +* Is there documentation or examples that go with code contributions? `There are additional suggestions for writing good examples in the examples README `_. * Are comments and documentation written in clear English, with no spelling or grammar errors? @@ -39,4 +39,6 @@ If this process passes, it will be merged onto the public github repository. Legal Part ---------- -Before a contribution can be accepted, you will need to sign our :doc:`Contributor Agreement `. You will be prompted for this automatically as part of the Pull Request process. +Before a contribution can be accepted, you will need to sign our `Contributor Agreement `_. You will be prompted for this automatically as part of the Pull Request process. + + diff --git a/docs/Doxyfile b/docs/Doxyfile index 8328d44ca3..f905de74ce 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -1,13 +1,13 @@ -PROJECT_NAME = "ESP32 Programming Guide" -XML_OUTPUT = xml -GENERATE_LATEX = NO -GENERATE_MAN = NO -GENERATE_RTF = NO -CASE_SENSE_NAMES = NO -INPUT = ../components/esp32/include/esp_wifi.h ../components/driver/include/driver/gpio.h ../components/esp32/include/rom/gpio.h -RECURSIVE = YES -QUIET = YES -JAVADOC_AUTOBRIEF = YES -GENERATE_HTML = NO -GENERATE_XML = YES -WARN_LOGFILE = "DoxyGenWarningLog.txt" \ No newline at end of file +PROJECT_NAME = "ESP32 Programming Guide" +XML_OUTPUT = xml +GENERATE_LATEX = NO +GENERATE_MAN = NO +GENERATE_RTF = NO +CASE_SENSE_NAMES = NO +INPUT = ../components/esp32/include/esp_wifi.h ../components/driver/include/driver/gpio.h ../components/esp32/include/rom/gpio.h ../components/bt/include/bt.h +RECURSIVE = YES +QUIET = YES +JAVADOC_AUTOBRIEF = YES +GENERATE_HTML = NO +GENERATE_XML = YES +WARN_LOGFILE = "DoxyGenWarningLog.txt" diff --git a/docs/api/bt.rst b/docs/api/bt.rst new file mode 100644 index 0000000000..16f30dc4e6 --- /dev/null +++ b/docs/api/bt.rst @@ -0,0 +1,31 @@ +Bluetooth API +============= + +Overview +-------- + +`Instructions `_ + +Application Example +------------------- + +`Instructions `_ + +Reference +--------- + +`Instructions `_ + +Type Definitions +^^^^^^^^^^^^^^^^ + +.. doxygentypedef:: vhci_host_callback + +Functions +^^^^^^^^^ + +.. doxygenfunction:: API_vhci_host_check_send_available +.. doxygenfunction:: API_vhci_host_register_callback +.. doxygenfunction:: API_vhci_host_send_packet +.. doxygenfunction:: bt_controller_init + diff --git a/docs/api/esp_wifi.rst b/docs/api/esp_wifi.rst index 48b4db204a..e4ec59fc82 100644 --- a/docs/api/esp_wifi.rst +++ b/docs/api/esp_wifi.rst @@ -1,6 +1,21 @@ Wi-Fi API ========= +Overview +-------- + +`Instructions `_ + +Application Example +------------------- + +`Instructions `_ + +Reference +--------- + +`Instructions `_ + Macros ------ diff --git a/docs/api/example.rst b/docs/api/example.rst deleted file mode 100644 index 88ecb4601d..0000000000 --- a/docs/api/example.rst +++ /dev/null @@ -1,41 +0,0 @@ -Example Visualizations -====================== - -Function prototpe ------------------ - -.. c:function:: esp_err_t esp_wifi_get_ap_list (uint16_t *number, wifi_ap_list_t *ap_list) -.. c:function:: esp_err_t esp_wifi_set_protocol (wifi_interface_t ifx, uint8_t protocol_bitmap) - - -Function definition -------------------- - -Wi-Fi -^^^^^ -.. doxygenfunction:: esp_wifi_init -.. doxygenfunction:: esp_wifi_set_config - -GPIO -^^^^ -.. doxygenfunction:: gpio_isr_register - -Led Control -^^^^^^^^^^^ - -.. doxygenfunction:: ledc_timer_set - - -Enum definition ---------------- - -.. doxygenenum:: wifi_auth_mode_t - - -Struct definition ------------------ - -.. doxygenstruct:: wifi_scan_config_t - :members: - - diff --git a/docs/api/gpio.rst b/docs/api/gpio.rst index 11b0e4a463..c12c991ce4 100644 --- a/docs/api/gpio.rst +++ b/docs/api/gpio.rst @@ -1,9 +1,24 @@ GPIO API ======== -Functions +Overview +-------- + +`Instructions `_ + +Application Example +------------------- + +`Instructions `_ + +Reference --------- +`Instructions `_ + +Functions +^^^^^^^^^ + .. doxygenfunction:: gpio_config .. doxygenfunction:: gpio_set_intr_type .. doxygenfunction:: gpio_intr_enable @@ -16,9 +31,7 @@ Functions .. doxygenfunction:: gpio_wakeup_disable .. doxygenfunction:: gpio_isr_register -*Example code:* - -Configuration of GPIO as an output +*Example code:* Configuration of GPIO as an output .. code-block:: c @@ -30,7 +43,7 @@ Configuration of GPIO as an output io_conf.pull_up_en = 0; //disable pull-up mode gpio_config(&io_conf); //configure GPIO with the given settings -Configuration of GPIO as an input +*Example code:* Configuration of GPIO as an input .. code-block:: c @@ -43,7 +56,8 @@ Configuration of GPIO as an input gpio_config(&io_conf); //configure GPIO with the given settings -Low level ROM GPIO functions +ROM GPIO functions +^^^^^^^^^^^^^^^^^^ .. doxygenfunction:: gpio_init .. doxygenfunction:: gpio_output_set @@ -65,3 +79,5 @@ Low level ROM GPIO functions .. doxygenfunction:: gpio_pad_pulldown .. doxygenfunction:: gpio_pad_unhold .. doxygenfunction:: gpio_pad_hold + + diff --git a/docs/api/template.rst b/docs/api/template.rst new file mode 100644 index 0000000000..8b1dfd4c50 --- /dev/null +++ b/docs/api/template.rst @@ -0,0 +1,61 @@ +Template API +============= + +Overview +-------- + +INSTRUCTIONS: Provide overview where and how this API may be used. For large number of functions, break down description into groups. + + +Application Example +------------------- + +INSTRUCTIONS: Provide one or more pratical examples to demonstrate functionality of this API. + + +Reference +--------- + +INSTRUCTIONS: Provide list of API memebers divided into sections. Use coresponding **.. doxygen** directices, so member documentation is auto updated. + +* Data Structures **.. doxygenstruct** +* Macros **.. doxygendefine** +* Type Definitions **.. doxygentypedef** +* Enumerations **.. doxygenenum** +* Functions **.. doxygenfunction** +* Variables **.. doxygenvariable** + +Include code snippotes to ilustrate functionality of particular functions where applicable. Skip section hearder if empty. + + +Data Structures +^^^^^^^^^^^^^^^ + +.. Data Structures .. doxygenstruct + +Macros +^^^^^^ + +.. Macros .. doxygendefine + +Type Definitions +^^^^^^^^^^^^^^^^ + +.. Type Definitions .. doxygentypedef + +Enumerations +^^^^^^^^^^^^ + +.. Enumerations .. doxygenenum + +Functions +^^^^^^^^^ + +.. Functions .. doxygenfunction + +Variables +^^^^^^^^^ + +.. Variables .. doxygenvariable + + diff --git a/docs/index.rst b/docs/index.rst index 84f37b5600..5c4d7025c6 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,5 +1,3 @@ -.. Read the Docs Template documentation master file - ESP32 Programming Guide ======================= @@ -25,7 +23,7 @@ Contents: Eclipse IDE .. toctree:: - :caption: Want More? + :caption: What Else? :maxdepth: 1 partition-tables @@ -37,8 +35,9 @@ Contents: :maxdepth: 1 Wi-Fi + Bluetooth GPIO - api/example + Template .. toctree:: :caption: Technical Reference From f05cd619f4bdbdfc2019b4e9f800b82ae6a13f3b Mon Sep 17 00:00:00 2001 From: Krzysztof Date: Wed, 26 Oct 2016 22:17:58 +0200 Subject: [PATCH 211/343] Sample cleaning of markup --- components/driver/include/driver/gpio.h | 148 ++++++++++++------------ docs/api/gpio.rst | 7 ++ 2 files changed, 81 insertions(+), 74 deletions(-) diff --git a/components/driver/include/driver/gpio.h b/components/driver/include/driver/gpio.h index 9b47c88e69..001be2a39d 100644 --- a/components/driver/include/driver/gpio.h +++ b/components/driver/include/driver/gpio.h @@ -157,39 +157,39 @@ typedef enum { } gpio_num_t; typedef enum { - GPIO_INTR_DISABLE = 0, /* disable GPIO interrupt */ - GPIO_INTR_POSEDGE = 1, /* GPIO interrupt type : rising edge */ - GPIO_INTR_NEGEDGE = 2, /* GPIO interrupt type : falling edge */ - GPIO_INTR_ANYEDGE = 3, /* GPIO interrupt type : both rising and falling edge */ - GPIO_INTR_LOW_LEVEL = 4, /* GPIO interrupt type : input low level trigger */ - GPIO_INTR_HIGH_LEVEL = 5, /* GPIO interrupt type : input high level trigger */ + GPIO_INTR_DISABLE = 0, /*!< disable GPIO interrupt */ + GPIO_INTR_POSEDGE = 1, /*!< GPIO interrupt type : rising edge */ + GPIO_INTR_NEGEDGE = 2, /*!< GPIO interrupt type : falling edge */ + GPIO_INTR_ANYEDGE = 3, /*!< GPIO interrupt type : both rising and falling edge */ + GPIO_INTR_LOW_LEVEL = 4, /*!< GPIO interrupt type : input low level trigger */ + GPIO_INTR_HIGH_LEVEL = 5, /*!< GPIO interrupt type : input high level trigger */ GPIO_INTR_MAX, } gpio_int_type_t; typedef enum { - GPIO_MODE_INPUT = GPIO_MODE_DEF_INPUT, /* GPIO mode : input only */ - GPIO_MODE_OUTPUT = GPIO_MODE_DEF_OUTPUT, /* GPIO mode : output only mode */ - GPIO_MODE_OUTPUT_OD = ((GPIO_MODE_DEF_OUTPUT)|(GPIO_MODE_DEF_OD)), /* GPIO mode : output only with open-drain mode */ - GPIO_MODE_INPUT_OUTPUT_OD = ((GPIO_MODE_DEF_INPUT)|(GPIO_MODE_DEF_OUTPUT)|(GPIO_MODE_DEF_OD)), /* GPIO mode : output and input with open-drain mode*/ - GPIO_MODE_INPUT_OUTPUT = ((GPIO_MODE_DEF_INPUT)|(GPIO_MODE_DEF_OUTPUT)), /* GPIO mode : output and input mode */ + GPIO_MODE_INPUT = GPIO_MODE_DEF_INPUT, /*!< GPIO mode : input only */ + GPIO_MODE_OUTPUT = GPIO_MODE_DEF_OUTPUT, /*!< GPIO mode : output only mode */ + GPIO_MODE_OUTPUT_OD = ((GPIO_MODE_DEF_OUTPUT)|(GPIO_MODE_DEF_OD)), /*!< GPIO mode : output only with open-drain mode */ + GPIO_MODE_INPUT_OUTPUT_OD = ((GPIO_MODE_DEF_INPUT)|(GPIO_MODE_DEF_OUTPUT)|(GPIO_MODE_DEF_OD)), /*!< GPIO mode : output and input with open-drain mode*/ + GPIO_MODE_INPUT_OUTPUT = ((GPIO_MODE_DEF_INPUT)|(GPIO_MODE_DEF_OUTPUT)), /*!< GPIO mode : output and input mode */ } gpio_mode_t; typedef enum { - GPIO_PULLUP_DISABLE = 0x0, /* disable GPIO pull-up resistor */ - GPIO_PULLUP_ENABLE = 0x1, /* enable GPIO pull-up resistor */ + GPIO_PULLUP_DISABLE = 0x0, /*!< disable GPIO pull-up resistor */ + GPIO_PULLUP_ENABLE = 0x1, /*!< enable GPIO pull-up resistor */ } gpio_pullup_t; typedef enum { - GPIO_PULLDOWN_DISABLE = 0x0, /* disable GPIO pull-down resistor */ - GPIO_PULLDOWN_ENABLE = 0x1, /* enable GPIO pull-down resistor */ + GPIO_PULLDOWN_DISABLE = 0x0, /*!< disable GPIO pull-down resistor */ + GPIO_PULLDOWN_ENABLE = 0x1, /*!< enable GPIO pull-down resistor */ } gpio_pulldown_t; typedef struct { - uint64_t pin_bit_mask; /* GPIO pin: set with bit mask, each bit maps to a GPIO */ - gpio_mode_t mode; /* GPIO mode: set input/output mode */ - gpio_pullup_t pull_up_en; /* GPIO pull-up */ - gpio_pulldown_t pull_down_en; /* GPIO pull-down */ - gpio_int_type_t intr_type; /* GPIO interrupt type */ + uint64_t pin_bit_mask; /*!< GPIO pin: set with bit mask, each bit maps to a GPIO */ + gpio_mode_t mode; /*!< GPIO mode: set input/output mode */ + gpio_pullup_t pull_up_en; /*!< GPIO pull-up */ + gpio_pulldown_t pull_down_en; /*!< GPIO pull-down */ + gpio_int_type_t intr_type; /*!< GPIO interrupt type */ } gpio_config_t; typedef enum { @@ -199,10 +199,10 @@ typedef enum { } gpio_level_t; typedef enum { - GPIO_PULLUP_ONLY, /* Pad pull up */ - GPIO_PULLDOWN_ONLY, /* Pad pull down */ - GPIO_PULLUP_PULLDOWN, /* Pad pull up + pull down*/ - GPIO_FLOATING, /* Pad floating */ + GPIO_PULLUP_ONLY, /*!< Pad pull up */ + GPIO_PULLDOWN_ONLY, /*!< Pad pull down */ + GPIO_PULLUP_PULLDOWN, /*!< Pad pull up + pull down*/ + GPIO_FLOATING, /*!< Pad floating */ } gpio_pull_mode_t; typedef void (*gpio_event_callback)(gpio_num_t gpio_intr_num); @@ -224,20 +224,20 @@ typedef void (*gpio_event_callback)(gpio_num_t gpio_intr_num); */ /** - * @brief GPIO common configuration + * @brief GPIO common configuration * * Use this Function ,Configure GPIO's Mode,pull-up,PullDown,IntrType * - * @parameter[in] pGPIOConfig - * pGPIOConfig.pin_bit_mask : Configure GPIO pins bits,set this parameter with bit mask. + * @param[in] pGPIOConfig + * pGPIOConfig.pin_bit_mask : Configure GPIO pins bits,set this parameter with bit mask. * If you want to configure GPIO34 and GPIO16, pin_bit_mask=GPIO_Pin_16|GPIO_Pin_34; - * pGPIOConfig.mode : Configure GPIO mode,such as output ,input... - * pGPIOConfig.pull_up_en : Enable or Disable pull-up - * pGPIOConfig.pull_down_en : Enable or Disable pull-down - * pGPIOConfig.intr_type : Configure GPIO interrupt trigger type - * @return ESP_OK: success ; - * ESP_ERR_INVALID_ARG: parameter error - * ESP_FAIL : GPIO error + * pGPIOConfig.mode : Configure GPIO mode,such as output ,input... + * pGPIOConfig.pull_up_en : Enable or Disable pull-up + * pGPIOConfig.pull_down_en : Enable or Disable pull-down + * pGPIOConfig.intr_type : Configure GPIO interrupt trigger type + * @return ESP_OK: success ; + * ESP_ERR_INVALID_ARG: parameter error + * ESP_FAIL : GPIO error * */ esp_err_t gpio_config(gpio_config_t *pGPIOConfig); @@ -246,12 +246,12 @@ esp_err_t gpio_config(gpio_config_t *pGPIOConfig); /** * @brief GPIO set interrupt trigger type * - * @parameter[in] gpio_num : GPIO number. + * @param[in] gpio_num : GPIO number. * If you want to set output level of GPIO16, gpio_num should be GPIO_NUM_16 (16); - * @parameter[in] intr_type: interrupt type, select from gpio_int_type_t + * @param[in] intr_type: interrupt type, select from gpio_int_type_t * - * @return ESP_OK : success - * ESP_ERR_INVALID_ARG: parameter error + * @return ESP_OK : success + * ESP_ERR_INVALID_ARG: parameter error * */ esp_err_t gpio_set_intr_type(gpio_num_t gpio_num, gpio_int_type_t intr_type); @@ -259,11 +259,11 @@ esp_err_t gpio_set_intr_type(gpio_num_t gpio_num, gpio_int_type_t intr_type); /** * @brief enable GPIO module interrupt signal * - * @parameter[in] gpio_num : GPIO number. + * @param[in] gpio_num : GPIO number. * If you want to set output level of GPIO16, gpio_num should be GPIO_NUM_16 (16); * - * @return ESP_OK : success - * ESP_ERR_INVALID_ARG: parameter error + * @return ESP_OK : success + * ESP_ERR_INVALID_ARG: parameter error * */ esp_err_t gpio_intr_enable(gpio_num_t gpio_num); @@ -271,78 +271,78 @@ esp_err_t gpio_intr_enable(gpio_num_t gpio_num); /** * @brief disable GPIO module interrupt signal * - * @parameter[in] gpio_num : GPIO number. + * @param[in] gpio_num : GPIO number. * If you want to set output level of GPIO16, gpio_num should be GPIO_NUM_16 (16); * - * @return ESP_OK : success - * ESP_ERR_INVALID_ARG: parameter error + * @return ESP_OK : success + * ESP_ERR_INVALID_ARG: parameter error * */ esp_err_t gpio_intr_disable(gpio_num_t gpio_num); /** - * @brief GPIO set output level + * @brief GPIO set output level * - * @parameter[in] gpio_num : GPIO number. + * @param[in] gpio_num : GPIO number. * If you want to set output level of GPIO16, gpio_num should be GPIO_NUM_16 (16); - * @parameter[in] level : Output level. 0: low ; 1: high + * @param[in] level : Output level. 0: low ; 1: high * - * @return ESP_OK : success - * ESP_FAIL : GPIO error + * @return ESP_OK : success + * ESP_FAIL : GPIO error * */ esp_err_t gpio_set_level(gpio_num_t gpio_num, uint32_t level); /** - * @brief GPIO get input level + * @brief GPIO get input level * - * @parameter[in] gpio_num : GPIO number. + * @param[in] gpio_num : GPIO number. * If you want to get level of pin GPIO16, gpio_num should be GPIO_NUM_16 (16); * - * @return 0 : the GPIO input level is 0 + * @return 0 : the GPIO input level is 0 * 1 : the GPIO input level is 1 * */ int gpio_get_level(gpio_num_t gpio_num); /** - * @brief GPIO set direction + * @brief GPIO set direction * * Configure GPIO direction,such as output_only,input_only,output_and_input * - * @parameter[in] gpio_num : Configure GPIO pins number,it should be GPIO number. + * @param[in] gpio_num : Configure GPIO pins number,it should be GPIO number. * If you want to set direction of GPIO16, gpio_num should be GPIO_NUM_16 (16); - * @parameter[in] mode : Configure GPIO direction,such as output_only,input_only,... + * @param[in] mode : Configure GPIO direction,such as output_only,input_only,... * - * @return ESP_OK : success - * ESP_ERR_INVALID_ARG : fail - * ESP_FAIL : GPIO error + * @return ESP_OK : success + * ESP_ERR_INVALID_ARG : fail + * ESP_FAIL : GPIO error * */ esp_err_t gpio_set_direction(gpio_num_t gpio_num, gpio_mode_t mode); /** - * @brief GPIO set pull + * @brief GPIO set pull * * User this Function,configure GPIO pull mode,such as pull-up,pull-down * - * @parameter[in] gpio_num : Configure GPIO pins number,it should be GPIO number. + * @param[in] gpio_num : Configure GPIO pins number,it should be GPIO number. * If you want to set pull up or down mode for GPIO16,gpio_num should be GPIO_NUM_16 (16); - * @parameter[in] pull : Configure GPIO pull up/down mode,such as pullup_only,pulldown_only,pullup_and_pulldown,... + * @param[in] pull : Configure GPIO pull up/down mode,such as pullup_only,pulldown_only,pullup_and_pulldown,... * - * @return ESP_OK : success - * ESP_ERR_INVALID_ARG : fail - * ESP_FAIL : GPIO error + * @return ESP_OK : success + * ESP_ERR_INVALID_ARG : fail + * ESP_FAIL : GPIO error * */ esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull); /** - * @brief enable GPIO wake-up function. + * @brief enable GPIO wake-up function. * - * @param gpio_num_t gpio_num : GPIO number. + * @param gpio_num : GPIO number. * - * @param gpio_int_type_t intr_type : only GPIO_INTR_LOLEVEL\GPIO_INTR_HILEVEL can be used + * @param intr_type : only GPIO_INTR_LOLEVEL\GPIO_INTR_HILEVEL can be used * * @return ESP_OK: success * ESP_ERR_INVALID_ARG: parameter error @@ -350,9 +350,9 @@ esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull); esp_err_t gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type); /** - * @brief disable GPIO wake-up function. + * @brief disable GPIO wake-up function. * - * @param gpio_num_t gpio_num: GPIO number + * @param gpio_num: GPIO number * * @return ESP_OK: success * ESP_ERR_INVALID_ARG: parameter error @@ -365,13 +365,13 @@ esp_err_t gpio_wakeup_disable(gpio_num_t gpio_num); * Users should know that which CPU is running and then pick a INUM that is not used by system. * We can find the information of INUM and interrupt level in soc.h. * TODO: to move INUM options to menu_config - * @parameter uint32_t gpio_intr_num : GPIO interrupt number,check the info in soc.h, and please see the core-isa.h for more details - * @parameter void (* fn)(void* ) : interrupt handler function. + * @param gpio_intr_num : GPIO interrupt number,check the info in soc.h, and please see the core-isa.h for more details + * @param (*fn)(void* ) : interrupt handler function. * Note that the handler function MUST be defined with attribution of "IRAM_ATTR". - * @parameter void * arg : parameter for handler function + * @param arg : parameter for handler function * - * @return ESP_OK : success ; - * ESP_FAIL: gpio error + * @return ESP_OK : success ; + * ESP_FAIL: gpio error */ esp_err_t gpio_isr_register(uint32_t gpio_intr_num, void (*fn)(void*), void * arg); diff --git a/docs/api/gpio.rst b/docs/api/gpio.rst index c12c991ce4..3c5c122921 100644 --- a/docs/api/gpio.rst +++ b/docs/api/gpio.rst @@ -16,6 +16,13 @@ Reference `Instructions `_ +Enumerations +^^^^^^^^^^^^ + +.. doxygenenum:: gpio_int_type_t +.. doxygenenum:: gpio_mode_t +.. doxygenenum:: gpio_pull_mode_t + Functions ^^^^^^^^^ From 1263cd340eb492581f4f179e28eb7c6df3fec644 Mon Sep 17 00:00:00 2001 From: Krzysztof Date: Thu, 27 Oct 2016 21:20:30 +0200 Subject: [PATCH 212/343] Add missing annotations --- components/nvs_flash/include/nvs.h | 42 +++++++++++++++++------------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/components/nvs_flash/include/nvs.h b/components/nvs_flash/include/nvs.h index 912ea22103..d0c9908afb 100644 --- a/components/nvs_flash/include/nvs.h +++ b/components/nvs_flash/include/nvs.h @@ -28,23 +28,27 @@ extern "C" { */ typedef uint32_t nvs_handle; -#define ESP_ERR_NVS_BASE 0x1100 -#define ESP_ERR_NVS_NOT_INITIALIZED (ESP_ERR_NVS_BASE + 0x01) -#define ESP_ERR_NVS_NOT_FOUND (ESP_ERR_NVS_BASE + 0x02) -#define ESP_ERR_NVS_TYPE_MISMATCH (ESP_ERR_NVS_BASE + 0x03) -#define ESP_ERR_NVS_READ_ONLY (ESP_ERR_NVS_BASE + 0x04) -#define ESP_ERR_NVS_NOT_ENOUGH_SPACE (ESP_ERR_NVS_BASE + 0x05) -#define ESP_ERR_NVS_INVALID_NAME (ESP_ERR_NVS_BASE + 0x06) -#define ESP_ERR_NVS_INVALID_HANDLE (ESP_ERR_NVS_BASE + 0x07) -#define ESP_ERR_NVS_REMOVE_FAILED (ESP_ERR_NVS_BASE + 0x08) -#define ESP_ERR_NVS_KEY_TOO_LONG (ESP_ERR_NVS_BASE + 0x09) -#define ESP_ERR_NVS_PAGE_FULL (ESP_ERR_NVS_BASE + 0x0a) -#define ESP_ERR_NVS_INVALID_STATE (ESP_ERR_NVS_BASE + 0x0b) -#define ESP_ERR_NVS_INVALID_LENGTH (ESP_ERR_NVS_BASE + 0x0c) +#define ESP_ERR_NVS_BASE 0x1100 /*!< Starting number of error codes */ +#define ESP_ERR_NVS_NOT_INITIALIZED (ESP_ERR_NVS_BASE + 0x01) /*!< The storage driver is not initialized */ +#define ESP_ERR_NVS_NOT_FOUND (ESP_ERR_NVS_BASE + 0x02) /*!< Id namespace doesn’t exist yet and mode is NVS_READONLY */ +#define ESP_ERR_NVS_TYPE_MISMATCH (ESP_ERR_NVS_BASE + 0x03) /*!< TBA */ +#define ESP_ERR_NVS_READ_ONLY (ESP_ERR_NVS_BASE + 0x04) /*!< Storage handle was opened as read only */ +#define ESP_ERR_NVS_NOT_ENOUGH_SPACE (ESP_ERR_NVS_BASE + 0x05) /*!< There is not enough space in the underlying storage to save the value */ +#define ESP_ERR_NVS_INVALID_NAME (ESP_ERR_NVS_BASE + 0x06) /*!< Namespace name doesn’t satisfy constraints */ +#define ESP_ERR_NVS_INVALID_HANDLE (ESP_ERR_NVS_BASE + 0x07) /*!< Handle has been closed or is NULL */ +#define ESP_ERR_NVS_REMOVE_FAILED (ESP_ERR_NVS_BASE + 0x08) /*!< The value wasn’t updated because flash write operation has failed. The value was written however, and update will be finished after re-initialization of nvs, provided that flash operation doesn’t fail again. */ +#define ESP_ERR_NVS_KEY_TOO_LONG (ESP_ERR_NVS_BASE + 0x09) /*!< TBA */ +#define ESP_ERR_NVS_PAGE_FULL (ESP_ERR_NVS_BASE + 0x0a) /*!< TBA */ +#define ESP_ERR_NVS_INVALID_STATE (ESP_ERR_NVS_BASE + 0x0b) /*!< TBA */ +#define ESP_ERR_NVS_INVALID_LENGTH (ESP_ERR_NVS_BASE + 0x0c) /*!< TBA */ +/** + * @brief Mode of opening the non-volatile storage + * + */ typedef enum { - NVS_READONLY, - NVS_READWRITE + NVS_READONLY, /*!< Read only */ + NVS_READWRITE /*!< Read and write */ } nvs_open_mode; /** @@ -129,24 +133,26 @@ esp_err_t nvs_set_blob(nvs_handle handle, const char* key, const void* value, si * It is suggested that nvs_get/set_str is used for zero-terminated C strings, and * nvs_get/set_blob used for arbitrary data structures. * - * Example of using nvs_get_i32: + * \code{c} + * // Example of using nvs_get_i32: * int32_t max_buffer_size = 4096; // default value * esp_err_t err = nvs_get_i32(my_handle, "max_buffer_size", &max_buffer_size); * assert(err == ESP_OK || err == ESP_ERR_NVS_NOT_FOUND); * // if ESP_ERR_NVS_NOT_FOUND was returned, max_buffer_size will still * // have its default value. * - * Example (without error checking) of using nvs_get_str to get a string into dynamic array: + * // Example (without error checking) of using nvs_get_str to get a string into dynamic array: * size_t required_size; * nvs_get_str(my_handle, "server_name", NULL, &required_size); * char* server_name = malloc(required_size); * nvs_get_str(my_handle, "server_name", server_name, &required_size); * - * Example (without error checking) of using nvs_get_blob to get a binary data + * // Example (without error checking) of using nvs_get_blob to get a binary data * into a static array: * uint8_t mac_addr[6]; * size_t size = sizeof(mac_addr); * nvs_get_blob(my_handle, "dst_mac_addr", mac_addr, &size); + * \endcode * * @param[in] handle Handle obtained from nvs_open function. * @param[in] key Key name. Maximal length is determined by the underlying From 234739f51a917ae3b27c551471d906d548678b09 Mon Sep 17 00:00:00 2001 From: Krzysztof Date: Thu, 27 Oct 2016 21:22:35 +0200 Subject: [PATCH 213/343] Draft of non-volatile storage component documentation --- docs/Doxyfile | 2 +- docs/api/nvs.rst | 68 +++++++++++++++++++++++++++++++++++++++++++ docs/api/template.rst | 9 ++++++ docs/index.rst | 1 + 4 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 docs/api/nvs.rst diff --git a/docs/Doxyfile b/docs/Doxyfile index f905de74ce..bb55b8ba39 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -4,7 +4,7 @@ GENERATE_LATEX = NO GENERATE_MAN = NO GENERATE_RTF = NO CASE_SENSE_NAMES = NO -INPUT = ../components/esp32/include/esp_wifi.h ../components/driver/include/driver/gpio.h ../components/esp32/include/rom/gpio.h ../components/bt/include/bt.h +INPUT = ../components/esp32/include/esp_wifi.h ../components/driver/include/driver/gpio.h ../components/esp32/include/rom/gpio.h ../components/bt/include ../components/nvs_flash/include RECURSIVE = YES QUIET = YES JAVADOC_AUTOBRIEF = YES diff --git a/docs/api/nvs.rst b/docs/api/nvs.rst new file mode 100644 index 0000000000..227a1c1f7f --- /dev/null +++ b/docs/api/nvs.rst @@ -0,0 +1,68 @@ +.. include:: ../../components/nvs_flash/README.rst + +Reference +--------- + +Enumerations +^^^^^^^^^^^^ + +.. doxygenenum:: nvs_open_mode + +Functions +^^^^^^^^^ + +.. doxygenfunction:: nvs_flash_init +.. doxygenfunction:: nvs_flash_init_custom + +.. doxygenfunction:: nvs_open + +*Note: the following nvs_set_X function are "the same" except the data type accepted* + +.. doxygenfunction:: nvs_set_i8 +.. doxygenfunction:: nvs_set_u8 +.. doxygenfunction:: nvs_set_i16 +.. doxygenfunction:: nvs_set_u16 +.. doxygenfunction:: nvs_set_i32 +.. doxygenfunction:: nvs_set_u32 +.. doxygenfunction:: nvs_set_i64 +.. doxygenfunction:: nvs_set_u64 +.. doxygenfunction:: nvs_set_str +.. doxygenfunction:: nvs_set_blob + +*Note: the following nvs_get_X functions are "the same" except the data type returned* + +.. doxygenfunction:: nvs_get_i8 +.. doxygenfunction:: nvs_get_u8 +.. doxygenfunction:: nvs_get_i16 +.. doxygenfunction:: nvs_get_u16 +.. doxygenfunction:: nvs_get_i32 +.. doxygenfunction:: nvs_get_u32 +.. doxygenfunction:: nvs_get_i64 +.. doxygenfunction:: nvs_get_u64 +.. doxygenfunction:: nvs_get_str +.. doxygenfunction:: nvs_get_blob + +.. doxygenfunction:: nvs_erase_key +.. doxygenfunction:: nvs_erase_all +.. doxygenfunction:: nvs_commit +.. doxygenfunction:: nvs_close + +Error codes +^^^^^^^^^^^ + +.. doxygendefine:: ESP_ERR_NVS_BASE +.. doxygendefine:: ESP_ERR_NVS_NOT_INITIALIZED +.. doxygendefine:: ESP_ERR_NVS_NOT_FOUND +.. doxygendefine:: ESP_ERR_NVS_TYPE_MISMATCH +.. doxygendefine:: ESP_ERR_NVS_READ_ONLY +.. doxygendefine:: ESP_ERR_NVS_NOT_ENOUGH_SPACE +.. doxygendefine:: ESP_ERR_NVS_INVALID_NAME +.. doxygendefine:: ESP_ERR_NVS_INVALID_HANDLE +.. doxygendefine:: ESP_ERR_NVS_REMOVE_FAILED +.. doxygendefine:: ESP_ERR_NVS_KEY_TOO_LONG +.. doxygendefine:: ESP_ERR_NVS_PAGE_FULL +.. doxygendefine:: ESP_ERR_NVS_INVALID_STATE +.. doxygendefine:: ESP_ERR_NVS_INVALID_LENGTH + + + diff --git a/docs/api/template.rst b/docs/api/template.rst index 8b1dfd4c50..0f2623c47f 100644 --- a/docs/api/template.rst +++ b/docs/api/template.rst @@ -6,6 +6,15 @@ Overview INSTRUCTIONS: Provide overview where and how this API may be used. For large number of functions, break down description into groups. +Use the folowing heading levels: + +* # with overline, for parts +* \* with overline, for chapters +* =, for sections +* -, for subsections +* ^, for subsubsections +* ", for paragraphs + Application Example ------------------- diff --git a/docs/index.rst b/docs/index.rst index 5c4d7025c6..9b62885bb1 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -37,6 +37,7 @@ Contents: Wi-Fi Bluetooth GPIO + NVS Template .. toctree:: From fa002b490966ba3e4112a0d6f459ced22c7aa0ca Mon Sep 17 00:00:00 2001 From: Krzysztof Date: Fri, 28 Oct 2016 14:43:48 +0200 Subject: [PATCH 214/343] Fixed headers to match python doc standard --- components/nvs_flash/README.rst | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/components/nvs_flash/README.rst b/components/nvs_flash/README.rst index 2f1c469135..ade5518aa5 100644 --- a/components/nvs_flash/README.rst +++ b/components/nvs_flash/README.rst @@ -7,14 +7,14 @@ Introduction Non-volatile storage (NVS) library is designed to store key-value pairs in flash. This sections introduces some concepts used by NVS. Underlying storage -~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^ Currently NVS uses a portion of main flash memory through ``spi_flash_{read|write|erase}`` APIs. The range of flash sectors to be used by the library is provided to ``nvs_flash_init`` function. Future versions of this library may add other storage backends to keep data in another flash chip (SPI or I2C), RTC, FRAM, etc. Keys and values -~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^ NVS operates on key-value pairs. Keys are ASCII strings, maximum key length is currently 15 characters. Values can have one of the following types: @@ -32,12 +32,12 @@ Keys are required to be unique. Writing a value for a key which already exists b Data type check is also performed when reading a value. An error is returned if data type of read operation doesn’t match the data type of the value. Namespaces -~~~~~~~~~~ +^^^^^^^^^^ To mitigate potential conflicts in key names between different components, NVS assigns each key-value pair to one of namespaces. Namespace names follow the same rules as key names, i.e. 15 character maximum length. Namespace name is specified in the ``nvs_open`` call. This call returns an opaque handle, which is used in subsequent calls to ``nvs_read_*``, ``nvs_write_*``, and ``nvs_commit`` functions. This way, handle is associated with a namespace, and key names will not collide with same names in other namespaces. Security, tampering, and robustness -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ NVS library doesn't implement tamper prevention measures. It is possible for anyone with physical access to the flash chip to alter, erase, or add key-value pairs. @@ -59,12 +59,12 @@ Internals --------- Log of key-value pairs -~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^ NVS stores key-value pairs sequentially, with new key-value pairs being added at the end. When a value of any given key has to be updated, new key-value pair is added at the end of the log and old key-value pair is marked as erased. Pages and entries -~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^ NVS library uses two main entities in its operation: pages and entries. Page is a logical structure which stores a portion of the overall log. Logical page corresponds to one physical sector of flash memory. Pages which are in use have a *sequence number* associated with them. Sequence numbers impose an ordering on pages. Higher sequence numbers correspond to pages which were created later. Each page can be in one of the following states: @@ -101,7 +101,7 @@ Mapping from flash sectors to logical pages doesn't have any particular order. L +----------+ +----------+ +----------+ +----------+ Structure of a page -~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^ For now we assume that flash sector size is 4096 bytes and that ESP32 flash encryption hardware operates on 32-byte blocks. It is possible to introduce some settings configurable at compile-time (e.g. via menuconfig) to accommodate flash chips with different sector sizes (although it is not clear if other components in the system, e.g. SPI flash driver and SPI flash cache can support these other sizes). @@ -133,7 +133,7 @@ CRC32 value in header is calculated over the part which doesn't include state va The following sections describe structure of entry state bitmap and entry itself. Entry and entry state bitmap -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Each entry can be in one of the following three states. Each state is represented with two bits in the entry state bitmap. Final four bits in the bitmap (256 - 2 * 126) are unused. @@ -148,7 +148,7 @@ Erased (2'b00) Structure of entry -~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^ For values of primitive types (currently integers from 1 to 8 bytes long), entry holds one key-value pair. For string and blob types, entry holds part of the whole key-value pair. In case when a key-value pair spans multiple entries, all entries are stored in the same page. @@ -200,7 +200,7 @@ Variable length values (strings and blobs) are written into subsequent entries, Namespaces -~~~~~~~~~~ +^^^^^^^^^^ As mentioned above, each key-value pair belongs to one of the namespaces. Namespaces identifiers (strings) are stored as keys of key-value pairs in namespace with index 0. Values corresponding to these keys are indexes of these namespaces. @@ -218,10 +218,9 @@ As mentioned above, each key-value pair belongs to one of the namespaces. Namesp Item hash list -~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^ To reduce the number of reads performed from flash memory, each member of Page class maintains a list of pairs: (item index; item hash). This list makes searches much quicker. Instead of iterating over all entries, reading them from flash one at a time, ``Page::findItem`` first performs search for item hash in the hash list. This gives the item index within the page, if such an item exists. Due to a hash collision it is possible that a different item will be found. This is handled by falling back to iteration over items in flash. Each node in hash list contains a 24-bit hash and 8-bit item index. Hash is calculated based on item namespace and key name. CRC32 is used for calculation, result is truncated to 24 bits. To reduce overhead of storing 32-bit entries in a linked list, list is implemented as a doubly-linked list of arrays. Each array holds 29 entries, for the total size of 128 bytes, together with linked list pointers and 32-bit count field. Minimal amount of extra RAM useage per page is therefore 128 bytes, maximum is 640 bytes. - From 2d56953ee458266e00bba2788ec6821823eddd8d Mon Sep 17 00:00:00 2001 From: Krzysztof Date: Sat, 29 Oct 2016 20:54:58 +0200 Subject: [PATCH 215/343] docu makup update --- components/bt/include/bt.h | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/components/bt/include/bt.h b/components/bt/include/bt.h index 1e89f96aa1..f476334b12 100644 --- a/components/bt/include/bt.h +++ b/components/bt/include/bt.h @@ -28,37 +28,36 @@ extern "C" { * * This function should be called only once, before any other BT functions are called. */ -void bt_controller_init(); +void bt_controller_init(void); -/** @brief: vhci_host_callback +/** @brief vhci_host_callback * used for vhci call host function to notify what host need to do * * notify_host_send_available: notify host can send packet to controller * notify_host_recv: notify host that controller has packet send to host */ typedef struct vhci_host_callback { - void (*notify_host_send_available)(void); int (*notify_host_recv)(uint8_t *data, uint16_t len); } vhci_host_callback_t; -/** @brief: API_vhci_host_check_send_available +/** @brief API_vhci_host_check_send_available * used for check actively if the host can send packet to controller or not. - * return true for ready to send, false means cannot send packet + * @return true for ready to send, false means cannot send packet */ bool API_vhci_host_check_send_available(void); -/** @brief: API_vhci_host_send_packet +/** @brief API_vhci_host_send_packet * host send packet to controller - * param data is the packet point, the param len is the packet length - * return void + * @param data the packet point + *,@param len the packet length */ void API_vhci_host_send_packet(uint8_t *data, uint16_t len); -/** @brief: API_vhci_host_register_callback +/** @brief API_vhci_host_register_callback * register the vhci referece callback, the call back * struct defined by vhci_host_callback structure. - * param is the vhci_host_callback type variable + * @param callback vhci_host_callback type variable */ void API_vhci_host_register_callback(const vhci_host_callback_t *callback); From 905d27815c4889be2250e408e9194fd3ae70d058 Mon Sep 17 00:00:00 2001 From: Krzysztof Date: Sat, 29 Oct 2016 23:00:30 +0200 Subject: [PATCH 216/343] API samples - Logging library - Virtual file system component --- docs/Doxyfile | 31 ++++++++++++++++++++----------- docs/api/bt.rst | 2 +- docs/api/log.rst | 20 ++++++++++++++++++++ docs/api/nvs.rst | 4 ++-- docs/api/vfs.rst | 27 +++++++++++++++++++++++++++ docs/index.rst | 4 +++- 6 files changed, 73 insertions(+), 15 deletions(-) create mode 100644 docs/api/log.rst create mode 100644 docs/api/vfs.rst diff --git a/docs/Doxyfile b/docs/Doxyfile index bb55b8ba39..9c53aff1f3 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -1,13 +1,22 @@ PROJECT_NAME = "ESP32 Programming Guide" -XML_OUTPUT = xml -GENERATE_LATEX = NO -GENERATE_MAN = NO -GENERATE_RTF = NO -CASE_SENSE_NAMES = NO -INPUT = ../components/esp32/include/esp_wifi.h ../components/driver/include/driver/gpio.h ../components/esp32/include/rom/gpio.h ../components/bt/include ../components/nvs_flash/include -RECURSIVE = YES + +INPUT = ../components/esp32/include/esp_wifi.h ../components/driver/include/driver ../components/esp32/include/rom/gpio.h ../components/bt/include ../components/nvs_flash/include ../components/log/include ../components/vfs/include + +WARN_NO_PARAMDOC = YES + +RECURSIVE = NO +CASE_SENSE_NAMES = NO +EXTRACT_ALL = NO + +GENERATE_XML = YES +XML_OUTPUT = xml + +GENERATE_HTML = NO +HAVE_DOT = NO +GENERATE_LATEX = NO +GENERATE_MAN = NO +GENERATE_RTF = NO + QUIET = YES -JAVADOC_AUTOBRIEF = YES -GENERATE_HTML = NO -GENERATE_XML = YES -WARN_LOGFILE = "DoxyGenWarningLog.txt" +WARN_LOGFILE = "doxygen-warning-log.txt" + diff --git a/docs/api/bt.rst b/docs/api/bt.rst index 16f30dc4e6..72ab9fbd12 100644 --- a/docs/api/bt.rst +++ b/docs/api/bt.rst @@ -19,7 +19,7 @@ Reference Type Definitions ^^^^^^^^^^^^^^^^ -.. doxygentypedef:: vhci_host_callback +.. doxygenstruct:: vhci_host_callback Functions ^^^^^^^^^ diff --git a/docs/api/log.rst b/docs/api/log.rst new file mode 100644 index 0000000000..8e0f2d85da --- /dev/null +++ b/docs/api/log.rst @@ -0,0 +1,20 @@ +.. include:: ../../components/log/README.rst + +API Reference +------------- + +Enumerations +^^^^^^^^^^^^ + +.. doxygenenum:: esp_log_level_t + +Functions +^^^^^^^^^ + +.. doxygenfunction:: esp_log_level_set +.. doxygenfunction:: esp_log_set_vprintf +.. doxygenfunction:: esp_log_write + +.. FIXME esp_log_timestamp + + diff --git a/docs/api/nvs.rst b/docs/api/nvs.rst index 227a1c1f7f..fc2bba5a16 100644 --- a/docs/api/nvs.rst +++ b/docs/api/nvs.rst @@ -1,7 +1,7 @@ .. include:: ../../components/nvs_flash/README.rst -Reference ---------- +API Reference +------------- Enumerations ^^^^^^^^^^^^ diff --git a/docs/api/vfs.rst b/docs/api/vfs.rst new file mode 100644 index 0000000000..97ea1a5848 --- /dev/null +++ b/docs/api/vfs.rst @@ -0,0 +1,27 @@ +.. include:: ../../components/vfs/README.rst + +API Reference +------------- + +Defines +^^^^^^^ + +.. doxygendefine:: ESP_VFS_PATH_MAX +.. doxygendefine:: ESP_VFS_FLAG_DEFAULT +.. doxygendefine:: ESP_VFS_FLAG_CONTEXT_PTR + + +Structures +^^^^^^^^^^ + +.. doxygenstruct:: esp_vfs_t + +Functions +^^^^^^^^^ + +.. doxygenfunction:: esp_vfs_dev_uart_register +.. doxygenfunction:: esp_vfs_register + + + + diff --git a/docs/index.rst b/docs/index.rst index 9b62885bb1..72c5df13f4 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -37,7 +37,9 @@ Contents: Wi-Fi Bluetooth GPIO - NVS + Logging + Non-volatile storage + Virtual filesystem Template .. toctree:: From f6118c67b09f479297a959ce6b0714d717e2ebbc Mon Sep 17 00:00:00 2001 From: Krzysztof Date: Sat, 29 Oct 2016 23:00:46 +0200 Subject: [PATCH 217/343] Fixed desription of logging library --- components/log/README.rst | 61 +++++++++++++++++++++++++ components/log/include/esp_log.h | 76 ++++---------------------------- 2 files changed, 69 insertions(+), 68 deletions(-) create mode 100644 components/log/README.rst diff --git a/components/log/README.rst b/components/log/README.rst new file mode 100644 index 0000000000..d378179c8f --- /dev/null +++ b/components/log/README.rst @@ -0,0 +1,61 @@ +Logging library +=============== + +Overview +-------- + +Log library has two ways of managing log verbosity: compile time, set via menuconfig; and runtime, using ``esp_log_set_level`` function. + +At compile time, filtering is done using ``CONFIG_LOG_DEFAULT_LEVEL`` macro, set via menuconfig. All logging statments for levels higher than ``CONFIG_LOG_DEFAULT_LEVEL`` will be removed by the preprocessor. + +At run time, all logs below ``CONFIG_LOG_DEFAULT_LEVEL`` are enabled by default. ``esp_log_set_level`` function may be used to set logging level per module. Modules are identified by their tags, which are human-readable ASCII zero-terminated strings. + +How to use this library +----------------------- + +In each C file which uses logging functionality, define TAG variable like this: + +.. code-block:: c + + static const char* TAG = "MyModule"; + +then use one of logging macros to produce output, e.g: + +.. code-block:: c + + ESP_LOGW(TAG, "Baud rate error %.1f%%. Requested: %d baud, actual: %d baud", error * 100, baud_req, baud_real); + +Several macros are available for different verbosity levels: + +* ``ESP_LOGE`` - error +* ``ESP_LOGW`` - warning +* ``ESP_LOGI`` - info +* ``ESP_LOGD`` - debug +* ``ESP_LOGV`` - verbose + +Additionally there is an _EARLY_ variant for each of these macros (e.g. ``ESP_EARLY_LOGE`` ).These variants can run in startup code, before heap allocator and syscalls have been initialized. When compiling bootloader, normal ``ESP_LOGx`` macros fall back to the same implementation as ``ESP_EARLY_LOGx`` macros. So the only place where ``ESP_EARLY_LOGx`` have to be used explicitly is the early startup code, such as heap allocator initialization code. + +(Note that such distinction would not have been necessary if we would have an ``ets_vprintf`` function in the ROM. Then it would be possible to switch implementation from _EARLY_ version to normal version on the fly. Unfortunately, ``ets_vprintf`` in ROM has been inlined by the compiler into ``ets_printf``, so it is not accessible outside.) + +To override default verbosity level at file or component scope, define ``LOG_LOCAL_LEVEL`` macro. At file scope, define it before including ``esp_log.h``, e.g.: + +.. code-block:: c + + #define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE + #include "esp_log.h" + + +At component scope, define it in component makefile: + +.. code-block:: make + + CFLAGS += -D LOG_LOCAL_LEVEL=ESP_LOG_DEBUG + +To configure logging output per module at runtime, add calls to ``esp_log_set_level`` function: + +.. code-block:: c + + esp_log_set_level("*", ESP_LOG_ERROR); // set all components to ERROR level + esp_log_set_level("wifi", ESP_LOG_WARN); // enable WARN logs from WiFi stack + esp_log_set_level("dhcpc", ESP_LOG_INFO); // enable INFO logs from DHCP client + diff --git a/components/log/include/esp_log.h b/components/log/include/esp_log.h index 8ca6e241d4..2878dc5015 100644 --- a/components/log/include/esp_log.h +++ b/components/log/include/esp_log.h @@ -24,76 +24,16 @@ extern "C" { #endif /** - * @brief Logging library - * - * Log library has two ways of managing log verbosity: compile time, set via - * menuconfig, and runtime, using esp_log_set_level function. - * - * At compile time, filtering is done using CONFIG_LOG_DEFAULT_LEVEL macro, set via - * menuconfig. All logging statments for levels higher than CONFIG_LOG_DEFAULT_LEVEL - * will be removed by the preprocessor. - * - * At run time, all logs below CONFIG_LOG_DEFAULT_LEVEL are enabled by default. - * esp_log_set_level function may be used to set logging level per module. - * Modules are identified by their tags, which are human-readable ASCII - * zero-terminated strings. - * - * How to use this library: - * - * In each C file which uses logging functionality, define TAG variable like this: - * - * static const char* TAG = "MyModule"; - * - * then use one of logging macros to produce output, e.g: - * - * ESP_LOGW(TAG, "Baud rate error %.1f%%. Requested: %d baud, actual: %d baud", error * 100, baud_req, baud_real); - * - * Several macros are available for different verbosity levels: - * - * ESP_LOGE — error - * ESP_LOGW — warning - * ESP_LOGI — info - * ESP_LOGD - debug - * ESP_LOGV - verbose - * - * Additionally there is an _EARLY_ variant for each of these macros (e.g. ESP_EARLY_LOGE). - * These variants can run in startup code, before heap allocator and syscalls - * have been initialized. - * When compiling bootloader, normal ESP_LOGx macros fall back to the same implementation - * as ESP_EARLY_LOGx macros. So the only place where ESP_EARLY_LOGx have to be used explicitly - * is the early startup code, such as heap allocator initialization code. - * - * (Note that such distinction would not have been necessary if we would have an - * ets_vprintf function in the ROM. Then it would be possible to switch implementation - * from _EARLY version to normal version on the fly. Unfortunately, ets_vprintf in ROM - * has been inlined by the compiler into ets_printf, so it is not accessible outside.) - * - * To override default verbosity level at file or component scope, define LOG_LOCAL_LEVEL macro. - * At file scope, define it before including esp_log.h, e.g.: - * - * #define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE - * #include "esp_log.h" - * - * At component scope, define it in component makefile: - * - * CFLAGS += -D LOG_LOCAL_LEVEL=ESP_LOG_DEBUG - * - * To configure logging output per module at runtime, add calls to esp_log_set_level function: - * - * esp_log_set_level("*", ESP_LOG_ERROR); // set all components to ERROR level - * esp_log_set_level("wifi", ESP_LOG_WARN); // enable WARN logs from WiFi stack - * esp_log_set_level("dhcpc", ESP_LOG_INFO); // enable INFO logs from DHCP client + * @brief Log level * */ - - typedef enum { - ESP_LOG_NONE, // No log output - ESP_LOG_ERROR, // Critical errors, software module can not recover on its own - ESP_LOG_WARN, // Error conditions from which recovery measures have been taken - ESP_LOG_INFO, // Information messages which describe normal flow of events - ESP_LOG_DEBUG, // Extra information which is not necessary for normal use (values, pointers, sizes, etc). - ESP_LOG_VERBOSE // Bigger chunks of debugging information, or frequent messages which can potentially flood the output. + ESP_LOG_NONE, /*!< No log output */ + ESP_LOG_ERROR, /*!< Critical errors, software module can not recover on its own */ + ESP_LOG_WARN, /*!< Error conditions from which recovery measures have been taken */ + ESP_LOG_INFO, /*!< Information messages which describe normal flow of events */ + ESP_LOG_DEBUG, /*!< Extra information which is not necessary for normal use (values, pointers, sizes, etc). */ + ESP_LOG_VERBOSE /*!< Bigger chunks of debugging information, or frequent messages which can potentially flood the output. */ } esp_log_level_t; typedef int (*vprintf_like_t)(const char *, va_list); @@ -143,7 +83,7 @@ void esp_log_write(esp_log_level_t level, const char* tag, const char* format, . * * @return timestamp, in milliseconds */ -uint32_t esp_log_timestamp(); +uint32_t esp_log_timestamp(void); #if CONFIG_LOG_COLORS From 079f5faad88353ec64d44bbe08d612e514fc0819 Mon Sep 17 00:00:00 2001 From: Krzysztof Date: Sat, 29 Oct 2016 23:15:27 +0200 Subject: [PATCH 218/343] Fixed confused Sphinx Sphinx failed to phrase esp_log_timestamp reorderdering esp_log_write and esp_log_timestamp fixed this issue --- components/log/include/esp_log.h | 23 +++++++++++------------ docs/api/log.rst | 3 +-- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/components/log/include/esp_log.h b/components/log/include/esp_log.h index 2878dc5015..6716f6e10f 100644 --- a/components/log/include/esp_log.h +++ b/components/log/include/esp_log.h @@ -29,7 +29,7 @@ extern "C" { */ typedef enum { ESP_LOG_NONE, /*!< No log output */ - ESP_LOG_ERROR, /*!< Critical errors, software module can not recover on its own */ + ESP_LOG_ERROR, /*!< Critical errors, software module can not recover on its own */ ESP_LOG_WARN, /*!< Error conditions from which recovery measures have been taken */ ESP_LOG_INFO, /*!< Information messages which describe normal flow of events */ ESP_LOG_DEBUG, /*!< Extra information which is not necessary for normal use (values, pointers, sizes, etc). */ @@ -60,17 +60,6 @@ void esp_log_level_set(const char* tag, esp_log_level_t level); */ void esp_log_set_vprintf(vprintf_like_t func); -/** - * @brief Write message into the log - * - * This function is not intended to be used directly. Instead, use one of - * ESP_LOGE, ESP_LOGW, ESP_LOGI, ESP_LOGD, ESP_LOGV macros. - * - * This function or these macros should not be used from an interrupt. - */ -void esp_log_write(esp_log_level_t level, const char* tag, const char* format, ...) __attribute__ ((format (printf, 3, 4))); - - /** * @brief Function which returns timestamp to be used in log output * @@ -85,6 +74,16 @@ void esp_log_write(esp_log_level_t level, const char* tag, const char* format, . */ uint32_t esp_log_timestamp(void); +/** + * @brief Write message into the log + * + * This function is not intended to be used directly. Instead, use one of + * ESP_LOGE, ESP_LOGW, ESP_LOGI, ESP_LOGD, ESP_LOGV macros. + * + * This function or these macros should not be used from an interrupt. + */ +void esp_log_write(esp_log_level_t level, const char* tag, const char* format, ...) __attribute__ ((format (printf, 3, 4))); + #if CONFIG_LOG_COLORS #define LOG_COLOR_BLACK "30" diff --git a/docs/api/log.rst b/docs/api/log.rst index 8e0f2d85da..dc76a30470 100644 --- a/docs/api/log.rst +++ b/docs/api/log.rst @@ -13,8 +13,7 @@ Functions .. doxygenfunction:: esp_log_level_set .. doxygenfunction:: esp_log_set_vprintf +.. doxygenfunction:: esp_log_timestamp .. doxygenfunction:: esp_log_write -.. FIXME esp_log_timestamp - From 19af5b7a764ae33a29001cb392f5a20ce4400432 Mon Sep 17 00:00:00 2001 From: Krzysztof Date: Sat, 29 Oct 2016 23:35:12 +0200 Subject: [PATCH 219/343] Changed title of docs --- docs/conf.py | 4 ++-- docs/index.rst | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 5ba76d7f25..8a8821fb0d 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -57,8 +57,8 @@ source_suffix = '.rst' master_doc = 'index' # General information about the project. -project = u'Read the Docs Template' -copyright = u'2014, Read the Docs' +project = u'ESP32 Programming Guide' +copyright = u'2016, Espressif' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the diff --git a/docs/index.rst b/docs/index.rst index 72c5df13f4..e194992089 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,6 +1,10 @@ ESP32 Programming Guide ======================= +.. caution:: + + This is DRAFT - mind your step + Contents: .. toctree:: From 12efd96fb489ea3e697c32f24406aff2f96d7ff0 Mon Sep 17 00:00:00 2001 From: Krzysztof Date: Sun, 30 Oct 2016 19:37:45 +0100 Subject: [PATCH 220/343] Corrected documentation style This is for better visuaization with Sphinx --- components/nvs_flash/include/nvs.h | 23 +++++++++++++++-------- components/nvs_flash/include/nvs_flash.h | 2 ++ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/components/nvs_flash/include/nvs.h b/components/nvs_flash/include/nvs.h index d0c9908afb..8418959793 100644 --- a/components/nvs_flash/include/nvs.h +++ b/components/nvs_flash/include/nvs.h @@ -62,12 +62,13 @@ typedef enum { * underlying implementation, but is guaranteed to be * at least 16 characters. Shouldn't be empty. * @param[in] open_mode NVS_READWRITE or NVS_READONLY. If NVS_READONLY, will - * open a handle for reading only. All write requests will - * be rejected for this handle. + * open a handle for reading only. All write requests will + * be rejected for this handle. * @param[out] out_handle If successful (return code is zero), handle will be * returned in this argument. * - * @return - ESP_OK if storage handle was opened successfully + * @return + * - ESP_OK if storage handle was opened successfully * - ESP_ERR_NVS_NOT_INITIALIZED if the storage driver is not initialized * - ESP_ERR_NVS_NOT_FOUND id namespace doesn't exist yet and * mode is NVS_READONLY @@ -90,7 +91,8 @@ esp_err_t nvs_open(const char* name, nvs_open_mode open_mode, nvs_handle *out_ha * @param[in] value The value to set. * @param[in] length For nvs_set_blob: length of binary value to set, in bytes. * - * @return - ESP_OK if value was set successfully + * @return + * - ESP_OK if value was set successfully * - ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is NULL * - ESP_ERR_NVS_READ_ONLY if storage handle was opened as read only * - ESP_ERR_NVS_INVALID_NAME if key name doesn't satisfy constraints @@ -168,7 +170,8 @@ esp_err_t nvs_set_blob(nvs_handle handle, const char* key, const void* value, si * zero, will be set to the actual length of the value * written. For nvs_get_str this includes zero terminator. * - * @return - ESP_OK if the value was retrieved successfully + * @return + * - ESP_OK if the value was retrieved successfully * - ESP_ERR_NVS_NOT_FOUND if the requested key doesn't exist * - ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is NULL * - ESP_ERR_NVS_INVALID_NAME if key name doesn't satisfy constraints @@ -197,7 +200,8 @@ esp_err_t nvs_get_blob(nvs_handle handle, const char* key, void* out_value, size * implementation, but is guaranteed to be at least * 16 characters. Shouldn't be empty. * - * @return - ESP_OK if erase operation was successful + * @return + * - ESP_OK if erase operation was successful * - ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is NULL * - ESP_ERR_NVS_READ_ONLY if handle was opened as read only * - ESP_ERR_NVS_NOT_FOUND if the requested key doesn't exist @@ -213,7 +217,8 @@ esp_err_t nvs_erase_key(nvs_handle handle, const char* key); * @param[in] handle Storage handle obtained with nvs_open. * Handles that were opened read only cannot be used. * - * @return - ESP_OK if erase operation was successful + * @return + * - ESP_OK if erase operation was successful * - ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is NULL * - ESP_ERR_NVS_READ_ONLY if handle was opened as read only * - other error codes from the underlying storage driver @@ -230,7 +235,8 @@ esp_err_t nvs_erase_all(nvs_handle handle); * @param[in] handle Storage handle obtained with nvs_open. * Handles that were opened read only cannot be used. * - * @return - ESP_OK if the changes have been written successfully + * @return + * - ESP_OK if the changes have been written successfully * - ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is NULL * - other error codes from the underlying storage driver */ @@ -255,3 +261,4 @@ void nvs_close(nvs_handle handle); #endif #endif //ESP_NVS_H + diff --git a/components/nvs_flash/include/nvs_flash.h b/components/nvs_flash/include/nvs_flash.h index ce98f39407..1cade0e956 100644 --- a/components/nvs_flash/include/nvs_flash.h +++ b/components/nvs_flash/include/nvs_flash.h @@ -22,6 +22,8 @@ extern "C" { Temporarily, this region is hardcoded as a 12KB (0x3000 byte) region starting at 24KB (0x6000 byte) offset in flash. + + @return ESP_OK if flash was successfully initialised. */ esp_err_t nvs_flash_init(void); From d66f05c61b561c04d46cbe2aeb1cdb54fd0c2fb9 Mon Sep 17 00:00:00 2001 From: Krzysztof Date: Sun, 30 Oct 2016 19:38:44 +0100 Subject: [PATCH 221/343] Guide on documenting code --- docs/_static/1.png | Bin 11412 -> 0 bytes .../_static/doc-code-documentation-inline.png | Bin 0 -> 52513 bytes .../doc-code-documentation-rendered.png | Bin 0 -> 93186 bytes docs/_static/doc-code-function.png | Bin 0 -> 194398 bytes docs/_static/doc-code-member.png | Bin 0 -> 75946 bytes docs/_static/doc-code-void-function.png | Bin 0 -> 68465 bytes docs/documenting-code.rst | 126 ++++++++++++++++++ docs/index.rst | 7 +- 8 files changed, 132 insertions(+), 1 deletion(-) delete mode 100644 docs/_static/1.png create mode 100644 docs/_static/doc-code-documentation-inline.png create mode 100644 docs/_static/doc-code-documentation-rendered.png create mode 100644 docs/_static/doc-code-function.png create mode 100644 docs/_static/doc-code-member.png create mode 100644 docs/_static/doc-code-void-function.png create mode 100644 docs/documenting-code.rst diff --git a/docs/_static/1.png b/docs/_static/1.png deleted file mode 100644 index 4920892781f90c3db323f82033866c3f7116c073..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11412 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%0DWzu{GG6s#(R>PU8MZ5tw{ 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 literal 0 HcmV?d00001 diff --git a/docs/_static/doc-code-function.png b/docs/_static/doc-code-function.png new file mode 100644 index 0000000000000000000000000000000000000000..758971ce7271bb175d27d063643f21c03e00b8df GIT binary patch literal 194398 zcmcG$by$>L+cl1X(m9lrij;In!zc)dbVx{vw9?%p(k-Bb#0Ur&NOz5NGaxt8F+)oX z!w>@uGrtS(_j%s$IDX&1AICvVTzht$*SXiZ*4o7B>8MkZ-6A6*BBIoI^4Nfg=qdsD z4kft(JX09Kjs|{RcYLJ%h=`~vg&b!?3_K?Fcw**FM8rgU`F&-O2LlG4Wbsio^)YmJ z@bS0tvM17Zw)JxN1|Hqkb#QRDwTJ9J@FXH4BxyW;WE5bvlSll*av-oiM{1hKnN=sk z^_Skn!-->5Jwi~Wx^>&$LA+*4tGegKI~TKhX4e7nr`7#09UL6i&+(X1MRmD$Ml*rA zYDM^Zce8iE=udfxr4WpX9v_G-O1S{|)o}eOPT;=}Nd8|uc)7^J!LD*L7CZY-{fm0x zD$2yfSNui=jlTLw>&q@+2K%!}zZYTl)ltm20bXO*SLQTxoR5P-loS}acNL#Mea7de z{T^!q^tq??7g+p$q_N;0d1GuaZe_Bhp14X(aZv!D^u^`3!8c{k*M;4%%Ym&k#1p`0 z-AJoD^%gbv-|0=2NYz(@edHlHp( zzeAml;5eAGzwtAnaYBU3|Lbna(%xZGPdaZ}>eOs;F%i(Y#@w7oxYFWc#0n=t#tL%b zE7VO9CDhQ~t|YWNd$1fqE$oCw?d}Re;WIO4_KC(#kSRe&!1Op;4n6M zzn!1QyK}T09Lc|b8@rrf8+3(+ju;=GPFoFB`mseII+JaB+%E{e| zh=>rMPfJUq%T)-ZGjDKH!uCkF4Xm)nCwrKdD zsj05PL9&aB3%>jJ)BLdY_4Sz#*y0lsXc-x!UFYftPL^A5Xks}+;GyToHXEaP9-f}5 zu)f~jTCQO&9(>?%wuIwqjg^Qu|Fal=5IryvSq%R(mV#Ia*#bQ5xW*vS>tN4O3Bz)F zQmS;s@8jd+q^><`gd}{ozPR6xTN8N=8^+;JV12NQIhcmc@cBN+ywY)1ibj>&Ku5$) z^nh-d!5(3Ds$B}Nwf+0YL~_3E4i{s;CgIFazcIA2hDzF&*zh{U<5Bk7( zeXI1jj}KmpDkvn*&OQ%81uv!B^yVLyl?k%=ZRGjCy7SQAUpnk`$a=7sRQ-C13hH#D zKIGJkza$V}l%jOM%PIt|y8Gk>0e>OBLl4DX4?AgDx+5Z@8zlB?g-cP?(zBSx5vkRGu{^$D2O$Ac5YKF zZ9lY%8Xwo6_norzlI--NykZ&aK2xnqp3P>7J3l*nb;n_v1Uu^A&J}#-i{Z4yE&0v4 zW*#+S%w%4oPk=uDk{l!%2@K#EiSyw}&`dVkZ~XS{zL1?V4znnkid=%7j<~O0l=FV0 zGUVeieTRf9@+{%jrD;K+&ry6l5h_18L-wzP9euYR8H|1)DG6G_A2+0a{P-hU=YDbo>hSI<)j*c5~Q8r+0*Jf!GHGdG4G z@7n_TxUqSBVCX6W!&NKz-7ldhBru6&oa;c9gdp2U=-YX^=_8h^L@I3jL=4Ls5BN#f#-GT`XUy>X_MB2mEg-fC{kx}-r$*hz$3#c(11Z{cww85w zvZcBCGZBmf3EdNy^~|uBTJRVpw#1n?AKh!M_gwM;o(DtDCZK~FE!x`J&o@_PMn(VyIuMTX6opvpp7iz~nLW^A^`{-W+-x)m3;X zJKSk2j)oUJWgN`i0o{qLA5Z8^jP>q7jOBA+P=`Km+Ot=XUp|l6WQewYAz6N0{*LB0 zS43~xtWL*%8R`!Slqd^8^vRA1Y%czi?i8H;#6Sl7xi0VJr73 zZelKSFIeu*okzz!TMU0UPUNd4-M4q6#p*J4Q;M&1%|!ZhG3O)8B^x@ zBy?e?c%}xdEhZ;7mrV#%O=W|EEN=pPkkjAaK8g_Ql5b1qy`r+*yY4?o2swwN3 zas$FSj9?zE%Z(>hr`?o|wV9cj5#I^=^fxTFh4HdBAC#iaL_N++A!od~V2Bmol^-uF zsS&JESC;8_{HUL zGrQ?|v$xtLFHu+g_W@O8J1?Ti+?( zAVJ^k4+hPd|!;aZ4c+^Xa-GvaHg|wZ^xfS|@Yn1mo%H!;3XXrYh^D ztka9G%u7=Wy3Bak*v250baJ~$pM`J+S&t#!9f^dY$@$l3Uc@FQzDIp$n$18$lWs=W zq~?q#_X;h^haCT! z$ONm8nEZIoE$=sdjc_=jYc1t9JidC4f)UbG+XN93zuNdL-&N-?*X%bP@61RnVstl? zVy6ldjFM$AY`?V|7X0S8kEqp4WzT+2CipVLEiAJ(Si35?|0e!MHzZUTE^|1@LBTkt zcG&aO2VF5o=@t1#xL**l&zmyE%d1V=0}eh_<-Yy&fso$Mw+RRcu88sW6AiJ1(*d6Q zRlKq1iEaGNBQTovnkeE@`?an+&h6ynPuUlCXH}>bKSyObySZhc9YF+&l`6rXLgTEA z|A{wRf}CXVYDs28nSeu?$aRI@>co7(L|AF_qFvv%2NdsOnCBk1)+V?#((ePej|G$o`ELX&`lIAKOikzp=M@h~bDgvc%P#gbQ#RY*zPm)0HFp zSDfX+LP2oCV%zgKSC01yho!UB9mt+_TV8Y5)UN9JKH4jJvat|N8MddvVeLb|f0)3I!!HUMZ5J7v0z&rzaLQNCL#_?nH~*bQ|dj;!Fla0As_CRrWavHcEctPAGV&|9k;4$vPjN|9IvL z0>ip{nuN55F58o`YG=@g$%2M#d0Fr1FNOh?N8Q6XNRP70-}G(xWo`zo-wie~`;6VV z&ZP<9r`-N-QvGz#)qdK*)|8YKMsZ@3yLiaa_pd#W8a|muc;gv@As#}Nr*zQIbR%Ccz%k_oKkF^*H-Pm4o-=1;${u&@{OvZz76 z`nSsYH)HbPWd}0LJDo;tEp|SamATB1WC`PEG<9@IBojQnz0+;ve8hTfx6m)t${*wU z`f^g%6o_n7x}@3 z7xBZ7Cu5FcUA|~tA8^OKRp1%}P(@grsh7YU&R(v+HJ0$=MnX9#_L_%6a1eayDH~H} zToV!OJkRgb4W_HMjWo#p1Eiqk=<=kW6%~_`O;-#h5m~5kcX7^@%fu)3{_q3q7TE_k z{XjwZS~JOEUReU9bNo8T5V4yRS)J#KTA(1WwuHrHS?T!zsBf#r^n9~`3eA^+5LpOK zc)wYgsr*6l!eTgq{5`Xc2zcR5*q%2uy)O*FHL1t@Uk_nmR;Ltrj~Nd-G6EH{;q?gK zW5Czhq&u(s#kU44Eodc96+F}6az%*{h^g|a8}KD62~W>&>bl;$F zOBCRz6NZhdw(%VXDqM(7K*bf=$5GXuhmmeZvYE)aC49X?2G_M*rbmWcI>Pzm0>AG4 z3x*i~7P|l5)&A&;Mln6&QlPXI`rlyGLt2Xo{EOxi=m_yq(SPwDfMABn{>7zULfx?O zf{u|Jc@Is4I=Cd`o()s}ZSemni`HHxKt?ghTf7||9nbqmh!;%2ZWiilFI-)dz&Hf; z=I-vKGNY19nZo|hYhLU*+e!cZkoZ$RnYpu={oWZZ+@d@qgl5VhXV$ITbv(|_PRjSy z*XLp^Cg!*aTNX<&t77Lu?3n&F#rdi`wyW0oHS5nz3S2G}W8v2pWS96ne4^pFv+au4 zcc!TSQ`rw+HqWGPhY*GZWIOy*QqSt!(g)_CCg%OyGUm=DK=S~QaM#?NIeGT-t2oH9 z(NZv~?U(#)-5cSLP1D?M?JP|*-Gobk8f5|gTl)W5xEBQ4LsqPDhDPgao$Q}o>U4bK0ggCGKAKY3Ca z6wjIfzRAOf29vL=06DZND}z@dfzH9FFhx^uD<>iM0-S?mXLUpz1{uUvk%AH27JR!g?JYg zJksD6E9=?=!U`C_A`VxuzW8IZ)|5dRVOXj&;1NpOcUfcpF@$ykXiWXo+_4;IO{Sa1;pv^l?x=Uf_b4ylqOsnQgXN-HT7#&%Wjz$_@lVoVw zBU%;~*>)0c>2fu=400(038{zwjJhAlUcL`+qE$$CwiW(MZ2T>U|E6X%*j(uww)DyR zD-nW!I6L5FMaiQ7QwCW|XxVZRgm{eq=xDu-nuWtVP@9jWsI{0iEhRH)& zh~MvUe8GIO5O%&xLP_~y3VFnTkYs0XKj7gOL(LhTlf&A6(uP6|S>vlIB;pAIfj6uo zP@U%s5W>YlaG5pCYA)FR|3CQkuAP_?E>JS6?IfR3JX{zLK52pvXw=AYb8{c$UKX*> zW6fOtIPj^3;Z`_@Y?JifOC**{IjZRCy;E2m7|tg^HdE>J_FI-U97n^Ka2&8z3SbS`#-1{F=oT2eP-Gz@-<%dz2ZbYD_( zj?vODXspvi5)6Lb;${7-`cyx+p$5R{KmS8$YMxF{+7d{IiG|YK|2WTaJ!qc&``=(1g!pk!osj1k%o- zTWDT=o`Cg9r#ti(0%&k{1JpeXlk;o7n_nbT#^Yi11Y4XQ(ZoMd4#ILKnmBoR`PX;oJ&Yoz*4T(|N_oN}22-d{DZk&dC!T-SjU>NePg& zT?r;vV?bsBW{d`$472>dMt!96+1wt#$4Yl`@abq3VWERLF{v?}VW!4TN=i!4W3%7A zqX8(s*D#PY8L)mc=@xe*+X6?D=R#M;X5Ekb3%wP42;hqeutts-JDE=CRk3YqCMG8S z;Tb;1X>|qyK;#|d7OAHU9)v?`@)4g+@!BoH@h?WXu$@fp9&x9Gbsz$p(8fJ0tIQ(m z3|4i?BUuJJ0AA`o|IKU7%gwEUCak9GjsgL8$ij!09rsrPa(O}4at0j%^m=F4M)if@ zn~iIX^@6LT`HJ78<}LWp?(0u`z?LgL-Q5<({9(JVt#f>ySXNaw0W%W&gbzUpP+^w6kYt+YWhv8+FMa^Zxv*60! zoKl;C?QV4a&GGccGeiinjHx!D7!sC%;4#plxVrR_@JhRSB&@d9DA{S=vyVOVgSX@^ zqUub#^_Syiw;Sc=4Uo|KJcUdLR*Vo{Q9;4(4ihJ5#ecg^FbV-!w+{@TkiAG_M#6#$ zSHQMQGzcF;h>4)rUwB|6;%=wZ4YtXCDxIET5r>^pUlLq+QY~x)^prk&{QBC{PfzeY zB4Od@do8;7?=`;L#(|1$VSIdiW5-!dKwpnGtnmj-&R*Vo^RhxduN(yMGh+o09Z|4i zcCcmEfvF|VdQ0Lm;aIRUmSIc#s~Z~nL?EY{TTO3-e;F7Ud{+Df6wg?5_cm_wP)12X zQ6=p1HRp)0HLi0~f4M(~8@#-sE38ZJ{0f4usBQk)1^6vye_gefvE8`_-8q#<5>O~W zlzLsIha;M5WiQ|aobJqAS3ZZaRl2qtvh9@ZO!T!vKB8f353WY$fnfh!3J_-Wqxso~@81XcXG_gDbL}H?6~6)HXbwm{Q6&CB zkatu5{5K@*t2>Q583K|LfNH@Z*T@za^3us6;?_Vl!U{oj5_k9XBxObbwZ)cO`qYc& z&yKfezid-pbpw_&FdLD}<$*@3-n)0tDY(P|U}6r~;-44!-(5J2K@9h0SZJbk8=o+q z)Mz3395E-^$o6}bV<@P)o) z&6`i}!Y+=cinFg16Omsn!cN67@b_+pM#Ze?utuhrV(sr1J%efmB zs2Zajji6S--kx7ruwO|-#&;&TQ6;g-dOcnjv5E+EIQlcWqWm-_0WZ3k)js2~Ch>=! zCy<(5C*Dpaf>I<*z$!;-_7EPX*u>BSaSj&Am&w035|Tv#P;QaGQ;@C+h8v%KoSmPg z)VTFlLR3_*q+_7`y8g_w(AAwIsZeH>f^ny>&@cc)N zzXU@XA0|)*Bg|+`k8$3GKRj8y3KKkSbp=&f;Ki|(JN9-6Rq4VEpuUCL^YA4Gz^11) zqlB2i1+j=fsi0&zHv1O^>f^;HpA10gTZfdc7LQUHZg(YF(HH~VPM2WtH`%8@J&sLB zc%>7tj&e3Q+#eIzFXiF-o*l$X8R;Tf>fl1=-lvH`L2V<+Ibm~VBO)zu|2Sl;a{Q;Q zP;i+UTHE2c>juXJd4;`}h!(1~9>|6nl{Zt{iq)1jGB(@ZgV4P=RoI-%@cv@+i1>!U z`^?NCnD6xYAZCXCt4eqet+13+68$mrC~=mL5^i55(Cy{RLdKVB5T1pThDGxsj-{yX zA3S)8969ux<5Bevu%elm%;X!H;92_k@WGotQ~1O!l$86`{V>0JQ)Z3|mRrOTm*4U<(SW%22%11;fkgUV#^ zrfiw6jW%M~!xqjSyv95whsy_ahmmSY_Fue=UXxGrzIKCQrEB-IA9L0_>Naq@R1QmO zWO32B82u`mG}=_2+w{^?M?J{X`m!lX6`(W{>2vtZNERu|uHaC;b~@vY%em%08nqnzrhSWxLs#+Wz27m;Ln00mbn$|1{B!i!`zYAVP+z|Lg3<>b zInZax^l_lbvZD_>npARrRpea^P*}J7Wx0A$gD9;D>Ajp}94>@^IgpL@s*A<*5???; zINqdBcJP3Tq0sKhMxH(i>n_bRH0m`z({p{I>gwu3t6o`dffO+Zs8-CV=3+`PbM9oKc*U6-Q}H}3?|f;+)vt4@ zth`#OfV9#>*Q2x)<8Ytt&Zh+#bs8sY*Lf#(H)mtCeiJ}$YgaL628lf2oiIqGFA*9& z`qU3CP^f zzBn{WI_zR(F2xhr4q!{l=kaG-%VI9m7W_eBQXg+w zQoA{zmn0ljGJ zLoCb2A9uy>*#p!f|2&@yU$syhV)MJ=^TOcA*`&u*7@7Enf#q1DsC&E`28a4GRVI@p z(1a<`k2h&U5iDe4%JPs|?V1fJeMvd7bUKz-GT~*eS0M{wQjy=&iv{A{P8z(P#NpHr z46}L2u93T$TqS5ZTO@$92;~U~mzwWsldpR`j^psl>fJPWm%cD#D%E^sXZwDGwFl;g z(e;+nObm3DD$z9T7&sXwOr_^M!%@fiT)3FV4=;i6DUtU8FUB56mk$~q5X8qvn-YER ztG4TuZ}4Lm@z4ZqfNuOT`W9F_4$u~e!^cJ=omhwD^UReI=0pG`MS25pL9>EJGVl|& zP{#HW3olH8Lm4K9u4+Fd*&y8y_{dS2`bg{vlRHIDk||=Ux z4yp>t>l7Kl&cYfj$G;Pp$9b`-E|GdwCJQey6C7L{V*wwG>$rhExzC zuQ%;oErOw#h}b)u*t~1VM3~R&%?`un535iV$s4gt-C$N@Dmv`!37FXU0PwG@)wK(y zfmE!!fq{X5G2#|fw?Jhs6kigkZ(xv?s3Il4IS^HT)mK;0r(x)%co)0`wR)4~E_6{~ z{n`!SwILTEb|>$mEM)7fX9b#P7%*U`xUU^FggNxLixlR zL|V4*yEMELwf6GK4q9p!=Pf3@S6aEQmcn;-&s-A?!S36z=%jW+j!2_HzGq0Q)*GxW zpzY>`6D_@;dXEoGl|)AT1&JHo&bpG`_R_^ej&uK%aE4GR@vi*b6xNTSB;hFSqm{;w zoIp{u;W+?vY`JWxcW}PldN3#;p1alIGO)$fl zU}95FW5H8_mZ5fU`u1B6tnnqUr@y|iO<%WB7|r64>BykG0*K=iMoE2}&WSb|4(=`< z;<@M99H%1c+HNho^_muWbS2JGV}S}4U%?U!@IU+PM>2@I0LVo%#Y7JbPuZvop~lxs z61V=IcR_-SzS>%R_Fh}86APTpPwCCVj>^*~c$79uDG~$0Np8~ucztv^bRVgpBKb>| zJq4;?^nh(dxOjh6o8+(4L;`@rM9uvkNO6bz^TUz`&g1Ipn;#UHC9|s{+j12$_8unr z!9gNBacfAG9kI#aiBimqmyv}@oq2xn9YifCIk)V|6^Umk?jD#DB9opokX?sNN_fnU zRFzvDJl&;*dMs&@J)Ch~ewut%Gc}`vmw$&?tWYrlj#^2tXr#e=r`64 zW6^vS6%~69d!-j)wYjCK;5~Nw1$qfP8 zR4ow+DF6t5f;j_Vi&)=P7gGdKAUNw;T+0P=E!e|g51kg|nsR9@bMt$Tg{gUPT!~U# z2-T?ctUjkl@OX#ZeE2&u5JQ`*HC{}%-2kk)5z}_;i1EwylQ+I zCokpi{jxPsX~}(8t~Wn8oPga>)1`gY(j*<`2$0GR;?jj!_ifHj!-9bo_=T3~{pK4n zb!{dw1><6Za$=skbzfaOT<}b(g13msdVUN8Rx{QWvR>7KS+}GlrL>}N>-8^7fvtfx zk5wC2D&_Np6Th>&aeXNXP0Y;P{tx-gKaXf+2 z^R&^pm+FiRc6bkDsn{@jHR`2OHuc1_D5L{|3lLtAPXX-VS>(+X3z?M&UVpYi1;!vP z{o^1haZ6KlKy&}=u+But6nExuY zsA>p3?4@!=)v5lKqAq=GSGn=-qH5YaO$)K*gFw3$BGEB1rtD&9Nc)5i%%_(9!WoQd-*9X>%49Y;MjfCof-TO&+n$!dYYE;z9v%?wfmi zzm>~5{+2>~XvnpW&ex|=Y=Q~Hk1SljGX|{y+LXzTr3f0ew1UTI>G&D8kOSu?N2|G+xkL+h^-zRQ*+CpmuHFtIW!RX~W1B1X?VGRupjMbIP zU%D?{bN~wi8T-$~3=84`9bkDeIJ^}4`|9=AQy;s+Fswok_4J6wLvFgk*uO|2i-S{Jo_O_&z*o_2?PCnh;Nzw?xMIY0OfIaBS!4pf+<(sA8XEm21rcP7{{ zNDh#DenRoxVrD{mpTOxgHH^0#QA*y-gh@o$&}%Q#OwZ139^TjCSCynwLJ6Tl4}Wgh zGDA&bP#u5=27Tdkh)H1^zk1z&!JaC3|IukW!=G!)A(i`b_~-y@_Fn0gJoEtSQxS|8 zmPrNU>Pn1q4QM>g4kHA|KG!1$ZKB!O%7{srGbzk#pODkIOuwKyKdPuBdSsS;8o1YZ z?MvDFM?h$lGnuI3f}QO%szNq*A7oMw>w0=V|MU>9>E8a8n8egrbl7ygO3P-Z^EI>f zlf%}Kmoq=Q6hu1D2nV|rA_qolL5R-6({=?R5>l+d> zY}0!N37F1p$bydMj$b7PEDIv7pNL5^08?0Yb@g!bn^UvZ2+u=D@sc_iu7|BRq+(^= z@AQGQSMlpxwx?e?ZEONGM!>H#Y?<2Ufu> zsF8~P4TrHoAu-uuB`@@!tJeWG@p0p545t;x?+FQ72f@}u(G{9)0uBy5J5xh%b94l( z1GNOt9~l1izcF)R%C2vk6qBd$^|BFwf4q#Ci7sC(M-cOpt~#}OjT#`^+Z1}-yQYi- z`zer~kX=D~mfk54Z$Gk4$~K{vV0?m04r&~252d%^;<{|UrXC3Tpy^B)5Gq+3haP!} ziE)*=Y%HJu=7wk8gqXtd*V%jg(?^wWh=3@L0UV~zSFUC-0OJ_~DJI${C3DmVR2@!o zni?g@s~B{9cWa7y-!t)EJ3ZT`@B34^Gtp(r^JmjWP~I1iS>im{$($93r{~IJs&;;l zcbkA~oJ zftMPXF&iLsEq?ZEr=+C3G(p;P8=9E#avWLdj}laM@RA14o^e}E+`44ps{jW;st?6o zXDW}kTd7>?`@O90B#Os!$?WnxybWe)nVB){@_x&w8&IZZH?hK^qGGd%)WX8Mr&OQ6 zekG-%q6#>kaa_ZADMOP#d|+S{dL9Xwj|+-c3`9f{Z}!rTa0evk<>m1$adebu=e*0# z{>pA2y$uyhq=ViiaX17t8-dU`I%_C5!o@iCg6Ym_~&BU9>K1YHBox1O-y zWfunY$m99v)w-WMOsqqng>hb%{D%gEgM+K`2du7(t!Dp_MnCN!;+5u52+*@~?~0}@ z!L>-MZEyR zIdB)SdY@7N_Sf(bwUVi?JQNcyPP?;p${5@&T_AxB`=@{4&0y{!{QUW5ct}uWiPo2O zh=FSu4p`i%>FDY0^9$JV1U!mxm!DrlzLVl)3*OlZ_j0Rtl=WVx$PfC%&k_RxHcNY1 z#{nZG_~9yh??6ui#?h*@8wQwsFeTjtNhIVx;zy$!1sNK)`MCOv-U{OR{O71enc+;V z;~EaIPZ-}Dfps#$u&N;&@=F~XN++_X=b=S2AC~8vyu}rSg{h#}Zrt1J45awVP<{^M` z#0rs;x;`B+hOm1U4X9c}j^~Gf(KSpkib!=N1%k63ce~g|2Zx$~V%4ZQX=!Q2b18W^ zhECQL1F0%9)6xpr2Wa=6>PtbMN?8Q3bDW!vzbJh%RzUP=3~_p?(xN9T!k$?{--h2+ z0cxXYh?ykgXv$!ymzbcztnb=5wB)&hBSYi zp-UO3;m#dPOV)c+JwR%D)LGlpQv0$w}-gFF39x$$|DQ;Ip%~itxUY zB^3ykdg}O69DQk+e`+;E!a6@}c;*C}*pO~VQ)XvorSQcjiK6}l=D@oT;TQ*uRx{S| zS|s7%RwDJfScd<=jfu(lc(Oof!%~>J67>*wFSH8XsYAOiKjhd1cM=xB0;u4e;ARsd1i^A;e!zjAYy@F_-0*1VTz(wnIstnhGSZOSk!pA zELKxfGZhL2FQ)e`3hz0p4#vk$y<`sl%@S6us9RPxEo!qixTtQGo^%Cx^RzFZny((2 zIUBgt^rdjo2UV=cGYHgj$x^PyQWQOLq?S|X$1Z};XW(`+0)OV*VV3QzE8)nu2u+Im zd3}9-@x+%g4Bi?VaUr_L%Hp{n+No4&qZp(Y)7!qaN)ZF4BPTJFfNwm1uf48r3JBTy z8#s8e<{4SIed$KEZ}nP<9n$EEWntw~h*3P7hrdRD+`2L6lWe@7bt%|N`5bO50LKEv z6(SUUu1bCJLDYM1=*Z4?_#_j3}a9iN~m9BZR67YIv zHn1=fyO93!_T=GPwYWpnN4M(Ev?Q?)<1Uy)+=?)UT*bYoOb&vyiog~V;>w$|2 zirW-LKYtfs9m5=RD^q*MZ)7|;izNk|$NKH*9KDW+R#K}WnTGHp=0wem*E;YqVhxq*Th8xZ=%Mx$p&#p}i;sD#Z+-QV@Td)X8me-F!0sb`Y zF<0&`!WI<2Mdy7bp5b`<0=N&xm3g|stP~kzhvDa&jPEuJV>|PZU34Ee_XDI}2-=|T ztAj|ElKNPBK5*lV6&&Pp?8s<)zuH@PUXR_VMyT+;!Y;Bs675`Z8vSYO{usS93y$4T zZQoFI-s^&G2T_b(WxQ=NF_*H)Tq{|6rx`1qY_KIdpC!UePvF(beb+Z)Kl<|nz~}P_ zO60D4$~8CLQs+(5>#oWDv^CEkdT1$7UjqiHQyy(K3}Sdoe9 ze(hQg_@XZVt-BsR*_NEywxc4TP#S&j5|4)90it8Wg(P0y( z#||j&lmf*ayULD^iy-$BVZ3v*T_h!AH282#<#{ZN)ODF!LK`a7ecnZbi2&Nm7@H$K z8Tb1L%qQ|i^k*9IzSP_5^elT-KoMop8`p1mf+G6Erb?b|WTziR;DAV@+kQFClAT$YpYdmzu zdH?cAP|ZhcF{ZzSbk=j6VSvY5D%HgC(9g)`M}Scm!f2I)baTBtswTYK=qx`(7S*O+ z_V{p6L!F7xYZJn5tX11!A2kHwzn8?yN=$Ih{i#Tvo143O;lsK*Fs4oJlrO>3JV2{T z1*{0~HC6;h0{3Wyp^S={+|`Buv0x7ja6;i+Ba_H_uWa0+u>|Q~H#J^w&3AKC>2OOF z>Aka(c=FpuB}OrOCv`)%m8a(oZT!vn;Nv~RfSK9ZWOAZ*a+ui2m&B7_(u*k$#*d}% z%(nPf;9OU~1)MhxewOxK)`7_ciX3Ah%+QKmGpvO>8f*qvoFJdb298rfllm|Bw(9YL z*Pe91sR2X=Fw2hlwUH;EKTRP%J8%F%ID5)TSGT5P<`AdLgFg}vPe;ZHI@m+JA4nGL461ELn{#N8#Lingk8rjL# zucR>YtAIiC1P5XEUm>}YcS=X7l_>scr>bEdWQ;6xQ3iOaHF0w^oI}ERddIggki5cX z{_ym=$y+EC+PY-K@tS0JBamYEoL2=UG{xI%>58s6!A+=r)Z)dH26N4rEEvea1zu9rpX`8Np?npYN$9nKZ;PTKN>PBYY4*5S1h>$M@CXRfCCv#(Db;98^DaL zU*Bl|b?A5tGs&8o-9uQy3o#@yere24Ow6v75jSVF;(W}^*xvZ)a%0TDV@%f@=NYLu zO#%IZ<=t_8NqromExcm)axtZCWun7YMt_Pfp2|2((!Q$p6iSWO&CJd4@De;hE7|d& zb)_LY#o#bpBcph*&qUe4Jf2o60E@4c|J`;&zgFK=+i~$BcCl58SJJ%GalJiC7_a^~ zgmds)H>%ZkRdJ8{$s679j^ZWC&Pfm<*JaTCblw~8e1{$Yc+#CsQms6!yAz%dfV^9+ zkb%iwe=CgV9dh>x91cBuj0c1mc9MN;Hlu1nN=jzmxav3B1Ckg@1u99b zod{eqL%B3t`fd%wk=F6iv(G6qGP`^}xa>PzBObH6x@sJWBt(#C;}X<~PYv|ZWIklFds zZ@bw8s*8qeqY%6b84OBYz7BMRAnH7Hs84`Gg~qhXlatSChx#|-C6z0b)G|Lu-i@z^ z1*QXR6C>ntJ`BM zR9)B*ISF8N=Z=eothPn+)}4+veK*GyV?Bkgu_xoli|==p(i0Stc}x^WeF) z(H|;!y%Bo##eIOPGYX&B7)9E7Qkn|p1h`L#zWNrQYBCXdXX1m-2 zMPJx1in@@C>!H$QMRyM})PSgEbsXNKbiW6v>JyJ6!&YR=hBcfdc@e7?%|C35JIHj^ z8?H%5n|0oCBy-bww|381IIY+On`;zQydPqfvVl20jPr7#*{m#F{c^3#y=7Nw=6f&M zI~W8o0`;p!CM$`-z21HTcKcsR%ssGtf8fA}^gEfa?|3N7hMQOvPsZ*!0wU&S4Ac)> zJ6&v7D(Vk9_#vRP^^(pr&fdc|4L-v@@k^;#?^ zOcgoVW_fyw&7Mo_TwbuVhrnCUOTiZ!&BT*a+n-(| zvOn$0Pt?;c=q$$W`MqbS&!|it^y(+U@MCW6u4k86hn?D=;zLFUT5qv<`uSy?{K8CL zo_b2DNbSUmuHTG@^!E91-Px%fgGRCQUMtaW zt<|MjkyYtE;}(}k#FjJ?WkDsFP#LPmR@APVIgB1u9g+vGNtI#<+6TCK^{bI&9~mZhtF>R4h}{* z*)TnxxN2|q$RkOfG?Sd=NjxK>DqJSbPyjXcobgHprf-=B8i6Uj=7B8aby>lTEB4ee z-L*xUO?9toAkeshxcm{;sMFkiP1aCjgEAS@uX?v9N~HzNSN^m%_vgFySV>9phnYR9 zrYka`v5KL*F~m_m)A`I>mL&zQPR#{suho_AR2v@rAh6cPXS{Vk<)n6pv~;u7sp{~- z=+m?hf>D*UR+%SK%{PGKA8i++I(%7t@v?`y)T+G-z4~N(8K#f?+Y)sQeH z^4&_a0(vR7P2Z?>?N;fPaLVhpUD54We!j!}z{O1AD?+Ft_ikDu%f>OIgua6o^Ij(6 z2)vN&);lhSR%%uiK(?9H_g;AwOISqcZ;i(kMz-N~V__{fHl|h)&%J?|nc%xX682-j z?_c|D=6}xO0sgnZ$dGX{HwXh-l-ogUJdn|_jtPt}a?jl)xD$@u4`yv_Yz(E|CW)qa z_jqziYS-q@snByIzceea)Wj;JXK#wa4IbANy;);7X+;KZpPX-Ca!eW8%=89&p$SS(sM7D1vFm#?{)|svG(c$O z)|JSjl0@ldraY1VAfjz4!n}h7qM_o3^9HWcd*SBvS{U7y*N2TTNk$&7`!d&+Vq9Om zuCcb0tHE-zN)(iQrQ|>T@Wo|U?R<kdYy5iESJ@Am^m$^^VVFU z!8-x%BK2{L^!WY&>N0RE1FBKJLrIC$vyS~>Gk^W+y?dv&4JTBs?GWj*$WL;H1}R}f znj$YgV^gFO2uyCCz<~>KA2fI-(z<6S+Z}EF&tg){TY66@4WOd-4#_HlMy2I|(+vV3 zlXyULk$rT*O7rksUub##MSeGd<`puzYeIyALuqfHTp@`<)>JgM{@Y#9+En2^!qsF> zxya31H9n}lUGqr(ci(cwh5Wn%0{7T9-ir~*1_81oue%_nm@zJ{2QVtXI?ZqzE8Mu z^JI~^lD78rWjKg~`UXT26SWN-^SnG^u@Q3$BBV}^Amtp+!#1TN^J6Pn}0Fq4r{+Lv5-p>jz((fQ0Qbf^q>3wF6O$sE2v=T<%zf8dx;t4y4_%q zEH%$pnOD8`vH(O5AvFNbzXWg6eLyZbAwM;G0lNhB{_FSk7pNkUXQH@-fyvf`RA+J@XQK{w(vC}cX`8$#Y+cqOk-4V{oTU;yp0a;2jkl5v!FFUnr^K9 zSU@rnCTLJUPd2w-J=V}p&sC6L2o`#rh$K7$s#FuA4VAIctYcJs6Gp!WtjV_hp6<@W z;Z7*!o7lk|-B>`(F?9ldWYOmqsZsl3R;fY?MC-7nzd$02V`D_=_0wZ(i3MUaH(UJY zey%$)kLD_o!b6RxTl%POz7@V(Q^?+Y^sV^+W9lr!s*1XHts>o05}Q=IyStPYq&qj# zy=kNyK~TC&>28oNX{2-0&8B;w#rvM`obMl(Ke%wkTyu_bKlivfIR=T_Y7&3?NUF9h z6uK{p$LKAqHsv5GbItxHa{pVhUTitJLL3n-w-vv!^*BQ?pQ70Oo~5~pa|AwS$5rd} z(MC)F5GI@Y@ICDGOt#J-@5ogKFPEgnQ5I!n@T$aa`=}KM1N(Jq2wcAhep>ti1#Y_Z zUgS<6fA(XewM_W`hf~y}{Fk@k-?Lu(_|}OlgpMa?MekNpzD7i*VjrM5R&Ft_vtdj3 z$^G_ek~S6D(rYLW2YURqM-$k($Dqa=%|`AR*0>L5^ITah~|fvElR2IhSXziK+6EGcWvN{+ejoY?Jxt+(cu5LVmJ*)_+x&#(V2143Q_3scMuI6m7&S0Lg2f4 z!|&41Q(~(BaJ^#uOui?Dm)IrY1*aIzZ*;KasFwe8V*3C8PiCE0r8)?63twLHAp;CR zO6#M(9c@oX;0@vQ&}VULKUKf)X;?sSo{{LcZvLr-gV=~Kzt)bX$yXI30ADcFG-SDS zM8wv%{cd_WwM#Nb8;lVfZDQfddW`S+o%gBsa?ECL@@mD4nH$#Od2adexC$5X!L)zQ zTf=^-_@Z5}cvldbZnvyHvOZloz%}m+lF{{*9+02YwKmUAn&)Q+YGfAB_I_b?HmE5a z-r25PdyQ?=VHt($3o4Lj9un8Lei_-)FYYf*tIoH7kTx#L&Dn0*Nnk=EZli#RMoKcy z>r=oX5L|yJnSYiNSsnjxGUoIQ6_%y3S_tw0aRBc`9lp+c>qhO=u&#Rh3!|<2)DKHF zc}*{@d-vp-nWU|?D9ZW2R3uhW)pBoASMlQw67&`y689xHT7C2ta(_o?jjR-g+AV@f z&!8ZuZ^HPdgi&qPU&LjGa$)hes`e`V?(^Wv42hk zoX2Kn?b)OwDJfa|4HX9DrLJwLEP;gK6XJ8Hyy&qRtMw+AyD16e$VU&vj_)SoYK_nl zo~wp|U2v`}K5DG09 zxBhGR5SLR^fbWS}!2g|E+Qf^@nREy!IEmDN`7m=z7%(%xE}l+yV#A>AO4{UvL0!kV z7#M}!^MjzG{e@utR0J9elnXy(?0La8>EWct8`55JZ$UDBt#!m5H^@IbqI$Zdb!pGE zTAKD{KEfTQv|6*6a3m>p4%Y1gN*6^?h?x*k%M%r8g^R5dv1D0uZQZWIcs|5u+L@)XB;2|fnL%v^0{_D)Tzg<= z`_Z~5WkLB!ugAp6oHtZ@i}O8=U3lD5m`ADDpQzCin4dg5HA#7%ICl~aGnnDYbSK(4 zKDyl5+fMe*J56<2JIXSC&^|v@-dYYj6H_6n?NPt!uI*e0Owl+L0YfsTT6pkqj_^YO zK*gH!dsy68|2w*DyO*xVe{q335E(Ku4K)h)dyQl|uu4&wO2Xnu(uXwu!v!hK-6xc|7n@o7=^Vix_n#yInkPN;0PWLP^R^G|D4o|oua4)cP_(#y)P3&*jH~C{j_>JY} zI1YzP@x2SJN^4MZ{PbY<5Kewov4zip>Mu!+Gjw9MGZo1kMFUSmS@rj{1I+(wt&Wt3}UU0 zLR2qLzxwMG%@u*TF%2#`_}7|AkUwsr+11GDd)wxdPEZ|GGAR1o+i(+@*ybayw=-3} z=R_cw6?fo3lS3X}^L9lPjjrgT>Hlt_a*_en3;t7)kEJz#k{IBzv^`-@8@NoROsmBNxTlJV)33sY6KG-hz>ihf)DVM;Tr%NKHU z_NK9=g|zMa#kVO1(AdNQR_5>qgeBvd?!l2-((7tY@UL;|v`YD1x#g6u(7(}m84)-M zVP1`!yz`~%TL z6*gIuH2T_F8d{55^xj*OIZw*h3@khYEMrpczN}~;RZJFBUTf6TLdPW>)U@$w+5{;g z-rv$6laLWPB8XsukE|ti+Q6HM=G4DR(cFBuKYqz?zmk5<^ouLM!?lv>$IpcuJQHk)k$ef4P?h>4Px+d zkv|l8%2&{f+uI=yHHTXL<0m7v>j&7}IYJADC*+A~jmX3<#dqP}gtcx%NZHnvm`O@? z)b_Npl8RCpV8Su2Wf~fz@O# zpq*w^DG=cQ)EbcQn}@5DR# zn{k|ZMWW+yP8I!(>AdIBxyPH3x~LiDw#;C+W9R@3V*Azq_!afjjk+q?0CSe#<_@8m zXs^GHP73~ahxXe-Le5Sj_@&VX#nU=Pt&yd+5ugb3kMGLdd84PN_Z&;>4M8W`bT|VX zZ5we2t8h_OLo7!s#kTT?hn<%~LPwMcWo0jR2z~CR@cMxe+8<;J#qj$!?~!$i`{diz zIDfL6w2t^FyU`x4_A`Q3Ah8EH&2WpJl9tGQFVyTR2G}I|xt?we@1EEq?@yMR)P=hK z{{CFDxfI^oD!k;mlL5W*r-^&~Yb6>)z@!;|HT*v5Eg(z-Sl=+nW?YQXl-@4lvrh*| z=86LGU@9&yb!pi3mXl9mXy~4hw&nBgDIKzj8}NNrrnxl*=lx%N0Dum8c4zP-=52*v zU;cp&DE7!9ca81fPcDuSaHB(ENcWDI)j+t7V4yXdEBDB(p$6Eq} z`mssZUsG4K$z5@~2&L+k8I1iM5N8z@t~X7AJ4y4n<(#~E$sL-r!YM7?xW*F31L?a$ zXmxU>@L^iuct^tSwBv3(vEtEF(;kg{#oAAumIUcN!cpeM9^-eGl$C470acTyb&nGF zbbxJZt^P1U=m>RKdh;|Zpj&xixS#$pWrpTSdh!$1gRYMZLW_=mK;!M$pze#H%Hfj$ zu*=_pIeD(GM@=&ujY5fss6JU6M&Vbbr@4@@9ceR5C;7Kfy)gE1XIxFW(#mZgEHCRy zHZYS20#TO1oDm}lS>DJ1p*1*SN>KQulB|Mk0dwasZ!Lz3u%f>|sv#=M_uM#izOu}m z29IpPSMG*3upI-3^>RChwRRDO)6-E_#?o!EZq1+S+y!^X&K zD}1cFq_t_-mbPyfUKD6H{GiX?q|2hKe+)*3Ip{b$|s11m&yO30kOqHC*&nQBW z9sXo_w8nZjw1y)0@_DCgwPD)jKD;G8 zkkF}SGIZ392(yzWSvaQ!w%edqCtkcdt-*`va^bkGe*+F<+>RY{K4_L4oL*5Jt3U>% z0spHkH8pjgjJcv>G~t)yh$kSO#>kfe&_n|pqr{peaCs=a{XSm`gJGJ%c@MvP83Ya7 z_L|}+q1tCB?z3AKq+~$lcSF0GANy+(MU)m-Qi1G#5(;rdsYAD2#nRS8uo_LiRzZ-t zc#hlN#;S-t*7_J3XsEl2!FupMWjoAON?he@eg3=-$OP+zpZ)>&d_7D}8$A(tXLrK&m6fVOZ=78vh|Y$8uzX)#dk&p{ z66`>f3#Iwbc_I9Qp+V2Gi!Dq}W?k?d8o9bz9w9$!o^SC-v;cqYcSGJvV1>(|tW}*& zeMRPOeY%@nl>rY3{=7T7w zr&a{4t&FhC90bQPrGT`bIMCiIM~s}CxL$H9q^zqraZ4BEFC=-D|2)y%=?H^l)MO5o zTQ^O^f&}Wo$H&rYL%5B7GSp3aC?V^ju9w`@w}CwMWKKO1PE^xDU8Oj-F2X3Qxwh|q z=2KmCi88O4#eEB9g^_1~tr_}yT^3=ks;?t;^~R_F1^KB#l3Xw3)e$1$-2$H%F1Zz@ zb{Vk4V)~tz9BeQb=iZsm@Z~AFchu9opFv*4qL7l8X>YW8^GbOhRc$ZyJfnN};6Pjl z#xMucN4!7$!tGicdA%olQf$3&Gu5R35LJWZyhdD!Y$M4=SyE!qDn+FnvS`|*LSNk% z`YmhoYuUXB&IDs-Rn1#9t7|B3oO%$ zXq-{zcGaX2SRshQChM8UqVf@nTz5MJ32%76oF6#?gUdQ^xxAeki}65H(h~!YsI6E! zCfD=QiLP$BRqGgINq5CxqD}=J(7s9{K zRFK&|5}~PK_T^fcsR2qa>4jlsk!Y4k>>P>w%w)5^4c;YeWA zyY;u>rie0MJ~}FDN|Mt1+AZfpRS6(1qv__gUn&mKe-C3Tr%SBYSvm*~OY5F3|M%+k zA%}T#ULIj~r(ulsy_3IbpBDkW>2DXAFZO zCp3;1k#al+HHyB23dwCZSpj&Ga+VgF+>w31ZOO3tgR@(WZTX$BbYdhQC@#BFwqKKB zh{Q$rLHI$Z;_{!Fka~#CXzchmYF?4jB&dlpGk%L|sbu0LVem5R=Z@}Nr;^&Rd|mM2 z-gs*-klo-RjU=A%Bv_8OJw_(B1Qs~;MYzcd)o|`4a>}kX%D57@iK7L!6cGjHm}W^g zrUz;^l=kyUy2UT4ejp*YOz6MC5{knLfZ#HPw}*b5Orn{`5Kv|5;7*tBL;iTRsCb!{e`8p&4UDn~gI z3q4Kl+kN>bW@5|hebPk_f@h_^j|(b!aXB~L5XG;gy_UP?fjI7%3h&e+u?bZ4^5*Ly|zm~7a@&?G^FXUzGL=S`%X5oDE)22|$b?*Lu4?iG=g>unF2T1A(3=0^M7I|#CG zI1Nwt+b>Mgb1=+GCY%^S7Lk~kE1+z%@}Jl2J&;^Ck%Qnnd*6*~lSkHN${Byx@fh?8 zij1b2+jCRp{^$l{gBG!39Y3X2ayh)nTeirpswX{>#gBYMC}z0ojnZ4`&f{e=PxW1J zXULpuAzk4)+9hS}F^TsRIk(v??sfEkQ<_d@lJzNip1-wp5Y|PmLKpltQ|28tt`p`! ztXq%zRmo}V#z*1$0|a67t=PuVmlv4ke|oLy(rXx1=NH36nLS$f-N<%G*bY2z2FCMu zy61duj~KudXv)%|;7xj3tM*?1Mx1|#JcZ-aCMT!gRYV!Qf1kA9+q2+90IWA3Vm?+o z`WX){yRM?G#gQKKN|GxDeoJvqFERWM=C~Pt3yCGc`Qhu5e0mRTzi&Cu=|ER2=gU)5 zQw4tti+5y&o}Rs|XRRc5hFPqw=jZ2J4m21=aK8+|(r6fJVPOF<1o1!NDuL?1Y*ogI{qoAQVSmcDFAtR{2(d4i9ZBZ5G4k8cjra=OG)eUU}bUX)*p4 z(R6LRSPGm{<#PNrvZnY~=3y+8Jn=K#T5%EfC>=#76nzj(kJ%ghM|}Vs6E+-CGXM_n z7u6DzZnzv=S)GVSdhK1_)i6n>#_xD*qeE9@y&+BVYGl#ugje&hbI zN`1iEM#ezz`<(7LHCp#egMXOZl;>Tn!XCm{m`JNBEWSaLD_O^)9&`jYIp2**q#ab= zzw()d8u0mVP7~44PZK(X_2iZo_44bvViY)2)sb(O~=R10NW?*RZV6(p2%>q-!|VPEO)lj+@b+ z>E&7)YtM5A;4~>V>zC5B4TZ-F{p}FoNS1t}fKNOuCPZVL!@Tk=W1(;bqq~GdhAfP$ zne*k2tGbGHKxA_Fo^&+9^68qm>^9ry$+quEG`1;P?{m0@c}4&|8p_Vs&gOO>|~ ze>Lgi#NupJd%GXT$ftD!H<%GkPe%hA^qdB(46e&a*m6Ic&9L%8IZ`X%X6^%uH!<{qwYANM^7Lp}v zPf1M0NNF~@961%u-jW~6cw1pg`f8beUUTZ=o{a7#KpAnAqJL|^Jmnv-@~d))6t_kWku|ajOm88?mxPAc0ZL05QIg$$7A)1 zaA?MgcPMFl2oo}7`0gg046Zo)wneJpTLpL0fU$W)kWDLa+$LYHX;TcHiBydaqLIHp z!do?Wd`on&unASdf5Lv?$-PIb{^RICh=t_Y$-??lpw42Tq)hs= zT%3M*WHc6bc99V`4phH#bopf_0Rs4h0w;;)I#tz(FwU&M-mG7TqVzgS0@EW|c3cB5 z7IX#moGh7O-6%pfK*&|&;bolk;=K}}kQ6tG`F4m8ht2H)@8<+cTFi|Dn-BtNyymqz zcW#qjz6eZM3M^-GM%8L<7nI$M6`xsx1Fd--cPJX2j1}Lf%Vt^;huwvC{>@08ais?Qq0)kmWqH$0$GP&k1De^wDF6`9w~TCvJ&ZrxGlu(*zFccLS*TM`Mk&;Z zZ5I%T=zD~1EW}Sm`NviQNe6%(rj6r?t=#>;pOWW3;%iqx?e}te=DBN?JDn1!69FIo zrGO@FtorV(;H|yPhgu@{3Z1AJy)t7nhp4s|_dhUsoP>R=2FTn$0(c&{R8elti7mZC zEG}j=?R3b5u5_h=tU^$)yQW+rd_%vnxwLP}`=@FA<40k$Hq;qw0`RyOQPhUrI(}C8 z-(kU5VQTRN;UHFuwW_w04HKrSBTwuTq?`3uaxY{_}$nvGt#A zCm(QQwQb>|%87m@5g@XdmB}WxBvZWI&z%l;7a{t>8w%xVmCSPpE$NTn7)iLggJSqQGvU4^ums4M zR_|5r#>>~!wZ_KHuelXC(*#c)<#YeqJX{^f_>sQ7PA^D~EungH>!ctc2(ilaL^1+g zZRY$VpY|@pzAJ%1psny1aU9OeJz~oqpV+4ki>wpebZqTL`VUHW&wV1{6~0OuSv3tF zS;~MElX=yb*OD6mDh0m&>@UpE2gG>)`xW}nX{PGdDy~;u#pI%C$M~b-^ed~b;G8FW z*Xs*Y@yH|-4A+LdrYh7CCCuWA61F@u%?qdM5^EID(ItIFg|wOhVk9Z)1dqL_Ntdxd>B9XzhvPg=tVwnQ0nepy z5mwTO8+{p*l#T+rAdiY%VLYn_pGK~>eoJM$?vh@(r~z?oOr%XiUR4nV4HD^%8jMft zx`0xLFexu2l>^fwFQReZn3!or{G*Z=hZI)vls+BsG z^FXf1<8s-=e`g{xOT66KO=FegDg0Su8vj;I9EHAED)yL^T`9ehv4Q7g_rMH|t`lt& zxixYWSEhUv4Js^^xe?5yM8JE;(*4;M-LgJA?X*z= zMma3ue8pt-uH@LJb|$fr7EYqszECbb6N+|;$$Pu!AXA6JM7SEcSFQM9KpQMu)L3=P ztLR-;{Kclpr>Ao|F4Pit6`ICjuaG7*PWPJQ{DYMikymXz&eYrsK|!H$4$8BN+rPwb z@vaZ?Z@1`>56YexwfgF;}5yVojc|`OF9QBM$*9i7;2*=O?t; z`SopCPeP3o{Vj^7Ky=V%C@%y4&C%YZo7n@Pw&36ah*`YIuIFe7+Hw+;)|Z@b^}G0w zOL7tw_i3|DfDzo{I#xvanIG7U{Ud}IcIv(} za_oxA4IDe!mrya{`mHcZmF@mILu-7|t1SCN5bM)Vy>K{bWV_^RFNc1-V>&hY^W08* zjYK5Vs3}^0B1{9?p$cSRGnoiIQ4w`=l;>H@WA%{^s@;CQGT%a)mJm5EDD5ElkDv66 z>WB9YO}p7k=|dm(nUJfCM~F`x`YT<*agn*W;}!iz3f)j1s~R)n#~ag*F= z-gpxrBElBs?uPc*C_i1EpLYjgi_&-Rw(UH_4DOptnG!&sB9M~vO*Yf|v^L>)_Ibu@RxU^V-25PJh9A?s0Z_^Wf`s(^Q}LIGYeD%LM^29zY_YH zu?vm|oMwX{)?+P@1#6Ma2Kb9HGMKcyH6O;5oV{Zo`*cQ7kUi6B?J}D1K_khS5KHfY zMEn3a<1ycf#&yg3rzRuftMgd|Qy~M=x-7KAvR8h;~61%b4*ZwD9C`jxtprz|i&&pOVhFQ^m_dA*<5)x^nyjCF3 zHyWqi;$FsG#K~Lg+GyYPtnWSgNlbnXh#1G5yI3nebUdU-EB(v_I$!Vt5Km{4aJM<; zx48c*QPrd1D~1Al0~c*4o%n=>h=$(f%{M=zO^b_=5P5nBelbd!m1(Z+zJ>$du)AQ}bs|wbh-QNTHdGMl6|{Sp^&<>NH?|+&mgHPWltb zC?O*wPt47Q^F|F;lBJm3Xq5b!EPHodBRWA00wtOJz|+*z)g9+f@omS=q!~@hF#o~s zlklN(GVuqxr_;ND@5n5Q-&w!9AnraE=J)6mjfuOs)c73l8Iy6W3=Iz#fOk56WP0s- zWI35OC9tJ1ub@_Rs^OKp?sNIz|4&(A%&F_d$HlG(9)n2t@aaL!BPa?U zBCo0j@;kA!*B8P2LH*dmWN$Bs90rqwq}m=&xBZlDvr0?@dto%Q9zGkd; z3)`o8CRmw6=S2|3AJ?;dLI^PB3GPfTmidn9bELXOl(4^kv2~{}wIRbpQ)J26mfv|d z>aI$P;F2RO zY)oTgM;ru%ptmIL)u=r+L~z>ZSd0h^(eUbOAM?-CIsO_Cgk#P%gJzKg07yzyo?glZ zb?ca`PA$0h?^RN?S0Exs;pV#nre1YNq6_e4M$EqYA2Ua9`r1;G*h8l z;0Cso9y2FSL?)0C%Q&J~)gekm`K^U5%CQfpHu8e=bBMY9S#!{cW9}h%B#d0E3m~&jd4(t#GlepreBy#wYRL zeSS3Gkuo3^HzGX+8OV=GH7YC30#OtC3vHYt#`i{KVG5<9%E=$DQ&eFzc!0XR zLspMISe_f_7084@Km1AO%M8$ktr!sbDpj;xxpIwi_;6Tt;L6^5w%#A zByb7Jqjg9h{C2f+9gb!qXBz+JD<8*0eM=8tyWIKu*hI}->U>4+?_`l68Z*vVfd31r zADk#A;UOtVexC&wJ{@rw9ojmM>A8Ty%_xE*h7$lO@K>Pz)GfZH^O{^Fv~f~XBmecE z*&TdNAnhp@@FPJwm_qb5-z*KkmoQRDS&;LXEl_}_kTCnq$(oo?LrI13A;JnrJv}lx zwLYzU$KTgBGd*2?5nfKkBj8l7U6eQw8SveERV3?IFkC6t--PA(lqW4$_)S9aobLOF z3c|l1*DYe^ey9cfcB``z|(xlUOVaZr(0#{yJ@n1J>SK zbvm3MhAf+Wm?;FDFAqeTJco7`kq5i@IQGZ6xFk6O-_e!`m0M zH&kKKlX=-U`0L_sDo6PHU)06vNf>H-MfyiMcqNHM)BGM8S=W@wAcUVEw@zdz36S*z zW0uyQ-!z2oDV9{Oz~KWE~@@Oge3)jAVJ1Z!A_Z^pUuxVPtW7-8Vgc% zAL7vFGn2zR8~KxUi%7^RWNmbKKjn_CFWsK=dmnQ@=$Dz89ldB6$KTX&TmLk_5;Mf_ zKi85jbITm_1OPkfzQkLTOe1+zAHaugu5Qx37x_H(&%PdNYwXvw@?t0dGo%m=SosCY zPxXj)zM5qg#nTx0V&$|^gW_LGprE4426Rw7AdFELRw7E()K+K$YZTz2C)KY#cxg8| z3u=e)>rE6Nsr`54VdbAuAdnt*agK+ffN{*C`Tezi;eu{U>+A51g~>l9(%3qIcbcXDDfk^%B6CojCa zJ0OoH6hvms$T0C=(o$K~33PlB)h#9YpykfseVMWgBJU)%nk?|vK!dk2ynp*S(-)X6 zf-$amYHE;n1vsOYoc}{k8XLbTJfKemR8wSmH$@Clre3_gL<56u`0(L8OT$WK;3j_* z^n$6XQa_O;2UIKD4SE3+Cv2#=*>_=|z!PZ^zk0q5lG$gdo z>VGk+cv_3JBU*DbpQiy&f<}6UZ9>~)`r7bkALQN6kHDW*nA7edE~w64fkYa&{6S{c z?LrUu*KJb3jwB8}0DyfHy#~VH>|I-n@Le9{~Qv>5@kB|jE})87v@wctq&+b+5;E^b3^0D_MlIQ8=*8M?c#3#;rkK3mb$ z{l+?){X*a}^|m?fEIyeyWaF0_zt*RS(5HhbJ;m>8ZbWE+OT(E^LErSFvhnYUI?H zsFb(+xp0Q&bP^^eY2{hC{xvlq?wmu>wVA?U7&`i{^I_o2vBWC=zYjL>Z}?AMaqzIJ z+fZ`&%i0DFD!Iga11%Pgi@aa$NCZkpQ2WRxj>xa&AI*Pk=H}ZR(kfq1aYVL{qUA^N z(;uYT$7}YMHg5HFAb~!N3c@hz@~W7TZ$Go_R;8122nLL%>Tf1#L`k||4LV&xjquMf zJ>|BzquI^!G5SC!*afUv%ljIlnLtVFJqzT@wE9wf5ZYO5@fu+4Y)WThN zj923^A#STktq1L-dK=DaTtPoa%725&FduNn4t>bSK!V}wEazN-9N%v!Kz{?z+jn4A zKh47TT6uN+Yb)NgKMBEpKQgxZf|+JAqGXi&A6ie6R9C0i47?_ncI;QRmv)F_-to}g zrLyxf_9)niM(PSq2-%>Q5K3oVb*-3LsWJ8}N@jP|;pCVso<=?{LMBbnv9w~14^wBd z|AmXX;6yEV$Fup39L>;1M{llYN0GKV4>_HaAY3&!;HM5MjuhGP361F7JFi-$$-%kB&p`>PXwy-e&@JmK zUm;0F|Ap& zHg|iAw}s=ysJ_EVJJkrt_^ z)QoY7?GU82xmPy)acx*Pm7r*ipm`^`szcS?&jfI*Sc>kaa18Dg1OlzU^hhLmRbrbc zv0B*cf|#QIu6;=HZkAlUh_5N#68gSK9djI>R?5kj@N1xRO=^<9+%fhD*1T431_FjF zhdWn`99}1F;;yxX{5&GP6Q`Fjz>3Ebi{L?~a3#iqN}Qap3?TS|;d<(fFvD}wN&RrlGbp=s$Bz4UronNi%LMN zwIe*MXNa+u!>5+Qz~CRfb(xHW1bOwBG*zRl*!=2O@mI1O!joZwFkvMY8F@x!8FNFV z>YK8@tRjlbI?wPC%hp25mI67vfFQ7gjg-0>!N-H@9=;DE!T@*6X}}BKbGB_H{k#UC*bIP3UAJdsJ5_e zLcK5fW{e+D4=9wNHOEH%3zRpf^d(4_*n-n7w~-lvNct`U|F$?=y(eyoBXp(yO+Jx6{;JfH zx^2n`C>fjq0dLwtes=$TiQ34s-#O(UHzyR+ ziN;b@4VWeigfa7iK=f=1(uog-)G>)kxlX}!k>{zV>xa;oD3;!EmX8t|e)ZAU3UBRX z&0qBTBcWkJI|@4R#zIrPADUjQ3E>KaswHq-xJI@z3>Bi^7FDkHBb|_=%4Oc*Y)o*= z^+{)rF)HJ4eGOkt*T=7OQT~K58hY1xzJ!<`<+alaJXxuNwbq_4(uqbE)L6;x)Y5m& z^!w44Wj-Wihl!pw5}PB*KJk1}XR1p)%xARMQE<{Pvh@RW(Lz6dR*x1tNDz(jVP-2Q z5=@+>y`z?z_TR3Kh|Vr4lT1X0wnH-~-oK|mn33x#GF8kMiI=q@ouD2beizRtqqCHg z)I!a6QJa+4o`>bRl^gwLwoO$#bfKNEYR>oJO=(u8J}-oj<0AJ$MUpL3Xi4`ECbCod zQ)InW^^BrEs=24APp~iO4Sl1}e9uVtk|S5KH2vRrp*&r;-2j{N_buQ`3w|P%0hMPl zW){^_;}Js zipxqk2xgrt`a#yzlR!6_HOyPpAm!be1!F?VkQyDDlnZ_|s>l>g#|IZZ+&40!5%_M} zhG7t^G7OHG`n+OJ^?a7XYm9hV&Tovd4yo-gw3e~~Nr#oly4Jh0PD%Y!!m_`~`uRP` zovYUXR=h>7=FUxhkVx0+%S!p4>kS=N3)OE+jd#8C9KabYxNADEQuH9KZRZn?#|q}C zmGD}kVUERG%3BHFe~8+Po>a;nSqx~E`>uSW$sTd6}y{@!}R7dJB7G)uvOWrSi#~irhCO?s*`xOXt5b*w!0_ zW{l0gWHbdPC#t#PBbw&j>k0!Mgr%wtkgzSyXq{76&eF$=Nd6=6$6)V2Si)@{1&up4 zkio|ntqO}4-PtA7uljw&{vbb*YaiB<0JL8y5jI&@h@Tob&4Hbvu!>wGpR9}YUULJu zlp?k(UCZU<+nGXDB6wsGBVk(5OrL!WR~_u#Kt= zepSKf^>wfOK2Yb`BPlF(Shsbr9o>Bp6HG!bX{7ba_UgEA8|WF{u6-1?yF|)Fjg;{l z!$=Bf9GNpFO<-#_O&Y$3dPiQ@RtLK2W9cg9PRyr-jjPW_lI{nZ!k?eZEdmDDsC~H;@+QxfU zcT}K7aD-LOSu#0YPA8r%F#}`)A1CeFI_Agy_lkm#&-M zrb!2AOC4J>OC8<}na=t_R!6-p=0DO%xzr~^qtx0fo$EWxxs)M&cP#Np4W}jSREcF~2vUtKjI*mD0 zD>|3*auuj)J6|&j@3g+gw%3Vmcm-AC)sDrZ0ygqHp3`9L2^|Uqrg$S>3+`N(q1F#D zqZijfqmCHPU7T5V5JjJZevwy>zrDnL4me!v^SkMK2p#y#`{=I z+IM_9ByT;b)t;e?lJ?xo?8n{Lln$W?X$wQB&#EWb>M4Qr%oC0_9i934D(Rr0;CmW( z&=cuvuJJU8Q2W<~`)~$^rh;u3+Yt^PWma4XFaKp;1308>qEmY$PD9dQSdTz%EB+St z@bIdg59U~ip|mHQeu3os8aX&-7BFqRV}Bc8XSpu4@H0f+>S|49(G4>1glKpnh_)Kp zPAuCMIzcm}V54SeZ|do3oODBbveugo-i$y(RSKvXE9>ujA>`vYfaEa8)^EgH)^$AX z!yUnQWb-j-)k&|Fd&8$%&FL2`3x%!ocnFh`yJ}xC^F-XVotU zAHh87aWONp@zP+Y#|@6FSA3_H%ewJ?GsZf`Z#jb_DGti}er=SFjB8dkTlbquRCL-RWS)q=y+@CK$-RAN(%V^g6IIM*SnrMOzi{)4{9G)^ zJZH<^+Fl?HZkUt&^mJl!w=iprhBfnwt)H7&cMA4|!Ve15RV%J9y6qf0Av?=oBayT* z;SP)qqpp$B_(!0I;vyD3$5iQ?)pk<^K9J1vM;YMNmzn!a8P0 z@v3rr*~V}sjiohkmfMu*V^^cB9=hYFr$fryMfZ4}-Dfj^kJ=0+?If-P`IVH99@~QV z;iTGc)ws^NU?ZD3POIv1$p)`Zkb#9Lo!cf^ym2UFTxFU%jyygEu9L zw=yx_JR)BD=&KE0MybpO2CJu44bGBsY^c8yj3+r@mTn_BL`$7m&sTUyovsZ3^fia!OI**9m5<*#HgpV=RO7AV%f_$f%w#P_9+J4GlE%#Gis7;@$ znGF=?>tSYhBZGf=ovV&AjBW+0TpGrX$bCUpE{d$DMfEhcl`Em2SI2<7lZ!>&I2zo^ zAaj_uZ@`fG@$ zBID#iryD5(n?NK-Sd9xxyZ4g<@{wY#@y&f`q z{(7?cUK)Z|oq%N)l1AFaH0;C+Mlj^x4nwaqnKSPoKFF)VA>Iq9BT`WNmx|(jumusN zM=B68*tL)CXD!06qHDs4vHLK$RZl8pR-?8!8*~-x1M#%$ZN^h8=Dwun=|WODtP0b! z4ht`_eSNDN;Xo85sP+=S@Gi=`X$|bh_$KlV?z`jb@+6R?Ou_ODP6X!SkBu0v6!3wy zob?PYRrFP7M~=Z}o9M-b##;Uunr*~iX+sr0!JfW-Ra&KWIz{d1@B)Hoy#28UupU%QrFP9pKGy=iIy!r;OGT zQd)%ihu2+#v}m}9*5QMwT?@-Lm0aa0m%^T<=%3x1{to~cLFc}R5%=W2^$vTm>1-Cn zmq+Y*Yb-h9i>S7KboQ4c`kWhBZc<{B;d_c2{@m91~vyaVA;`=C>`!WN{j=RxOs?jS2S)#*_9A^2ulx# zA@?Jg{jgU#<+Nzbd5N-FM;YQp+KMlX!jT|rynXOE@)3TD#WbA zE*!{dMDu{CU+RNJ1Hw(z8FYkDg@9v@*na#tP8MY#q2w&~9^8mk0TI&Vtf#;e4&EEE zIk^axUH#}D91wNiOm9Dm-p*)j+`SSnit@O)Q+$)wNNjQ31iP#{beV=waDE+LICvPr zRqe9=s7O14W2tE<8g4_lp9?m6c;Q50hIr2i*t>1OlEXpB7iDx|%28}^b;DUvrklpv zkuCJb2Deb;4vKnSG_VH;d(qk$kNs{dVVx)Pl1z}ps4oe?2aY!ID6AHBUne@mF}C|R zVsB~*T1V>ObI47Ke^!?i|1LuOZ#|bTavRW==Z!r++p#6J3RR*!?H(Aw;4FrGhdaw~ zKIk1RJr#+_I#EW8XX_Q;dCWA1(cvuY6ZQS>^JfuJl!@rvv^`KLfr9DE+jEoLrV6YEG=|{0cG!p%42GA<@b@dNm$SeTNBXdG)IUiUC z`@A--ej3Fx_s>JINN$1)W9a6}!)wMEo}=;ZTSb z-i@gmue=9aauF7?3T_o$XlqNxK9}uq%ql^4Lmu+tUGS>!IUx`SM8Q;yBd$B8X$yO~ zkDd3y2cjYgs-9?`o5lu^aegPZ`THVne8O)V5~BTKD_Z*IDY?BQ z6bDZ@Az0Kq{Z*&o8M+&uwZ?`Nd#bcQCq)#TLev~SunoIo5^*565O<0SoIQ6Bha{rP zFi#`xycM<_KZQ7h%al%03E27D;83|p+0BV?3bMhbv=)qxwIVNRA0FBAKAv`5jTf9& z<7u0fcj6$hp zRMtnpF3=illNz)D5ho3)2n^c}_pD-^KD8U~MW>>*YY)S~H+9W$To$*E5a5s|Ad&Bu;f;OqJ z8W&EvVwDfYe=E{s9q^clgJ+%A;00%M9K7k_jo7|nG}Xkx+U_VWv@$|XXstSlm3t2& zq+W=Bh78r?tnW(fh|Wdn%pGGIH2d*^tq^(T(&oQePOMxZL{hjSR5RSYD3FmGVwno#8=pf^{^KT(kv_p)9e_!>cX(tW*Hu}UV-PG*Wx*cRe0KV zI}YU4i?xpLYUN)N5IO#7m3oN z+AwO1gR#W=FitmhP9y%so{m^pxvj+`R!c?NGT-y5y&JJJK3}|XCnAp@gX8fy)bb)@ zwK#QRKUR64m*U^lQ-;X!og(fy!m}KY?O1|ELi}eA45F&i0K_Rr^AtI1bHsU zwuCA)YQ?ot{HJw~;ziMj*L(c`>~k8=yNHIi<0?F9wH6yAQ_^qlcZY+u>(b>=gSQ~gjNOX$HJe&*L zi3ddbc|pX%BionYIU)WFgy3tej23m57hKY`_Y58+fpmk|FY@Hn^?yQ7nk z)?9)7G%5AIrm7v(ouCBDgr*cOv68ysj!g>S%W-0k83n~OQf zZ*D=WXmn2h{=?|%NPwO5F+_BkCt;6`H6YY$8MeliqE6K5g^?Su_hP2O1j}6RkMw2Y zfagZszx4w=r#;UTqG7k;Osps$M5$gI1LuI9u*vJeaCQSo1k5Z4YX zL|L{>=7r})o%59KHaKLInny~<29bJpJGKP{A!))6ZJf%iW7y^CjF3jk`pfAOjT=|d z0CLJVkFxWd^mZq~!Px_6T6;ukG>Q>6njQATv#d$fmbEzUu^l^3M79WEdEEP>p34pWqdFW+gV|cog*9^?67D1Mr`_UBeuJE z!Q00hz6bVTudO{C9qnPgYb&;FSceT(ZU~H+-NGqz6aRC;gyx!yu($U`YNv(O`EVC1 z5^aRQID?F~S*se2QBOSqJT4DY@iXR!mV+SUz`;GFC6v9(V|*(7`r=7gUFBCjoqT) zNEp@7HWbXTpT` z>_d3jF91Q6nvD&6H>!fM&eH*o*%PidoAUf%?eB~eqOHhhVQQ=#ry_*-jZH>M-f1}c`yfHY zk!h$3@sW;r+CxC5M8FKngB!m?=d7a`p>F*xM69Y=D6_&>b|@5iR2x#2t<_8&x0RTGlp z_et?z+LR{5|1n%>)EZWUmGC>d65Hc)k(C{QH;x^Jf4TN8#)eTGZ3U}Pe`JgZ@h`;o zfm2DEz^FpxX;-ZAk4K}a77=Ic@Pg+Vly$eGO>8m_2F!6#UmXJ*(KwFN#D8;T7*<)k z;y8Q$d7GgIobg?T%@=Y|F^js<48^}M9DJit$uw+gM0~^{tUPjB{2oF@VF1?KI^$%0 zCt7>jks%sCuh|^I`8M-JHjZ?4_H>{{q@^uK*Ww9foQekx;$I*dyDdfDq9Wf1|4NY` zMfzbHYU}L<2hWCwigE1lE^G_Gh_aq8w6rC_cK>c6wsXY347mH-VMS!2j7JQY;8c(; z-ajTpy1aH9^0Q82SMUj3C=lekiykv=djn&AE~{}Sc9l3 z3dT|!cbsjWrsrS859-6Q{Gc5iGb_>4Yrbb|PY-&BMOk5L!08Y#IG?zPI+i)&8-*V~ zfHmGxXb?iEFvAmToe$xBi^!WjqU?%t!fOtGNbB#H;@@#!0MfOxYHXkYuCA-FGqnaS z@smoy(Fw{5ewifJeA!fMuh(w^Mr_5eLH}4!YCe8Dx+5&uHR*v=Zk} z*x?=b@CorR8rA*X^(bv_K)Z-w?e^0$I#Plo2R7luGbw1iB(ium#lJV)L<7Yvxyo@S z^dQy;T@;NYAzqi&3I zJbFZU6;k8uagXf|tcff@x3Rvt472!maPdX5S$T>gs1!#IiSj9_0!<@A{6}nnZDJM* zEo^5;T4S+Al<~cQ{0p!Ko;$hElWOHI18STWy6RWZ7Viqb!>fv+f0NfKx<+mR0Ou$~}J=h$X zCCz^H-t@NiN<>}Qi~HS}}8yFlC z725y?g?Q*6>_=_-3HZ9W;B;v}24>l#eD%e@s3b>v(cD^%l*}NkvvNT|Nhzw^I?$(k z9~tgMS-cgV@C!#;>uklp3Bv=OXl@hY>g;Z;b+y8w!fG^j(G6lVvJwts$$|awDX&K* zC&b1cltavstwQ9~UVxPl-{&ieP*7Wrg1Tzdbo63K2{t zC+x90=#;2Hfu6E(91Y$9kD8fGLyQb!xGfR81A=gG(1g9NUtW!z49)uv_O_v^vm7Ua zKg3dRZv<90ig)QjzqvL;dG<*h4G;~SP|*;H$T3eQ6Ah-SVt;IQ+y2Oa7ishU7PscP0eWT zqpf!xE?(G&CGPGBsck`JOCF*k_F>tv0K`_8ApGPGycv~@hWazGadv@UMFSFIovP|QJEiz6+7O>TLCe$=YMp#7cK3LNJ~40jV^0ponDEm_EtIf zWw4`Eq^s4iDHuTeB}JGCeL^rEc3Xvw=Q5Bb-o3Gdra--Ng5OAg7WTPr#IlgnNN?{# zamFFMy=5_0oXZh{qaIPG?6CN#H_o;+Aurn#%eTIRmo@QEsoB?3j_BZZSQp}gm(LcX zed?LM8Z6i7>eCr6aVaPg&r+J_k7X_n*qv4>D*Fz^p4x>~UV%7S+lB_2-i5#)xBe4$~K7Vf&jc{<%aNSd;UdvFj|ga z|BYB19D(SD7J1z|(a`Q4X4%ys8ay7b3+6WvhmTevEZ7;#JR^ii?m|w2E8cRjhks2A z>g$qm(DhwBVe2b|5qth)u*Y^E0%~ed)>4Y%i~I2MJ`WskrqcmVTy8;4V-}7cTaJgl z&&W;_j-0+6o`{gZtytw5i1T$VXkt3*=n`?j4_kwnbB_4H{g@EYEhxzK!|EOH;)TN} zk;lj7D~-0JBz_nEY_k@7^7;%Dsi$U4h)&L}diuZt1QnE{x>b}1Ev?ey5X0-o(=`0mu{Lw4ovjyXdS!&Q}{jeMtxw zTOCArLn{WlQ(^Dxg`k{l7xPF^$DVp>VQ>#7tE$uQ(_kXwnA72R8)xasT>tau6WhuFaqg%TZqW)vuj`# zn}K|bHtg7N1I~wS!>S|RI4!<)6VpgX2RdoiV?F{^1?S=Ey%}ply|MLVI@&dTz>a_p z@%#nFr?F?>Qf$0fhCEU4w26j8OYIqKb>5CWqP{E;MdW9Z1~ZyPIl=tbWfuR0PDtu9_F=QH1CHd@h_bX% zG=}=L$?-r}GU1ug)Se0_x0i6I ztI#QJ(|v!%jlk66e~v5s)~B98Xjlvi#Oan9qq{5?=luMT)HM5qbM?jl2-=!rVdJ<4 z&)F@e(Fx-tAPW(L;gS?K}ivM9$W(Q)Y%MvW&b#0g93F{B= zzG%ruQ$-BaBH@B9o^V)+r)^i^onxX#E;XpwJdWMHll;nYRPK)uR?J_)Nw*rf--^YrR5hxfP zKyLC$91c&Ag%-^#vJwKY)h`ld;+{RVDL8QC13bHLBVOIV0WUjl!W$x!pJOk@bS0c* z44nnOSP>SE)73_EE>U^3rVD|;9e)w=`qbXFSQB<0nLV6h40H-HdHmdd9B;U?p8vtV z1}qASl<$A1eFtu9Vw?zB zhi62bpKqS%zZn~ALs8aIyw6G9jw|t`<5ny=k&OBw_L`)_-6I$YvgdyoBQ3Gmd)Nmj z>&z1*r^X~Ir5Q zEt_G&Z#z{8IiVL7vJg`hczOftij&o3e?Zkv0xfTLtX%OxxS6Z_AbLaLC)Cd=?l-(iD(j! z&|Vt{C)ee8#(o8!7J2tco27XDsEbIaBcdp%LG<~(a4#DWqCvZ!hG_1ir#TXP4sXJ< zHY@S0_%2Voi-ugYNO(fzli5q zancpGXU^f!aUrtgbp<1>$c@~DyKT4OV8w{pzIO&jM@tdly%VokEtO_m&)94h@k0+* z=G->aTY%s&8&Q5N$8(ONeA?#>S0RR&o=1o4kSYZCYkOCSys!dKIPJ!!s9f}mxNEGA z6J7e*V?A{tj0!6e;4Ng?ZPwSJ)d`4jztHKAfSXX(23Zy!8md@ z1@(Nq(Ry4s=Y?IOky+p#4fThMM>q-xIJuNPnxg!65bMV-@4<`KD?}Wu zz+)~4;U*gYl$rz08StW)x4lcTTM zDWE5uX2hOzz+%Uxc*i}+{`h=T!3I}6c3Ul$X`N;8iw;(BFK$3L>vAE|^JB&R)ACVjA^thWHrAhyuyC7+ zZ{p;F{pnTXX@0D~3K!3A$5TgK5nM|fdKrw~_8fS5t}~b2qHJ6w>c1Bc?t*K{0J=@R z=q&QX2d-=JgeVhVaJ0hy+$ywC+=?{aDjKlc4vTwq}j9{M)ctzCl&pMi&71(7qqFFjC5OLHT3pT59)=TlSs};PfdeGIA3(sSLh;3(Q;0Q)L;$h?Nh2tE(7LC$` zGgf$4)SJ(_FpX@)GkbQyA)^3ITBaUuxCp01uVax{0OC7ldi$G*+iwT{@)zLUceQ|< zgPFxY?VWsmwZNHRui1d?@t@4@c5GxwjsmdLO3SY^axHrP*;?-GY(sMwhv_@e!oRzF zFrb$zG+`O;LpR-j>R~ft!pKlBI=WiLwK~OhJH>Td(IVp2JYkAMg1s`ViM?vN>(J3Q z)F!!#!oUroEiGv6=|XEq9YXw9VOc~5inD^T*xnxZ1+o&mi2WHQNIJC%i%*1$OfAZU zfo`;kYc_Xxp^fGco#GmO{j%U39T`ObpxG{#1@s6fL=TAg9cn<@IY&Hm&oijWvY1I;U2VzbkZdD@i}F1BEn@uPq5!2$8TI$F>^V4eUvB;r8-CK#$h+*vz3>lcMuS$@m{c}-Csi09|C zG<9}OJc~p$&Ifx$`J#VoPD-3GpNEF1ed0>tuCq(`O$EiW(~^ork?=l#hT z6W^~(mP_XA($t7=$#^xVOY=K3{STl|j{~LynkRL&pqVB}A{`8JpLhnQ%RZ6jSZ?z@ zTY5N3sy&M+ySsYYurwk|mKSvC`NGLm)NoW&MuljyiL!v@h5329#I?0J5a$kX^j5@A zTfg`wBic8SuPp@dU^8+Hys*Y@Gn@-W9-7VTYnVjY-yzBadC!hcbc^?<@Z~!Xi2Iwr zk~t1~Y4XCK>=+v8ka??Fq)R@hj05=%w7hxAHxYI1Xb*;peDRu{JzPsgS)Z5IU+T2s5oDw+x9+wXDvv;p7tK`tyzz^iuY{mHvio%1P9~O zWD;etC@*-;CXw#w^I;rO9`vw05Z}6euwSOTLCsmg|7Y*7f-K3lJU#qDrjbbxW3qYC z!^mVZn1jA`X53<$g{? zaz2Z&hA7ur@Zdr*4fXTG9g;OO>>DWXVQ|$cMSWt zss3KdLhhk{7whsH73E5iTl!gf_O z|J4{~sV}+BJAt>j-7qczxgy7YhS)?D4#e=mJvaOY$Cz4M5`WoFnCdSZUy;AuWn--d zH?L^Q^?Sjb#?KZdu%1Zg+k3ZhY3*iWb%FVfeo~UJav`mJf2r&@mN!oPJ239-s1Ed} z;*Ask(u5e+ItdOr&0C&l_=~$Ttm6zP3R{`dTd^9aNl&@Oza*5X0l@DfBl#pbmzKr7 zp40Dxg_RizF#M14Cog3^{u8|8dxa~N1FY^muZQ!;C$4vjf1gmTzV|!HrF`mng1>m2 z&lzb&{)}6Z6(kzhNAh^7tT4*_+?{U9Uw98EB@qvi#rX|FW7TK<4H^w zE9WYD)L}k~`2Q%cRsDMLgP`>4Zp|~kvdr3{hWq?vE0cj|nOs?9MV*AEU}bB2g^zQa)ZXt)7457T zMD+fZ?T^j6i*9p~X~#3CR+Sxte?Ix1HaM%U$*ltX&oA4%e;f$^yn%9uLmZ{kE10Ws`ytXv%Rh;E5&?}+p0F=O3!~(kGkii zhK7d5Qz(A^PQ!rONuZ4LeuHV;6831o_IdEk840I>8%Tg9;1GE@xRMJODrBmi99H3q_Q{^zrq;&+a}a? zt6wJ`75}HoUr+IGFk5&xyV=o@*Adt;<~XCFp`r0K$`Hu^=;-nPV@89zIh}@vhQ?n- zM+bC^&KeqW9C$r=zW7&G_|fYzuC8K}0N^038$(p&#B=NFIXq%=X?Ls+I@gj)gu5H@ zl|6K{x6|4)$mpW}(7o}87ynk)mxgF-iRWtY8Qu%=C$OcDp5+&BJo8IL5&z$nbgH6Q z`Ty4qWp%0RHT{kr{~Au0b&I_m)?zd?G~P7)+D7-6^ZZk014HUYbQ&5O8XC{y`Ql%v zgMagHu>ISAi!CF=aqxL;F;tX9VtNUwnQ zjuZm&Lb;lfKv1eTE_sQBcPTq3zFsIB+ng!yR>#4AoY(3&`ucFIeqevh?sp{}YOtfB zp`r0CZq?a``q+E?8(CC$9@fy%(9n1u&lmrPo$zb3usxhhN=!WUlN-#mq>z}9Plt$o zg@ukB!fsvWj(0EtzM&-LH#5DzY~{fmUi@2Fnd_o?vWM)(b{d<@X`bkzb$;Wu>-kr9 z8Gc>Gf2y*ir=th&&zVik>$FumG&D4xO?cO&>MxWr{=Z49r*Gw_Tb5cwL*q5%jT`f? z*TcX2cUb?&{}J-?90#Aqx;{W&ZVtKav#Q8mZcHFCshA$eu5i0s%S`rl($UdQYgs1o zK3;_6_ONuQt>9lq{69p$wZihY@wFW&qKwG8T-~dR|KF!KIFA1EDW6>4U(5eDsr4-D zwH`bT4UK2x(>A)_BvR1KI&{UAW^PLwsx$ z{%*Iqefth>;d#{dEj`iezRpl?FfMmfXy3LRN}PWm@&CG`c{uv;@-RHnudmk>`_U|Guu{k%y(9k5yjwP0LOJj6Y7Ew}COhI`Q-Ba5ywfn9n{-4dB z`2WA-svJjtnVc-^Qr|;a((_u)>%CjChK9!XC#G*|e;t2itpDJeHn~?rL*o_mpZ#a* z%9s4j-#8Au9=urm%S+q-^}mLc6vx3IA5Hu}o4bueYH#`f^9vRKR+~-Tlt&rnqwH63 zLV^Hg6(bD|4UH$s9bI@h)JOhmwK+i=8X7+aZ`_1mWnj6%fN^aNo7wC*_~WCA|7YXh zKBo45{l6mq_2ysRVy1C@(`qBG1Teo#uUE(YYiMX_JW1i$0{@Uy z4UJdL8z=r9ym-Rzt49<6&&IFqq4+oa!o+{k_#%IoP^~uR%BDQ4Mr|8@4GoQ_DHUJw zPmWc<{zGDo>N_+vG&D5+I-W27Eg~qZtJy6r#kREMIQZkEiT`I4-7}?%|G$l|W^&_~ zv%YoD@+QAd-CNnGnvO+ni9QVtji<>Uo97=y@GHJT+5e+$!Le<;hK7cQ#$Uzr#sBx3 z@cYA~iT`I4-#?>{fmOu+#4kkrPi-00P05ro{z`*hr7h{Hp`q~%lzl#w&W&G*pZNC) z)npIPJI-imXlVS1+_(X*t`HjPIPiM#T8jV8)j6iuURDs>SevdPrXrotni47(&HQvT z9S-J~CjQrqyS$avq>6r}Q4j7Mcbxh8VKJ`I-;qOfc?yxWMU+l&V)>q9-)y#R#)b#z zn_5yg%=^JG8<-v{Cb2S&nEDdx=eIGuw)3S;Y_9ZD(a}iP+K#pq>^@cux_P>~2ADDI zJhh6N&1PkByqffC#f}T9lwf=F7cfGwWqwT+{EDwo#`qV1@1Z_6%%&CkdiojP)E|0z zX$_4Z2OHMiIa+&asGeM6>u1x)DIV6mL{EPYU5jh{l>6*kEz%Yb)KES+!O~Avf%kOq z8#CtLBsm=(j!B{&+t`@n-~kvGnd+^lb#RXL$1G--t*K7R%gZRMYNUO5ncYLS;D;Cg z78a*ks2px1wXTi&hC-@`TdA2@ePWm4XJFM!BUy%bybC81JUAWc%Gs0*nwE_}+W;Vc zY(Z@pl}560?$MPmEG*A;(>^)P!q2F+`>v!@75)DpY4&a%m4cN@-B&_vO&-Y&rDV30 zl2n~Vd{Yhe3kJ+TmBJHSm>S6DwEKCEMc(5|Y6LNZD+i{>W-~G~(MtQw5*v>goW(pz za#Scjd5!##eU~=VHUrHO+={)*d$&I1Y}F{!KVx-cvsqZ0>7;XFg2k6k=O%-V_xSbY z&$-!ti2D3jV?(z-PVaCRBRcC#ElvF6VrF5c0@u4C6fQiycZ!ndliewJBs=r|?GN}S zw~j%h;3~k#EX#+M4+im!|2a-HI%eLd_n}r37QYM`>lu28tmyEO7cA1@MqjPSV z?X5XFMh6*O-|L#NvbNAmht$(~rSa2GGc+^A(4$UmkDU#sXM5>fG47YqFPB{wraS1E zo@e<-YxHfH)`~cL=Plk&u4Ci}n)w-{KUO zPsf^K+Jb3|x&A70tgJW8W}y1W~+)rNI*l(JH9zLR|a%;Pw}x_+EbL!CI87*5Ra7CS$c;yxC<2N*Ug~~_#xzTD;#pj32ATL7i+^l8 zbQfOZT2eA?-=mS+SZW}yIGxft{f{EXSBFw?4|67V@zsYK-ybuJv(>nHL{Yx<{Fc#X z*`YrB8qNik^uJ1~TjG1o z>*Ob%;!=JCV?#w;4EMpOd)9HmF0G}mTu4ZuM2VKBG6~4`$A92y!?CS(lb!3zm8Qk- z{bls$gMsFpOI*#Xrt?P=|I$8MrYWmVBB5)Nl^^K2yGzvsg`CHC-1_~$c3FA}i}J^- zsh_`grj22#m588k@aX#)!4=4&p^+-PCQ@yD}sMvft{%-@gD~dSlH+- zAt5mZZ+{G@xq>!H3emaCzc`7GQIzot%F z=Qm&6OJrW5yEBbjk;U{b4N%fvMd?5tO(SL8%C2Q$zTP6zn@UJ) zC?>DBhbg7vb0C~-&lBRO9 z+iEE3X`*3%8{=Q0wv^#L|CD4O>hpO)D+beEX-FevwTO_@G1!@dduR>=X0!d6B*|*p zW_-Aetfpc$U$fhr8PF@Kv|o#HhWegL$-5G=T5Blos-|Lmj@1J{DVf<=?xj%fsob|@ zWSnK?{Y>jjjn|W25y!RAbNoIkp7^>dih4#^deLf1HY@t2UdmdtaSr&FBay)b)s~Uo zSVQx|1_tXqnF;a48#a^V zdwT^L%C&9v^oT&PsAajy#HiGh*)Ga^#O@l!?&j8|F335t%Z9E3+`>+BB=A1&)um)e zJ*u9VLs_(OcWaipg&w*m2PkfodeYcH-Q)^8iXH51Fg#GIrn6$Wp9$ULEu_^nPfKSd z>GefqG*!~EVcZW6Z1SE%!;NIix%9?j@`oo_G#-$*#$`rFstC=z%TcehTr4V<^psK1 z)5nw}A~hK#58BGrXJ$zq9nu}PiQQsCDU*8To+VUGuV9z#MwXWr#Qp~9k-DBL=L@86 zPC3SLSqv)-_ABLRueZ6~?To7pp@{#vI=nohDIaTq;Q0u%laKVX>E<=^;v*ilk1|QY}H^ zo^RVVOi|M!{#WuYyR(@QUEEbq z_o~tZZe?|*nc~(G^155-UXgZIO{(%hoxJ}XGgG}Zi!VwM+bkWMV#U#ozq>g_hoc== zv_sL*5cA5l=1pcN>WMA#=cLDRPUMOvlX{Zd-p+{5-s583ou|1&@t1|-FRSQSH$3#0 zHXS1)jZzni$*u|GnA<%(ng>)L{bHmITOFZXeg7gd+nZ>UNXBZ>voO_2Vp%X}J-+5x zdIm}2OS9Wr84y2iv6|Re=w@tbl=`j)vgNs1?E_32#0sQc-CFFXx?Re#qk*=C6}I+W zzmb(E{pG+Q)BC>N#MVkLIih7UM9bu~S5wm4Ow)qyr|VSw8S;Gbf9Ns)lHs~eienV=eA-ouS*Eu9; z;tB4UvNtr(!MZv`ahVVI+IpzUbLV&Nr}?AXcU+T3)Hk(^Zi%AZyj(dObBk}IZt{uG zQQnTpreeXUR@3R8RNNDt`7ZK4r$f(hEFqoZ*)6p~EwqQ>7IlKJW5PHee1*4fo#JR* zBCR@!$k&I-&2{E<^nFf7T<2K0D-W9HS=CL^T6&#N<9xXqc$v4{+_)Znkt1GTaMF^ z4})&-mG?LN-&eojqnvt1U-U^y9P-M1EzzlW`Na1cNBmFmQLr0+U8`*9C#kRSIlj&t-?{&4FvetrKe9|zv#3x79)yQJY}mHgCT zZUsHyYK|`-ixd18A5T0xSHwkG*w5%;7_u5&8Ro1iA8oDb)vO!{%MpAi2x z5#logS-3dPfbs zo{f#&odtRu5^##X$LWYWoRIrF6}78FJa$Yy1V}wO6Y9jVSZ6+V`-0zwrINRx$241x zf6@)!ayi0pTu<gDLn&ALX042+jpx<2~2Yd=VB-&9+qn)+vf} zuJehijVn= zrxVv3X5^fd@%k7=`7ZK)_c;-9L#}n^Zq1m8RI$BEvkA2j)e%D7pJRkicoY(Sxg14J2k| z(>7gCRL2v_5p5%OL9x?HV5kR|irV<66#H_X|0$)OccNlA9&(v) zQc}p9laz>!SCzT*f#-34d+Q7SC}r}Q|4q&$CR4rsqB$Vq*9={R_`7pA#fP)W_xa50 z8~z-gNYV7RkHFkF%J+C=*CH@m&fDp@Ui9?uPyn=Ia zGZQ0aIK_q#-1kuYcT{@dl$J)NPX0NQM|eRPp~KG>|M^88+-iME@o!n9xgwAYQYVju z+~E_~kNKxNu0)P5h=`ZkAi+&SrjNZ$BCm2PF_zSUWeJ_7dXAM4B);OSgh(z1Ug5(B z=lC=*nDT8i#_dt6%KiD$SK2-Qb5ie5bD_A?-e%Yz{S0hukLB|q{sw=z^SSu%GkhTJ z=4XDccs2GiXEU?D&`w&mztme7se6|>lMq6D_p~~UY^lH=p^O z;(JmN2}=Qq%)4#zPvKb*w%ASd4QzQWgmXZY2P zn_@2`2L{7t-3XadVkE#b4eN ze<^k0Q*ZH?UQXO-n3H-U0smSz`5CwQz26PK5H0h8%SZf;%XRK|FC($?%VQMV-`P>b zsN=xv!Cx)@ZM)I{SEZ6#+9(DM>#a#7C6~~rek_=!qc}~RZ!B4v(fE3M;297~V(BEC zhwR-vy!aQ#YB6E5?l3mmN9Xtq2CKOD7dm5cCbL776!{R@SBOhk1nFZP#3uL&OMSrSzUgA%Gc*)B@qTy$RmMK5*LzFe&6Vq9^^Lfy;?|5r>UeN#bg7{NdHa$Dvr?%K9 z?I|mDC=I&ug<^13ah1wX&520vF#G90nadU{w zynB3HG{CZP2ct>y;{a2&Sxp#>Ym}s3v|47!Pr1W;J`v=L5Vmah z5Gak>S84U)RCTn~NTcB;_Se%SWl}*zhB*7X9%QX5ZtP&57XRY>7K^zOc#r#a@(#O_ z7X27$5};nnC}GUDMNNSZPRSJv%CD`aezLQr!N_Voz{&42KUu_e7Z*HgN~BEc$fyqC zn;RDi7+jP9ae!dIOT3p*!oa49&DCPgy1Q|wd05KGBK3Hamcm;&r>4-fB_i5km&!Y? z52kWE_#8LtC(w%xZ%JcYQI|l`l2!6v0sxcP?Q|umM&L{PqNL~k-kS}So0aKdk3uNVK>m`%e(hq-YnE{?RGMv6OgaPmISiMV{m zZ3YosKD__HhwurV*v=@$nQnX(RY1R7tBi2hZH`bb?^x1ZLTr{BpL-?HBzds4P{keB z3w&GD$>xrcjd}UE*JU2GO|#;7*Qdq5a$NEDeEc3O#+hdBGYM-3_d8E zo`p@nz(Dm~{5z)^Xh|VB#RJ!#W!f6UxLsaLm(;DSm~dj-N2Pq^3A=50#)k1viT0sB zf1lLAk@#q?)%P(af^saJqAaam|ys*%EpeNgCO6Fe4J82 zp9F6feHTF?SGify&766Wv}g}5Mn#j_-6(!Ik2`+KT%UB>4;(BlerIcp3aJOh-K8Yt zdWcAiq|%^-*U!fQ&_FN0Vjdz&MDIHhnRKm-q+hG%y7zr9R}acNbr2fs%GKglrsdss zOp6i}`f)ZcnMSjjk(MyNkoxB)e$Q&2qp8S~_X3k?Q;gcSi+-h_GD(lp78P|h(X^oS zCM!MvaU6+CqIk59pwbfB=0_>bzR9hhNc=0G7tLmq>RWfke^pl`klNp;wx?F}1ZlC} zTnLRIsjGp~u6*tWUf^hGGVP)-3{$1J1dFJz9#!pqdwGD$x;V;b7U`<@=c|wyYPXD% zmj-FuOK=WwCU|614IG}0&CzbIQJX!RL!MI9c@_DWoH(<|VB_pTEPQK0CLGk1-iOm{Y2#IjzR6!F9%1_u~eYsz4 z$4k3%@r-ok8)>V1#YSw>hON(uuarR6e?;;?{H#(>!~=`osKQn8m(|KwvpR}Ye|d>} z&6BJdy73PcA5k&Dv@uPD)gt6hTH$Dp&H#>6@z}ASQ{@l}5s{N@!oG z#Wy&fl7&sFK8kaahBQTlN^uio(mcQ;@i%a7>{p%5QhO+Yd0~{S zKACp zw|C79tZdOQf9sF+s2gc1xrj!H!i#VH42_H~5X$6+R0($6s8|@p)9Ch<__f z6D4^1-@>!KliGnQa`HU+CcBo2{b4$XXKY=kevwcbbmgym`T4H*+2UUs2g4NYMGtt( z=MtazU*UcC)BN^M5XCFo(r}EE5b7*KyNHs}E^4X+`6eNgoS7HP*PZcvE++cp(zU)X z0(BDwB;>dfHRbqxE&?T8761LLKboxvU^TB%oN^K8;zmXune1+{Opz{vCZwc|73F|= zgk(v>)r>}Y^I0m2AIN*1;j_T2d>(L>kG&<>%gCkqpwIaZo)-UBmfHjPAUT7)Sw~NW z2->+8FZ_!{FiL|vSR0B{L?F>a{WNx@;gu2~!h7h&s}b3@ne2_`eb=*mAZ4PY^%LK# z5@n!X0cE43$fE+cy~|$d5b0t(p<09bNy=6#u#w!V+)thkNJ5Z#itw z_ckt7O^nEOhsmWUF>lXMm3;=^j&T-OI*CZlp=^GQnZ7746;#r`E`erj6!D$PR|{BN z>)`Jb>^=VfB!5A54P<6r<98u`xL4OxGdabK{$V>YKb(b+i2ulGi^B#E!an9d*e{ao z@kRA3iZb-7KI<~hMGf>V4&WbionMPh@0H0%Ubnbg)x!7zYIb*fm>TgDzmqcgNXq0x z_cQ#(Gny(99M5m96wxc^uG8HR#hKtV+7)B8Y_ZfG$G1U}9v=yIf^KuWd4@H!0rOBSpGK!s zvZQCcDGa~%a)PBDa4TzJVz`W(aiN3^*kz^CCU#f3<0L_PnbKeLD#X8vTwq$Jxh|OC z_F;w{KGU)-qBHI$zjisT`ozz~E8jT=ea zCrD2eP1P`9pKNOzASF3~TZMMoXMugYRXV((vs1duqfBIh#rIwF>oNyYY*vgsrwG63&Gh<}^-#WL~j zZwKF(Af}qy@i9iWr0sD$dvmFQ@X*uv^epWUmsU`QGdAa+$Fq5q+2@pxGMBEYz!_%= zMjy5t%hZ%6D>lWr_I9=px3X_RSCF;^uz`@2(CS`YTDz@#NdwM&=y(^U}O= z;@^Q%5BBZnDR!7@$RXC>3opL_`~!S(bGd<&2;kfP8Ps-m(psHOLR#y-0qG{{$qM(S zc;aw72fteJzs1OO9Z|6flr%%Gh71F&_iCb1NoeOmY1ShGVmz7jlOcO*$ zT;OJ97jqJE#)aPDe$6mTyW(WmEAb3;!KJoW?FHNu|HV&<|8+X$dFOm0soC6>Xn2*D zQcu2+JZoB?q~0O^=T~Y84DuspWP$d^$Ho8iG1Fe+%GJzV>K^;;B9+DdT#C%5b=QPW z1ax`!1F7)&42n41m}w?B<}$~Wp#|X&xSk=ulM4K@PJK-pzrSQPstx-88(&4n(B4F{ z=kYA@Z)9pHl}q-=K66W{B|KLOMf7m6d1SKdeNj=Av!n(&+-LX&jjV7qL zO-ev850jJ_z_rXqbe1u)b3OPXrHX0mj=ZNHozaNVY(Ahz^AXeuzvsB$G%hYt!OG@9 z6rV&y5I^GZmeyT*%kFX~D_I&gsk5Ew+>W@+chL_x9_o%)jndO7P1lPaY2IM4HI%pf zVyIr+lyr*tHX1NU{WOdHm`q)S1VoZCJgbT<({?@g{r&NKMEtiEI&nQUnU*JX#8Ph} z;W<8JzCirz78;2Pzd*>SZ?e)lwSL-^@mR-6KV4&g~7J5sV^kOYZP~a@D>+vq}D^#h>S1$2`j~xbf~{ z2^WIhxl=#PrpchDRkvegSJ_OFC8|r4@Xe}WTK)C3G-hF(izyWupl6^pnoB-mRBUcz zFwN6fvyp0c{XbeW$qI5fF$!+Nj}y zl>g1@LGc9-)1!Qi*$-^QCf8TS=$f4o|8}rFnzv`E%{hZ-+n746VMqLo*PrpCl4MtI{V!px2Y=|%2bP0gfHsi)JqL=;66r%p(F z9NSti`NiJc?|J#9kZm>-%l-Kx>Ko{NWc^w5N{y7s11^*FJ@MQJnUUE_Rs6?^`0s7>c})B(b+bD2 z3b*B$I&NR}T;r$e~Z_ zoWka86@lTG@E)0!pVcJ{TvbCGsTUE^N@kk^S9i+?e2FdwJ z+4E~Y3RQakw;3DA$2BpPs>vaGr-td78fSEQ!_ixIIFyxr-py`SSN2gR_y%knSADn#1lQivYwc?c+M@nZK-BN*jPNC9qay zQbjUe1;t{|qmoW3@9Ak~w;xWFeKr=>7Apw|l)$&Fg^uY_`ew!%Tv`|LBf*M@e}C@~ zk_M*L4g=FxEqA;;@n{@W>w+T07rH`lO7I}CrJp{zUa?EXzLtAp2~Kw-W$x+nv+Qm% zH#bCmYXUdDz7;XpOy}$bb0V^ghIYatu5h`ih5E@c2IPGP7FXF;8yz!SYqN~Zj7U0% z7#zyrPFMiJ9b@+N9DrfIo|x2YoGX!fKQY3GYGd;AnL~%Y; znJ=;V!Y?Nl$@h{hC(g$tkv%-FrnPr&o<+S9DK1l46o*?%xrlv*X{ri?I2KVPGGLpb zrU*`Wxe`7yOy6iN{-NS4+@sWCKWnqK+;ep&tfP${sk=30zI+rAP1f?JG-_rxR;TEj zXdxu>7~dr%k~K8K=-QU@&4Ai6H!eiS5YnZY44O3TKL1X&#r~N&c-l1kbZkdj8w-^YFm8zLAzG zsh17meCHoP=;(s9D{EBc+~z`L9O*-23@Y_uc8)pSL3>GTG29j{WpbO~K`E25dO{<= z3xJ>SnLhg&B&oJvf(~Li)rQeN&ahqV?uO+!dU)4puL+fRNuqTx*nJi@9XtIIyc?20{(=%9Zqguu_UA5t;fu0%rq&gq z>CCx|TncA~85k?VH!c+aCJBg?>nC#wOcw!F)60<9NYCV;)P;Fg6|-IMBPZ9H#kSU_z=I=$@6jAoW+-1ail+EbWx5I?N_{V3a{Q*E2i2 zUnZ-=`2?liBX&mW)MF3PG1Z^SwZI4X^bFHJ(?z4w!4?)u*1X|R?buYiKNpfh2yT(K{)=MDfux%t~67$8S!Qh@ZGg=;Rao0!aW{QsBy;avB(( zF2mi;mB?-hr0dDvem7k^pY>hPE2^e?W6zmz~`yN%#*Cobogi3aE;H}4K_oj;GOi2s9n{&#oQnVlP< ze|lWnl18!%134X4NcWDtgV(%0Nm=fBj%SzBG%o3p{9E3!U@|Pzlzo!B4FgO)DgJF% zw%2DFn&=`v;T*@p1Bve&VsvF)%5sJ3;#k~MD#Sl3Oo_h?;L!vL0OsO;K9td=aHXZ z!=QL`wQic18LCUe|GqnJ_gx5x$)IUYnOOK(&3!JfR{YyonrI_c0+OPIdfdbA@oiir zccYy+6%kCXM96wmJ3bz#dB^>nM6{Rr)b{}q1M^}qO8RY#w?}a;)sC&w~lyU04BqyKc1Fv&@75{)6`B_9HmrK6Q(a{vn&H7H3*W2Yc z@nlb|(BGYer-=EP7by$}mYq>@3cUH;{Veag-^8V|nQ2L{Zl;dlxHG)#b%Afwe7TjI zLu^JBlOoJErPBIG9#<#Oei3|wBYsX21cj2jrf2t%*?+aVPhH1fS%UOZRS(LNo(H32 zw7-I=v~q^`%UK%9%_&NAuke}oSw0K9#ns|W0wObMTiuYTeV&}OYa9tU&!>Sm`AX9K zq1!$DyM_+v;jv-aRwmfGNuYIs552B&NrXtd&hpT4Z%Mh-t&Ke zQ&|sd2jrbeX)^CGxxBGkQ;oWw3K@{#v#9yIhar36PJ zU4dxjS(ovw#i>c3xC1Z8n40Nj^>?*Z9=u5+C^8;H%^^29&YX z<}uQeGAJ2eP(SUO^&LbcCXgTvrhT@D+}JciL6Hw%cuM|wIdi9~RTaD2V})c?#8LW; zuJf&xcA}#%NxhTzllT14=Nw;z-zR!(Q$&`T_4zVfrP2CC%JXCYD;$Z>r)5oP>bGdG z4CGwEIX>{e#^?SQaFW1b$nfGhKzrD1>x}dya#HHbd!Cm$A%Su2mNKSR0_DzVjs#xe zUC#@A6%t7L^eTn}yFMjv^}VEJyYsn}^~e4fc_%oWxc()1k8Ro;3W+ao!#;awLH?c2 zgX|iS0g`R217xOO-~;dT9ElNMQIbnoVhR27{<^ge!a}a|xs>xKe)9f-KE#c$t9fp- zZqQKT%V|IHGrpJkSp3(=KIgev)viu1v=~OoEAZhnkMn%uf1Y=P0toARxIlt!V~C8@ zvwRdCM()DF;@`M6N>S!L!n@}lHmKrTcBYHDSz1GZ z@9~w`+(%*`pZF+q62@6^_-~uBpX@wOj!0R4B4zS+V5p>j`oQ3OcU^pJ)@44FGWk6E zE;q_@2}vlVLj=#$edK#6J){$4rDl-ZKZVkdW7+8=J|%$&#}_iodKU>f_xO`iM?9`_ zy|9u#H9*wS*Ir6gRu$u_$lGM7BZ~(qVh8dr&rPn>+1>FRu4EQbw`%V>+LDJ;LfMg*1zX@OMGTGvyu(A-6<-{1Nc&@C*p74l{)6rG^z#^`ne|Z%R|VVw>%z< z7)99DM{>Tpo5{r%;^Lyn9i3&QD-M4N{N{{nw3K>rO78ce__a?Y%^!)6yHnpU{#yd` zqAW5yM(o1dIz~}p5`ned>c91qRfNT#;vKP(Z&Q4@m6b(oW)-6j@vp3=G&hpPMJbo} zJR~0?BPm?gE46|3xiSeL#b5d;{_?8$%RHLZ4N+~Z52oW3d6~aRU2thAATYIvydGtK z&Wl-@t|2h|93M$pD*1CfAxwOt*xi1v8`+pH#3@)A>UfziBp}OPkn_9i^w)S2)ji4l z6XM?{?NoPNBv<^;sO{S)@-82Go#tXu6~h)Iea!_Vl(+8t%hvjI+;eIr46v~_R*iSK z(!SZX%%?s#`8rhcVAEi)*K+-EgAZQ?T;xH=!p~@PwI7$~i~sMn!>?2_iv_C~;iDB( znE+x^Civ~_U=jgxn2NZ^s}=v^zm~em$hyh>UL)I5dzExs#3+|^%49M#JH{4#{ldwf zTwvX_gMQcacqO+gLmrIkr%9u{n^}2xhqF;O*|A7|JX;qilR?)I!b{&&L?VsG0 zq`D$h~MO5Rhs zR-H`!$aD7JQ$45DPdTU59Z9G9EXSW>@6UL|b5ZhGdA5>PgFJix^RSfH-a9DIdl~Pv zSLf|%QtG|^YSl&*`&R#D_XSElRR68K%ieYJPRhIQ{Z>h%a>Em2^H#k75J%bIS3D zHu7+2kJVz&(?`>@pGWe1v$BYSk~aD0L3w9Si{#T21*w#;QoofUfxk&_P=&wpcde#R zJ-_EKm9*^ar$zZ{_6(n(*n`90s%7%Tvz|n9QcaVZ2kL#F@ZW+u@pAvU56k2rl(JOw z&QT^xJEfYQN&1Chyk=`M0z|$}@F}-`fA3;3(658`;?#>ZhJm&nac5=AU}*(YpC; z?CsjFYL7{6KRxQdjjI2a z-^sI;->dgj^GmsIuRbXMmV9&60ed^XSC$SWUAvNRYFjVmW%vK~<0eG|INoF5U#d8K zyOg8a-YV(cOT!DWm(^bTWzYAguX)&RC^n+xi}D`Iwd#95;~`30YLNRr>bsP$%t|gi z&tI}TNqN?N-VRNtOL;drreEnMD&`ay>gQNidlHo2i~UPkA4*fbabx~7DAOsWp|DDKi^lAZBAD9vLub2Og z6aNlgJmL4%^Qy(a8U=1EV{C8nuGb0vc>f%qg(Og|S0YS_CJmj0hbK|CxbblE%xi~@ z_1Sv-f==*f&$Im5?Kp4yUgu{07+VLMz;siAx0 ziQW&5XRymqdm@)Szv1_u=XmSEH@p)bMC{O}mUkMj1l_Kg-=x($<^t7mvrbvSR6|2U z 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 z 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

;I(ha`GRE$HxxVa*M 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�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%0A*xDh0ukabP29;z35}tw95`1;_ea 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 . You are doing it by inserting special commands, for instance ``@param``, into standard comments blocks like for example ``/* @param ratio this is oxygen to air ratio */``. + +Doxygen is phrasing the code, extracting the commands together with subsequent text, and building documentation out of it. + +Typical comment block, that contains documentation of a function, looks like below. + +.. image:: _static/doc-code-documentation-inline.png + :align: center + :alt: Sample inline code documentation + +Doxygen supports couple of formatting styles. It also gives you great flexibility on level of details to include in documentation. To get the taste of available features please check data reach and very well organized `Doxygen Manual `_ . + +Why we need it? +--------------- + +The purpose of this description is to provide quick summary on documentation style used in `espressif/esp-idf `_ repository. + +The ultimate goal is to ensure that all the code is consistently documented, so we can use tools like `Sphinx `_ and `Breathe `_ to aid preparation and automatic updates of API documentation when the code changes. The above piece of code renders in Sphinx like below: + +.. image:: _static/doc-code-documentation-rendered.png + :align: center + :alt: Sample inline code after rendering + + +Go for it! +---------- + +When writing code for this repository, please follow guidelines below. + + 1. Document all building blocks of code: functions, structs, typedefs, enums, macros, etc. Provide enough information on purpose, functionality and limitations of documented items, as you would like to see them documented when reading the code by others. + + 2. Documentation of function should describe what this function does. If it accepts input parameters and returns some value, all they should be explained. + + 3. Do not add a data type before parameter or any other characters besides spaces. All spaces and line breaks are compressed into a single space. If you like to break a line, then break it twice. + + .. image:: _static/doc-code-function.png + :align: center + :alt: Sample function documented inline and after rendering + + 4. If function has void input or does not return any value, then skip ``@param`` or ``@return`` + + .. image:: _static/doc-code-void-function.png + :align: center + :alt: Sample void function documented inline and after rendering + + 5. When documenting members of a ``struct``, ``typedef`` or ``enum``, place specific comment like below after each member. + + .. image:: _static/doc-code-member.png + :align: center + :alt: Sample of member documentation inline and after rendering + + 6. To provide well formatted lists, break the line after command (like ``@return`` in example below). + + :: + + ... + * + * @return + * - ESP_OK if erase operation was successful + * - ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is NULL + * - ESP_ERR_NVS_READ_ONLY if handle was opened as read only + * - ESP_ERR_NVS_NOT_FOUND if the requested key doesn't exist + * - other error codes from the underlying storage driver + * + ... + + + 7. Overview of functionality of documented header file, or group of files that make a library, should be placed in separate ``README.rst`` file. + +Go one extra mile +----------------- + +There are are couple of tips how you can make your documentation even better and more useful to the reader. + +Add code snippets to illustrate implementation. To do so, enclose the snippet using ``@code{c}`` and ``@endcode`` commands. + +:: + + ... + * + * @code{c} + * // Example of using nvs_get_i32: + * int32_t max_buffer_size = 4096; // default value + * esp_err_t err = nvs_get_i32(my_handle, "max_buffer_size", &max_buffer_size); + * assert(err == ESP_OK || err == ESP_ERR_NVS_NOT_FOUND); + * // if ESP_ERR_NVS_NOT_FOUND was returned, max_buffer_size will still + * // have its default value. + * @endcode + * + ... + +To highlight some information use command ``@attention`` or ``@note``. Example below also shows how to use a numbered list. + +:: + + ... + * + * @attention + * 1. This API only impact WIFI_MODE_STA or WIFI_MODE_APSTA mode + * 2. If the ESP32 is connected to an AP, call esp_wifi_disconnect to disconnect. + * + ... + + +Use markdown to make your documentation even more readable. With markdown you can add headers, links, tables and more. + +:: + + ... + * + * [ESP32 Technical Reference](http://espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf) + * + ... + +Wrap up +------- + +We love good code that is doing cool things. +We love it even better, if it is well documented, so we can qickly make it run and also do the cool things. + diff --git a/docs/index.rst b/docs/index.rst index e194992089..da03346e71 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -3,7 +3,11 @@ ESP32 Programming Guide .. caution:: - This is DRAFT - mind your step + This DRAF version of documentation developed within `ESP-IDF 1.0 Release plan `_. + It is scheduled for merging with `espressif/esp-idf `_ repository at the release date. + Before merging it may be incomplete, or not fully in sync with espressif/esp-idf. + Please mind your step! + Contents: @@ -58,6 +62,7 @@ Contents: :maxdepth: 1 contributing + documenting-code contributor-agreement .. toctree:: From 73944e680053610e7718cdb21763e28dae08b246 Mon Sep 17 00:00:00 2001 From: Krzysztof Date: Sun, 30 Oct 2016 19:54:10 +0100 Subject: [PATCH 222/343] Typo corrections --- docs/documenting-code.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/documenting-code.rst b/docs/documenting-code.rst index f07f464ed9..51a0dbf7d3 100644 --- a/docs/documenting-code.rst +++ b/docs/documenting-code.rst @@ -4,7 +4,7 @@ Documenting Code Introduction ------------ -When documenting code for this repository, please follow `Doxygen style `_ . You are doing it by inserting special commands, for instance ``@param``, into standard comments blocks like for example ``/* @param ratio this is oxygen to air ratio */``. +When documenting code for this repository, please follow `Doxygen style `_. You are doing it by inserting special commands, for instance ``@param``, into standard comments blocks like for example ``/* @param ratio this is oxygen to air ratio */``. Doxygen is phrasing the code, extracting the commands together with subsequent text, and building documentation out of it. @@ -14,7 +14,7 @@ Typical comment block, that contains documentation of a function, looks like bel :align: center :alt: Sample inline code documentation -Doxygen supports couple of formatting styles. It also gives you great flexibility on level of details to include in documentation. To get the taste of available features please check data reach and very well organized `Doxygen Manual `_ . +Doxygen supports couple of formatting styles. It also gives you great flexibility on level of details to include in documentation. To get the taste of available features please check data reach and very well organized `Doxygen Manual `_. Why we need it? --------------- @@ -35,7 +35,7 @@ When writing code for this repository, please follow guidelines below. 1. Document all building blocks of code: functions, structs, typedefs, enums, macros, etc. Provide enough information on purpose, functionality and limitations of documented items, as you would like to see them documented when reading the code by others. - 2. Documentation of function should describe what this function does. If it accepts input parameters and returns some value, all they should be explained. + 2. Documentation of function should describe what this function does. If it accepts input parameters and returns some value, all of them should be explained. 3. Do not add a data type before parameter or any other characters besides spaces. All spaces and line breaks are compressed into a single space. If you like to break a line, then break it twice. @@ -76,7 +76,7 @@ When writing code for this repository, please follow guidelines below. Go one extra mile ----------------- -There are are couple of tips how you can make your documentation even better and more useful to the reader. +There are couple of tips how you can make your documentation even better and more useful to the reader. Add code snippets to illustrate implementation. To do so, enclose the snippet using ``@code{c}`` and ``@endcode`` commands. @@ -122,5 +122,5 @@ Wrap up ------- We love good code that is doing cool things. -We love it even better, if it is well documented, so we can qickly make it run and also do the cool things. +We love it even better, if it is well documented, so we can quickly make it run and also do the cool things. From 8d6b78232728d7a987a2cae690fdd820cf8cf36a Mon Sep 17 00:00:00 2001 From: Wangjialin Date: Tue, 1 Nov 2016 09:22:09 +0800 Subject: [PATCH 223/343] Modify UART driver: 1. Add a ring buffer for UART TX. If the buffer size is set to zero, driver will not use a buffer. But we need a task to send data from buffer to fifo. I tried directly copy data in ISR, but the code looked too long for ISR. 2. Modify the format in uart.h --- components/driver/include/driver/uart.h | 712 +++++++++++++----------- components/driver/uart.c | 421 ++++++++------ 2 files changed, 633 insertions(+), 500 deletions(-) diff --git a/components/driver/include/driver/uart.h b/components/driver/include/driver/uart.h index dafdf54a84..3ea77b2d02 100644 --- a/components/driver/include/driver/uart.h +++ b/components/driver/include/driver/uart.h @@ -24,175 +24,168 @@ extern "C" { #include "soc/uart_struct.h" #include "esp_err.h" #include "driver/periph_ctrl.h" +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" +#include "freertos/xtensa_api.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "freertos/ringbuf.h" #include extern const char* UART_TAG; #define UART_FIFO_LEN (128) //Do not change this, this value describes the length of the gardware FIFO in the ESP32 #define UART_INTR_MASK 0x1ff #define UART_LINE_INV_MASK (0x3f << 19) +#define UART_BITRATE_MAX 5000000 typedef enum { - UART_DATA_5_BITS = 0x0, //word length: 5bits - UART_DATA_6_BITS = 0x1, //word length: 6bits - UART_DATA_7_BITS = 0x2, //word length: 7bits - UART_DATA_8_BITS = 0x3, //word length: 8bits + UART_DATA_5_BITS = 0x0, /*!< word length: 5bits*/ + UART_DATA_6_BITS = 0x1, /*!< word length: 6bits*/ + UART_DATA_7_BITS = 0x2, /*!< word length: 7bits*/ + UART_DATA_8_BITS = 0x3, /*!< word length: 8bits*/ UART_DATA_MAX_BITS = 0X4, } uart_word_length_t; typedef enum { - UART_STOP_BITS_1 = 0x1, //stop bit: 1bit - UART_STOP_BITS_1_5 = 0x2, //stop bit: 1.5bits - UART_STOP_BITS_2 = 0x3, //stop bit: 2bits + UART_STOP_BITS_1 = 0x1, /*!< stop bit: 1bit*/ + UART_STOP_BITS_1_5 = 0x2, /*!< stop bit: 1.5bits*/ + UART_STOP_BITS_2 = 0x3, /*!< stop bit: 2bits*/ UART_STOP_BITS_MAX = 0x4, } uart_stop_bits_t; typedef enum { - UART_NUM_0 = 0x0, //base address 0x3ff40000 - UART_NUM_1 = 0x1, //base address 0x3ff50000 - UART_NUM_2 = 0x2, //base address 0x3ff6E000 + UART_NUM_0 = 0x0, /*!< UART base address 0x3ff40000*/ + UART_NUM_1 = 0x1, /*!< UART base address 0x3ff50000*/ + UART_NUM_2 = 0x2, /*!< UART base address 0x3ff6E000*/ UART_NUM_MAX, } uart_port_t; typedef enum { - UART_PARITY_DISABLE = 0x0, //Disable UART parity - UART_PARITY_EVEN = 0x10, //Enable UART even parity - UART_PARITY_ODD = 0x11 //Enable UART odd parity + UART_PARITY_DISABLE = 0x0, /*!< Disable UART parity*/ + UART_PARITY_EVEN = 0x10, /*!< Enable UART even parity*/ + UART_PARITY_ODD = 0x11 /*!< Enable UART odd parity*/ } uart_parity_t; typedef enum { - UART_BITRATE_300 = 300, - UART_BITRATE_600 = 600, - UART_BITRATE_1200 = 1200, - UART_BITRATE_2400 = 2400, - UART_BITRATE_4800 = 4800, - UART_BITRATE_9600 = 9600, - UART_BITRATE_19200 = 19200, - UART_BITRATE_38400 = 38400, - UART_BITRATE_57600 = 57600, - UART_BITRATE_74880 = 74880, - UART_BITRATE_115200 = 115200, - UART_BITRATE_230400 = 230400, - UART_BITRATE_460800 = 460800, - UART_BITRATE_921600 = 921600, - UART_BITRATE_1843200 = 1843200, - UART_BITRATE_3686400 = 3686400, - UART_BITRATE_MAX = 5000000, -} uart_baudrate_t; //you can set any rate you need in this range - -typedef enum { - UART_HW_FLOWCTRL_DISABLE = 0x0, //disable hardware flow control - UART_HW_FLOWCTRL_RTS = 0x1, //enable RX hardware flow control (rts) - UART_HW_FLOWCTRL_CTS = 0x2, //enable TX hardware flow control (cts) - UART_HW_FLOWCTRL_CTS_RTS = 0x3, //enable hardware flow control + UART_HW_FLOWCTRL_DISABLE = 0x0, /*!< disable hardware flow control*/ + UART_HW_FLOWCTRL_RTS = 0x1, /*!< enable RX hardware flow control (rts)*/ + UART_HW_FLOWCTRL_CTS = 0x2, /*!< enable TX hardware flow control (cts)*/ + UART_HW_FLOWCTRL_CTS_RTS = 0x3, /*!< enable hardware flow control*/ UART_HW_FLOWCTRL_MAX = 0x4, } uart_hw_flowcontrol_t; typedef enum { - UART_INVERSE_DISABLE = 0x0, //Disable UART wire output inverse - UART_INVERSE_RXD = (uint32_t)UART_RXD_INV_M, //UART RXD input inverse - UART_INVERSE_CTS = (uint32_t)UART_CTS_INV_M, //UART CTS input inverse - UART_INVERSE_TXD = (uint32_t)UART_TXD_INV_M, //UART TXD output inverse - UART_INVERSE_RTS = (uint32_t)UART_RTS_INV_M, //UART RTS output inverse + UART_INVERSE_DISABLE = 0x0, /*!< Disable UART wire output inverse*/ + UART_INVERSE_RXD = (uint32_t)UART_RXD_INV_M, /*!< UART RXD input inverse*/ + UART_INVERSE_CTS = (uint32_t)UART_CTS_INV_M, /*!< UART CTS input inverse*/ + UART_INVERSE_TXD = (uint32_t)UART_TXD_INV_M, /*!< UART TXD output inverse*/ + UART_INVERSE_RTS = (uint32_t)UART_RTS_INV_M, /*!< UART RTS output inverse*/ } uart_inverse_t; typedef struct { - uart_baudrate_t baud_rate; //UART baudrate - uart_word_length_t data_bits; //UART byte size - uart_parity_t parity; //UART parity mode - uart_stop_bits_t stop_bits; //UART stop bits - uart_hw_flowcontrol_t flow_ctrl; //UART hw flow control mode(cts/rts) - uint8_t rx_flow_ctrl_thresh ; //UART hw RTS threshold + int baud_rate; /*!< UART baudrate*/ + uart_word_length_t data_bits; /*!< UART byte size*/ + uart_parity_t parity; /*!< UART parity mode*/ + uart_stop_bits_t stop_bits; /*!< UART stop bits*/ + uart_hw_flowcontrol_t flow_ctrl; /*!< UART hw flow control mode(cts/rts)*/ + uint8_t rx_flow_ctrl_thresh ; /*!< UART hw RTS threshold*/ } uart_config_t; typedef struct { - uint32_t intr_enable_mask; //UART interrupt enable mask, choose from UART_XXXX_INT_ENA_M under UART_INT_ENA_REG(i), connect with bit-or operator - uint8_t rx_timeout_thresh; //UART timeout interrupt threshold(unit: time of sending one byte) - uint8_t txfifo_empty_intr_thresh; //UART TX empty interrupt threshold. - uint8_t rxfifo_full_thresh; //UART RX full interrupt threshold. + uint32_t intr_enable_mask; /*!< UART interrupt enable mask, choose from UART_XXXX_INT_ENA_M under UART_INT_ENA_REG(i), connect with bit-or operator*/ + uint8_t rx_timeout_thresh; /*!< UART timeout interrupt threshold(unit: time of sending one byte)*/ + uint8_t txfifo_empty_intr_thresh; /*!< UART TX empty interrupt threshold.*/ + uint8_t rxfifo_full_thresh; /*!< UART RX full interrupt threshold.*/ } uart_intr_config_t; - typedef enum { - UART_DATA, - UART_BREAK, - UART_BUFFER_FULL, - UART_FIFO_OVF, - UART_FRAME_ERR, - UART_PARITY_ERR, - UART_EVENT_MAX, + UART_DATA, /*!< UART data event*/ + UART_BREAK, /*!< UART break event*/ + UART_BUFFER_FULL, /*!< UART RX buffer full event*/ + UART_FIFO_OVF, /*!< UART FIFO overflow event*/ + UART_FRAME_ERR, /*!< UART RX frame error event*/ + UART_PARITY_ERR, /*!< UART RX parity event*/ + UART_DATA_BREAK, /*!< UART TX data and break event*/ + UART_EVENT_MAX, /*!< UART event max index*/ } uart_event_type_t; typedef struct { uart_event_type_t type; union { struct { + int brk_len; size_t size; + uint8_t data[]; } data; - }; } uart_event_t; - - /** * @brief Set UART data bits. * - * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param uart_word_length_t data_bit : UART data bits + * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param data_bit UART data bits * - * @return ESP_OK : Success - * ESP_FAIL: Parameter error + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error */ esp_err_t uart_set_word_length(uart_port_t uart_num, uart_word_length_t data_bit); /** * @brief Get UART data bits. * - * @param uart_port_t uart_no: UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 * - * @return ESP_FAIL : Parameter error - * ESP_OK : Success, result will be put in (*data_bit) + * @return + * - ESP_FAIL Parameter error + * - ESP_OK Success, result will be put in (*data_bit) */ esp_err_t uart_get_word_length(uart_port_t uart_num, uart_word_length_t* data_bit); /** * @brief Set UART stop bits. * - * @param uart_port_t uart_no: UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param uart_stop_bits_t bit_num : UART stop bits + * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param bit_num UART stop bits * - * @return ESP_OK : Success - * ESP_FAIL: Fail + * @return + * - ESP_OK Success + * - ESP_FAIL Fail */ esp_err_t uart_set_stop_bits(uart_port_t uart_no, uart_stop_bits_t bit_num); /** * @brief Set UART stop bits. * - * @param uart_port_t uart_no: UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 * - * @return ESP_FAIL : Parameter error - * ESP_OK : Success, result will be put in (*stop_bit) + * @return + * - ESP_FAIL Parameter error + * - ESP_OK Success, result will be put in (*stop_bit) */ esp_err_t uart_get_stop_bits(uart_port_t uart_num, uart_stop_bits_t* stop_bit); /** * @brief Set UART parity. * - * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param uart_parity_t parity_mode : the enum of uart parity configuration + * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param parity_mode the enum of uart parity configuration * - * @return null + * @return + * - ESP_FAIL Parameter error + * - ESP_OK Success */ esp_err_t uart_set_parity(uart_port_t uart_no, uart_parity_t parity_mode); /** * @brief Get UART parity mode. * - * @param uart_port_t uart_no: UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 * - * @return ESP_FAIL : Parameter error - * ESP_OK : Success, result will be put in (*parity_mode) + * @return + * - ESP_FAIL Parameter error + * - ESP_OK Success, result will be put in (*parity_mode) * */ esp_err_t uart_get_parity(uart_port_t uart_num, uart_parity_t* parity_mode); @@ -200,32 +193,37 @@ esp_err_t uart_get_parity(uart_port_t uart_num, uart_parity_t* parity_mode); /** * @brief Set UART baud rate. * - * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param uint32_t baud_rate : UART baud-rate, we can choose one from uart_baudrate_t, or set a value. + * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param baud_rate UART baud-rate. * - * @return null + * @return + * - ESP_FAIL Parameter error + * - ESP_OK Success */ esp_err_t uart_set_baudrate(uart_port_t uart_no, uint32_t baud_rate); /** * @brief Get UART bit-rate. * - * @param uart_port_t uart_no: UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param uart_no: UART_NUM_0, UART_NUM_1 or UART_NUM_2 * - * @return ESP_FAIL : Parameter error - * ESP_OK : Success, result will be put in (*baudrate) + * @return + * - ESP_FAIL Parameter error + * - ESP_OK Success, result will be put in (*baudrate) * */ esp_err_t uart_get_baudrate(uart_port_t uart_num, uint32_t* baudrate); /** * @brief Set UART line inverse mode - * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param uint32_t inverse_mask : Choose the wires that need to be inversed - * (Should be chosen from uart_inverse_t, combine with OR-OPERATION) + * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param inverse_mask Choose the wires that need to be inversed. * - * @return ESP_OK : Success - * ESP_FAIL: Parameter error + * (inverse_mask should be chosen from uart_inverse_t, combine with OR-OPERATION) + * + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error */ esp_err_t uart_set_line_inverse(uart_port_t uart_no, uint32_t inverse_mask) ; @@ -233,57 +231,65 @@ esp_err_t uart_set_line_inverse(uart_port_t uart_no, uint32_t inverse_mask) ; /** * @brief Set hardware flow control. * - * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param uart_hw_flowcontrol_t flow_ctrl : Hardware flow control mode - * @param uint8_t rx_thresh : Threshold of Hardware RX flow control(0 ~ UART_FIFO_LEN) + * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param flow_ctrl Hardware flow control mode + * @param rx_thresh Threshold of Hardware RX flow control(0 ~ UART_FIFO_LEN) * - * @return ESP_OK : Success - * ESP_FAIL: Parameter error + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error */ esp_err_t uart_set_hw_flow_ctrl(uart_port_t uart_no, uart_hw_flowcontrol_t flow_ctrl, uint8_t rx_thresh); /** * @brief Get hardware flow control mode - * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 * - * @return ESP_FAIL : Parameter error - * ESP_OK : Success, result will be put in (*flow_ctrl) + * @return + * - ESP_FAIL Parameter error + * - ESP_OK Success, result will be put in (*flow_ctrl) */ esp_err_t uart_get_hw_flow_ctrl(uart_port_t uart_num, uart_hw_flowcontrol_t* flow_ctrl); /** * @brief Clear UART interrupt status * - * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param uint32_t clr_mask : Bit mask of the status that to be cleared. - * enable_mask should be chosen from the fields of register UART_INT_CLR_REG + * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param clr_mask Bit mask of the status that to be cleared. * - * @return ESP_OK : Success - * ESP_FAIL: Parameter error + * (enable_mask should be chosen from the fields of register UART_INT_CLR_REG) + * + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error */ esp_err_t uart_clear_intr_status(uart_port_t uart_num, uint32_t clr_mask); /** * @brief Set UART interrupt enable * - * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param uint32_t enable_mask : Bit mask of the enable bits. - * enable_mask should be chosen from the fields of register UART_INT_ENA_REG + * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param enable_mask Bit mask of the enable bits. * - * @return ESP_OK : Success - * ESP_FAIL: Parameter error + * (enable_mask should be chosen from the fields of register UART_INT_ENA_REG) + * + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error */ esp_err_t uart_enable_intr_mask(uart_port_t uart_num, uint32_t enable_mask); /** * @brief Clear UART interrupt enable bits * - * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param uint32_t disable_mask : Bit mask of the disable bits. - * Disable_mask should be chosen from the fields of register UART_INT_ENA_REG + * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param disable_mask Bit mask of the disable bits. * - * @return ESP_OK : Success - * ESP_FAIL: Parameter error + * (disable_mask should be chosen from the fields of register UART_INT_ENA_REG) + * + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error */ esp_err_t uart_disable_intr_mask(uart_port_t uart_num, uint32_t disable_mask); @@ -291,42 +297,46 @@ esp_err_t uart_disable_intr_mask(uart_port_t uart_num, uint32_t disable_mask); /** * @brief Enable UART RX interrupt(RX_FULL & RX_TIMEOUT INTERRUPT) * - * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 * - * @return ESP_OK : Success - * ESP_FAIL: Parameter error + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error */ esp_err_t uart_enable_rx_intr(uart_port_t uart_num); /** * @brief Disable UART RX interrupt(RX_FULL & RX_TIMEOUT INTERRUPT) * - * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 * - * @return ESP_OK : Success - * ESP_FAIL: Parameter error + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error */ esp_err_t uart_disable_rx_intr(uart_port_t uart_num); /** * @brief Disable UART TX interrupt(RX_FULL & RX_TIMEOUT INTERRUPT) * - * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 * - * @return ESP_OK : Success - * ESP_FAIL: Parameter error + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error */ esp_err_t uart_disable_tx_intr(uart_port_t uart_num); /** * @brief Enable UART TX interrupt(RX_FULL & RX_TIMEOUT INTERRUPT) * - * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param int enable : 1: enable; 0: disable - * @param int thresh : Threshold of TX interrupt, 0 ~ UART_FIFO_LEN + * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param enable 1: enable; 0: disable + * @param thresh Threshold of TX interrupt, 0 ~ UART_FIFO_LEN * - * @return ESP_OK : Success - * ESP_FAIL: Parameter error + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error */ esp_err_t uart_enable_tx_intr(uart_port_t uart_num, int enable, int thresh); @@ -337,29 +347,31 @@ esp_err_t uart_enable_tx_intr(uart_port_t uart_num, int enable, int thresh); * We can find the information of INUM and interrupt level in soc.h. * * - * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param uint8_t uart_intr_num : UART interrupt number,check the info in soc.h, and please refer to core-isa.h for more details - * @param void (* fn)(void* ) : Interrupt handler function. - * Note that the handler function MUST be defined with attribution of "IRAM_ATTR" for now. - * @param void * arg : parameter for handler function + * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param uart_intr_num UART interrupt number,check the info in soc.h, and please refer to core-isa.h for more details + * @param fn Interrupt handler function. + * @attention + * The ISR handler function MUST be defined with attribution of "IRAM_ATTR" for now. + * @param arg parameter for handler function * - * @return ESP_OK : Success - * ESP_FAIL: Parameter error + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error */ esp_err_t uart_isr_register(uart_port_t uart_num, uint8_t uart_intr_num, void (*fn)(void*), void * arg); /** * @brief Set UART pin number * - * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param tx_io_num : UART TX pin GPIO number - * @param rx_io_num : UART RX pin GPIO number - * @param rts_io_num : UART RTS pin GPIO number - * @param cts_io_num : UART CTS pin GPIO number + * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param tx_io_num UART TX pin GPIO number + * @param rx_io_num UART RX pin GPIO number + * @param rts_io_num UART RTS pin GPIO number + * @param cts_io_num UART CTS pin GPIO number * - * - * @return ESP_OK : Success - * ESP_FAIL: Parameter error + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error */ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int rts_io_num, int cts_io_num); @@ -367,97 +379,107 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r * @brief UART set RTS level (before inverse) * UART rx hardware flow control should not be set. * - * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param int level : 1: RTS output low(active) - * 0: RTS output high(block) + * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param level 1: RTS output low(active); 0: RTS output high(block) * - * @return ESP_OK : Success - * ESP_FAIL: Parameter error + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error */ esp_err_t uart_set_rts(uart_port_t uart_num, int level); /** * @brief UART set DTR level (before inverse) * - * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param int level : 1: DTR output low - * 0: DTR output high + * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param level 1: DTR output low; 0: DTR output high * - * @return ESP_OK : Success - * ESP_FAIL: Parameter error + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error */ esp_err_t uart_set_dtr(uart_port_t uart_num, int level); /** * @brief UART parameter configure * - * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param uart_config_t *uart_config: UART parameter settings + * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param uart_config UART parameter settings * - * @return ESP_OK : Success - * ESP_FAIL: Parameter error + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error */ esp_err_t uart_param_config(uart_port_t uart_num, uart_config_t *uart_config); /** * @brief UART interrupt configure * - * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param uart_intr_config_t *p_intr_conf: UART interrupt settings + * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param p_intr_conf UART interrupt settings * - * @return ESP_OK : Success - * ESP_FAIL: Parameter error + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error */ esp_err_t uart_intr_config(uart_port_t uart_num, uart_intr_config_t *p_intr_conf); /** * @brief Install UART driver. + * * UART ISR handler will be attached to the same CPU core that this function is running on. * Users should know that which CPU is running and then pick a INUM that is not used by system. * We can find the information of INUM and interrupt level in soc.h. * - * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param int buffer_size : UART ring buffer size - * @param int queue_size : UART event queue size/depth. - * @param int uart_intr_num : UART interrupt number,check the info in soc.h, and please refer to core-isa.h for more details + * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param rx_buffer_size UART RX ring buffer size + * @param tx_buffer_size UART TX ring buffer size, if set to zero, driver will not use TX buffer and TX task. + * @param queue_size UART event queue size/depth. + * @param uart_intr_num UART interrupt number,check the info in soc.h, and please refer to core-isa.h for more details + * @param uart_queue UART event queue handle, if set NULL, driver will not use an event queue. + * @param buf_type UART RX ring_buffer type * - * @return ESP_OK : Success - * ESP_FAIL: Parameter error + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error */ -esp_err_t uart_driver_install(uart_port_t uart_num, int buffer_size, int queue_size, int uart_intr_num, void* uart_queue); +esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_buffer_size, int queue_size, int uart_intr_num, void* uart_queue, ringbuf_type_t rx_buf_type); /** * @brief Uninstall UART driver. * - * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 * - * @return ESP_OK : Success - * ESP_FAIL: Parameter error + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error */ esp_err_t uart_driver_delete(uart_port_t uart_num); /** * @brief Wait UART TX FIFO empty * - * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param TickType_t ticks_to_wait: Timeout, count in RTOS ticks + * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param ticks_to_wait Timeout, count in RTOS ticks * - * @return ESP_OK : Success - * ESP_FAIL : Parameter error - * ESP_ERR_TIMEOUT: Timeout + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error + * - ESP_ERR_TIMEOUT Timeout */ -esp_err_t uart_wait_tx_fifo_empty(uart_port_t uart_num, TickType_t ticks_to_wait); +esp_err_t uart_wait_tx_done(uart_port_t uart_num, TickType_t ticks_to_wait); /** * @brief Send data to the UART port from a given buffer and length, * This function will not wait for the space in TX FIFO, just fill the TX FIFO and return when the FIFO is full. * - * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param char* buffer : data buffer address - * @param uint32_t len : data length to send + * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param buffer data buffer address + * @param len data length to send * - * @return -1 : Parameter error - * OTHERS(>=0): The number of data that pushed to the TX FIFO + * @return + * - (-1) Parameter error + * - OTHERS(>=0) The number of data that pushed to the TX FIFO */ int uart_tx_chars(uart_port_t uart_no, char* buffer, uint32_t len); @@ -465,12 +487,13 @@ int uart_tx_chars(uart_port_t uart_no, char* buffer, uint32_t len); * @brief Send data to the UART port from a given buffer and length, * This function will not return until all the data have been sent out, or at least pushed into TX FIFO. * - * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param char* src : data buffer address - * @param size_t size : data length to send + * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param src data buffer address + * @param size data length to send * - * @return -1 : Parameter error - * OTHERS(>=0): The number of data that pushed to the TX FIFO + * @return + * - (-1) Parameter error + * - OTHERS(>=0) The number of data that pushed to the TX FIFO */ int uart_tx_all_chars(uart_port_t uart_num, const char* src, size_t size); @@ -478,57 +501,62 @@ int uart_tx_all_chars(uart_port_t uart_num, const char* src, size_t size); * @brief Send data to the UART port from a given buffer and length, * This function will not return until all the data and the break signal have been sent out. * - * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param char* src : data buffer address - * @param size_t size : data length to send - * @param int brk_len : break signal length (unit: one bit's time@current_baudrate) + * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param src data buffer address + * @param size data length to send + * @param brk_len break signal length (unit: one bit's time@current_baudrate) * - * @return -1 : Parameter error - * OTHERS(>=0): The number of data that pushed to the TX FIFO + * @return + * - (-1) Parameter error + * - OTHERS(>=0) The number of data that pushed to the TX FIFO */ int uart_tx_all_chars_with_break(uart_port_t uart_num, const char* src, size_t size, int brk_len); /** * @brief UART read one char * - * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param TickType_t ticks_to_wait : Timeout, count in RTOS ticks + * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param ticks_to_wait Timeout, count in RTOS ticks * - * @return -1 : Error - * Others : return a char data from UART. + * @return + * - (-1) Error + * - Others return a char data from UART. */ int uart_read_char(uart_port_t uart_num, TickType_t ticks_to_wait); /** * @brief UART read bytes from UART buffer * - * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param uint8_t* buf : pointer to the buffer. - * @param uint32_t length : data length - * @param TickType_t ticks_to_wait: Timeout, count in RTOS ticks + * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param buf pointer to the buffer. + * @param length data length + * @param ticks_to_wait: Timeout, count in RTOS ticks * - * @return -1 : Error - * Others : return a char data from uart fifo. + * @return + * - (-1) Error + * - Others return a char data from uart fifo. */ int uart_read_bytes(uart_port_t uart_num, uint8_t* buf, uint32_t length, TickType_t ticks_to_wait); /** * @brief UART ring buffer flush * - * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 * - * @return ESP_OK : Success - * ESP_FAIL: Parameter error + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error */ esp_err_t uart_flush(uart_port_t uart_num); /** * @brief Set the serial output port for ets_printf function, not effective for ESP_LOGX macro. * - * @param uart_port_t uart_no : UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 * - * @return ESP_OK : Success - * ESP_FAIL: Parameter error, or UART driver not installed. + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error, or UART driver not installed. */ esp_err_t uart_set_print_port(uart_port_t uart_no); @@ -536,141 +564,155 @@ esp_err_t uart_set_print_port(uart_port_t uart_no); * @brief Get the current serial port for ets_printf function * * - * @return current print port: 0: UART0; - * 1: UART1; - * 2: UART2; + * @return current print port(0: UART0; 1: UART1; 2: UART2) */ -int uart_get_print_port(); +int uart_get_print_port(void); /***************************EXAMPLE********************************** * * * ----------------EXAMPLE OF UART SETTING --------------------- - * //1. Setup UART - * #include "freertos/queue.h" - * #define UART_INTR_NUM 17 //choose one interrupt number from soc.h - * //a. Set UART parameter - * int uart_num = 0; //uart port number + * @code{c} + * //1. Setup UART + * #include "freertos/queue.h" + * #define UART_INTR_NUM 17 //choose one interrupt number from soc.h + * //a. Set UART parameter + * int uart_num = 0; //uart port number + * uart_config_t uart_config = { + * .baud_rate = UART_BITRATE_115200, //baudrate + * .data_bits = UART_DATA_8_BITS, //data bit mode + * .parity = UART_PARITY_DISABLE, //parity mode + * .stop_bits = UART_STOP_BITS_1, //stop bit mode + * .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, //hardware flow control(cts/rts) + * .rx_flow_ctrl_thresh = 120, //flow control threshold + * }; + * uart_param_config(uart_num, &uart_config); + * //b1. Setup UART driver(with UART queue) + * QueueHandle_t uart_queue; + * uart_driver_install(uart_num, 1024 * 2, 10, UART_INTR_NUM, &uart_queue);//parameters here are just an example + * //b2. Setup UART driver(without UART queue) + * uart_driver_install(uart_num, 1024 * 2, 10, UART_INTR_NUM, NULL); //parameters here are just an example + *@endcode + *-----------------------------------------------------------------------------* + * @code{c} + * //2. Set UART pin + * uart_set_pin(uart_num, -1, -1, 15, 13); //set UART pin, not needed if use default pins. + * @endcode + *-----------------------------------------------------------------------------* + * @code{c} + * //3. Read data from UART. + * uint8_t data[128]; + * int length = 0; + * length = uart_read_bytes(uart_num, data, sizeof(data), 100); + * @endcode + *-----------------------------------------------------------------------------* + * @code{c} + * //4. Write data to UART. + * char* test_str = "This is a test string.\n" + * uart_tx_all_chars(uart_num, (const char*)test_str, strlen(test_str)); + * @endcode + *-----------------------------------------------------------------------------* + * @code{c} + * //5. Write data to UART, end with a break signal. + * uart_tx_all_chars_with_break(0, "test break\n",strlen("test break\n"), 100); + * @endcode + *-----------------------------------------------------------------------------* + * @code{c} + * //6. an example of echo test with hardware flow control on UART1 + * void uart_loop_back_test() + * { + * int uart_num = 1; * uart_config_t uart_config = { - * .baud_rate = UART_BITRATE_115200, //baudrate - * .data_bits = UART_DATA_8_BITS, //data bit mode - * .parity = UART_PARITY_DISABLE, //parity mode - * .stop_bits = UART_STOP_BITS_1, //stop bit mode - * .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, //hardware flow control(cts/rts) - * .rx_flow_ctrl_thresh = 120, //flow control threshold + * .baud_rate = 115200, + * .data_bits = UART_DATA_8_BITS, + * .parity = UART_PARITY_DISABLE, + * .stop_bits = UART_STOP_BITS_1, + * .flow_ctrl = UART_HW_FLOWCTRL_CTS_RTS, + * .rx_flow_ctrl_thresh = 122, * }; - * uart_param_config(uart_num, &uart_config); - * //b1. Setup UART driver(with UART queue) - * QueueHandle_t uart_queue; - * uart_driver_install(uart_num, 1024 * 2, 10, UART_INTR_NUM, &uart_queue);//parameters here are just an example - * //b2. Setup UART driver(without UART queue) - * uart_driver_install(uart_num, 1024 * 2, 10, UART_INTR_NUM, NULL); //parameters here are just an example - * - *-----------------------------------------------------------------------------* - * //2. Set UART pin - * uart_set_pin(uart_num, -1, -1, 15, 13); //set UART pin, not needed if use default pins. - * - *-----------------------------------------------------------------------------* - * //3. Read data from UART. - * uint8_t data[128]; - * int length = 0; - * length = uart_read_bytes(uart_num, data, sizeof(data), 100); - * - *-----------------------------------------------------------------------------* - * //4. Write data to UART. - * char* test_str = "This is a test string.\n" - * uart_tx_all_chars(uart_num, (const char*)test_str, strlen(test_str)); - * - *-----------------------------------------------------------------------------* - * //5. Write data to UART, end with a break signal. - * uart_tx_all_chars_with_break(0, "test break\n",strlen("test break\n"), 100); - * - *-----------------------------------------------------------------------------* - * - * //6. an example of echo test with hardware flow control on UART1 - * void uart_loop_back_test() - * { - * int uart_num = 1; - * uart_config_t uart_config = { - * .baud_rate = 115200, - * .data_bits = UART_DATA_8_BITS, - * .parity = UART_PARITY_DISABLE, - * .stop_bits = UART_STOP_BITS_1, - * .flow_ctrl = UART_HW_FLOWCTRL_CTS_RTS, - * .rx_flow_ctrl_thresh = 122, - * }; - * uart_param_config(uart_num, &uart_config); //Config UART1 parameters - * uart_set_pin(uart_num, 16, 17, 18, 19); //Set UART1 pins(TX: IO16, RX: IO17, RTS: IO18, CTS: IO19) - * esp_log_level_set(UART_TAG, ESP_LOG_ERROR); //Set UART log level - * uart_driver_install(uart_num, 1024 * 2, 10, 17, NULL); //Install UART driver( We don't need an event queue here) - * uint8_t data[1000]; - * while(1) { - * int len = uart_read_bytes(uart_num, data, sizeof(data), 10); //Read data from UART - * uart_tx_all_chars(uart_num, (const char*)data, len); //Write data back to UART - * } + * uart_param_config(uart_num, &uart_config); //Config UART1 parameters + * uart_set_pin(uart_num, 16, 17, 18, 19); //Set UART1 pins(TX: IO16, RX: IO17, RTS: IO18, CTS: IO19) + * esp_log_level_set(UART_TAG, ESP_LOG_ERROR); //Set UART log level + * //Install UART driver( We don't need an event queue here) + * uart_driver_install(uart_num, 1024 * 2, 1024*4, 10, 17, NULL, RINGBUF_TYPE_BYTEBUF); + * uint8_t data[1000]; + * while(1) { + * int len = uart_read_bytes(uart_num, data, sizeof(data), 10); //Read data from UART + * uart_tx_all_chars(uart_num, (const char*)data, len); //Write data back to UART * } - * + * } + * @endcode *-----------------------------------------------------------------------------* - * //7. An example of using UART event queue on UART0. - * - * #include "freertos/queue.h" - * QueueHandle_t uart0_queue; //A queue to handle UART event. - * void uart_task(void *pvParameters) - * { - * int uart_num = (int)pvParameters; - * uart_event_t event; - * uint8_t dtmp[1000]; - * for(;;) { - * if(xQueueReceive(uart0_queue, (void * )&event, (portTickType)portMAX_DELAY)) { //Waiting for UART event. - * ESP_LOGI(UART_TAG, "uart[%d] event:", uart_num); - * switch(event.type) { - * case UART_DATA: //Event of UART receving data - * ESP_LOGI(UART_TAG,"data, len: %d\n", event.data.size); - * int len = uart_read_bytes(uart_num, dtmp, event.data.size, 10); - * ESP_LOGI(UART_TAG, "uart read: %d\n", len); - * break; - * case UART_FIFO_OVF: //Event of HW FIFO overflow detected - * ESP_LOGI(UART_TAG, "hw fifo overflow\n"); - * break; - * case UART_BUFFER_FULL: //Event of UART ring buffer full - * ESP_LOGI(UART_TAG, "ring buffer full\n"); - * break; - * case UART_BREAK: - * ESP_LOGI(UART_TAG, "uart rx break\n"); //Event of UART RX break detected - * break; - * case UART_PARITY_ERR: //Event of UART parity check error - * ESP_LOGI(UART_TAG, "uart parity error\n"); - * break; - * case UART_FRAME_ERR: //Event of UART frame error - * ESP_LOGI(UART_TAG, "uart frame error\n"); - * break; - * default: //Others - * ESP_LOGI(UART_TAG, "uart event type: %d\n", event.type); - * break; - * } - * } - * } - * vTaskDelete(NULL); - * } - * - * void uart_queue_test() - * { - * int uart_num = 0; - * uart_config_t uart_config = { - * .baud_rate = 115200, - * .data_bits = UART_DATA_8_BITS, - * .parity = UART_PARITY_DISABLE, - * .stop_bits = UART_STOP_BITS_1, - * .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, - * .rx_flow_ctrl_thresh = 122, - * }; - * uart_param_config(uart_num, &uart_config); //Set UART parameters - * uart_set_pin(uart_num, -1, -1, 15, 13); //Set UART pins,(-1: default pin, no change.) - * esp_log_level_set(UART_TAG, ESP_LOG_INFO); //Set UART log level - * uart_driver_install(uart_num, 1024 * 2, 10, 17, &uart0_queue); //Install UART driver, and get the queue. - * xTaskCreate(uart_task, "uTask", 2048*8, (void*)uart_num, 10, NULL); //Create a task to handler UART event from ISR + * @code{c} + * //7. An example of using UART event queue on UART0. + * #include "freertos/queue.h" + * //A queue to handle UART event. + * QueueHandle_t uart0_queue; + * void uart_task(void *pvParameters) + * { + * int uart_num = (int)pvParameters; + * uart_event_t event; + * uint8_t dtmp[1000]; + * for(;;) { + * //Waiting for UART event. + * if(xQueueReceive(uart0_queue, (void * )&event, (portTickType)portMAX_DELAY)) { + * ESP_LOGI(UART_TAG, "uart[%d] event:", uart_num); + * switch(event.type) { + * //Event of UART receving data + * case UART_DATA: + * ESP_LOGI(UART_TAG,"data, len: %d\n", event.data.size); + * int len = uart_read_bytes(uart_num, dtmp, event.data.size, 10); + * ESP_LOGI(UART_TAG, "uart read: %d\n", len); + * break; + * //Event of HW FIFO overflow detected + * case UART_FIFO_OVF: + * ESP_LOGI(UART_TAG, "hw fifo overflow\n"); + * break; + * //Event of UART ring buffer full + * case UART_BUFFER_FULL: + * ESP_LOGI(UART_TAG, "ring buffer full\n"); + * break; + * //Event of UART RX break detected + * case UART_BREAK: + * ESP_LOGI(UART_TAG, "uart rx break\n"); + * break; + * //Event of UART parity check error + * case UART_PARITY_ERR: + * ESP_LOGI(UART_TAG, "uart parity error\n"); + * break; + * //Event of UART frame error + * case UART_FRAME_ERR: + * ESP_LOGI(UART_TAG, "uart frame error\n"); + * break; + * //Others + * default: + * ESP_LOGI(UART_TAG, "uart event type: %d\n", event.type); + * break; + * } * } + * } + * vTaskDelete(NULL); + * } * + * void uart_queue_test() + * { + * int uart_num = 0; + * uart_config_t uart_config = { + * .baud_rate = 115200, + * .data_bits = UART_DATA_8_BITS, + * .parity = UART_PARITY_DISABLE, + * .stop_bits = UART_STOP_BITS_1, + * .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, + * .rx_flow_ctrl_thresh = 122, + * }; + * uart_param_config(uart_num, &uart_config); //Set UART parameters + * uart_set_pin(uart_num, -1, -1, 15, 13); //Set UART pins,(-1: default pin, no change.) + * esp_log_level_set(UART_TAG, ESP_LOG_INFO); //Set UART log level + * //Install UART driver, and get the queue. + * uart_driver_install(uart_num, 1024 * 2, 1024*4, 10, 17, &uart0_queue, RINGBUF_TYPE_BYTEBUF); + * xTaskCreate(uart_task, "uTask", 2048*8, (void*)uart_num, 10, NULL); //Create a task to handler UART event from ISR + * } + * @endcode * ***************************END OF EXAMPLE**********************************/ diff --git a/components/driver/uart.c b/components/driver/uart.c index 29e4522d6d..eeb2c64208 100644 --- a/components/driver/uart.c +++ b/components/driver/uart.c @@ -30,13 +30,15 @@ #include "soc/uart_struct.h" const char* UART_TAG = "UART"; -#define UART_CHECK(a, str) if (!(a)) { \ +#define UART_CHECK(a, str) if (!(a)) { \ ESP_LOGE(UART_TAG,"%s:%d (%s):%s\n", __FILE__, __LINE__, __FUNCTION__, str); \ return ESP_FAIL; \ } -#define DEFAULT_EMPTY_THRESH 10 -#define DEFAULT_FULL_THRESH 120 -#define DEFAULT_TOUT_THRESH 10 +#define UART_EMPTY_THRESH_DEFAULT (10) +#define UART_FULL_THRESH_DEFAULT (120) +#define UART_TOUT_THRESH_DEFAULT (10) +#define UART_TX_TASK_DEPTH_DEFAULT (256*2+64) +#define UART_TX_TASK_PRIO_DEFAULT (10) #define UART_ENTER_CRITICAL_ISR(mux) portENTER_CRITICAL_ISR(mux) #define UART_EXIT_CRITICAL_ISR(mux) portEXIT_CRITICAL_ISR(mux) #define UART_ENTER_CRITICAL(mux) portENTER_CRITICAL(mux) @@ -46,13 +48,19 @@ typedef struct { uart_port_t uart_num; SemaphoreHandle_t tx_fifo_sem; SemaphoreHandle_t tx_mutex; + SemaphoreHandle_t tx_buffer_mutex; SemaphoreHandle_t tx_done_sem; SemaphoreHandle_t tx_brk_sem; - SemaphoreHandle_t rx_sem; + SemaphoreHandle_t rx_mux; QueueHandle_t xQueueUart; int queue_size; int intr_num; - RingbufHandle_t ring_buffer; + int rx_buf_size; + ringbuf_type_t rx_buf_type; + RingbufHandle_t rx_ring_buf; + int tx_buf_size; + RingbufHandle_t tx_ring_buf; + TaskHandle_t tx_task_handle; bool buffer_full_flg; bool tx_waiting; int cur_remain; @@ -66,20 +74,6 @@ static uart_obj_t *p_uart_obj[UART_NUM_MAX] = {0}; static uart_dev_t* UART[UART_NUM_MAX] = {&UART0, &UART1, &UART2}; static portMUX_TYPE uart_spinlock[UART_NUM_MAX] = {portMUX_INITIALIZER_UNLOCKED, portMUX_INITIALIZER_UNLOCKED, portMUX_INITIALIZER_UNLOCKED}; -//Fill UART tx_fifo and return a number, -//This function by itself is not thread-safe, always call from within a muxed section. -static int uart_fill_fifo(uart_port_t uart_num, char* buffer, uint32_t len) -{ - uint8_t i = 0; - uint8_t tx_fifo_cnt = UART[uart_num]->status.txfifo_cnt; - uint8_t tx_remain_fifo_cnt = (UART_FIFO_LEN - tx_fifo_cnt); - uint8_t copy_cnt = (len >= tx_remain_fifo_cnt ? tx_remain_fifo_cnt : len); - for(i = 0; i < copy_cnt; i++) { - WRITE_PERI_REG(UART_FIFO_AHB_REG(uart_num), buffer[i]); - } - return copy_cnt; -} - esp_err_t uart_set_word_length(uart_port_t uart_num, uart_word_length_t data_bit) { UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); @@ -315,11 +309,11 @@ esp_err_t uart_isr_register(uart_port_t uart_num, uint8_t uart_intr_num, void (* //only one GPIO pad can connect with input signal esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int rts_io_num, int cts_io_num) { -// UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); -// UART_CHECK((tx_io_num < 0 || (GPIO_IS_VALID_OUTPUT_GPIO(tx_io_num))), "tx_io_num error"); -// UART_CHECK((rx_io_num < 0 || (GPIO_IS_VALID_GPIO(rx_io_num))), "rx_io_num error"); -// UART_CHECK((rts_io_num < 0 || (GPIO_IS_VALID_OUTPUT_GPIO(rts_io_num))), "rts_io_num error"); -// UART_CHECK((cts_io_num < 0 || (GPIO_IS_VALID_GPIO(cts_io_num))), "cts_io_num error"); + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_CHECK((tx_io_num < 0 || (GPIO_IS_VALID_OUTPUT_GPIO(tx_io_num))), "tx_io_num error"); + UART_CHECK((rx_io_num < 0 || (GPIO_IS_VALID_GPIO(rx_io_num))), "rx_io_num error"); + UART_CHECK((rts_io_num < 0 || (GPIO_IS_VALID_OUTPUT_GPIO(rts_io_num))), "rts_io_num error"); + UART_CHECK((cts_io_num < 0 || (GPIO_IS_VALID_GPIO(cts_io_num))), "cts_io_num error"); int tx_sig, rx_sig, rts_sig, cts_sig; switch(uart_num) { @@ -443,7 +437,6 @@ static void IRAM_ATTR uart_rx_intr_handler_default(void *param) uart_obj_t *p_uart = (uart_obj_t*) param; uint8_t uart_num = p_uart->uart_num; uart_dev_t* uart_reg = UART[uart_num]; - uint8_t buf_idx = 0; uint32_t uart_intr_status = UART[uart_num]->int_st.val; static int rx_fifo_len = 0; @@ -478,7 +471,7 @@ static void IRAM_ATTR uart_rx_intr_handler_default(void *param) UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); uart_event.type = UART_DATA; uart_event.data.size = rx_fifo_len; - if(pdFALSE == xRingbufferSendFromISR(p_uart->ring_buffer, p_uart->data_buf, p_uart->data_len, &HPTaskAwoken)) { + if(pdFALSE == xRingbufferSendFromISR(p_uart->rx_ring_buf, p_uart->data_buf, p_uart->data_len, &HPTaskAwoken)) { UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); uart_reg->int_ena.rxfifo_full = 0; uart_reg->int_ena.rxfifo_tout = 0; @@ -544,108 +537,7 @@ static void IRAM_ATTR uart_rx_intr_handler_default(void *param) } /**************************************************************/ -esp_err_t uart_driver_install(uart_port_t uart_num, int buffer_size, int queue_size, int uart_intr_num, void* uart_queue) -{ - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); - if(p_uart_obj[uart_num] == NULL) { - ESP_INTR_DISABLE(uart_intr_num); - p_uart_obj[uart_num] = (uart_obj_t*) malloc(sizeof(uart_obj_t)); - if(p_uart_obj[uart_num] == NULL) { - ESP_LOGE(UART_TAG, "UART driver malloc error\n"); - return ESP_FAIL; - } - p_uart_obj[uart_num]->uart_num = uart_num; - p_uart_obj[uart_num]->tx_fifo_sem = xSemaphoreCreateBinary(); - xSemaphoreGive(p_uart_obj[uart_num]->tx_fifo_sem); - p_uart_obj[uart_num]->tx_done_sem = xSemaphoreCreateBinary(); - xSemaphoreGive(p_uart_obj[uart_num]->tx_done_sem); - p_uart_obj[uart_num]->tx_brk_sem = xSemaphoreCreateBinary(); - - p_uart_obj[uart_num]->tx_mutex = xSemaphoreCreateMutex(); - p_uart_obj[uart_num]->rx_sem = xSemaphoreCreateMutex(); - p_uart_obj[uart_num]->intr_num = uart_intr_num; - p_uart_obj[uart_num]->queue_size = queue_size; - - if(uart_queue) { - p_uart_obj[uart_num]->xQueueUart = xQueueCreate(queue_size, sizeof(uart_event_t)); - *((QueueHandle_t*) uart_queue) = p_uart_obj[uart_num]->xQueueUart; - ESP_LOGI(UART_TAG, "queue free spaces: %d\n", uxQueueSpacesAvailable(p_uart_obj[uart_num]->xQueueUart)); - } else { - p_uart_obj[uart_num]->xQueueUart = NULL; - } - p_uart_obj[uart_num]->buffer_full_flg = false; - p_uart_obj[uart_num]->tx_waiting = false; - p_uart_obj[uart_num]->rd_ptr = NULL; - p_uart_obj[uart_num]->cur_remain = 0; - p_uart_obj[uart_num]->head_ptr = NULL; - p_uart_obj[uart_num]->ring_buffer = xRingbufferCreate(buffer_size, 0); - } else { - ESP_LOGE(UART_TAG, "UART driver already installed\n"); - return ESP_FAIL; - } - uart_isr_register(uart_num, uart_intr_num, uart_rx_intr_handler_default, p_uart_obj[uart_num]); - uart_intr_config_t uart_intr = { - .intr_enable_mask = UART_RXFIFO_FULL_INT_ENA_M - | UART_RXFIFO_TOUT_INT_ENA_M - | UART_FRM_ERR_INT_ENA_M - | UART_RXFIFO_OVF_INT_ENA_M - | UART_BRK_DET_INT_ENA_M, - .rxfifo_full_thresh = DEFAULT_FULL_THRESH, - .rx_timeout_thresh = DEFAULT_TOUT_THRESH, - .txfifo_empty_intr_thresh = DEFAULT_EMPTY_THRESH - }; - uart_intr_config(uart_num, &uart_intr); - ESP_INTR_ENABLE(uart_intr_num); - return ESP_OK; -} - -//Make sure no other tasks are still using UART before you call this function -esp_err_t uart_driver_delete(uart_port_t uart_num) -{ - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); - if(p_uart_obj[uart_num] == NULL) { - ESP_LOGI(UART_TAG, "ALREADY NULL\n"); - return ESP_OK; - } - ESP_INTR_DISABLE(p_uart_obj[uart_num]->intr_num); - uart_disable_rx_intr(uart_num); - uart_disable_tx_intr(uart_num); - uart_isr_register(uart_num, p_uart_obj[uart_num]->intr_num, NULL, NULL); - - if(p_uart_obj[uart_num]->tx_fifo_sem) { - vSemaphoreDelete(p_uart_obj[uart_num]->tx_fifo_sem); - p_uart_obj[uart_num]->tx_fifo_sem = NULL; - } - if(p_uart_obj[uart_num]->tx_done_sem) { - vSemaphoreDelete(p_uart_obj[uart_num]->tx_done_sem); - p_uart_obj[uart_num]->tx_done_sem = NULL; - } - if(p_uart_obj[uart_num]->tx_brk_sem) { - vSemaphoreDelete(p_uart_obj[uart_num]->tx_brk_sem); - p_uart_obj[uart_num]->tx_brk_sem = NULL; - } - if(p_uart_obj[uart_num]->tx_mutex) { - vSemaphoreDelete(p_uart_obj[uart_num]->tx_mutex); - p_uart_obj[uart_num]->tx_mutex = NULL; - } - if(p_uart_obj[uart_num]->rx_sem) { - vSemaphoreDelete(p_uart_obj[uart_num]->rx_sem); - p_uart_obj[uart_num]->rx_sem = NULL; - } - if(p_uart_obj[uart_num]->xQueueUart) { - vQueueDelete(p_uart_obj[uart_num]->xQueueUart); - p_uart_obj[uart_num]->xQueueUart = NULL; - } - if(p_uart_obj[uart_num]->ring_buffer) { - vRingbufferDelete(p_uart_obj[uart_num]->ring_buffer); - p_uart_obj[uart_num]->ring_buffer = NULL; - } - free(p_uart_obj[uart_num]); - p_uart_obj[uart_num] = NULL; - return ESP_OK; -} - -esp_err_t uart_wait_tx_fifo_empty(uart_port_t uart_num, TickType_t ticks_to_wait) +esp_err_t uart_wait_tx_done(uart_port_t uart_num, TickType_t ticks_to_wait) { UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); UART_CHECK((p_uart_obj[uart_num]), "uart driver error"); @@ -657,17 +549,9 @@ esp_err_t uart_wait_tx_fifo_empty(uart_port_t uart_num, TickType_t ticks_to_wait return ESP_ERR_TIMEOUT; } ticks_to_wait = ticks_end - xTaskGetTickCount(); - //take 1st tx_done_sem - res = xSemaphoreTake(p_uart_obj[uart_num]->tx_done_sem, (portTickType)ticks_to_wait); - if(res == pdFALSE) { - ESP_LOGE(UART_TAG, "take uart done sem error, should not get here.\n"); - xSemaphoreGive(p_uart_obj[uart_num]->tx_done_sem); - xSemaphoreGive(p_uart_obj[uart_num]->tx_mutex); - return ESP_ERR_TIMEOUT; - } + xSemaphoreTake(p_uart_obj[uart_num]->tx_done_sem, 0); ticks_to_wait = ticks_end - xTaskGetTickCount(); if(UART[uart_num]->status.txfifo_cnt == 0) { - xSemaphoreGive(p_uart_obj[uart_num]->tx_done_sem); xSemaphoreGive(p_uart_obj[uart_num]->tx_mutex); return ESP_OK; } @@ -676,11 +560,9 @@ esp_err_t uart_wait_tx_fifo_empty(uart_port_t uart_num, TickType_t ticks_to_wait res = xSemaphoreTake(p_uart_obj[uart_num]->tx_done_sem, (portTickType)ticks_to_wait); if(res == pdFALSE) { uart_disable_intr_mask(uart_num, UART_TX_DONE_INT_ENA_M); - xSemaphoreGive(p_uart_obj[uart_num]->tx_done_sem); xSemaphoreGive(p_uart_obj[uart_num]->tx_mutex); return ESP_ERR_TIMEOUT; } - xSemaphoreGive(p_uart_obj[uart_num]->tx_done_sem); xSemaphoreGive(p_uart_obj[uart_num]->tx_mutex); return ESP_OK; } @@ -696,6 +578,20 @@ static esp_err_t uart_set_break(uart_port_t uart_num, int break_num) return ESP_OK; } +//Fill UART tx_fifo and return a number, +//This function by itself is not thread-safe, always call from within a muxed section. +static int uart_fill_fifo(uart_port_t uart_num, char* buffer, uint32_t len) +{ + uint8_t i = 0; + uint8_t tx_fifo_cnt = UART[uart_num]->status.txfifo_cnt; + uint8_t tx_remain_fifo_cnt = (UART_FIFO_LEN - tx_fifo_cnt); + uint8_t copy_cnt = (len >= tx_remain_fifo_cnt ? tx_remain_fifo_cnt : len); + for(i = 0; i < copy_cnt; i++) { + WRITE_PERI_REG(UART_FIFO_AHB_REG(uart_num), buffer[i]); + } + return copy_cnt; +} + int uart_tx_chars(uart_port_t uart_num, char* buffer, uint32_t len) { UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); @@ -727,7 +623,7 @@ static int uart_tx_all(uart_port_t uart_num, const char* src, size_t size, bool size_t sent = uart_fill_fifo(uart_num, (char*) src, size); if(sent < size) { p_uart_obj[uart_num]->tx_waiting = true; - uart_enable_tx_intr(uart_num, 1, DEFAULT_EMPTY_THRESH); + uart_enable_tx_intr(uart_num, 1, UART_EMPTY_THRESH_DEFAULT); } size -= sent; src += sent; @@ -742,12 +638,55 @@ static int uart_tx_all(uart_port_t uart_num, const char* src, size_t size, bool return original_size; } +static void uart_tx_task(void* arg) +{ + uart_obj_t* p_uart = (uart_obj_t*) arg; + size_t size; + uart_event_t evt; + for(;;) { + char* data = (char*) xRingbufferReceive(p_uart->tx_ring_buf, &size, portMAX_DELAY); + if(data == NULL) { + continue; + } + memcpy(&evt, data, sizeof(evt)); + if(evt.type == UART_DATA) { + uart_tx_all(p_uart->uart_num, (const char*) data + sizeof(uart_event_t), evt.data.size, 0, 0); + } else if(evt.type == UART_DATA_BREAK) { + uart_tx_all(p_uart->uart_num, (const char*) data + sizeof(uart_event_t), evt.data.size, 1, evt.data.brk_len); + } + vRingbufferReturnItem(p_uart->tx_ring_buf, data); + } + vTaskDelete(NULL); +} + int uart_tx_all_chars(uart_port_t uart_num, const char* src, size_t size) { UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); - UART_CHECK((p_uart_obj[uart_num]), "uart driver error"); + UART_CHECK((p_uart_obj[uart_num] != NULL), "uart driver error"); UART_CHECK(src, "buffer null"); - return uart_tx_all(uart_num, src, size, 0, 0); + if(p_uart_obj[uart_num]->tx_buf_size > 0) { + if(xRingbufferGetMaxItemSize(p_uart_obj[uart_num]->tx_ring_buf) > (size + sizeof(uart_event_t))) { + uart_event_t *evt = (uart_event_t*) malloc(sizeof(uart_event_t) + size); + if(evt == NULL) { + ESP_LOGE(UART_TAG, "UART EVT MALLOC ERROR\n"); + return -1; + } + xSemaphoreTake(p_uart_obj[uart_num]->tx_buffer_mutex, (portTickType)portMAX_DELAY); + evt->type = UART_DATA; + evt->data.size = size; + memcpy(evt->data.data, src, size); + xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void*) evt, sizeof(uart_event_t) + size, portMAX_DELAY); + free(evt); + evt = NULL; + xSemaphoreGive(p_uart_obj[uart_num]->tx_buffer_mutex); + return size; + } else { + ESP_LOGW(UART_TAG, "UART TX BUFFER TOO SMALL[0], SEND DIRECTLY\n"); + return uart_tx_all(uart_num, src, size, 0, 0); + } + } else { + return uart_tx_all(uart_num, src, size, 0, 0); + } } int uart_tx_all_chars_with_break(uart_port_t uart_num, const char* src, size_t size, int brk_len) @@ -757,7 +696,29 @@ int uart_tx_all_chars_with_break(uart_port_t uart_num, const char* src, size_t s UART_CHECK((size > 0), "uart size error"); UART_CHECK((src), "uart data null"); UART_CHECK((brk_len > 0 && brk_len < 256), "break_num error"); - return uart_tx_all(uart_num, src, size, 1, brk_len); + if(p_uart_obj[uart_num]->tx_buf_size > 0) { + if(xRingbufferGetMaxItemSize(p_uart_obj[uart_num]->tx_ring_buf) > (size)) { + uart_event_t *evt = (uart_event_t*) malloc(sizeof(uart_event_t) + size); + if(evt == NULL) { + return -1; + } + xSemaphoreTake(p_uart_obj[uart_num]->tx_buffer_mutex, (portTickType)portMAX_DELAY); + evt->type = UART_DATA_BREAK; + evt->data.size = size; + evt->data.brk_len = brk_len; + memcpy(evt->data.data, src, size); + xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void*) evt, sizeof(uart_event_t) + size, portMAX_DELAY); + free(evt); + evt = NULL; + xSemaphoreGive(p_uart_obj[uart_num]->tx_buffer_mutex); + return size; + } else { + ESP_LOGW(UART_TAG, "UART TX BUFFER TOO SMALL[1], SEND DIRECTLY\n"); + return uart_tx_all(uart_num, src, size, 1, brk_len); + } + } else { + return uart_tx_all(uart_num, src, size, 1, brk_len); + } } int uart_read_char(uart_port_t uart_num, TickType_t ticks_to_wait) @@ -768,18 +729,18 @@ int uart_read_char(uart_port_t uart_num, TickType_t ticks_to_wait) size_t size; int val; portTickType ticks_end = xTaskGetTickCount() + ticks_to_wait; - if(xSemaphoreTake(p_uart_obj[uart_num]->rx_sem,(portTickType)ticks_to_wait) != pdTRUE) { + if(xSemaphoreTake(p_uart_obj[uart_num]->rx_mux,(portTickType)ticks_to_wait) != pdTRUE) { return -1; } if(p_uart_obj[uart_num]->cur_remain == 0) { ticks_to_wait = ticks_end - xTaskGetTickCount(); - data = (uint8_t*) xRingbufferReceive(p_uart_obj[uart_num]->ring_buffer, &size, (portTickType) ticks_to_wait); + data = (uint8_t*) xRingbufferReceive(p_uart_obj[uart_num]->rx_ring_buf, &size, (portTickType) ticks_to_wait); if(data) { p_uart_obj[uart_num]->head_ptr = data; p_uart_obj[uart_num]->rd_ptr = data; p_uart_obj[uart_num]->cur_remain = size; } else { - xSemaphoreGive(p_uart_obj[uart_num]->rx_sem); + xSemaphoreGive(p_uart_obj[uart_num]->rx_mux); return -1; } } @@ -787,18 +748,18 @@ int uart_read_char(uart_port_t uart_num, TickType_t ticks_to_wait) p_uart_obj[uart_num]->rd_ptr++; p_uart_obj[uart_num]->cur_remain--; if(p_uart_obj[uart_num]->cur_remain == 0) { - vRingbufferReturnItem(p_uart_obj[uart_num]->ring_buffer, p_uart_obj[uart_num]->head_ptr); + vRingbufferReturnItem(p_uart_obj[uart_num]->rx_ring_buf, p_uart_obj[uart_num]->head_ptr); p_uart_obj[uart_num]->head_ptr = NULL; p_uart_obj[uart_num]->rd_ptr = NULL; if(p_uart_obj[uart_num]->buffer_full_flg) { - BaseType_t res = xRingbufferSend(p_uart_obj[uart_num]->ring_buffer, p_uart_obj[uart_num]->data_buf, p_uart_obj[uart_num]->data_len, 1); + BaseType_t res = xRingbufferSend(p_uart_obj[uart_num]->rx_ring_buf, p_uart_obj[uart_num]->data_buf, p_uart_obj[uart_num]->data_len, 1); if(res == pdTRUE) { p_uart_obj[uart_num]->buffer_full_flg = false; uart_enable_rx_intr(p_uart_obj[uart_num]->uart_num); } } } - xSemaphoreGive(p_uart_obj[uart_num]->rx_sem); + xSemaphoreGive(p_uart_obj[uart_num]->rx_mux); return val; } @@ -807,23 +768,22 @@ int uart_read_bytes(uart_port_t uart_num, uint8_t* buf, uint32_t length, TickTyp UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); UART_CHECK((buf), "uart_num error"); UART_CHECK((p_uart_obj[uart_num]), "uart driver error"); - uint8_t* data = NULL; size_t size; size_t copy_len = 0; int len_tmp; - if(xSemaphoreTake(p_uart_obj[uart_num]->rx_sem,(portTickType)ticks_to_wait) != pdTRUE) { + if(xSemaphoreTake(p_uart_obj[uart_num]->rx_mux,(portTickType)ticks_to_wait) != pdTRUE) { return -1; } while(length) { if(p_uart_obj[uart_num]->cur_remain == 0) { - data = (uint8_t*) xRingbufferReceive(p_uart_obj[uart_num]->ring_buffer, &size, (portTickType) ticks_to_wait); + data = (uint8_t*) xRingbufferReceive(p_uart_obj[uart_num]->rx_ring_buf, &size, (portTickType) ticks_to_wait); if(data) { p_uart_obj[uart_num]->head_ptr = data; p_uart_obj[uart_num]->rd_ptr = data; p_uart_obj[uart_num]->cur_remain = size; } else { - xSemaphoreGive(p_uart_obj[uart_num]->rx_sem); + xSemaphoreGive(p_uart_obj[uart_num]->rx_mux); return copy_len; } } @@ -838,11 +798,11 @@ int uart_read_bytes(uart_port_t uart_num, uint8_t* buf, uint32_t length, TickTyp copy_len += len_tmp; length -= len_tmp; if(p_uart_obj[uart_num]->cur_remain == 0) { - vRingbufferReturnItem(p_uart_obj[uart_num]->ring_buffer, p_uart_obj[uart_num]->head_ptr); + vRingbufferReturnItem(p_uart_obj[uart_num]->rx_ring_buf, p_uart_obj[uart_num]->head_ptr); p_uart_obj[uart_num]->head_ptr = NULL; p_uart_obj[uart_num]->rd_ptr = NULL; if(p_uart_obj[uart_num]->buffer_full_flg) { - BaseType_t res = xRingbufferSend(p_uart_obj[uart_num]->ring_buffer, p_uart_obj[uart_num]->data_buf, p_uart_obj[uart_num]->data_len, 1); + BaseType_t res = xRingbufferSend(p_uart_obj[uart_num]->rx_ring_buf, p_uart_obj[uart_num]->data_buf, p_uart_obj[uart_num]->data_len, 1); if(res == pdTRUE) { p_uart_obj[uart_num]->buffer_full_flg = false; uart_enable_rx_intr(p_uart_obj[uart_num]->uart_num); @@ -850,7 +810,7 @@ int uart_read_bytes(uart_port_t uart_num, uint8_t* buf, uint32_t length, TickTyp } } } - xSemaphoreGive(p_uart_obj[uart_num]->rx_sem); + xSemaphoreGive(p_uart_obj[uart_num]->rx_mux); return copy_len; } @@ -858,30 +818,38 @@ esp_err_t uart_flush(uart_port_t uart_num) { UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); UART_CHECK((p_uart_obj[uart_num]), "uart driver error"); - uart_obj_t* p_uart = p_uart_obj[uart_num]; uint8_t* data; size_t size; //rx sem protect the ring buffer read related functions - xSemaphoreTake(p_uart->rx_sem, (portTickType)portMAX_DELAY); + xSemaphoreTake(p_uart->rx_mux, (portTickType)portMAX_DELAY); while(true) { if(p_uart->head_ptr) { - vRingbufferReturnItem(p_uart->ring_buffer, p_uart->head_ptr); + vRingbufferReturnItem(p_uart->rx_ring_buf, p_uart->head_ptr); p_uart->rd_ptr = NULL; p_uart->cur_remain = 0; p_uart->head_ptr = NULL; } - data = (uint8_t*) xRingbufferReceive(p_uart->ring_buffer, &size, (portTickType) 0); + data = (uint8_t*) xRingbufferReceive(p_uart->rx_ring_buf, &size, (portTickType) 0); if(data == NULL) { break; } - vRingbufferReturnItem(p_uart->ring_buffer, data); + vRingbufferReturnItem(p_uart->rx_ring_buf, data); } p_uart->rd_ptr = NULL; p_uart->cur_remain = 0; p_uart->head_ptr = NULL; - xSemaphoreGive(p_uart->rx_sem); - uart_wait_tx_fifo_empty(uart_num, portMAX_DELAY); + xSemaphoreGive(p_uart->rx_mux); + xSemaphoreTake(p_uart->tx_mutex, (portTickType)portMAX_DELAY); + do { + data = (uint8_t*) xRingbufferReceive(p_uart->tx_ring_buf, &size, (portTickType) 0); + if(data == NULL) { + break; + } + vRingbufferReturnItem(p_uart->rx_ring_buf, data); + } while(1); + xSemaphoreGive(p_uart->tx_mutex); + uart_wait_tx_done(uart_num, portMAX_DELAY); uart_reset_fifo(uart_num); return ESP_OK; } @@ -915,7 +883,6 @@ esp_err_t uart_set_print_port(uart_port_t uart_num) { UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); UART_CHECK((p_uart_obj[uart_num]), "UART driver error"); - s_uart_print_nport = uart_num; switch(s_uart_print_nport) { case UART_NUM_0: @@ -940,3 +907,127 @@ int uart_get_print_port() return s_uart_print_nport; } +esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_buffer_size, int queue_size, int uart_intr_num, void* uart_queue, ringbuf_type_t rx_buf_type) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_CHECK((rx_buffer_size > 0), "uart rx buffer length error\n"); + if(p_uart_obj[uart_num] == NULL) { + ESP_INTR_DISABLE(uart_intr_num); + p_uart_obj[uart_num] = (uart_obj_t*) malloc(sizeof(uart_obj_t)); + if(p_uart_obj[uart_num] == NULL) { + ESP_LOGE(UART_TAG, "UART driver malloc error\n"); + return ESP_FAIL; + } + p_uart_obj[uart_num]->uart_num = uart_num; + p_uart_obj[uart_num]->tx_fifo_sem = xSemaphoreCreateBinary(); + xSemaphoreGive(p_uart_obj[uart_num]->tx_fifo_sem); + p_uart_obj[uart_num]->tx_done_sem = xSemaphoreCreateBinary(); + p_uart_obj[uart_num]->tx_brk_sem = xSemaphoreCreateBinary(); + p_uart_obj[uart_num]->tx_mutex = xSemaphoreCreateMutex(); + p_uart_obj[uart_num]->tx_buffer_mutex = xSemaphoreCreateMutex(); + p_uart_obj[uart_num]->rx_mux = xSemaphoreCreateMutex(); + p_uart_obj[uart_num]->intr_num = uart_intr_num; + p_uart_obj[uart_num]->queue_size = queue_size; + + if(uart_queue) { + p_uart_obj[uart_num]->xQueueUart = xQueueCreate(queue_size, sizeof(uart_event_t)); + *((QueueHandle_t*) uart_queue) = p_uart_obj[uart_num]->xQueueUart; + ESP_LOGI(UART_TAG, "queue free spaces: %d\n", uxQueueSpacesAvailable(p_uart_obj[uart_num]->xQueueUart)); + } else { + p_uart_obj[uart_num]->xQueueUart = NULL; + } + p_uart_obj[uart_num]->buffer_full_flg = false; + p_uart_obj[uart_num]->tx_waiting = false; + p_uart_obj[uart_num]->rd_ptr = NULL; + p_uart_obj[uart_num]->cur_remain = 0; + p_uart_obj[uart_num]->head_ptr = NULL; + p_uart_obj[uart_num]->rx_buf_type = rx_buf_type; + p_uart_obj[uart_num]->rx_ring_buf = xRingbufferCreate(rx_buffer_size, rx_buf_type); + if(tx_buffer_size > 0) { + p_uart_obj[uart_num]->tx_ring_buf = xRingbufferCreate(tx_buffer_size, RINGBUF_TYPE_NOSPLIT); + p_uart_obj[uart_num]->tx_buf_size = tx_buffer_size; + xTaskCreate(uart_tx_task, "uart_tx_task", UART_TX_TASK_DEPTH_DEFAULT, (void*)p_uart_obj[uart_num], UART_TX_TASK_PRIO_DEFAULT, &p_uart_obj[uart_num]->tx_task_handle); + + } else { + p_uart_obj[uart_num]->tx_ring_buf = NULL; + p_uart_obj[uart_num]->tx_buf_size = 0; + p_uart_obj[uart_num]->tx_task_handle = NULL; + } + } else { + ESP_LOGE(UART_TAG, "UART driver already installed\n"); + return ESP_FAIL; + } + uart_isr_register(uart_num, uart_intr_num, uart_rx_intr_handler_default, p_uart_obj[uart_num]); + uart_intr_config_t uart_intr = { + .intr_enable_mask = UART_RXFIFO_FULL_INT_ENA_M + | UART_RXFIFO_TOUT_INT_ENA_M + | UART_FRM_ERR_INT_ENA_M + | UART_RXFIFO_OVF_INT_ENA_M + | UART_BRK_DET_INT_ENA_M, + .rxfifo_full_thresh = UART_FULL_THRESH_DEFAULT, + .rx_timeout_thresh = UART_TOUT_THRESH_DEFAULT, + .txfifo_empty_intr_thresh = UART_EMPTY_THRESH_DEFAULT + }; + uart_intr_config(uart_num, &uart_intr); + ESP_INTR_ENABLE(uart_intr_num); + return ESP_OK; +} + +//Make sure no other tasks are still using UART before you call this function +esp_err_t uart_driver_delete(uart_port_t uart_num) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + if(p_uart_obj[uart_num] == NULL) { + ESP_LOGI(UART_TAG, "ALREADY NULL\n"); + return ESP_OK; + } + ESP_INTR_DISABLE(p_uart_obj[uart_num]->intr_num); + uart_disable_rx_intr(uart_num); + uart_disable_tx_intr(uart_num); + uart_isr_register(uart_num, p_uart_obj[uart_num]->intr_num, NULL, NULL); + + if(p_uart_obj[uart_num]->tx_task_handle) { + vTaskDelete(p_uart_obj[uart_num]->tx_task_handle); + p_uart_obj[uart_num]->tx_task_handle = NULL; + } + if(p_uart_obj[uart_num]->tx_fifo_sem) { + vSemaphoreDelete(p_uart_obj[uart_num]->tx_fifo_sem); + p_uart_obj[uart_num]->tx_fifo_sem = NULL; + } + if(p_uart_obj[uart_num]->tx_done_sem) { + vSemaphoreDelete(p_uart_obj[uart_num]->tx_done_sem); + p_uart_obj[uart_num]->tx_done_sem = NULL; + } + if(p_uart_obj[uart_num]->tx_brk_sem) { + vSemaphoreDelete(p_uart_obj[uart_num]->tx_brk_sem); + p_uart_obj[uart_num]->tx_brk_sem = NULL; + } + if(p_uart_obj[uart_num]->tx_mutex) { + vSemaphoreDelete(p_uart_obj[uart_num]->tx_mutex); + p_uart_obj[uart_num]->tx_mutex = NULL; + } + if(p_uart_obj[uart_num]->tx_buffer_mutex) { + vSemaphoreDelete(p_uart_obj[uart_num]->tx_buffer_mutex); + p_uart_obj[uart_num]->tx_buffer_mutex = NULL; + } + if(p_uart_obj[uart_num]->rx_mux) { + vSemaphoreDelete(p_uart_obj[uart_num]->rx_mux); + p_uart_obj[uart_num]->rx_mux = NULL; + } + if(p_uart_obj[uart_num]->xQueueUart) { + vQueueDelete(p_uart_obj[uart_num]->xQueueUart); + p_uart_obj[uart_num]->xQueueUart = NULL; + } + if(p_uart_obj[uart_num]->rx_ring_buf) { + vRingbufferDelete(p_uart_obj[uart_num]->rx_ring_buf); + p_uart_obj[uart_num]->rx_ring_buf = NULL; + } + if(p_uart_obj[uart_num]->tx_ring_buf) { + vRingbufferDelete(p_uart_obj[uart_num]->tx_ring_buf); + p_uart_obj[uart_num]->tx_ring_buf = NULL; + } + + free(p_uart_obj[uart_num]); + p_uart_obj[uart_num] = NULL; + return ESP_OK; +} From fc6b52574a337fd4f4b7a13155eea488582e1b0d Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Tue, 1 Nov 2016 13:07:10 +0800 Subject: [PATCH 224/343] components/openssl: refactor the SSL port function and debug function --- components/openssl/include/internal/ssl_dbg.h | 28 ++++++--- components/openssl/include/platform/ssl_opt.h | 48 ++++++++++++++++ .../openssl/include/platform/ssl_port.h | 16 +++++- components/openssl/library/ssl_cert.c | 8 +-- components/openssl/library/ssl_lib.c | 24 ++++---- components/openssl/library/ssl_pkey.c | 8 +-- components/openssl/library/ssl_stack.c | 14 ++--- components/openssl/library/ssl_x509.c | 8 +-- components/openssl/platform/ssl_pm.c | 57 +++++++++++-------- components/openssl/platform/ssl_port.c | 6 +- 10 files changed, 148 insertions(+), 69 deletions(-) create mode 100644 components/openssl/include/platform/ssl_opt.h diff --git a/components/openssl/include/internal/ssl_dbg.h b/components/openssl/include/internal/ssl_dbg.h index d6ae47499e..1b0a73f167 100644 --- a/components/openssl/include/internal/ssl_dbg.h +++ b/components/openssl/include/internal/ssl_dbg.h @@ -15,21 +15,33 @@ #ifndef _SSL_DEBUG_H_ #define _SSL_DEBUG_H_ +#include "platform/ssl_opt.h" +#include "platform/ssl_port.h" + #ifdef __cplusplus extern "C" { #endif -#define SSL_DEBUG_ENBALE 1 +#ifndef SSL_DEBUG_ENBALE +#define SSL_DEBUG_ENBALE 0 +#endif + +#ifndef SSL_DEBUG_LEVEL #define SSL_DEBUG_LEVEL 0 -#define SSL_ASSERT_ENABLE 1 -#define SSL_DEBUG_LOCATION_ENABLE 1 +#endif -#if SSL_DEBUG_ENBALE - extern int ets_printf(const char *fmt, ...); +#ifndef SSL_ASSERT_ENABLE +#define SSL_ASSERT_ENABLE 0 +#endif - #define SSL_PRINT ets_printf -#else - #define SSL_PRINT(...) +#ifndef SSL_DEBUG_LOCATION_ENABLE +#define SSL_DEBUG_LOCATION_ENABLE 0 +#endif + +#ifndef SSL_PRINT + #include "stdio.h" + extern int printf(const char *fmt, ...); + #define SSL_PRINT printf #endif #if SSL_DEBUG_LOCATION_ENABLE diff --git a/components/openssl/include/platform/ssl_opt.h b/components/openssl/include/platform/ssl_opt.h new file mode 100644 index 0000000000..01d438eb8a --- /dev/null +++ b/components/openssl/include/platform/ssl_opt.h @@ -0,0 +1,48 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef _SSL_OPT_H_ +#define _SSL_OPT_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +/** + * if not define "ESP32_IDF_PLATFORM", system will use esp8266 platform interface + */ +#define ESP32_IDF_PLATFORM + +/** + * openssl debug print function enable + */ +#define SSL_DEBUG_ENBALE 0 + +/** + * openssl debug print function level. function whose level is lower that "SSL_DEBUG_LEVEL" + * will not print message + */ +#define SSL_DEBUG_LEVEL 0 + +/** + * openssl assert function enable, it will check the input paramter and print the message + */ +#define SSL_ASSERT_ENABLE 0 + +/** + * openssl location function enable, it will print location of the positioning error + */ +#define SSL_DEBUG_LOCATION_ENABLE 0 + +#endif diff --git a/components/openssl/include/platform/ssl_port.h b/components/openssl/include/platform/ssl_port.h index 995d33e0e5..4a319c91ae 100644 --- a/components/openssl/include/platform/ssl_port.h +++ b/components/openssl/include/platform/ssl_port.h @@ -19,11 +19,15 @@ extern "C" { #endif +#include "platform/ssl_opt.h" + +#ifdef ESP32_IDF_PLATFORM + #include "esp_types.h" -void* ssl_zalloc(size_t size); -void *ssl_malloc(size_t size); -void ssl_free(void *p); +void *ssl_mem_zalloc(size_t size); +void *ssl_mem_malloc(size_t size); +void ssl_mem_free(void *p); void* ssl_memcpy(void *to, const void *from, size_t size); size_t ssl_strlen(const char *src); @@ -31,4 +35,10 @@ size_t ssl_strlen(const char *src); void ssl_speed_up_enter(void); void ssl_speed_up_exit(void); +#elif defined(SSL_PLATFORM_USER_INCLUDE) + +SSL_PLATFORM_USER_INCLUDE + +#endif + #endif diff --git a/components/openssl/library/ssl_cert.c b/components/openssl/library/ssl_cert.c index e4fd4d7785..0193a441e0 100644 --- a/components/openssl/library/ssl_cert.c +++ b/components/openssl/library/ssl_cert.c @@ -28,9 +28,9 @@ CERT *__ssl_cert_new(CERT *ic) X509 *ix; EVP_PKEY *ipk; - cert = ssl_zalloc(sizeof(CERT)); + cert = ssl_mem_zalloc(sizeof(CERT)); if (!cert) - SSL_RET(failed1, "ssl_zalloc\n"); + SSL_RET(failed1, "ssl_mem_zalloc\n"); if (ic) { ipk = ic->pkey; @@ -53,7 +53,7 @@ CERT *__ssl_cert_new(CERT *ic) failed3: EVP_PKEY_free(cert->pkey); failed2: - ssl_free(cert); + ssl_mem_free(cert); failed1: return NULL; } @@ -75,5 +75,5 @@ void ssl_cert_free(CERT *cert) EVP_PKEY_free(cert->pkey); - ssl_free(cert); + ssl_mem_free(cert); } diff --git a/components/openssl/library/ssl_lib.c b/components/openssl/library/ssl_lib.c index 9740282d13..23b8bf4cea 100644 --- a/components/openssl/library/ssl_lib.c +++ b/components/openssl/library/ssl_lib.c @@ -124,9 +124,9 @@ SSL_SESSION* SSL_SESSION_new(void) { SSL_SESSION *session; - session = ssl_zalloc(sizeof(SSL_SESSION)); + session = ssl_mem_zalloc(sizeof(SSL_SESSION)); if (!session) - SSL_RET(failed1, "ssl_zalloc\n"); + SSL_RET(failed1, "ssl_mem_zalloc\n"); session->peer = X509_new(); if (!session->peer) @@ -135,7 +135,7 @@ SSL_SESSION* SSL_SESSION_new(void) return session; failed2: - ssl_free(session); + ssl_mem_free(session); failed1: return NULL; } @@ -146,7 +146,7 @@ failed1: void SSL_SESSION_free(SSL_SESSION *session) { X509_free(session->peer); - ssl_free(session); + ssl_mem_free(session); } /** @@ -168,9 +168,9 @@ SSL_CTX* SSL_CTX_new(const SSL_METHOD *method) if (!cert) SSL_RET(go_failed2, "ssl_cert_new\n"); - ctx = (SSL_CTX *)ssl_zalloc(sizeof(SSL_CTX)); + ctx = (SSL_CTX *)ssl_mem_zalloc(sizeof(SSL_CTX)); if (!ctx) - SSL_RET(go_failed3, "ssl_zalloc:ctx\n"); + SSL_RET(go_failed3, "ssl_mem_zalloc:ctx\n"); ctx->method = method; ctx->client_CA = client_ca; @@ -199,7 +199,7 @@ void SSL_CTX_free(SSL_CTX* ctx) X509_free(ctx->client_CA); - ssl_free(ctx); + ssl_mem_free(ctx); } /** @@ -238,9 +238,9 @@ SSL *SSL_new(SSL_CTX *ctx) if (!ctx) SSL_RET(failed1, "ctx:NULL\n"); - ssl = (SSL *)ssl_zalloc(sizeof(SSL)); + ssl = (SSL *)ssl_mem_zalloc(sizeof(SSL)); if (!ssl) - SSL_RET(failed1, "ssl_zalloc\n"); + SSL_RET(failed1, "ssl_mem_zalloc\n"); ssl->session = SSL_SESSION_new(); if (!ssl->session) @@ -277,7 +277,7 @@ failed4: failed3: SSL_SESSION_free(ssl->session); failed2: - ssl_free(ssl); + ssl_mem_free(ssl); failed1: return NULL; } @@ -297,7 +297,7 @@ void SSL_free(SSL *ssl) SSL_SESSION_free(ssl->session); - ssl_free(ssl); + ssl_mem_free(ssl); } /** @@ -343,7 +343,7 @@ int SSL_shutdown(SSL *ssl) SSL_ASSERT(ssl); - if (SSL_get_state(ssl) != TLS_ST_OK) return 0; + if (SSL_get_state(ssl) != TLS_ST_OK) return 1; ret = SSL_METHOD_CALL(shutdown, ssl); diff --git a/components/openssl/library/ssl_pkey.c b/components/openssl/library/ssl_pkey.c index 20debfbcfc..dbd82dc9c2 100644 --- a/components/openssl/library/ssl_pkey.c +++ b/components/openssl/library/ssl_pkey.c @@ -25,9 +25,9 @@ EVP_PKEY* __EVP_PKEY_new(EVP_PKEY *ipk) int ret; EVP_PKEY *pkey; - pkey = ssl_zalloc(sizeof(EVP_PKEY)); + pkey = ssl_mem_zalloc(sizeof(EVP_PKEY)); if (!pkey) - SSL_RET(failed1, "ssl_zalloc\n"); + SSL_RET(failed1, "ssl_mem_zalloc\n"); if (ipk) { pkey->method = ipk->method; @@ -42,7 +42,7 @@ EVP_PKEY* __EVP_PKEY_new(EVP_PKEY *ipk) return pkey; failed2: - ssl_free(pkey); + ssl_mem_free(pkey); failed1: return NULL; } @@ -62,7 +62,7 @@ void EVP_PKEY_free(EVP_PKEY *pkey) { EVP_PKEY_METHOD_CALL(free, pkey); - ssl_free(pkey); + ssl_mem_free(pkey); } /** diff --git a/components/openssl/library/ssl_stack.c b/components/openssl/library/ssl_stack.c index 4ea40e7259..5dbb69af9d 100644 --- a/components/openssl/library/ssl_stack.c +++ b/components/openssl/library/ssl_stack.c @@ -30,13 +30,13 @@ OPENSSL_STACK* OPENSSL_sk_new(OPENSSL_sk_compfunc c) OPENSSL_STACK *stack; char **data; - stack = ssl_zalloc(sizeof(OPENSSL_STACK)); + stack = ssl_mem_zalloc(sizeof(OPENSSL_STACK)); if (!stack) - SSL_RET(failed1, "ssl_zalloc\n"); + SSL_RET(failed1, "ssl_mem_zalloc\n"); - data = ssl_zalloc(sizeof(*data) * MIN_NODES); + data = ssl_mem_zalloc(sizeof(*data) * MIN_NODES); if (!data) - SSL_RET(failed2, "ssl_zalloc\n"); + SSL_RET(failed2, "ssl_mem_zalloc\n"); stack->data = data; stack->num_alloc = MIN_NODES; @@ -45,7 +45,7 @@ OPENSSL_STACK* OPENSSL_sk_new(OPENSSL_sk_compfunc c) return stack; failed2: - ssl_free(stack); + ssl_mem_free(stack); failed1: return NULL; } @@ -65,6 +65,6 @@ void OPENSSL_sk_free(OPENSSL_STACK *stack) { SSL_ASSERT(stack); - ssl_free(stack->data); - ssl_free(stack); + ssl_mem_free(stack->data); + ssl_mem_free(stack); } diff --git a/components/openssl/library/ssl_x509.c b/components/openssl/library/ssl_x509.c index 06e6e7b544..d0426db18c 100644 --- a/components/openssl/library/ssl_x509.c +++ b/components/openssl/library/ssl_x509.c @@ -33,9 +33,9 @@ X509* __X509_new(X509 *ix) int ret; X509 *x; - x = ssl_zalloc(sizeof(X509)); + x = ssl_mem_zalloc(sizeof(X509)); if (!x) - SSL_RET(failed1, "ssl_malloc\n"); + SSL_RET(failed1, "ssl_mem_zalloc\n"); if (ix) x->method = ix->method; @@ -49,7 +49,7 @@ X509* __X509_new(X509 *ix) return x; failed2: - ssl_free(x); + ssl_mem_free(x); failed1: return NULL; } @@ -69,7 +69,7 @@ void X509_free(X509 *x) { X509_METHOD_CALL(free, x); - ssl_free(x); + ssl_mem_free(x); }; /** diff --git a/components/openssl/platform/ssl_pm.c b/components/openssl/platform/ssl_pm.c index eadd323e70..21c0ac58c9 100644 --- a/components/openssl/platform/ssl_pm.c +++ b/components/openssl/platform/ssl_pm.c @@ -86,10 +86,16 @@ int ssl_pm_new(SSL *ssl) const SSL_METHOD *method = ssl->method; - ssl_pm = ssl_zalloc(sizeof(struct ssl_pm)); + ssl_pm = ssl_mem_zalloc(sizeof(struct ssl_pm)); if (!ssl_pm) - SSL_ERR(ret, failed1, "ssl_zalloc\n"); + SSL_ERR(ret, failed1, "ssl_mem_zalloc\n"); + if (ssl->ctx->read_buffer_len < 2048 || + ssl->ctx->read_buffer_len > 8192) + return -1; + + max_content_len = ssl->ctx->read_buffer_len; + mbedtls_net_init(&ssl_pm->fd); mbedtls_net_init(&ssl_pm->cl_fd); @@ -144,6 +150,7 @@ failed3: mbedtls_ctr_drbg_free(&ssl_pm->ctr_drbg); failed2: mbedtls_entropy_free(&ssl_pm->entropy); + ssl_mem_free(ssl_pm); failed1: return -1; } @@ -160,7 +167,7 @@ void ssl_pm_free(SSL *ssl) mbedtls_ssl_config_free(&ssl_pm->conf); mbedtls_ssl_free(&ssl_pm->ssl); - ssl_free(ssl_pm); + ssl_mem_free(ssl_pm); ssl->ssl_pm = NULL; } @@ -392,7 +399,7 @@ int x509_pm_show_info(X509 *x) if (!x509_crt) return -1; - buf = ssl_malloc(X509_INFO_STRING_LENGTH); + buf = ssl_mem_malloc(X509_INFO_STRING_LENGTH); if (!buf) SSL_RET(failed1, ""); @@ -401,14 +408,14 @@ int x509_pm_show_info(X509 *x) SSL_RET(failed2, ""); buf[ret] = 0; - ssl_free(buf); + ssl_mem_free(buf); SSL_PRINT("%s", buf); return 0; failed2: - ssl_free(buf); + ssl_mem_free(buf); failed1: return -1; } @@ -417,9 +424,9 @@ int x509_pm_new(X509 *x, X509 *m_x) { struct x509_pm *x509_pm; - x509_pm = ssl_zalloc(sizeof(struct x509_pm)); + x509_pm = ssl_mem_zalloc(sizeof(struct x509_pm)); if (!x509_pm) - SSL_RET(failed1, "ssl_zalloc\n"); + SSL_RET(failed1, "ssl_mem_zalloc\n"); x->x509_pm = x509_pm; @@ -442,11 +449,11 @@ void x509_pm_free(X509 *x) if (x509_pm->x509_crt) { mbedtls_x509_crt_free(x509_pm->x509_crt); - ssl_free(x509_pm->x509_crt); + ssl_mem_free(x509_pm->x509_crt); x509_pm->x509_crt = NULL; } - ssl_free(x->x509_pm); + ssl_mem_free(x->x509_pm); x->x509_pm = NULL; } @@ -460,14 +467,14 @@ int x509_pm_load(X509 *x, const unsigned char *buffer, int len) mbedtls_x509_crt_free(x509_pm->x509_crt); if (!x509_pm->x509_crt) { - x509_pm->x509_crt = ssl_malloc(sizeof(mbedtls_x509_crt)); + x509_pm->x509_crt = ssl_mem_malloc(sizeof(mbedtls_x509_crt)); if (!x509_pm->x509_crt) - SSL_RET(failed1, "ssl_malloc\n"); + SSL_RET(failed1, "ssl_mem_malloc\n"); } - load_buf = ssl_malloc(len + 1); + load_buf = ssl_mem_malloc(len + 1); if (!load_buf) - SSL_RET(failed2, "ssl_malloc\n"); + SSL_RET(failed2, "ssl_mem_malloc\n"); ssl_memcpy(load_buf, buffer, len); load_buf[len] = '\0'; @@ -477,7 +484,7 @@ int x509_pm_load(X509 *x, const unsigned char *buffer, int len) mbedtls_x509_crt_init(x509_pm->x509_crt); ret = mbedtls_x509_crt_parse(x509_pm->x509_crt, load_buf, len + 1); - ssl_free(load_buf); + ssl_mem_free(load_buf); if (ret) SSL_RET(failed2, "mbedtls_x509_crt_parse, return [-0x%x]\n", -ret); @@ -485,7 +492,7 @@ int x509_pm_load(X509 *x, const unsigned char *buffer, int len) return 0; failed2: - ssl_free(x509_pm->x509_crt); + ssl_mem_free(x509_pm->x509_crt); x509_pm->x509_crt = NULL; failed1: return -1; @@ -495,7 +502,7 @@ int pkey_pm_new(EVP_PKEY *pk, EVP_PKEY *m_pkey) { struct pkey_pm *pkey_pm; - pkey_pm = ssl_zalloc(sizeof(struct pkey_pm)); + pkey_pm = ssl_mem_zalloc(sizeof(struct pkey_pm)); if (!pkey_pm) return -1; @@ -517,11 +524,11 @@ void pkey_pm_free(EVP_PKEY *pk) if (pkey_pm->pkey) { mbedtls_pk_free(pkey_pm->pkey); - ssl_free(pkey_pm->pkey); + ssl_mem_free(pkey_pm->pkey); pkey_pm->pkey = NULL; } - ssl_free(pk->pkey_pm); + ssl_mem_free(pk->pkey_pm); pk->pkey_pm = NULL; } @@ -535,14 +542,14 @@ int pkey_pm_load(EVP_PKEY *pk, const unsigned char *buffer, int len) mbedtls_pk_free(pkey_pm->pkey); if (!pkey_pm->pkey) { - pkey_pm->pkey = ssl_malloc(sizeof(mbedtls_pk_context)); + pkey_pm->pkey = ssl_mem_malloc(sizeof(mbedtls_pk_context)); if (!pkey_pm->pkey) - SSL_RET(failed1, "ssl_malloc\n"); + SSL_RET(failed1, "ssl_mem_malloc\n"); } - load_buf = ssl_malloc(len + 1); + load_buf = ssl_mem_malloc(len + 1); if (!load_buf) - SSL_RET(failed2, "ssl_malloc\n"); + SSL_RET(failed2, "ssl_mem_malloc\n"); ssl_memcpy(load_buf, buffer, len); load_buf[len] = '\0'; @@ -552,7 +559,7 @@ int pkey_pm_load(EVP_PKEY *pk, const unsigned char *buffer, int len) mbedtls_pk_init(pkey_pm->pkey); ret = mbedtls_pk_parse_key(pkey_pm->pkey, load_buf, len + 1, NULL, 0); - ssl_free(load_buf); + ssl_mem_free(load_buf); if (ret) SSL_RET(failed2, "mbedtls_pk_parse_key, return [-0x%x]\n", -ret); @@ -560,7 +567,7 @@ int pkey_pm_load(EVP_PKEY *pk, const unsigned char *buffer, int len) return 0; failed2: - ssl_free(pkey_pm->pkey); + ssl_mem_free(pkey_pm->pkey); pkey_pm->pkey = NULL; failed1: return -1; diff --git a/components/openssl/platform/ssl_port.c b/components/openssl/platform/ssl_port.c index b57e703a17..9fbc44deb6 100644 --- a/components/openssl/platform/ssl_port.c +++ b/components/openssl/platform/ssl_port.c @@ -15,6 +15,7 @@ #include "ssl_port.h" #include "string.h" #include "malloc.h" +#include "esp_system.h" /*********************************************************************************************/ /********************************* SSL general interface *************************************/ @@ -51,10 +52,11 @@ size_t ssl_strlen(const char *src) void ssl_speed_up_enter(void) { - + system_update_cpu_freq(SYS_CPU_160MHZ); } void ssl_speed_up_exit(void) { - + system_update_cpu_freq(SYS_CPU_80MHZ); } + From 16a4d56fe5af03005afc9a3b57e95219918841c6 Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Tue, 1 Nov 2016 13:09:54 +0800 Subject: [PATCH 225/343] components/openssl: remove some platform interface --- components/openssl/platform/ssl_port.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/components/openssl/platform/ssl_port.c b/components/openssl/platform/ssl_port.c index 9fbc44deb6..b333fdbfba 100644 --- a/components/openssl/platform/ssl_port.c +++ b/components/openssl/platform/ssl_port.c @@ -15,7 +15,6 @@ #include "ssl_port.h" #include "string.h" #include "malloc.h" -#include "esp_system.h" /*********************************************************************************************/ /********************************* SSL general interface *************************************/ @@ -52,11 +51,11 @@ size_t ssl_strlen(const char *src) void ssl_speed_up_enter(void) { - system_update_cpu_freq(SYS_CPU_160MHZ); + } void ssl_speed_up_exit(void) { - system_update_cpu_freq(SYS_CPU_80MHZ); + } From 8d1f360ca6835c2d13563da10bed97bb7c38cc6c Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Tue, 1 Nov 2016 13:10:56 +0800 Subject: [PATCH 226/343] components/openssl: ssl port use esp32_idf default --- components/openssl/platform/ssl_port.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/components/openssl/platform/ssl_port.c b/components/openssl/platform/ssl_port.c index b333fdbfba..1f19510116 100644 --- a/components/openssl/platform/ssl_port.c +++ b/components/openssl/platform/ssl_port.c @@ -13,6 +13,9 @@ // limitations under the License. #include "ssl_port.h" + +#ifdef ESP32_IDF_PLATFORM + #include "string.h" #include "malloc.h" @@ -59,3 +62,5 @@ void ssl_speed_up_exit(void) } +#endif + From bc710e5b885df673e13470de8ce99997acb7e4dd Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Tue, 1 Nov 2016 14:59:50 +0800 Subject: [PATCH 227/343] components/openssl: refacetor the SSL debug function Add the "ssl_opt.h" file to make user able t add its platform interface --- components/openssl/include/internal/ssl_dbg.h | 21 ++++++++++++------- .../openssl/include/platform/ssl_port.h | 3 +++ components/openssl/platform/ssl_port.c | 6 +++--- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/components/openssl/include/internal/ssl_dbg.h b/components/openssl/include/internal/ssl_dbg.h index 1b0a73f167..5b909955e4 100644 --- a/components/openssl/include/internal/ssl_dbg.h +++ b/components/openssl/include/internal/ssl_dbg.h @@ -38,10 +38,17 @@ #define SSL_DEBUG_LOCATION_ENABLE 0 #endif -#ifndef SSL_PRINT - #include "stdio.h" - extern int printf(const char *fmt, ...); - #define SSL_PRINT printf +#if SSL_DEBUG_ENBALE + #ifndef SSL_PRINT + #include "stdio.h" + extern int printf(const char *fmt, ...); + #define SSL_PRINT printf + #endif +#else + #ifdef SSL_PRINT + #undef SSL_PRINT + #define SSL_PRINT(...) + #endif #endif #if SSL_DEBUG_LOCATION_ENABLE @@ -56,11 +63,11 @@ #define SSL_ASSERT(s) #endif -#define SSL_ERR(err, go, ...) { SSL_DEBUG_LOCATION(); SSL_PRINT(__VA_ARGS__); ret = err; goto go; } +#define SSL_ERR(err, go, fmt, ...) { SSL_DEBUG_LOCATION(); SSL_PRINT(fmt, ##__VA_ARGS__); ret = err; goto go; } -#define SSL_RET(go, ...) { SSL_DEBUG_LOCATION(); SSL_PRINT(__VA_ARGS__); goto go; } +#define SSL_RET(go, fmt, ...) { SSL_DEBUG_LOCATION(); SSL_PRINT(fmt, ##__VA_ARGS__); goto go; } -#define SSL_DEBUG(level, ...) { if (level > SSL_DEBUG_LEVEL) {SSL_PRINT(__VA_ARGS__);} } +#define SSL_DEBUG(level, fmt, ...) { if (level > SSL_DEBUG_LEVEL) {SSL_PRINT(fmt, ##__VA_ARGS__);} } #ifdef __cplusplus } diff --git a/components/openssl/include/platform/ssl_port.h b/components/openssl/include/platform/ssl_port.h index 4a319c91ae..1e4c2f31f9 100644 --- a/components/openssl/include/platform/ssl_port.h +++ b/components/openssl/include/platform/ssl_port.h @@ -24,6 +24,7 @@ #ifdef ESP32_IDF_PLATFORM #include "esp_types.h" +#include "esp_log.h" void *ssl_mem_zalloc(size_t size); void *ssl_mem_malloc(size_t size); @@ -35,6 +36,8 @@ size_t ssl_strlen(const char *src); void ssl_speed_up_enter(void); void ssl_speed_up_exit(void); +#define SSL_PRINT(fmt, ...) ESP_LOGD("OpenSSL", fmt, ##__VA_ARGS__) + #elif defined(SSL_PLATFORM_USER_INCLUDE) SSL_PLATFORM_USER_INCLUDE diff --git a/components/openssl/platform/ssl_port.c b/components/openssl/platform/ssl_port.c index 1f19510116..ae3b849ca3 100644 --- a/components/openssl/platform/ssl_port.c +++ b/components/openssl/platform/ssl_port.c @@ -22,7 +22,7 @@ /*********************************************************************************************/ /********************************* SSL general interface *************************************/ -void* ssl_zalloc(size_t size) +void* ssl_mem_zalloc(size_t size) { void *p = malloc(size); @@ -32,12 +32,12 @@ void* ssl_zalloc(size_t size) return p; } -void *ssl_malloc(size_t size) +void *ssl_mem_malloc(size_t size) { return malloc(size); } -void ssl_free(void *p) +void ssl_mem_free(void *p) { free(p); } From 12e78e9590655a494e72e7e6d6cea391ecda32b3 Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Tue, 1 Nov 2016 15:16:14 +0800 Subject: [PATCH 228/343] components/openssl: add more debug stream output function --- components/openssl/include/internal/ssl_dbg.h | 34 ++++++++++++++----- .../openssl/include/platform/ssl_port.h | 4 ++- components/openssl/platform/ssl_pm.c | 2 +- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/components/openssl/include/internal/ssl_dbg.h b/components/openssl/include/internal/ssl_dbg.h index 5b909955e4..887fe2e82b 100644 --- a/components/openssl/include/internal/ssl_dbg.h +++ b/components/openssl/include/internal/ssl_dbg.h @@ -39,20 +39,36 @@ #endif #if SSL_DEBUG_ENBALE - #ifndef SSL_PRINT + #if !defined(SSL_PRINT_LOG) || !defined(SSL_ERROR_LOG) || !defined(SSL_LOCAL_LOG) #include "stdio.h" extern int printf(const char *fmt, ...); - #define SSL_PRINT printf + #ifndef SSL_PRINT_LOG + #define SSL_PRINT_LOG printf + #endif + #ifndef SSL_ERROR_LOG + #define SSL_ERROR_LOG printf + #endif + #ifndef SSL_LOCAL_LOG + #define SSL_LOCAL_LOG printf + #endif #endif #else - #ifdef SSL_PRINT - #undef SSL_PRINT - #define SSL_PRINT(...) + #ifdef SSL_PRINT_LOG + #undef SSL_PRINT_LOG + #define SSL_PRINT_LOG(...) + #endif + #ifdef SSL_ERROR_LOG + #undef SSL_ERROR_LOG + #define SSL_ERROR_LOG(...) + #endif + #ifdef SSL_LOCAL_LOG + #undef SSL_LOCAL_LOG + #define SSL_LOCAL_LOG(...) #endif #endif #if SSL_DEBUG_LOCATION_ENABLE - #define SSL_DEBUG_LOCATION() SSL_PRINT("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__) + #define SSL_DEBUG_LOCATION() SSL_LOCAL_LOG("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__) #else #define SSL_DEBUG_LOCATION() #endif @@ -63,11 +79,11 @@ #define SSL_ASSERT(s) #endif -#define SSL_ERR(err, go, fmt, ...) { SSL_DEBUG_LOCATION(); SSL_PRINT(fmt, ##__VA_ARGS__); ret = err; goto go; } +#define SSL_ERR(err, go, fmt, ...) { SSL_DEBUG_LOCATION(); SSL_ERROR_LOG(fmt, ##__VA_ARGS__); ret = err; goto go; } -#define SSL_RET(go, fmt, ...) { SSL_DEBUG_LOCATION(); SSL_PRINT(fmt, ##__VA_ARGS__); goto go; } +#define SSL_RET(go, fmt, ...) { SSL_DEBUG_LOCATION(); SSL_ERROR_LOG(fmt, ##__VA_ARGS__); goto go; } -#define SSL_DEBUG(level, fmt, ...) { if (level > SSL_DEBUG_LEVEL) {SSL_PRINT(fmt, ##__VA_ARGS__);} } +#define SSL_DEBUG(level, fmt, ...) { if (level > SSL_DEBUG_LEVEL) {SSL_PRINT_LOG(fmt, ##__VA_ARGS__);} } #ifdef __cplusplus } diff --git a/components/openssl/include/platform/ssl_port.h b/components/openssl/include/platform/ssl_port.h index 1e4c2f31f9..35c8dc18f9 100644 --- a/components/openssl/include/platform/ssl_port.h +++ b/components/openssl/include/platform/ssl_port.h @@ -36,7 +36,9 @@ size_t ssl_strlen(const char *src); void ssl_speed_up_enter(void); void ssl_speed_up_exit(void); -#define SSL_PRINT(fmt, ...) ESP_LOGD("OpenSSL", fmt, ##__VA_ARGS__) +#define SSL_PRINT_LOG(fmt, ...) ESP_LOGD("openssl", fmt, ##__VA_ARGS__) +#define SSL_ERROR_LOG(fmt, ...) ESP_LOGE("openssl", fmt, ##__VA_ARGS__) +#define SSL_LOCAL_LOG(fmt, ...) ESP_LOGD("openssl", fmt, ##__VA_ARGS__) #elif defined(SSL_PLATFORM_USER_INCLUDE) diff --git a/components/openssl/platform/ssl_pm.c b/components/openssl/platform/ssl_pm.c index 21c0ac58c9..92e72bfdb8 100644 --- a/components/openssl/platform/ssl_pm.c +++ b/components/openssl/platform/ssl_pm.c @@ -410,7 +410,7 @@ int x509_pm_show_info(X509 *x) ssl_mem_free(buf); - SSL_PRINT("%s", buf); + SSL_DEBUG(1, "%s", buf); return 0; From f0cd38a0799f13357761e134b108c8ab8dc40abf Mon Sep 17 00:00:00 2001 From: Liu Zhi Fu Date: Tue, 1 Nov 2016 15:25:46 +0800 Subject: [PATCH 229/343] lwip: remove tx flow control code --- components/lwip/api/sockets.c | 30 -------------------- components/lwip/include/lwip/port/lwipopts.h | 3 -- 2 files changed, 33 deletions(-) diff --git a/components/lwip/api/sockets.c b/components/lwip/api/sockets.c index df658578af..1529382f50 100755 --- a/components/lwip/api/sockets.c +++ b/components/lwip/api/sockets.c @@ -382,34 +382,6 @@ static void lwip_socket_unregister_membership(int s, const ip4_addr_t *if_addr, static void lwip_socket_drop_registered_memberships(int s); #endif /* LWIP_IGMP */ -#if ESP_LWIP -#include "esp_wifi_internal.h" -#include "esp_system.h" - -/* Please be notified that this flow control is just a workaround for fixing wifi Q full issue. - * Under UDP/TCP pressure test, we found that the sockets may cause wifi tx queue full if the socket - * sending speed is faster than the wifi sending speed, it will finally cause the packet to be dropped - * in wifi layer, it's not acceptable in some application. That's why we introdue the tx flow control here. - * However, current solution is just a workaround, we need to consider the return value of wifi tx interface, - * and feedback the return value to lwip and let lwip do the flow control itself. - */ -static inline void esp32_tx_flow_ctrl(void) -{ -//TODO we need to do flow control for UDP -#if 0 - uint8_t _wait_delay = 1; - - while ((system_get_free_heap_size() < HEAP_HIGHWAT) || esp_wifi_internal_tx_is_stop()){ - vTaskDelay(_wait_delay/portTICK_RATE_MS); - if (_wait_delay < 64) _wait_delay *= 2; - } -#endif -} - -#else -#define esp32_tx_flow_ctrl() -#endif - /** The global array of available sockets */ static struct lwip_sock sockets[NUM_SOCKETS]; #if ESP_THREAD_SAFE @@ -1392,8 +1364,6 @@ lwip_sendto(int s, const void *data, size_t size, int flags, #endif /* LWIP_TCP */ } - esp32_tx_flow_ctrl(); - if ((to != NULL) && !SOCK_ADDR_TYPE_MATCH(to, sock)) { /* sockaddr does not match socket type (IPv4/IPv6) */ sock_set_errno(sock, err_to_errno(ERR_VAL)); diff --git a/components/lwip/include/lwip/port/lwipopts.h b/components/lwip/include/lwip/port/lwipopts.h index 67a62b8227..b970ae5539 100755 --- a/components/lwip/include/lwip/port/lwipopts.h +++ b/components/lwip/include/lwip/port/lwipopts.h @@ -523,7 +523,6 @@ extern unsigned long os_random(void); #define ESP_IP4_ATON 1 #define ESP_LIGHT_SLEEP 1 - #define TCP_WND_DEFAULT (4*TCP_MSS) #define TCP_SND_BUF_DEFAULT (2*TCP_MSS) @@ -550,8 +549,6 @@ extern unsigned char misc_prof_get_tcp_snd_buf(void); #define CHECKSUM_CHECK_UDP 0 #define CHECKSUM_CHECK_IP 0 -#define HEAP_HIGHWAT 20*1024 - #define LWIP_NETCONN_FULLDUPLEX 1 #define LWIP_NETCONN_SEM_PER_THREAD 1 From edf5b103449e4120c0e1b03e40f0e82f17c38daf Mon Sep 17 00:00:00 2001 From: Liu Zhi Fu Date: Tue, 1 Nov 2016 15:34:30 +0800 Subject: [PATCH 230/343] esp32: update wifi lib 146f5962 - Make the return value of esp_wifi_internal_tx consistent with LWIP error code so that the up-layer can detect the out-of-memory error and take action accordingly, such do flow control. --- components/esp32/lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp32/lib b/components/esp32/lib index 9d18fd1a8f..b3090d8854 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit 9d18fd1a8f7610130e69f8be74ec68f6399221b1 +Subproject commit b3090d885413fb78c86e7b88116cdb5c8c5e9e68 From 8c1d1e19c230b5229fcb1463ceb3cd804728b9a8 Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Tue, 1 Nov 2016 15:41:10 +0800 Subject: [PATCH 231/343] OpenOCD doc fix, fix gdbstub --- components/esp32/gdbstub.c | 2 +- docs/openocd.rst | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/components/esp32/gdbstub.c b/components/esp32/gdbstub.c index d75fced4cd..a43793f835 100644 --- a/components/esp32/gdbstub.c +++ b/components/esp32/gdbstub.c @@ -351,7 +351,7 @@ static int gdbReadCommand() { -void gdbstubPanicHandler(XtExcFrame *frame) { +void esp_gdbstub_panic_handler(XtExcFrame *frame) { dumpHwToRegfile(frame); //Make sure txd/rxd are enabled PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U); diff --git a/docs/openocd.rst b/docs/openocd.rst index 57ee93db4a..cf1d25e60b 100644 --- a/docs/openocd.rst +++ b/docs/openocd.rst @@ -2,10 +2,10 @@ OpenOCD setup for ESP32 ----------------------- The ESP31 and ESP32 have two powerful Xtensa cores, allowing for a great deal of variety of program architectures. The FreeRTOS -OS that comes with ESP-IDF is capable multi-core pre-emptive multithreading, allowing for an intuitive way of writing software. +OS that comes with ESP-IDF is capable of multi-core pre-emptive multithreading, allowing for an intuitive way of writing software. The downside of the ease of programming is that debugging without the right tools is harder: figuring out a bug that is caused -by two threads, maybe even running simultaneously on two different CPU cures, can take a long time when all you have are printf +by two threads, maybe even running simultaneously on two different CPU cores, can take a long time when all you have are printf statements. A better and in many cases quicker way to debug such problems is by using a debugger, connected to the processors over a debug port. @@ -84,7 +84,7 @@ Connecting a debugger to OpenOCD OpenOCD should now be ready to accept gdb connections. If you have compiled the ESP32 toolchain using Crosstool-NG, or if you have downloaded a precompiled toolchain from the Espressif website, you should already have xtensa-esp32-elf-gdb, a version of gdb that can be used for this. First, make sure the project you want to debug is compiled and flashed -into the ESP32s SPI flash. Then, in a different console than OpenOCD is running in, invoke gdb. For example, for the +into the ESP32's SPI flash. Then, in a different console than OpenOCD is running in, invoke gdb. For example, for the template app, you would do this like such:: cd esp-idf-template From 578458604148beb6d4daedbdbae604d2f1406a7c Mon Sep 17 00:00:00 2001 From: Yinling Date: Tue, 1 Nov 2016 19:30:42 +0800 Subject: [PATCH 232/343] integrate unit test to CI --- .gitlab-ci.yml | 63 ++- .../CIConfigs/IT_Function_TCPIP_01.yml | 8 +- .../CIConfigs/IT_Function_TCPIP_02.yml | 2 +- .../CIConfigs/IT_Function_TCPIP_03.yml | 8 +- .../CIConfigs/IT_Function_TCPIP_04.yml | 2 +- .../CIConfigs/IT_Function_TCPIP_07.yml | 6 +- .../CIConfigs/IT_Function_TCPIP_08.yml | 6 +- .../CIConfigs/IT_Function_TCPIP_09.yml | 2 +- .../CIConfigs/IT_Function_TCPIP_11.yml | 2 +- .../CIConfigs/IT_Function_TCPIP_12.yml | 2 +- .../integration_test/InitialConditionAll.yml | 24 + .../idf_test/integration_test/TestEnvAll.yml | 47 +- components/idf_test/uint_test/TestCaseAll.yml | 1 - .../CIConfigs/UT_Function_SYS_01.yml | 8 + .../InitialConditionAll.yml | 24 + components/idf_test/unit_test/TestCaseAll.yml | 484 ++++++++++++++++++ .../TestCaseScript/IDFUnitTest/UnitTest.py | 47 ++ .../TestCaseScript/IDFUnitTest/__init__.py | 1 + .../{uint_test => unit_test}/TestEnvAll.yml | 47 +- 19 files changed, 699 insertions(+), 85 deletions(-) delete mode 100644 components/idf_test/uint_test/TestCaseAll.yml create mode 100644 components/idf_test/unit_test/CIConfigs/UT_Function_SYS_01.yml rename components/idf_test/{uint_test => unit_test}/InitialConditionAll.yml (99%) create mode 100644 components/idf_test/unit_test/TestCaseAll.yml create mode 100644 components/idf_test/unit_test/TestCaseScript/IDFUnitTest/UnitTest.py create mode 100755 components/idf_test/unit_test/TestCaseScript/IDFUnitTest/__init__.py rename components/idf_test/{uint_test => unit_test}/TestEnvAll.yml (95%) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index aff9bea8d1..e51c9dd020 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,5 +1,6 @@ stages: - build + - unit_test - test - deploy @@ -75,6 +76,23 @@ build_ssc: - chmod +x gen_misc_ng.sh - ./gen_misc_ng.sh +build_esp_idf_tests: + <<: *build_template + artifacts: + paths: + - ./esp-idf-tests/build/*.bin + - ./esp-idf-tests/build/*.elf + - ./esp-idf-tests/build/*.map + - ./esp-idf-tests/build/bootloader/*.bin + expire_in: 6 mos + + script: + - git clone $GITLAB_SSH_SERVER/idf/esp-idf-tests.git + - cd esp-idf-tests + - git checkout ${CI_BUILD_REF_NAME} || echo "Using default branch..." + - make defconfig + - make + build_examples: <<: *build_template artifacts: @@ -176,7 +194,7 @@ push_master_to_github: APP_NAME: "ssc" LOG_PATH: "$CI_PROJECT_DIR/$CI_BUILD_REF" # append test level folder to TEST_CASE_FILE_PATH in before_script of test job - TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/components/idf_test" + TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/components/idf_test/integration_test" # jobs MUST set CONFIG_FILE in before_script, and overwrite the variables above if necessary artifacts: @@ -222,13 +240,34 @@ push_master_to_github: # run test - python CIRunner.py -l $LOG_PATH -c $CONFIG_FILE -e $LOCAL_ENV_CONFIG_PATH -t $TEST_CASE_FILE_PATH bin_path $APP_NAME $BIN_PATH +# template for unit test jobs +.unit_test_template: &unit_test_template + <<: *test_template + allow_failure: false + stage: unit_test + + variables: + # jobs MUST set CONFIG_FILE in before_script, and overwrite the variables above if necessary + LOCAL_ENV_CONFIG_PATH: /home/gitlab-runner/LocalConfig/ESP32_IDF + BIN_PATH: "$CI_PROJECT_DIR/esp-idf-tests/build/" + LOG_PATH: "$CI_PROJECT_DIR/$CI_BUILD_REF" + APP_NAME: "ut" + TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/components/idf_test/unit_test" + +UT_Function_SYS_01: + <<: *test_template + tags: + - ESP32_IDF + - UT_T1_1 + before_script: + - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/UT_Function_SYS_01.yml + IT_Function_SYS_01: <<: *test_template tags: - ESP32_IDF - SSC_T1_1 before_script: - - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_SYS_01.yml IT_Function_WIFI_01: @@ -238,7 +277,6 @@ IT_Function_WIFI_01: - SSC_T1_1 - SSC_T2_1 before_script: - - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_01.yml IT_Function_WIFI_02: @@ -248,7 +286,6 @@ IT_Function_WIFI_02: - SSC_T1_1 - SSC_T2_1 before_script: - - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_02.yml IT_Function_TCPIP_01: @@ -258,7 +295,6 @@ IT_Function_TCPIP_01: - SSC_T1_1 - SSC_T2_1 before_script: - - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_01.yml IT_Function_TCPIP_02: @@ -268,7 +304,6 @@ IT_Function_TCPIP_02: - SSC_T1_1 - SSC_T2_1 before_script: - - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_02.yml IT_Function_TCPIP_03: @@ -278,7 +313,6 @@ IT_Function_TCPIP_03: - SSC_T1_1 - SSC_T2_1 before_script: - - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_03.yml IT_Function_TCPIP_04: @@ -288,7 +322,6 @@ IT_Function_TCPIP_04: - SSC_T1_1 - SSC_T2_1 before_script: - - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_04.yml IT_Function_TCPIP_05: @@ -298,7 +331,6 @@ IT_Function_TCPIP_05: - SSC_T1_1 - SSC_T2_1 before_script: - - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_05.yml IT_Function_TCPIP_06: @@ -307,7 +339,6 @@ IT_Function_TCPIP_06: - ESP32_IDF - SSC_T1_1 before_script: - - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_06.yml IT_Function_WIFI_03: @@ -316,7 +347,6 @@ IT_Function_WIFI_03: - ESP32_IDF - SSC_T3_PhyMode before_script: - - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_03.yml IT_Function_WIFI_04: @@ -325,7 +355,6 @@ IT_Function_WIFI_04: - ESP32_IDF - SSC_T1_APC before_script: - - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_04.yml IT_Function_WIFI_05: @@ -334,7 +363,6 @@ IT_Function_WIFI_05: - ESP32_IDF - SSC_T1_WEP before_script: - - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_05.yml IT_Function_WIFI_06: @@ -343,7 +371,6 @@ IT_Function_WIFI_06: - ESP32_IDF - SSC_T2_PhyMode before_script: - - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_06.yml IT_Function_TCPIP_07: @@ -354,7 +381,6 @@ IT_Function_TCPIP_07: - SSC_T1_2 - SSC_T2_1 before_script: - - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_07.yml IT_Function_TCPIP_08: @@ -363,7 +389,6 @@ IT_Function_TCPIP_08: - ESP32_IDF - SSC_T1_1 before_script: - - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_08.yml IT_Function_TCPIP_09: @@ -372,7 +397,6 @@ IT_Function_TCPIP_09: - ESP32_IDF - SSC_T1_1 before_script: - - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_09.yml IT_Function_TCPIP_10: @@ -383,7 +407,6 @@ IT_Function_TCPIP_10: - SSC_T1_2 - SSC_T2_1 before_script: - - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_10.yml IT_Function_TCPIP_11: @@ -391,8 +414,8 @@ IT_Function_TCPIP_11: tags: - ESP32_IDF - SSC_T1_1 + - SSC_T1_2 before_script: - - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_11.yml IT_Function_TCPIP_12: @@ -400,7 +423,5 @@ IT_Function_TCPIP_12: tags: - ESP32_IDF - SSC_T1_1 - - SSC_T1_2 before_script: - - TEST_CASE_FILE_PATH=$TEST_CASE_FILE_PATH/integration_test - CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_12.yml diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_01.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_01.yml index 25a3ccda99..e86fac28ae 100644 --- a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_01.yml +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_01.yml @@ -4,7 +4,7 @@ Filter: - Add: ID: [^TCPIP_DHCP_0302, TCPIP_DHCP_0302, TCPIP_DHCP_0301, TCPIP_TCP_0403, TCPIP_TCP_0402, TCPIP_TCP_0401, TCPIP_TCP_0407, TCPIP_TCP_0406, ^TCPIP_TCP_0411, TCPIP_TCP_0404, - TCPIP_TCP_0408, TCPIP_TCP_0110, TCPIP_TCP_0115, TCPIP_IP_0101, TCPIP_IP_0102, - ^TCPIP_IGMP_0102, ^TCPIP_IGMP_0101, ^TCPIP_IGMP_0104, TCPIP_IGMP_0104, TCPIP_IGMP_0103, - TCPIP_IGMP_0102, TCPIP_IGMP_0101, TCPIP_UDP_0108, TCPIP_UDP_0106, TCPIP_UDP_0107, - TCPIP_UDP_0105, TCPIP_UDP_0101, TCPIP_IGMP_0204, TCPIP_IGMP_0201, TCPIP_IGMP_0202] + TCPIP_TCP_0408, TCPIP_TCP_0110, ^TCPIP_TCP_0111, TCPIP_TCP_0115, TCPIP_IP_0101, + TCPIP_IP_0102, ^TCPIP_IGMP_0102, ^TCPIP_IGMP_0101, ^TCPIP_IGMP_0104, TCPIP_IGMP_0104, + TCPIP_IGMP_0103, TCPIP_IGMP_0102, TCPIP_IGMP_0101, TCPIP_UDP_0108, TCPIP_UDP_0106, + TCPIP_UDP_0107, TCPIP_UDP_0105, TCPIP_UDP_0101, TCPIP_IGMP_0204, TCPIP_IGMP_0201] diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_02.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_02.yml index 73618e0d70..a746cdd913 100644 --- a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_02.yml +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_02.yml @@ -2,7 +2,7 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC2, SSC1] Filter: - Add: - ID: [TCPIP_IGMP_0203, ^TCPIP_TCP_0403, ^TCPIP_TCP_0408, TCPIP_UDP_0201, TCPIP_UDP_0202, + ID: [TCPIP_IGMP_0202, TCPIP_IGMP_0203, ^TCPIP_TCP_0403, ^TCPIP_TCP_0408, TCPIP_UDP_0201, ^TCPIP_DHCP_0301, ^TCPIP_TCP_0101, ^TCPIP_TCP_0103, ^TCPIP_TCP_0105, ^TCPIP_TCP_0104, ^TCPIP_TCP_0107, ^TCPIP_TCP_0106, ^TCPIP_DHCP_0210, ^TCPIP_DHCP_0211, ^TCPIP_DHCP_0212, ^TCPIP_TCP_0404, TCPIP_TCP_0212, TCPIP_TCP_0210, ^TCPIP_TCP_0406, ^TCPIP_TCP_0407, diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_03.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_03.yml index b326ed721c..f5f0abe5db 100644 --- a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_03.yml +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_03.yml @@ -4,7 +4,7 @@ Filter: - Add: ID: [^TCPIP_IP_0102, ^TCPIP_UDP_0105, ^TCPIP_UDP_0107, ^TCPIP_UDP_0106, ^TCPIP_UDP_0101, TCPIP_TCP_0202, ^TCPIP_UDP_0108, ^TCPIP_IGMP_0201, ^TCPIP_IGMP_0203, ^TCPIP_IGMP_0202, - ^TCPIP_IGMP_0103, TCPIP_UDP_0114, TCPIP_UDP_0113, TCPIP_UDP_0112, TCPIP_DHCP_0205, - TCPIP_DHCP_0202, TCPIP_DHCP_0203, ^TCPIP_TCP_0102, TCPIP_TCP_0106, TCPIP_TCP_0107, - TCPIP_TCP_0104, TCPIP_TCP_0105, TCPIP_TCP_0102, TCPIP_TCP_0103, TCPIP_TCP_0101, - ^TCPIP_TCP_0116, ^TCPIP_TCP_0114, ^TCPIP_TCP_0115, ^TCPIP_TCP_0112, ^TCPIP_TCP_0113] + ^TCPIP_IGMP_0103, TCPIP_UDP_0114, TCPIP_UDP_0113, TCPIP_UDP_0112, TCPIP_UDP_0202, + TCPIP_DHCP_0205, TCPIP_DHCP_0202, TCPIP_DHCP_0203, ^TCPIP_TCP_0102, TCPIP_TCP_0106, + TCPIP_TCP_0107, TCPIP_TCP_0104, TCPIP_TCP_0105, TCPIP_TCP_0102, TCPIP_TCP_0103, + TCPIP_TCP_0101, ^TCPIP_TCP_0116, ^TCPIP_TCP_0114, ^TCPIP_TCP_0115, ^TCPIP_TCP_0112] diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_04.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_04.yml index 314de4a7e0..b59e8c60cd 100644 --- a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_04.yml +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_04.yml @@ -2,7 +2,7 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC2, SSC1] Filter: - Add: - ID: [^TCPIP_TCP_0110, ^TCPIP_TCP_0111, TCPIP_DHCP_0209, ^TCPIP_DHCP_0209, ^TCPIP_DHCP_0207, + ID: [^TCPIP_TCP_0113, ^TCPIP_TCP_0110, TCPIP_DHCP_0209, ^TCPIP_DHCP_0209, ^TCPIP_DHCP_0207, ^TCPIP_DHCP_0206, ^TCPIP_DHCP_0205, ^TCPIP_DHCP_0204, ^TCPIP_DHCP_0203, ^TCPIP_DHCP_0202, ^TCPIP_DHCP_0201, TCPIP_TCP_0204, TCPIP_TCP_0207, TCPIP_TCP_0206, TCPIP_TCP_0201, ^TCPIP_DHCP_0101, TCPIP_TCP_0203, ^TCPIP_DHCP_0103, ^TCPIP_DHCP_0208, TCPIP_TCP_0208, diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_07.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_07.yml index 9b3d943fed..839ac972f4 100644 --- a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_07.yml +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_07.yml @@ -2,9 +2,9 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC2, SSC1] Filter: - Add: - ID: [TCPIP_ICMP_0101, TCPIP_ICMP_0101, TCPIP_ICMP_0101, TCPIP_ICMP_0101, TCPIP_ICMP_0101, + ID: [TCPIP_UDP_0303, TCPIP_UDP_0303, TCPIP_UDP_0303, TCPIP_UDP_0303, TCPIP_UDP_0303, + TCPIP_ICMP_0101, TCPIP_ICMP_0101, TCPIP_ICMP_0101, TCPIP_ICMP_0101, TCPIP_ICMP_0101, TCPIP_DNS_0102, TCPIP_DNS_0102, TCPIP_DNS_0102, TCPIP_DNS_0102, TCPIP_DNS_0102, TCPIP_DNS_0101, TCPIP_DNS_0101, TCPIP_DNS_0101, TCPIP_DNS_0101, TCPIP_DNS_0101, ^TCPIP_ICMP_0101, ^TCPIP_ICMP_0101, ^TCPIP_ICMP_0101, ^TCPIP_ICMP_0101, ^TCPIP_ICMP_0101, - TCPIP_UDP_0109, TCPIP_UDP_0109, TCPIP_UDP_0109, TCPIP_UDP_0109, TCPIP_UDP_0109, - TCPIP_UDP_0104, TCPIP_UDP_0104, TCPIP_UDP_0104, TCPIP_UDP_0104, TCPIP_UDP_0104] + TCPIP_UDP_0109, TCPIP_UDP_0109, TCPIP_UDP_0109, TCPIP_UDP_0109, TCPIP_UDP_0109] diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_08.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_08.yml index a2f8f0df07..b318b09377 100644 --- a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_08.yml +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_08.yml @@ -2,9 +2,9 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC1] Filter: - Add: - ID: [TCPIP_UDP_0102, TCPIP_UDP_0102, TCPIP_UDP_0102, TCPIP_UDP_0102, TCPIP_UDP_0102, + ID: [TCPIP_UDP_0104, TCPIP_UDP_0104, TCPIP_UDP_0104, TCPIP_UDP_0104, TCPIP_UDP_0104, + TCPIP_UDP_0102, TCPIP_UDP_0102, TCPIP_UDP_0102, TCPIP_UDP_0102, TCPIP_UDP_0102, TCPIP_UDP_0103, TCPIP_UDP_0103, TCPIP_UDP_0103, TCPIP_UDP_0103, TCPIP_UDP_0103, ^TCPIP_UDP_0307, ^TCPIP_UDP_0307, ^TCPIP_UDP_0307, ^TCPIP_UDP_0307, ^TCPIP_UDP_0307, ^TCPIP_UDP_0306, ^TCPIP_UDP_0306, ^TCPIP_UDP_0306, ^TCPIP_UDP_0306, ^TCPIP_UDP_0306, - ^TCPIP_UDP_0305, ^TCPIP_UDP_0305, ^TCPIP_UDP_0305, ^TCPIP_UDP_0305, ^TCPIP_UDP_0305, - ^TCPIP_UDP_0304, ^TCPIP_UDP_0304, ^TCPIP_UDP_0304, ^TCPIP_UDP_0304, ^TCPIP_UDP_0304] + ^TCPIP_UDP_0305, ^TCPIP_UDP_0305, ^TCPIP_UDP_0305, ^TCPIP_UDP_0305, ^TCPIP_UDP_0305] diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_09.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_09.yml index 146b98cf7d..50b50a3eb6 100644 --- a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_09.yml +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_09.yml @@ -2,7 +2,7 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC1] Filter: - Add: - ID: [^TCPIP_UDP_0303, ^TCPIP_UDP_0303, ^TCPIP_UDP_0303, ^TCPIP_UDP_0303, ^TCPIP_UDP_0303, + ID: [^TCPIP_UDP_0304, ^TCPIP_UDP_0304, ^TCPIP_UDP_0304, ^TCPIP_UDP_0304, ^TCPIP_UDP_0304, ^TCPIP_UDP_0302, ^TCPIP_UDP_0302, ^TCPIP_UDP_0302, ^TCPIP_UDP_0302, ^TCPIP_UDP_0302, ^TCPIP_UDP_0301, ^TCPIP_UDP_0301, ^TCPIP_UDP_0301, ^TCPIP_UDP_0301, ^TCPIP_UDP_0301, ^TCPIP_UDP_0104, ^TCPIP_UDP_0104, ^TCPIP_UDP_0104, ^TCPIP_UDP_0104, ^TCPIP_UDP_0104, diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_11.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_11.yml index 86690db67c..be615d0878 100644 --- a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_11.yml +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_11.yml @@ -7,4 +7,4 @@ Filter: TCPIP_UDP_0307, TCPIP_UDP_0307, TCPIP_UDP_0307, TCPIP_UDP_0307, TCPIP_UDP_0307, TCPIP_UDP_0301, TCPIP_UDP_0301, TCPIP_UDP_0301, TCPIP_UDP_0301, TCPIP_UDP_0301, TCPIP_UDP_0302, TCPIP_UDP_0302, TCPIP_UDP_0302, TCPIP_UDP_0302, TCPIP_UDP_0302, - TCPIP_UDP_0303, TCPIP_UDP_0303, TCPIP_UDP_0303, TCPIP_UDP_0303, TCPIP_UDP_0303] + TCPIP_DNS_0103, TCPIP_DNS_0103, TCPIP_DNS_0103, TCPIP_DNS_0103, TCPIP_DNS_0103] diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_12.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_12.yml index 4e0495e44d..73b0187eed 100644 --- a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_12.yml +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_12.yml @@ -2,5 +2,5 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC1] Filter: - Add: - ID: [TCPIP_DNS_0103, TCPIP_DNS_0103, TCPIP_DNS_0103, TCPIP_DNS_0103, TCPIP_DNS_0103, + ID: [^TCPIP_UDP_0303, ^TCPIP_UDP_0303, ^TCPIP_UDP_0303, ^TCPIP_UDP_0303, ^TCPIP_UDP_0303, ^TCPIP_UDP_0110, ^TCPIP_UDP_0110, ^TCPIP_UDP_0110, ^TCPIP_UDP_0110, ^TCPIP_UDP_0110] diff --git a/components/idf_test/integration_test/InitialConditionAll.yml b/components/idf_test/integration_test/InitialConditionAll.yml index ba06af9f87..3821894552 100644 --- a/components/idf_test/integration_test/InitialConditionAll.yml +++ b/components/idf_test/integration_test/InitialConditionAll.yml @@ -2933,3 +2933,27 @@ initial condition: start: 87.0 tag: T3_PHY1 test script: InitCondBase +- check cmd set: + - '' + - - UT UT1 - + - [R UT1 C Tests C Failures C Ignored] + force restore cmd set: + - '' + - - FREBOOT UT1 + - [''] + - - UT UT1 - + - [R UT1 C Tests C Failures C Ignored] + initial condition detail: At UT menu page + restore cmd set: + - '' + - - FREBOOT UT1 + - [''] + - - UT UT1 - + - [R UT1 C Tests C Failures C Ignored] + restore post cmd set: + - '' + - - DELAY 0.1 + - [''] + script path: InitCondBase.py + tag: UTINIT1 + test script: InitCondBase diff --git a/components/idf_test/integration_test/TestEnvAll.yml b/components/idf_test/integration_test/TestEnvAll.yml index 2e59961d97..6b21760150 100644 --- a/components/idf_test/integration_test/TestEnvAll.yml +++ b/components/idf_test/integration_test/TestEnvAll.yml @@ -141,6 +141,29 @@ test environment: PC wired NIC should set static IP address within the same subnet with AP. Must use onboard wired NIC.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_Sleep1, + test environment detail: 'AP support DTIM placed with AT target. + + SSC target connect with Raspberry Pi by UART. + + Multimeter connect with Raspberry Pi via GPIB. + + Series multimeter between GND and VCC of SSC1. + + SSC1''s light sleep wakeup pin and wakeup indication connect with Raspberry Pi''s + GPIO. + + SSC1''s XPD connect with RSTB.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_Sleep2, + test environment detail: 'AP support DTIM placed with AT target. + + SSC target connect with Raspberry Pi by UART. + + Multimeter connect with Raspberry Pi via GPIB. + + Series multimeter between GND and VCC of SSC1. + + SSC1''s RSTB pin connect with Raspberry Pi''s GPIO.', test script: EnvBase} - {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_TempBox, test environment detail: '1 SSC target connect with PC by UART. @@ -191,28 +214,6 @@ test environment: test environment detail: '2 SSC target connect with PC by UART. Put them to Shield box.', test script: EnvBase} -- {PC OS: '', Special: Y, Target Count: 2.0, script path: EnvBase.py, tag: SSC_T2_Sleep1, - test environment detail: 'AP support DTIM placed with AT target. - - 2 SSC target connect with PC by UART. - - Multimeter connect with PC via GPIB. - - Series multimeter between GND and VCC of SSC1. - - SSC1''s light sleep wakeup pin and wakeup indication connect with AT2''s GPIO. - - SSC1''s XPD connect with RSTB.', test script: EnvBase} -- {PC OS: '', Special: Y, Target Count: 2.0, script path: EnvBase.py, tag: SSC_T2_Sleep2, - test environment detail: 'AP support DTIM placed with AT target. - - 2 SSC target connect with PC by UART. - - Multimeter connect with PC via GPIB. - - Series multimeter between GND and VCC of SSC1. - - SSC1''s RSTB pin connect with AT2''s GPIO.', test script: EnvBase} - {PC OS: '', Special: N, Target Count: 2.0, script path: EnvBase.py, tag: SSC_T2_SmartConfig, test environment detail: '2 SSC target connect with PC by UART. @@ -263,6 +264,8 @@ test environment: SSC2', additional param list: '', basic param list: '', script path: EnvBase.py, tag: UART_T1_2, test environment detail: '[TBD] ESP_8266通过UART_0通过USB, UART_1 TXD 通过 TTLcable 连到PC', test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 1.0, script path: EnvBase.py, tag: UT_T1_1, + test environment detail: Environment for running ESP32 unit tests, test script: EnvBase} - {PC OS: linux, Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: WebServer_T1_1, test environment detail: 'Web Server target connect with PC by UART. diff --git a/components/idf_test/uint_test/TestCaseAll.yml b/components/idf_test/uint_test/TestCaseAll.yml deleted file mode 100644 index 2b2c65e0bd..0000000000 --- a/components/idf_test/uint_test/TestCaseAll.yml +++ /dev/null @@ -1 +0,0 @@ -test cases: [] diff --git a/components/idf_test/unit_test/CIConfigs/UT_Function_SYS_01.yml b/components/idf_test/unit_test/CIConfigs/UT_Function_SYS_01.yml new file mode 100644 index 0000000000..86e191cedf --- /dev/null +++ b/components/idf_test/unit_test/CIConfigs/UT_Function_SYS_01.yml @@ -0,0 +1,8 @@ +Config: {execute count: 1, execute order: in order} +DUT: [UT1] +Filter: +- Add: + ID: [SYS_OS_0101, SYS_OS_0102, SYS_MISC_0103, SYS_MISC_0102, SYS_MISC_0105, SYS_MISC_0104, + SYS_MISC_0107, SYS_MISC_0106, SYS_MISC_0109, SYS_MISC_0108, SYS_MISC_0112, SYS_MISC_0113, + SYS_MISC_0110, SYS_MISC_0111, SYS_MISC_0115, SYS_LIB_0103, SYS_LIB_0102, SYS_LIB_0101, + SYS_LIB_0106, SYS_LIB_0105, SYS_LIB_0104] diff --git a/components/idf_test/uint_test/InitialConditionAll.yml b/components/idf_test/unit_test/InitialConditionAll.yml similarity index 99% rename from components/idf_test/uint_test/InitialConditionAll.yml rename to components/idf_test/unit_test/InitialConditionAll.yml index ba06af9f87..3821894552 100644 --- a/components/idf_test/uint_test/InitialConditionAll.yml +++ b/components/idf_test/unit_test/InitialConditionAll.yml @@ -2933,3 +2933,27 @@ initial condition: start: 87.0 tag: T3_PHY1 test script: InitCondBase +- check cmd set: + - '' + - - UT UT1 - + - [R UT1 C Tests C Failures C Ignored] + force restore cmd set: + - '' + - - FREBOOT UT1 + - [''] + - - UT UT1 - + - [R UT1 C Tests C Failures C Ignored] + initial condition detail: At UT menu page + restore cmd set: + - '' + - - FREBOOT UT1 + - [''] + - - UT UT1 - + - [R UT1 C Tests C Failures C Ignored] + restore post cmd set: + - '' + - - DELAY 0.1 + - [''] + script path: InitCondBase.py + tag: UTINIT1 + test script: InitCondBase diff --git a/components/idf_test/unit_test/TestCaseAll.yml b/components/idf_test/unit_test/TestCaseAll.yml new file mode 100644 index 0000000000..8732296bfc --- /dev/null +++ b/components/idf_test/unit_test/TestCaseAll.yml @@ -0,0 +1,484 @@ +test cases: +- CI ready: 'Yes' + ID: SYS_LIB_0101 + SDK: ESP32_IDF + Test App: testje + auto test: 'Yes' + category: Function + cmd set: + - IDFUnitTest/UnitTest + - - test_case = "12" + - [dummy] + comment: check if ROM is used for functions + execution time: 0 + expected result: 1. set succeed + initial condition: UTINIT1 + level: Unit + module: System + steps: 1. run lib test + sub module: Std Lib + summary: lib unit test + test environment: UT_T1_1 + test point 1: basic function + test point 2: lib + version: v1 (2016-10-26) +- CI ready: 'Yes' + ID: SYS_LIB_0102 + SDK: ESP32_IDF + Test App: testje + auto test: 'Yes' + category: Function + cmd set: + - IDFUnitTest/UnitTest + - - test_case = "13" + - [dummy] + comment: test time functions + execution time: 0 + expected result: 1. set succeed + initial condition: UTINIT1 + level: Unit + module: System + steps: 1. run lib test + sub module: Std Lib + summary: lib unit test + test environment: UT_T1_1 + test point 1: basic function + test point 2: lib + version: v1 (2016-10-26) +- CI ready: 'Yes' + ID: SYS_LIB_0103 + SDK: ESP32_IDF + Test App: testje + auto test: 'Yes' + category: Function + cmd set: + - IDFUnitTest/UnitTest + - - test_case = "14" + - [dummy] + comment: test sscanf function + execution time: 0 + expected result: 1. set succeed + initial condition: UTINIT1 + level: Unit + module: System + steps: 1. run lib test + sub module: Std Lib + summary: lib unit test + test environment: UT_T1_1 + test point 1: basic function + test point 2: lib + version: v1 (2016-10-26) +- CI ready: 'Yes' + ID: SYS_LIB_0104 + SDK: ESP32_IDF + Test App: testje + auto test: 'Yes' + category: Function + cmd set: + - IDFUnitTest/UnitTest + - - test_case = "15" + - [dummy] + comment: test sprintf function + execution time: 0 + expected result: 1. set succeed + initial condition: UTINIT1 + level: Unit + module: System + steps: 1. run lib test + sub module: Std Lib + summary: lib unit test + test environment: UT_T1_1 + test point 1: basic function + test point 2: lib + version: v1 (2016-10-26) +- CI ready: 'Yes' + ID: SYS_LIB_0105 + SDK: ESP32_IDF + Test App: testje + auto test: 'Yes' + category: Function + cmd set: + - IDFUnitTest/UnitTest + - - test_case = "16" + - [dummy] + comment: test atoX functions + execution time: 0 + expected result: 1. set succeed + initial condition: UTINIT1 + level: Unit + module: System + steps: 1. run lib test + sub module: Std Lib + summary: lib unit test + test environment: UT_T1_1 + test point 1: basic function + test point 2: lib + version: v1 (2016-10-26) +- CI ready: 'Yes' + ID: SYS_LIB_0106 + SDK: ESP32_IDF + Test App: testje + auto test: 'Yes' + category: Function + cmd set: + - IDFUnitTest/UnitTest + - - test_case = "17" + - [dummy] + comment: test ctype functions + execution time: 0 + expected result: 1. set succeed + initial condition: UTINIT1 + level: Unit + module: System + steps: 1. run lib test + sub module: Std Lib + summary: lib unit test + test environment: UT_T1_1 + test point 1: basic function + test point 2: lib + version: v1 (2016-10-26) +- CI ready: 'Yes' + ID: SYS_MISC_0102 + SDK: ESP32_IDF + Test App: testje + auto test: 'Yes' + category: Function + cmd set: + - IDFUnitTest/UnitTest + - - test_case = "21" + - [dummy] + comment: mbedtls MPI self-tests + execution time: 0 + expected result: 1. set succeed + initial condition: UTINIT1 + level: Unit + module: System + steps: 1. run bignum test + sub module: Misc + summary: bignum unit test + test environment: UT_T1_1 + test point 1: basic function + test point 2: bignum + version: v1 (2016-10-26) +- CI ready: 'Yes' + ID: SYS_MISC_0103 + SDK: ESP32_IDF + Test App: testje + auto test: 'Yes' + category: Function + cmd set: + - IDFUnitTest/UnitTest + - - test_case = "25" + - [dummy] + comment: test AES thread safety + execution time: 0 + expected result: 1. set succeed + initial condition: UTINIT1 + level: Unit + module: System + steps: 1. run hwcrypto test + sub module: Misc + summary: hwcrypto unit test + test environment: UT_T1_1 + test point 1: basic function + test point 2: hwcrypto + version: v1 (2016-10-26) +- CI ready: 'Yes' + ID: SYS_MISC_0104 + SDK: ESP32_IDF + Test App: testje + auto test: 'Yes' + category: Function + cmd set: + - IDFUnitTest/UnitTest + - - test_case = "26" + - [dummy] + comment: test AES acceleration + execution time: 0 + expected result: 1. set succeed + initial condition: UTINIT1 + level: Unit + module: System + steps: 1. run hwcrypto test + sub module: Misc + summary: hwcrypto unit test + test environment: UT_T1_1 + test point 1: basic function + test point 2: hwcrypto + version: v1 (2016-10-26) +- CI ready: 'Yes' + ID: SYS_MISC_0105 + SDK: ESP32_IDF + Test App: testje + auto test: 'Yes' + category: Function + cmd set: + - IDFUnitTest/UnitTest + - - test_case = "27" + - [dummy] + comment: test SHA thread safety + execution time: 0 + expected result: 1. set succeed + initial condition: UTINIT1 + level: Unit + module: System + steps: 1. run hwcrypto test + sub module: Misc + summary: hwcrypto unit test + test environment: UT_T1_1 + test point 1: basic function + test point 2: hwcrypto + version: v1 (2016-10-26) +- CI ready: 'Yes' + ID: SYS_MISC_0106 + SDK: ESP32_IDF + Test App: testje + auto test: 'Yes' + category: Function + cmd set: + - IDFUnitTest/UnitTest + - - test_case = "33" + - [dummy] + comment: context switch saves FP registers + execution time: 0 + expected result: 1. set succeed + initial condition: UTINIT1 + level: Unit + module: System + steps: 1. run fp test + sub module: Misc + summary: fp unit test + test environment: UT_T1_1 + test point 1: basic function + test point 2: fp + version: v1 (2016-10-26) +- CI ready: 'Yes' + ID: SYS_MISC_0107 + SDK: ESP32_IDF + Test App: testje + auto test: 'Yes' + category: Function + cmd set: + - IDFUnitTest/UnitTest + - - test_case = "34" + - [dummy] + comment: test FP sqrt + execution time: 0 + expected result: 1. set succeed + initial condition: UTINIT1 + level: Unit + module: System + steps: 1. run fp test + sub module: Misc + summary: fp unit test + test environment: UT_T1_1 + test point 1: basic function + test point 2: fp + version: v1 (2016-10-26) +- CI ready: 'Yes' + ID: SYS_MISC_0108 + SDK: ESP32_IDF + Test App: testje + auto test: 'Yes' + category: Function + cmd set: + - IDFUnitTest/UnitTest + - - test_case = "35" + - [dummy] + comment: test FP div + execution time: 0 + expected result: 1. set succeed + initial condition: UTINIT1 + level: Unit + module: System + steps: 1. run fp test + sub module: Misc + summary: fp unit test + test environment: UT_T1_1 + test point 1: basic function + test point 2: fp + version: v1 (2016-10-26) +- CI ready: 'Yes' + ID: SYS_MISC_0109 + SDK: ESP32_IDF + Test App: testje + auto test: 'Yes' + category: Function + cmd set: + - IDFUnitTest/UnitTest + - - test_case = "36" + - [dummy] + comment: test FP mul + execution time: 0 + expected result: 1. set succeed + initial condition: UTINIT1 + level: Unit + module: System + steps: 1. run fp test + sub module: Misc + summary: fp unit test + test environment: UT_T1_1 + test point 1: basic function + test point 2: fp + version: v1 (2016-10-26) +- CI ready: 'Yes' + ID: SYS_MISC_0110 + SDK: ESP32_IDF + Test App: testje + auto test: 'Yes' + category: Function + cmd set: + - IDFUnitTest/UnitTest + - - test_case = "37" + - [dummy] + comment: test FP add + execution time: 0 + expected result: 1. set succeed + initial condition: UTINIT1 + level: Unit + module: System + steps: 1. run fp test + sub module: Misc + summary: fp unit test + test environment: UT_T1_1 + test point 1: basic function + test point 2: fp + version: v1 (2016-10-26) +- CI ready: 'Yes' + ID: SYS_MISC_0111 + SDK: ESP32_IDF + Test App: testje + auto test: 'Yes' + category: Function + cmd set: + - IDFUnitTest/UnitTest + - - test_case = "3" + - [dummy] + comment: Test JPEG decompression library + execution time: 0 + expected result: 1. set succeed + initial condition: UTINIT1 + level: Unit + module: System + steps: 1. run JPEG decompression test + sub module: Misc + summary: JPEG decompression library unit test + test environment: UT_T1_1 + test point 1: basic function + test point 2: tjpgd + version: v1 (2016-10-31) +- CI ready: 'Yes' + ID: SYS_MISC_0112 + SDK: ESP32_IDF + Test App: testje + auto test: 'Yes' + category: Function + cmd set: + - IDFUnitTest/UnitTest + - - test_case = "22" + - [dummy] + comment: mbedtls AES self-tests + execution time: 0 + expected result: 1. set succeed + initial condition: UTINIT1 + level: Unit + module: System + steps: 1. run mbedtls AES self-tests + sub module: Misc + summary: mbedtls AES unit test + test environment: UT_T1_1 + test point 1: basic function + test point 2: mbedtls AES + version: v1 (2016-10-31) +- CI ready: 'Yes' + ID: SYS_MISC_0113 + SDK: ESP32_IDF + Test App: testje + auto test: 'Yes' + category: Function + cmd set: + - IDFUnitTest/UnitTest + - - test_case = "17" + - [dummy] + comment: mbedtls SHA self-tests + execution time: 0 + expected result: 1. set succeed + initial condition: UTINIT1 + level: Unit + module: System + steps: 1. run mbedtls SHA self-tests + sub module: Misc + summary: mbedtls SHA unit test + test environment: UT_T1_1 + test point 1: basic function + test point 2: mbedtls SHA + version: v1 (2016-10-31) +- CI ready: 'Yes' + ID: SYS_MISC_0115 + SDK: ESP32_IDF + Test App: testje + auto test: 'Yes' + category: Function + cmd set: + - IDFUnitTest/UnitTest + - - test_case = "28" + - [dummy] + comment: test SHA acceleration + execution time: 0 + expected result: 1. set succeed + initial condition: UTINIT1 + level: Unit + module: System + steps: 1. run SHA acceleration test + sub module: Misc + summary: SHA acceleration unit test + test environment: UT_T1_1 + test point 1: basic function + test point 2: SHA acceleration + version: v1 (2016-10-31) +- CI ready: 'Yes' + ID: SYS_OS_0101 + SDK: ESP32_IDF + Test App: testje + auto test: 'Yes' + category: Function + cmd set: + - IDFUnitTest/UnitTest + - - test_case = "31" + - [dummy] + comment: FreeRTOS Event Groups + execution time: 0 + expected result: 1. set succeed + initial condition: UTINIT1 + level: Unit + module: System + steps: 1. run freertos test + sub module: OS + summary: freertos unit test + test environment: UT_T1_1 + test point 1: basic function + test point 2: freertos + version: v1 (2016-10-26) +- CI ready: 'Yes' + ID: SYS_OS_0102 + SDK: ESP32_IDF + Test App: testje + auto test: 'Yes' + category: Function + cmd set: + - IDFUnitTest/UnitTest + - - test_case = "2" + - [dummy] + comment: Freertos TLS delete cb + execution time: 0 + expected result: 1. set succeed + initial condition: UTINIT1 + level: Unit + module: System + steps: 1. run Freertos TLS delete cb test + sub module: OS + summary: Freertos TLS delete cb unit test + test environment: UT_T1_1 + test point 1: basic function + test point 2: Freertos TLS delete cb + version: v1 (2016-10-31) diff --git a/components/idf_test/unit_test/TestCaseScript/IDFUnitTest/UnitTest.py b/components/idf_test/unit_test/TestCaseScript/IDFUnitTest/UnitTest.py new file mode 100644 index 0000000000..6e7cac4109 --- /dev/null +++ b/components/idf_test/unit_test/TestCaseScript/IDFUnitTest/UnitTest.py @@ -0,0 +1,47 @@ +import re +import time + +from TCAction import PerformanceTCBase +from TCAction import TCActionBase +from NativeLog import NativeLog + +class UnitTest(PerformanceTCBase.PerformanceTCBase): + def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): + PerformanceTCBase.PerformanceTCBase.__init__(self, name, test_env, cmd_set=cmd_set, + timeout=timeout, log_path=log_path) + + self.test_case = None + self.test_timeout = 6 + + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + pass + + def send_commands(self): + self.flush_data("UT1") + + try: + self.serial_write_line("UT1", self.test_case) + time.sleep(self.test_timeout) #wait for test to run before reading result + data = self.serial_read_data("UT1") + if re.search('[^0] Tests 0 F', data): #check that number of tests run != 0 and number of tests failed == 0 + self.set_result("Success") + else: + self.set_result("Fail") + + except StandardError,e: + NativeLog.add_exception_log(e) + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.send_commands() + +def main(): + pass + +if __name__ == '__main__': + pass diff --git a/components/idf_test/unit_test/TestCaseScript/IDFUnitTest/__init__.py b/components/idf_test/unit_test/TestCaseScript/IDFUnitTest/__init__.py new file mode 100755 index 0000000000..876a5d4023 --- /dev/null +++ b/components/idf_test/unit_test/TestCaseScript/IDFUnitTest/__init__.py @@ -0,0 +1 @@ +__all__ = ["UnitTest"] diff --git a/components/idf_test/uint_test/TestEnvAll.yml b/components/idf_test/unit_test/TestEnvAll.yml similarity index 95% rename from components/idf_test/uint_test/TestEnvAll.yml rename to components/idf_test/unit_test/TestEnvAll.yml index 2e59961d97..6b21760150 100644 --- a/components/idf_test/uint_test/TestEnvAll.yml +++ b/components/idf_test/unit_test/TestEnvAll.yml @@ -141,6 +141,29 @@ test environment: PC wired NIC should set static IP address within the same subnet with AP. Must use onboard wired NIC.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_Sleep1, + test environment detail: 'AP support DTIM placed with AT target. + + SSC target connect with Raspberry Pi by UART. + + Multimeter connect with Raspberry Pi via GPIB. + + Series multimeter between GND and VCC of SSC1. + + SSC1''s light sleep wakeup pin and wakeup indication connect with Raspberry Pi''s + GPIO. + + SSC1''s XPD connect with RSTB.', test script: EnvBase} +- {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_Sleep2, + test environment detail: 'AP support DTIM placed with AT target. + + SSC target connect with Raspberry Pi by UART. + + Multimeter connect with Raspberry Pi via GPIB. + + Series multimeter between GND and VCC of SSC1. + + SSC1''s RSTB pin connect with Raspberry Pi''s GPIO.', test script: EnvBase} - {PC OS: '', Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: SSC_T1_TempBox, test environment detail: '1 SSC target connect with PC by UART. @@ -191,28 +214,6 @@ test environment: test environment detail: '2 SSC target connect with PC by UART. Put them to Shield box.', test script: EnvBase} -- {PC OS: '', Special: Y, Target Count: 2.0, script path: EnvBase.py, tag: SSC_T2_Sleep1, - test environment detail: 'AP support DTIM placed with AT target. - - 2 SSC target connect with PC by UART. - - Multimeter connect with PC via GPIB. - - Series multimeter between GND and VCC of SSC1. - - SSC1''s light sleep wakeup pin and wakeup indication connect with AT2''s GPIO. - - SSC1''s XPD connect with RSTB.', test script: EnvBase} -- {PC OS: '', Special: Y, Target Count: 2.0, script path: EnvBase.py, tag: SSC_T2_Sleep2, - test environment detail: 'AP support DTIM placed with AT target. - - 2 SSC target connect with PC by UART. - - Multimeter connect with PC via GPIB. - - Series multimeter between GND and VCC of SSC1. - - SSC1''s RSTB pin connect with AT2''s GPIO.', test script: EnvBase} - {PC OS: '', Special: N, Target Count: 2.0, script path: EnvBase.py, tag: SSC_T2_SmartConfig, test environment detail: '2 SSC target connect with PC by UART. @@ -263,6 +264,8 @@ test environment: SSC2', additional param list: '', basic param list: '', script path: EnvBase.py, tag: UART_T1_2, test environment detail: '[TBD] ESP_8266通过UART_0通过USB, UART_1 TXD 通过 TTLcable 连到PC', test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 1.0, script path: EnvBase.py, tag: UT_T1_1, + test environment detail: Environment for running ESP32 unit tests, test script: EnvBase} - {PC OS: linux, Special: Y, Target Count: 1.0, script path: EnvBase.py, tag: WebServer_T1_1, test environment detail: 'Web Server target connect with PC by UART. From 1d3626c119d2acbb164571ce01dc5326f418172f Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 1 Nov 2016 20:08:29 +0800 Subject: [PATCH 233/343] docs: fix typos, build docs with gitlab CI --- .gitlab-ci.yml | 14 ++++++++++++++ docs/eclipse-setup.rst | 2 +- docs/index.rst | 5 +---- docs/requirements.txt | 7 ++++++- 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index aff9bea8d1..25e4d4f177 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -92,6 +92,20 @@ build_examples: - cd build_examples - ${IDF_PATH}/make/build_examples.sh +build_docs: + stage: build + image: espressif/esp32-ci-env + tags: + - build_docs + script: + - cd docs + - make html + artifacts: + paths: + - docs/_build/html + expire_in: 6 mos + + test_nvs_on_host: stage: test image: espressif/esp32-ci-env diff --git a/docs/eclipse-setup.rst b/docs/eclipse-setup.rst index 32d60a17a0..fbad93be6c 100644 --- a/docs/eclipse-setup.rst +++ b/docs/eclipse-setup.rst @@ -1,4 +1,4 @@ -Build and Falsh with Eclipse IDE +Build and Flash with Eclipse IDE ******************************** Installing Eclipse IDE diff --git a/docs/index.rst b/docs/index.rst index da03346e71..c973950615 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -3,10 +3,7 @@ ESP32 Programming Guide .. caution:: - This DRAF version of documentation developed within `ESP-IDF 1.0 Release plan `_. - It is scheduled for merging with `espressif/esp-idf `_ repository at the release date. - Before merging it may be incomplete, or not fully in sync with espressif/esp-idf. - Please mind your step! + Until ESP-IDF release 1.0, this documentation is a draft. It is incomplete and may have mistakes. Please mind your step! Contents: diff --git a/docs/requirements.txt b/docs/requirements.txt index 188f51e62d..debed28677 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1 +1,6 @@ -breathe \ No newline at end of file +# This is a list of python packages used to generate documentation. This file is used with pip: +# pip install requirements.txt +# +sphinx +sphinx-rtd-theme +breathe From c67ac340c71b2b623ca12a2ee3d85f6f6e6ca96c Mon Sep 17 00:00:00 2001 From: Yinling Date: Tue, 1 Nov 2016 20:33:23 +0800 Subject: [PATCH 234/343] use correct template for unit test jobs --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e51c9dd020..ae93421599 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -255,7 +255,7 @@ push_master_to_github: TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/components/idf_test/unit_test" UT_Function_SYS_01: - <<: *test_template + <<: *unit_test_template tags: - ESP32_IDF - UT_T1_1 From 4f71d741ec79c1a155d4130a3936f2971dd6caf9 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 1 Nov 2016 20:58:47 +0800 Subject: [PATCH 235/343] docs: deploy built docs --- .gitlab-ci.yml | 27 ++++++++++++++++++++++++++- docs/conf.py | 22 ++++++++++++++++++---- 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 25e4d4f177..931009f4b9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -103,7 +103,7 @@ build_docs: artifacts: paths: - docs/_build/html - expire_in: 6 mos + expire_in: 1 mos test_nvs_on_host: @@ -173,6 +173,31 @@ push_master_to_github: - git push --follow-tags github HEAD:master +deploy_docs: + before_script: + - echo "Not setting up GitLab key, not fetching submodules" + stage: deploy + only: + - master + - triggers + tags: + - deploy + image: espressif/esp32-ci-env + script: + - mkdir -p ~/.ssh + - chmod 700 ~/.ssh + - echo -n $DOCS_DEPLOY_KEY > ~/.ssh/id_rsa_base64 + - base64 --decode --ignore-garbage ~/.ssh/id_rsa_base64 > ~/.ssh/id_rsa + - chmod 600 ~/.ssh/id_rsa + - echo -e "Host $DOCS_SERVER\n\tStrictHostKeyChecking no\n\tUser $DOCS_SERVER_USER\n" >> ~/.ssh/config + - export GIT_VER=$(git describe --always) + - cd docs/_build/ + - mv html $GIT_VER + - tar czvf $GIT_VER.tar.gz $GIT_VER + - scp $GIT_VER.tar.gz $DOCS_SERVER:$DOCS_PATH + - ssh $DOCS_SERVER -x "cd $DOCS_PATH && tar xzvf $GIT_VER.tar.gz && rm -f latest && ln -s $GIT_VER latest" + + # AUTO GENERATED PART START, DO NOT MODIFY CONTENT BELOW # template for test jobs .test_template: &test_template diff --git a/docs/conf.py b/docs/conf.py index 8a8821fb0d..8a4a275c8a 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -26,9 +26,20 @@ import os # added by krzychb, 24-Oct-2016 # -from subprocess import call +from subprocess import call, Popen, PIPE +import shlex + call('doxygen') +# -- Function to get output of a command ---------------------------------- +def run_cmd_get_output(cmd): + process = Popen(shlex.split(cmd), stdout=PIPE) + (output, err) = process.communicate() + exit_code = process.wait() + if exit_code != 0: + raise RuntimeError('command line program has failed') + return output + # -- General configuration ------------------------------------------------ @@ -64,10 +75,13 @@ copyright = u'2016, Espressif' # |version| and |release|, also used in various other places throughout the # built documents. # -# The short X.Y version. -version = '1.0' +# This is supposed to be "the short X.Y version", but it's the only version +# visible when you open index.html. +# Display full version to make things less confusing. +# If needed, nearest tag is returned by 'git describe --abbrev=0'. +version = run_cmd_get_output('git describe') # The full version, including alpha/beta/rc tags. -release = '1.0' +release = run_cmd_get_output('git describe') # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. From e1f0c98ef531ed803bc5ad9100c0a971f8c272b2 Mon Sep 17 00:00:00 2001 From: Wangjialin Date: Tue, 1 Nov 2016 11:48:32 +0800 Subject: [PATCH 236/343] Modify gpio.h and ledc.h --- components/driver/include/driver/gpio.h | 436 ++++++++++++------------ components/driver/include/driver/ledc.h | 330 +++++++++--------- 2 files changed, 388 insertions(+), 378 deletions(-) diff --git a/components/driver/include/driver/gpio.h b/components/driver/include/driver/gpio.h index 001be2a39d..7106489d6c 100644 --- a/components/driver/include/driver/gpio.h +++ b/components/driver/include/driver/gpio.h @@ -27,43 +27,43 @@ extern "C" { #endif -#define GPIO_SEL_0 (BIT(0)) /* Pin 0 selected */ -#define GPIO_SEL_1 (BIT(1)) /* Pin 1 selected */ -#define GPIO_SEL_2 (BIT(2)) /* Pin 2 selected */ -#define GPIO_SEL_3 (BIT(3)) /* Pin 3 selected */ -#define GPIO_SEL_4 (BIT(4)) /* Pin 4 selected */ -#define GPIO_SEL_5 (BIT(5)) /* Pin 5 selected */ -#define GPIO_SEL_6 (BIT(6)) /* Pin 6 selected */ -#define GPIO_SEL_7 (BIT(7)) /* Pin 7 selected */ -#define GPIO_SEL_8 (BIT(8)) /* Pin 8 selected */ -#define GPIO_SEL_9 (BIT(9)) /* Pin 9 selected */ -#define GPIO_SEL_10 (BIT(10)) /* Pin 10 selected */ -#define GPIO_SEL_11 (BIT(11)) /* Pin 11 selected */ -#define GPIO_SEL_12 (BIT(12)) /* Pin 12 selected */ -#define GPIO_SEL_13 (BIT(13)) /* Pin 13 selected */ -#define GPIO_SEL_14 (BIT(14)) /* Pin 14 selected */ -#define GPIO_SEL_15 (BIT(15)) /* Pin 15 selected */ -#define GPIO_SEL_16 (BIT(16)) /* Pin 16 selected */ -#define GPIO_SEL_17 (BIT(17)) /* Pin 17 selected */ -#define GPIO_SEL_18 (BIT(18)) /* Pin 18 selected */ -#define GPIO_SEL_19 (BIT(19)) /* Pin 19 selected */ +#define GPIO_SEL_0 (BIT(0)) /*!< Pin 0 selected */ +#define GPIO_SEL_1 (BIT(1)) /*!< Pin 1 selected */ +#define GPIO_SEL_2 (BIT(2)) /*!< Pin 2 selected */ +#define GPIO_SEL_3 (BIT(3)) /*!< Pin 3 selected */ +#define GPIO_SEL_4 (BIT(4)) /*!< Pin 4 selected */ +#define GPIO_SEL_5 (BIT(5)) /*!< Pin 5 selected */ +#define GPIO_SEL_6 (BIT(6)) /*!< Pin 6 selected */ +#define GPIO_SEL_7 (BIT(7)) /*!< Pin 7 selected */ +#define GPIO_SEL_8 (BIT(8)) /*!< Pin 8 selected */ +#define GPIO_SEL_9 (BIT(9)) /*!< Pin 9 selected */ +#define GPIO_SEL_10 (BIT(10)) /*!< Pin 10 selected */ +#define GPIO_SEL_11 (BIT(11)) /*!< Pin 11 selected */ +#define GPIO_SEL_12 (BIT(12)) /*!< Pin 12 selected */ +#define GPIO_SEL_13 (BIT(13)) /*!< Pin 13 selected */ +#define GPIO_SEL_14 (BIT(14)) /*!< Pin 14 selected */ +#define GPIO_SEL_15 (BIT(15)) /*!< Pin 15 selected */ +#define GPIO_SEL_16 (BIT(16)) /*!< Pin 16 selected */ +#define GPIO_SEL_17 (BIT(17)) /*!< Pin 17 selected */ +#define GPIO_SEL_18 (BIT(18)) /*!< Pin 18 selected */ +#define GPIO_SEL_19 (BIT(19)) /*!< Pin 19 selected */ -#define GPIO_SEL_21 (BIT(21)) /* Pin 21 selected */ -#define GPIO_SEL_22 (BIT(22)) /* Pin 22 selected */ -#define GPIO_SEL_23 (BIT(23)) /* Pin 23 selected */ +#define GPIO_SEL_21 (BIT(21)) /*!< Pin 21 selected */ +#define GPIO_SEL_22 (BIT(22)) /*!< Pin 22 selected */ +#define GPIO_SEL_23 (BIT(23)) /*!< Pin 23 selected */ -#define GPIO_SEL_25 (BIT(25)) /* Pin 25 selected */ -#define GPIO_SEL_26 (BIT(26)) /* Pin 26 selected */ -#define GPIO_SEL_27 (BIT(27)) /* Pin 27 selected */ +#define GPIO_SEL_25 (BIT(25)) /*!< Pin 25 selected */ +#define GPIO_SEL_26 (BIT(26)) /*!< Pin 26 selected */ +#define GPIO_SEL_27 (BIT(27)) /*!< Pin 27 selected */ -#define GPIO_SEL_32 ((uint64_t)(((uint64_t)1)<<32)) /* Pin 32 selected */ -#define GPIO_SEL_33 ((uint64_t)(((uint64_t)1)<<33)) /* Pin 33 selected */ -#define GPIO_SEL_34 ((uint64_t)(((uint64_t)1)<<34)) /* Pin 34 selected */ -#define GPIO_SEL_35 ((uint64_t)(((uint64_t)1)<<35)) /* Pin 35 selected */ -#define GPIO_SEL_36 ((uint64_t)(((uint64_t)1)<<36)) /* Pin 36 selected */ -#define GPIO_SEL_37 ((uint64_t)(((uint64_t)1)<<37)) /* Pin 37 selected */ -#define GPIO_SEL_38 ((uint64_t)(((uint64_t)1)<<38)) /* Pin 38 selected */ -#define GPIO_SEL_39 ((uint64_t)(((uint64_t)1)<<39)) /* Pin 39 selected */ +#define GPIO_SEL_32 ((uint64_t)(((uint64_t)1)<<32)) /*!< Pin 32 selected */ +#define GPIO_SEL_33 ((uint64_t)(((uint64_t)1)<<33)) /*!< Pin 33 selected */ +#define GPIO_SEL_34 ((uint64_t)(((uint64_t)1)<<34)) /*!< Pin 34 selected */ +#define GPIO_SEL_35 ((uint64_t)(((uint64_t)1)<<35)) /*!< Pin 35 selected */ +#define GPIO_SEL_36 ((uint64_t)(((uint64_t)1)<<36)) /*!< Pin 36 selected */ +#define GPIO_SEL_37 ((uint64_t)(((uint64_t)1)<<37)) /*!< Pin 37 selected */ +#define GPIO_SEL_38 ((uint64_t)(((uint64_t)1)<<38)) /*!< Pin 38 selected */ +#define GPIO_SEL_39 ((uint64_t)(((uint64_t)1)<<39)) /*!< Pin 39 selected */ #define GPIO_PIN_REG_0 PERIPHS_IO_MUX_GPIO0_U #define GPIO_PIN_REG_1 PERIPHS_IO_MUX_U0TXD_U @@ -117,47 +117,47 @@ extern const uint32_t GPIO_PIN_MUX_REG[GPIO_PIN_COUNT]; #define GPIO_IS_VALID_OUTPUT_GPIO(gpio_num) ((GPIO_IS_VALID_GPIO(gpio_num)) && (gpio_num < 34)) //to decide whether it can be a valid GPIO number of output mode typedef enum { - GPIO_NUM_0 = 0, - GPIO_NUM_1 = 1, - GPIO_NUM_2 = 2, - GPIO_NUM_3 = 3, - GPIO_NUM_4 = 4, - GPIO_NUM_5 = 5, - GPIO_NUM_6 = 6, - GPIO_NUM_7 = 7, - GPIO_NUM_8 = 8, - GPIO_NUM_9 = 9, - GPIO_NUM_10 = 10, - GPIO_NUM_11 = 11, - GPIO_NUM_12 = 12, - GPIO_NUM_13 = 13, - GPIO_NUM_14 = 14, - GPIO_NUM_15 = 15, - GPIO_NUM_16 = 16, - GPIO_NUM_17 = 17, - GPIO_NUM_18 = 18, - GPIO_NUM_19 = 19, + GPIO_NUM_0 = 0, /*!< GPIO0, input and output */ + GPIO_NUM_1 = 1, /*!< GPIO1, input and output */ + GPIO_NUM_2 = 2, /*!< GPIO2, input and output */ + GPIO_NUM_3 = 3, /*!< GPIO3, input and output */ + GPIO_NUM_4 = 4, /*!< GPIO4, input and output */ + GPIO_NUM_5 = 5, /*!< GPIO5, input and output */ + GPIO_NUM_6 = 6, /*!< GPIO6, input and output */ + GPIO_NUM_7 = 7, /*!< GPIO7, input and output */ + GPIO_NUM_8 = 8, /*!< GPIO8, input and output */ + GPIO_NUM_9 = 9, /*!< GPIO9, input and output */ + GPIO_NUM_10 = 10, /*!< GPIO10, input and output */ + GPIO_NUM_11 = 11, /*!< GPIO11, input and output */ + GPIO_NUM_12 = 12, /*!< GPIO12, input and output */ + GPIO_NUM_13 = 13, /*!< GPIO13, input and output */ + GPIO_NUM_14 = 14, /*!< GPIO14, input and output */ + GPIO_NUM_15 = 15, /*!< GPIO15, input and output */ + GPIO_NUM_16 = 16, /*!< GPIO16, input and output */ + GPIO_NUM_17 = 17, /*!< GPIO17, input and output */ + GPIO_NUM_18 = 18, /*!< GPIO18, input and output */ + GPIO_NUM_19 = 19, /*!< GPIO19, input and output */ - GPIO_NUM_21 = 21, - GPIO_NUM_22 = 22, - GPIO_NUM_23 = 23, + GPIO_NUM_21 = 21, /*!< GPIO21, input and output */ + GPIO_NUM_22 = 22, /*!< GPIO22, input and output */ + GPIO_NUM_23 = 23, /*!< GPIO23, input and output */ - GPIO_NUM_25 = 25, - GPIO_NUM_26 = 26, - GPIO_NUM_27 = 27, + GPIO_NUM_25 = 25, /*!< GPIO25, input and output */ + GPIO_NUM_26 = 26, /*!< GPIO26, input and output */ + GPIO_NUM_27 = 27, /*!< GPIO27, input and output */ - GPIO_NUM_32 = 32, - GPIO_NUM_33 = 33, - GPIO_NUM_34 = 34, /*input mode only */ - GPIO_NUM_35 = 35, /*input mode only */ - GPIO_NUM_36 = 36, /*input mode only */ - GPIO_NUM_37 = 37, /*input mode only */ - GPIO_NUM_38 = 38, /*input mode only */ - GPIO_NUM_39 = 39, /*input mode only */ + GPIO_NUM_32 = 32, /*!< GPIO32, input and output */ + GPIO_NUM_33 = 33, /*!< GPIO32, input and output */ + GPIO_NUM_34 = 34, /*!< GPIO34, input mode only */ + GPIO_NUM_35 = 35, /*!< GPIO35, input mode only */ + GPIO_NUM_36 = 36, /*!< GPIO36, input mode only */ + GPIO_NUM_37 = 37, /*!< GPIO37, input mode only */ + GPIO_NUM_38 = 38, /*!< GPIO38, input mode only */ + GPIO_NUM_39 = 39, /*!< GPIO39, input mode only */ } gpio_num_t; typedef enum { - GPIO_INTR_DISABLE = 0, /*!< disable GPIO interrupt */ + GPIO_INTR_DISABLE = 0, /*!< Disable GPIO interrupt */ GPIO_INTR_POSEDGE = 1, /*!< GPIO interrupt type : rising edge */ GPIO_INTR_NEGEDGE = 2, /*!< GPIO interrupt type : falling edge */ GPIO_INTR_ANYEDGE = 3, /*!< GPIO interrupt type : both rising and falling edge */ @@ -175,13 +175,13 @@ typedef enum { } gpio_mode_t; typedef enum { - GPIO_PULLUP_DISABLE = 0x0, /*!< disable GPIO pull-up resistor */ - GPIO_PULLUP_ENABLE = 0x1, /*!< enable GPIO pull-up resistor */ + GPIO_PULLUP_DISABLE = 0x0, /*!< Disable GPIO pull-up resistor */ + GPIO_PULLUP_ENABLE = 0x1, /*!< Enable GPIO pull-up resistor */ } gpio_pullup_t; typedef enum { - GPIO_PULLDOWN_DISABLE = 0x0, /*!< disable GPIO pull-down resistor */ - GPIO_PULLDOWN_ENABLE = 0x1, /*!< enable GPIO pull-down resistor */ + GPIO_PULLDOWN_DISABLE = 0x0, /*!< Disable GPIO pull-down resistor */ + GPIO_PULLDOWN_ENABLE = 0x1, /*!< Enable GPIO pull-down resistor */ } gpio_pulldown_t; typedef struct { @@ -192,12 +192,6 @@ typedef struct { gpio_int_type_t intr_type; /*!< GPIO interrupt type */ } gpio_config_t; -typedef enum { - GPIO_LOW_LEVEL = 0, - GPIO_HIGH_LEVEL = 1, - GPIO_LEVEL_ERR, -} gpio_level_t; - typedef enum { GPIO_PULLUP_ONLY, /*!< Pad pull up */ GPIO_PULLDOWN_ONLY, /*!< Pad pull down */ @@ -207,254 +201,250 @@ typedef enum { typedef void (*gpio_event_callback)(gpio_num_t gpio_intr_num); -/** \defgroup Driver_APIs Driver APIs - * @brief Driver APIs - */ - -/** @addtogroup Driver_APIs - * @{ - */ - -/** \defgroup GPIO_Driver_APIs GPIO Driver APIs - * @brief GPIO APIs - */ - -/** @addtogroup GPIO_Driver_APIs - * @{ - */ - /** - * @brief GPIO common configuration + * @brief GPIO common configuration * - * Use this Function ,Configure GPIO's Mode,pull-up,PullDown,IntrType + * Configure GPIO's Mode,pull-up,PullDown,IntrType * - * @param[in] pGPIOConfig - * pGPIOConfig.pin_bit_mask : Configure GPIO pins bits,set this parameter with bit mask. - * If you want to configure GPIO34 and GPIO16, pin_bit_mask=GPIO_Pin_16|GPIO_Pin_34; - * pGPIOConfig.mode : Configure GPIO mode,such as output ,input... - * pGPIOConfig.pull_up_en : Enable or Disable pull-up - * pGPIOConfig.pull_down_en : Enable or Disable pull-down - * pGPIOConfig.intr_type : Configure GPIO interrupt trigger type - * @return ESP_OK: success ; - * ESP_ERR_INVALID_ARG: parameter error - * ESP_FAIL : GPIO error + * @param pGPIOConfig Pointer to GPIO configure struct + * + * @return + * - ESP_OK success + * - ESP_ERR_INVALID_ARG Parameter error * */ esp_err_t gpio_config(gpio_config_t *pGPIOConfig); /** - * @brief GPIO set interrupt trigger type + * @brief GPIO set interrupt trigger type * - * @param[in] gpio_num : GPIO number. - * If you want to set output level of GPIO16, gpio_num should be GPIO_NUM_16 (16); - * @param[in] intr_type: interrupt type, select from gpio_int_type_t + * @param gpio_num GPIO number. If you want to set output level of GPIO16, gpio_num should be GPIO_NUM_16 (16); + * @param intr_type Interrupt type, select from gpio_int_type_t * - * @return ESP_OK : success - * ESP_ERR_INVALID_ARG: parameter error + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG Parameter error * */ esp_err_t gpio_set_intr_type(gpio_num_t gpio_num, gpio_int_type_t intr_type); /** - * @brief enable GPIO module interrupt signal + * @brief Enable GPIO module interrupt signal * - * @param[in] gpio_num : GPIO number. - * If you want to set output level of GPIO16, gpio_num should be GPIO_NUM_16 (16); + * @param gpio_num GPIO number. If you want to set output level of GPIO16, gpio_num should be GPIO_NUM_16 (16); * - * @return ESP_OK : success - * ESP_ERR_INVALID_ARG: parameter error + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG Parameter error * */ esp_err_t gpio_intr_enable(gpio_num_t gpio_num); /** - * @brief disable GPIO module interrupt signal + * @brief Disable GPIO module interrupt signal * - * @param[in] gpio_num : GPIO number. - * If you want to set output level of GPIO16, gpio_num should be GPIO_NUM_16 (16); + * @param gpio_num GPIO number. If you want to set output level of GPIO16, gpio_num should be GPIO_NUM_16 (16); * - * @return ESP_OK : success - * ESP_ERR_INVALID_ARG: parameter error + * @return + * - ESP_OK success + * - ESP_ERR_INVALID_ARG Parameter error * */ esp_err_t gpio_intr_disable(gpio_num_t gpio_num); /** - * @brief GPIO set output level + * @brief GPIO set output level * - * @param[in] gpio_num : GPIO number. - * If you want to set output level of GPIO16, gpio_num should be GPIO_NUM_16 (16); - * @param[in] level : Output level. 0: low ; 1: high + * @param gpio_num GPIO number. If you want to set output level of GPIO16, gpio_num should be GPIO_NUM_16 (16); + * @param level Output level. 0: low ; 1: high * - * @return ESP_OK : success - * ESP_FAIL : GPIO error + * @return + * - ESP_OK Success + * - GPIO_IS_VALID_GPIO GPIO number error * */ esp_err_t gpio_set_level(gpio_num_t gpio_num, uint32_t level); /** - * @brief GPIO get input level + * @brief GPIO get input level * - * @param[in] gpio_num : GPIO number. - * If you want to get level of pin GPIO16, gpio_num should be GPIO_NUM_16 (16); + * @param gpio_num GPIO number. If you want to get level of pin GPIO16, gpio_num should be GPIO_NUM_16 (16); * - * @return 0 : the GPIO input level is 0 - * 1 : the GPIO input level is 1 + * @return + * - 0 the GPIO input level is 0 + * - 1 the GPIO input level is 1 * */ int gpio_get_level(gpio_num_t gpio_num); /** - * @brief GPIO set direction + * @brief GPIO set direction * * Configure GPIO direction,such as output_only,input_only,output_and_input * - * @param[in] gpio_num : Configure GPIO pins number,it should be GPIO number. - * If you want to set direction of GPIO16, gpio_num should be GPIO_NUM_16 (16); - * @param[in] mode : Configure GPIO direction,such as output_only,input_only,... + * @param gpio_num Configure GPIO pins number, it should be GPIO number. If you want to set direction of GPIO16, gpio_num should be GPIO_NUM_16 (16); + * @param mode GPIO direction * - * @return ESP_OK : success - * ESP_ERR_INVALID_ARG : fail - * ESP_FAIL : GPIO error + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG GPIO error * */ esp_err_t gpio_set_direction(gpio_num_t gpio_num, gpio_mode_t mode); /** - * @brief GPIO set pull + * @brief GPIO set pull * * User this Function,configure GPIO pull mode,such as pull-up,pull-down * - * @param[in] gpio_num : Configure GPIO pins number,it should be GPIO number. - * If you want to set pull up or down mode for GPIO16,gpio_num should be GPIO_NUM_16 (16); - * @param[in] pull : Configure GPIO pull up/down mode,such as pullup_only,pulldown_only,pullup_and_pulldown,... + * @param gpio_num GPIO number. If you want to set pull up or down mode for GPIO16,gpio_num should be GPIO_NUM_16 (16); + * @param pull GPIO pull up/down mode. * - * @return ESP_OK : success - * ESP_ERR_INVALID_ARG : fail - * ESP_FAIL : GPIO error + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG : Parameter error * */ esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull); /** - * @brief enable GPIO wake-up function. + * @brief enable GPIO wake-up function. * - * @param gpio_num : GPIO number. + * @param gpio_num GPIO number. * - * @param intr_type : only GPIO_INTR_LOLEVEL\GPIO_INTR_HILEVEL can be used + * @param intr_type GPIO wake-up type. Only GPIO_INTR_LOLEVEL\GPIO_INTR_HILEVEL can be used * - * @return ESP_OK: success - * ESP_ERR_INVALID_ARG: parameter error + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG Parameter error */ esp_err_t gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type); /** - * @brief disable GPIO wake-up function. + * @brief Disable GPIO wake-up function. * - * @param gpio_num: GPIO number + * @param gpio_num GPIO number * - * @return ESP_OK: success - * ESP_ERR_INVALID_ARG: parameter error + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG Parameter error */ esp_err_t gpio_wakeup_disable(gpio_num_t gpio_num); /** * @brief register GPIO interrupt handler, the handler is an ISR. * The handler will be attached to the same CPU core that this function is running on. + * @note * Users should know that which CPU is running and then pick a INUM that is not used by system. * We can find the information of INUM and interrupt level in soc.h. - * TODO: to move INUM options to menu_config - * @param gpio_intr_num : GPIO interrupt number,check the info in soc.h, and please see the core-isa.h for more details - * @param (*fn)(void* ) : interrupt handler function. - * Note that the handler function MUST be defined with attribution of "IRAM_ATTR". - * @param arg : parameter for handler function * - * @return ESP_OK : success ; - * ESP_FAIL: gpio error + * @param gpio_intr_num GPIO interrupt number,check the info in soc.h, and please see the core-isa.h for more details + * @param fn Interrupt handler function. + * + * @note + * Note that the handler function MUST be defined with attribution of "IRAM_ATTR". + * + * @param arg Parameter for handler function + * + * @return + * - ESP_OK Success ; + * - ESP_ERR_INVALID_ARG GPIO error */ esp_err_t gpio_isr_register(uint32_t gpio_intr_num, void (*fn)(void*), void * arg); /** * *************** ATTENTION ********************/ /** - * - * Each GPIO has its own separate configuration register, so we do not use - * a lock to serialize access to them. This works under the assumption that - * no situation will occur where two tasks try to configure the same GPIO - * pin simultaneously. It is up to the application developer to guarantee this. + *@attention + * Each GPIO has its own separate configuration register, so we do not use + * a lock to serialize access to them. This works under the assumption that + * no situation will occur where two tasks try to configure the same GPIO + * pin simultaneously. It is up to the application developer to guarantee this. */ - -/*----------EXAMPLE TO CONIFGURE GPIO AS OUTPUT ------------ */ -/* gpio_config_t io_conf; +/** + *----------EXAMPLE TO CONIFGURE GPIO AS OUTPUT ------------ * + * @code{c} + * gpio_config_t io_conf; * io_conf.intr_type = GPIO_INTR_DISABLE; //disable interrupt * io_conf.mode = GPIO_MODE_OUTPUT; //set as output mode * io_conf.pin_bit_mask = GPIO_SEL_18 | GPIO_SEL_19; //bit mask of the pins that you want to set,e.g.GPIO18/19 * io_conf.pull_down_en = 0; //disable pull-down mode * io_conf.pull_up_en = 0; //disable pull-up mode * gpio_config(&io_conf); //configure GPIO with the given settings + * @endcode **/ -/*----------EXAMPLE TO CONIFGURE GPIO AS OUTPUT ------------ */ -/* io_conf.intr_type = GPIO_INTR_POSEDGE; //set posedge interrupt + +/** + *----------EXAMPLE TO CONIFGURE GPIO AS OUTPUT ------------ * + * @code{c} + * io_conf.intr_type = GPIO_INTR_POSEDGE; //set posedge interrupt * io_conf.mode = GPIO_MODE_INPUT; //set as input * io_conf.pin_bit_mask = GPIO_SEL_4 | GPIO_SEL_5; //bit mask of the pins that you want to set, e.g.,GPIO4/5 * io_conf.pull_down_en = 0; //disable pull-down mode * io_conf.pull_up_en = 1; //enable pull-up mode * gpio_config(&io_conf); //configure GPIO with the given settings - *----------EXAMPLE TO SET ISR HANDLER ----------------------*/ -/* gpio_isr_register(18,gpio_intr_test,NULL); //hook the isr handler for GPIO interrupt - * //the first parameter is INUM, you can pick one form interrupt level 1/2 which is not used by the system. - * //NOTE1:user should arrange the INUMs that used, better not to use a same INUM for different interrupt. - * //NOTE2:do not pick the INUM that already occupied by the system. - * //NOTE3:refer to soc.h to check which INUMs that can be used. - *-------------EXAMPLE OF HANDLER FUNCTION-------------------*/ -/*#include "esp_attr.h" + * @endcode + */ +/** + *----------EXAMPLE TO SET ISR HANDLER ---------------------- + * @code{c} + * //the first parameter is INUM, you can pick one form interrupt level 1/2 which is not used by the system. + * gpio_isr_register(18,gpio_intr_test,NULL); //hook the isr handler for GPIO interrupt + * @endcode + * @note + * 1. user should arrange the INUMs that used, better not to use a same INUM for different interrupt. + * 2. do not pick the INUM that already occupied by the system. + * 3. refer to soc.h to check which INUMs that can be used. + */ +/** + *-------------EXAMPLE OF HANDLER FUNCTION-------------------* + * @code{c} + * #include "esp_attr.h" * void IRAM_ATTR gpio_intr_test(void* arg) - *{ - * //GPIO intr process - * ets_printf("in gpio_intr\n"); - * uint32_t gpio_num = 0; - * uint32_t gpio_intr_status = READ_PERI_REG(GPIO_STATUS_REG); //read status to get interrupt status for GPIO0-31 - * uint32_t gpio_intr_status_h = READ_PERI_REG(GPIO_STATUS1_REG);//read status1 to get interrupt status for GPIO32-39 - * SET_PERI_REG_MASK(GPIO_STATUS_W1TC_REG, gpio_intr_status); //Clear intr for gpio0-gpio31 - * SET_PERI_REG_MASK(GPIO_STATUS1_W1TC_REG, gpio_intr_status_h); //Clear intr for gpio32-39 - * do { - * if(gpio_num < 32) { - * if(gpio_intr_status & BIT(gpio_num)) { //gpio0-gpio31 - * ets_printf("Intr GPIO%d ,val: %d\n",gpio_num,gpio_get_level(gpio_num)); - * //This is an isr handler, you should post an event to process it in RTOS queue. - * } - * } else { - * if(gpio_intr_status_h & BIT(gpio_num - 32)) { - * ets_printf("Intr GPIO%d, val : %d\n",gpio_num,gpio_get_level(gpio_num)); - * //This is an isr handler, you should post an event to process it in RTOS queue. - * } - * } - * } while(++gpio_num < GPIO_PIN_COUNT); - *} - *----EXAMPLE OF I2C CONFIG AND PICK SIGNAL FOR IO MATRIX---*/ -/* gpio_config_t io_conf; - * io_conf.intr_type = GPIO_INTR_DISABLE; //disable interrupt - * io_conf.mode = GPIO_MODE_INPUT_OUTPUT_OD; //set as output mode - * io_conf.pin_bit_mask = GPIO_SEL_21 | GPIO_SEL_22; //bit mask of the pins that you want to set,e.g.GPIO21/22 - * io_conf.pull_down_en = 0; //disable pull-down mode - * io_conf.pull_up_en = 1; //enable pull-up mode - * gpio_config(&io_conf); //configure GPIO with the given settings - * gpio_matrix_out(21, EXT_I2C_SCL_O_IDX, 0, 0); //set output signal for io_matrix - * gpio_matrix_out(22, EXT_I2C_SDA_O_IDX, 0, 0); //set output signal for io_matrix - * gpio_matrix_in( 22, EXT_I2C_SDA_I_IDX, 0); //set input signal for io_matrix + * { + * //GPIO intr process + * ets_printf("in gpio_intr\n"); + * uint32_t gpio_num = 0; + * uint32_t gpio_intr_status = READ_PERI_REG(GPIO_STATUS_REG); //read status to get interrupt status for GPIO0-31 + * uint32_t gpio_intr_status_h = READ_PERI_REG(GPIO_STATUS1_REG);//read status1 to get interrupt status for GPIO32-39 + * SET_PERI_REG_MASK(GPIO_STATUS_W1TC_REG, gpio_intr_status); //Clear intr for gpio0-gpio31 + * SET_PERI_REG_MASK(GPIO_STATUS1_W1TC_REG, gpio_intr_status_h); //Clear intr for gpio32-39 + * do { + * if(gpio_num < 32) { + * if(gpio_intr_status & BIT(gpio_num)) { //gpio0-gpio31 + * ets_printf("Intr GPIO%d ,val: %d\n",gpio_num,gpio_get_level(gpio_num)); + * //This is an isr handler, you should post an event to process it in RTOS queue. + * } + * } else { + * if(gpio_intr_status_h & BIT(gpio_num - 32)) { + * ets_printf("Intr GPIO%d, val : %d\n",gpio_num,gpio_get_level(gpio_num)); + * //This is an isr handler, you should post an event to process it in RTOS queue. + * } + * } + * } while(++gpio_num < GPIO_PIN_COUNT); + * } + * @endcode + */ + +/** + *----EXAMPLE OF I2C CONFIG AND PICK SIGNAL FOR IO MATRIX---* + * @code{c} + * gpio_config_t io_conf; + * io_conf.intr_type = GPIO_INTR_DISABLE; //disable interrupt + * io_conf.mode = GPIO_MODE_INPUT_OUTPUT_OD; //set as output mode + * io_conf.pin_bit_mask = GPIO_SEL_21 | GPIO_SEL_22; //bit mask of the pins that you want to set,e.g.GPIO21/22 + * io_conf.pull_down_en = 0; //disable pull-down mode + * io_conf.pull_up_en = 1; //enable pull-up mode + * gpio_config(&io_conf); //configure GPIO with the given settings + * gpio_matrix_out(21, EXT_I2C_SCL_O_IDX, 0, 0); //set output signal for io_matrix + * gpio_matrix_out(22, EXT_I2C_SDA_O_IDX, 0, 0); //set output signal for io_matrix + * gpio_matrix_in( 22, EXT_I2C_SDA_I_IDX, 0); //set input signal for io_matrix + * @endcode * */ -/** - * @} - */ - -/** - * @} - */ - #ifdef __cplusplus } #endif diff --git a/components/driver/include/driver/ledc.h b/components/driver/include/driver/ledc.h index 79a6c7f9f3..3ab0ebff1e 100644 --- a/components/driver/include/driver/ledc.h +++ b/components/driver/include/driver/ledc.h @@ -30,68 +30,68 @@ extern "C" { #define LEDC_REF_CLK_HZ (1*1000000) typedef enum { - LEDC_HIGH_SPEED_MODE = 0, /*LEDC high speed speed_mode */ + LEDC_HIGH_SPEED_MODE = 0, /*!< LEDC high speed speed_mode */ //in this version, we only support high speed speed_mode. We will access low speed speed_mode later - //LEDC_LOW_SPEED_MODE, /*LEDC low speed speed_mode */ - LEDC_SPEED_MODE_MAX, + //LEDC_LOW_SPEED_MODE, /*!< LEDC low speed speed_mode */ + LEDC_SPEED_MODE_MAX, /*!< LEDC speed limit */ } ledc_mode_t; typedef enum { - LEDC_INTR_DISABLE = 0, /*Disable LEDC interrupt */ - LEDC_INTR_FADE_END, /*Enable LEDC interrupt */ + LEDC_INTR_DISABLE = 0, /*!< Disable LEDC interrupt */ + LEDC_INTR_FADE_END, /*!< Enable LEDC interrupt */ } ledc_intr_type_t; typedef enum { - LEDC_DUTY_DIR_DECREASE = 0, /*LEDC duty decrease direction */ - LEDC_DUTY_DIR_INCREASE = 1, /*LEDC duty increase direction */ + LEDC_DUTY_DIR_DECREASE = 0, /*!< LEDC duty decrease direction */ + LEDC_DUTY_DIR_INCREASE = 1, /*!< LEDC duty increase direction */ } ledc_duty_direction_t; typedef enum { - LEDC_REF_TICK = 0, /*LEDC timer clock divided from reference tick(1Mhz) */ - LEDC_APB_CLK, /*LEDC timer clock divided from APB clock(80Mhz)*/ + LEDC_REF_TICK = 0, /*!< LEDC timer clock divided from reference tick(1Mhz) */ + LEDC_APB_CLK, /*!< LEDC timer clock divided from APB clock(80Mhz)*/ } ledc_clk_src_t; typedef enum { - LEDC_TIMER_0 = 0, /*LEDC source timer TIMER0 */ - LEDC_TIMER_1, /*LEDC source timer TIMER1 */ - LEDC_TIMER_2, /*LEDC source timer TIMER2 */ - LEDC_TIMER_3, /*LEDC source timer TIMER3 */ + LEDC_TIMER_0 = 0, /*!< LEDC source timer TIMER0 */ + LEDC_TIMER_1, /*!< LEDC source timer TIMER1 */ + LEDC_TIMER_2, /*!< LEDC source timer TIMER2 */ + LEDC_TIMER_3, /*!< LEDC source timer TIMER3 */ } ledc_timer_t; typedef enum { - LEDC_CHANNEL_0 = 0, /*LEDC channel 0 */ - LEDC_CHANNEL_1, /*LEDC channel 1 */ - LEDC_CHANNEL_2, /*LEDC channel 2 */ - LEDC_CHANNEL_3, /*LEDC channel 3 */ - LEDC_CHANNEL_4, /*LEDC channel 4 */ - LEDC_CHANNEL_5, /*LEDC channel 5 */ - LEDC_CHANNEL_6, /*LEDC channel 6 */ - LEDC_CHANNEL_7, /*LEDC channel 7 */ + LEDC_CHANNEL_0 = 0, /*!< LEDC channel 0 */ + LEDC_CHANNEL_1, /*!< LEDC channel 1 */ + LEDC_CHANNEL_2, /*!< LEDC channel 2 */ + LEDC_CHANNEL_3, /*!< LEDC channel 3 */ + LEDC_CHANNEL_4, /*!< LEDC channel 4 */ + LEDC_CHANNEL_5, /*!< LEDC channel 5 */ + LEDC_CHANNEL_6, /*!< LEDC channel 6 */ + LEDC_CHANNEL_7, /*!< LEDC channel 7 */ } ledc_channel_t; typedef enum { - LEDC_TIMER_10_BIT = 10, /*LEDC PWM depth 10Bit */ - LEDC_TIMER_11_BIT = 11, /*LEDC PWM depth 11Bit */ - LEDC_TIMER_12_BIT = 12, /*LEDC PWM depth 12Bit */ - LEDC_TIMER_13_BIT = 13, /*LEDC PWM depth 13Bit */ - LEDC_TIMER_14_BIT = 14, /*LEDC PWM depth 14Bit */ - LEDC_TIMER_15_BIT = 15, /*LEDC PWM depth 15Bit */ + LEDC_TIMER_10_BIT = 10, /*!< LEDC PWM depth 10Bit */ + LEDC_TIMER_11_BIT = 11, /*!< LEDC PWM depth 11Bit */ + LEDC_TIMER_12_BIT = 12, /*!< LEDC PWM depth 12Bit */ + LEDC_TIMER_13_BIT = 13, /*!< LEDC PWM depth 13Bit */ + LEDC_TIMER_14_BIT = 14, /*!< LEDC PWM depth 14Bit */ + LEDC_TIMER_15_BIT = 15, /*!< LEDC PWM depth 15Bit */ } ledc_timer_bit_t; typedef struct { - int gpio_num; /*the LEDC output gpio_num, if you want to use gpio16, gpio_num = 16*/ - ledc_mode_t speed_mode; /*LEDC speed speed_mode, high-speed mode or low-speed mode*/ - ledc_channel_t channel; /*LEDC channel(0 - 7)*/ - ledc_intr_type_t intr_type; /*configure interrupt, Fade interrupt enable or Fade interrupt disable*/ - ledc_timer_t timer_sel; /*Select the timer source of channel (0 - 3)*/ - uint32_t duty; /*LEDC channel duty, the duty range is [0, (2**bit_num) - 1], */ + int gpio_num; /*!< the LEDC output gpio_num, if you want to use gpio16, gpio_num = 16*/ + ledc_mode_t speed_mode; /*!< LEDC speed speed_mode, high-speed mode or low-speed mode*/ + ledc_channel_t channel; /*!< LEDC channel(0 - 7)*/ + ledc_intr_type_t intr_type; /*!< configure interrupt, Fade interrupt enable or Fade interrupt disable*/ + ledc_timer_t timer_sel; /*!< Select the timer source of channel (0 - 3)*/ + uint32_t duty; /*!< LEDC channel duty, the duty range is [0, (2**bit_num) - 1], */ } ledc_channel_config_t; typedef struct { - ledc_mode_t speed_mode; /*LEDC speed speed_mode, high-speed mode or low-speed mode*/ - ledc_timer_bit_t bit_num; /*LEDC channel duty depth*/ - ledc_timer_t timer_num; /*The timer source of channel (0 - 3)*/ - uint32_t freq_hz; /*LEDC timer frequency(Hz)*/ + ledc_mode_t speed_mode; /*!< LEDC speed speed_mode, high-speed mode or low-speed mode*/ + ledc_timer_bit_t bit_num; /*!< LEDC channel duty depth*/ + ledc_timer_t timer_num; /*!< The timer source of channel (0 - 3)*/ + uint32_t freq_hz; /*!< LEDC timer frequency(Hz)*/ } ledc_timer_config_t; @@ -100,15 +100,10 @@ typedef struct { * * User this Function, configure LEDC channel with the given channel/output gpio_num/interrupt/source timer/frequency(Hz)/LEDC depth * - * @param[in] ledc_channel_config_t - * ledc_channel_config_t.speed_mode : LEDC speed speed_mode - * ledc_channel_config_t.gpio_num : LEDC output gpio_num, if you want to use gpio16, ledc_channel_config_t.gpio_num = 16 - * ledc_channel_config_t.channel : LEDC channel(0 - 7) - * ledc_channel_config_t.intr_type : configure interrupt, Fade interrupt enable or Fade interrupt disable - * ledc_channel_config_t.timer_sel : Select the timer source of channel (0 - 3), high speed channel must bind with high speed timer. - * ledc_channel_config_t.duty : LEDC channel duty, the duty range is [0, (2**timer_bit_num) - 1], - * @return ESP_OK: success - * ESP_ERR_INVALID_ARG: parameter error + * @param ledc_conf Pointer of LEDC channel configure struct + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG Parameter error * */ esp_err_t ledc_channel_config(ledc_channel_config_t* ledc_conf); @@ -118,14 +113,13 @@ esp_err_t ledc_channel_config(ledc_channel_config_t* ledc_conf); * * User this Function, configure LEDC timer with the given source timer/frequency(Hz)/bit_num * - * @param[in] ledc_timer_config_t - * ledc_timer_config_t.speed_mode : LEDC speed speed_mode - * ledc_timer_config_t.timer_num : Select the timer source of channel (0 - 3) - * ledc_timer_config_t.freq_hz : LEDC channel frequency(Hz), - * ledc_timer_config_t.bit_num : LEDC channel duty depth - * @return ESP_OK: success - * ESP_ERR_INVALID_ARG: parameter error - * ESP_FAIL: Can not find a proper pre-divider number base on the given frequency and the current bit_num. + * @param timer_conf Pointer of LEDC timer configure struct + * + * + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG Parameter error + * - ESP_FAIL Can not find a proper pre-divider number base on the given frequency and the current bit_num. * */ esp_err_t ledc_timer_config(ledc_timer_config_t* timer_conf); @@ -136,12 +130,13 @@ esp_err_t ledc_timer_config(ledc_timer_config_t* timer_conf); * Call this function to activate the LEDC updated parameters. * After ledc_set_duty, ledc_set_fade, we need to call this function to update the settings. * - * @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version + * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version * - * @param[in] channel : LEDC channel(0-7), select from ledc_channel_t + * @param channel LEDC channel(0-7), select from ledc_channel_t * - * @return ESP_OK: success - * ESP_ERR_INVALID_ARG: parameter error + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG Parameter error * */ esp_err_t ledc_update_duty(ledc_mode_t speed_mode, ledc_channel_t channel); @@ -151,12 +146,13 @@ esp_err_t ledc_update_duty(ledc_mode_t speed_mode, ledc_channel_t channel); * * Disable LEDC output, and set idle level * - * @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version + * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version * - * @param[in] channel : LEDC channel(0-7), select from ledc_channel_t + * @param channel LEDC channel(0-7), select from ledc_channel_t * - * @return ESP_OK: success - * ESP_ERR_INVALID_ARG: parameter error + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG Parameter error */ esp_err_t ledc_stop(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t idle_level); @@ -165,27 +161,29 @@ esp_err_t ledc_stop(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t idl * * Set LEDC frequency(Hz) * - * @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version + * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version * - * @param[in] timer_num : LEDC timer index(0-3), select from ledc_timer_t + * @param timer_num LEDC timer index(0-3), select from ledc_timer_t * - * @param[in] freq_hz : set the LEDC frequency + * @param freq_hz Set the LEDC frequency * - * @return ESP_OK: success - * ESP_ERR_INVALID_ARG: parameter error - * ESP_FAIL: Can not find a proper pre-divider number base on the given frequency and the current bit_num. + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG Parameter error + * - ESP_FAIL Can not find a proper pre-divider number base on the given frequency and the current bit_num. */ esp_err_t ledc_set_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num, uint32_t freq_hz); /** * @brief LEDC get channel frequency(Hz) * - * @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version + * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version * - * @param[in] timer_num : LEDC timer index(0-3), select from ledc_timer_t + * @param timer_num LEDC timer index(0-3), select from ledc_timer_t * - * @return 0 : error - * others : current LEDC frequency + * @return + * - 0 error + * - Others Current LEDC frequency * */ uint32_t ledc_get_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num); @@ -195,27 +193,29 @@ uint32_t ledc_get_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num); * * Set LEDC duty, After the function calls the ledc_update_duty function, the function can take effect. * - * @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version + * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version * - * @param[in] channel : LEDC channel(0-7), select from ledc_channel_t + * @param channel LEDC channel(0-7), select from ledc_channel_t * - * @param[in] duty : set the LEDC duty, the duty range is [0, (2**bit_num) - 1] + * @param duty Set the LEDC duty, the duty range is [0, (2**bit_num) - 1] * - * @return ESP_OK: success - * ESP_ERR_INVALID_ARG: parameter error + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG Parameter error */ esp_err_t ledc_set_duty(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t duty); /** * @brief LEDC get duty * - * @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version + * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version * - * @param[in] channel : LEDC channel(0-7), select from ledc_channel_t + * @param channel LEDC channel(0-7), select from ledc_channel_t * * - * @return -1: parameter error - * other value: current LEDC duty + * @return + * - (-1) parameter error + * - Others Current LEDC duty * */ int ledc_get_duty(ledc_mode_t speed_mode, ledc_channel_t channel); @@ -225,22 +225,23 @@ int ledc_get_duty(ledc_mode_t speed_mode, ledc_channel_t channel); * * Set LEDC gradient, After the function calls the ledc_update_duty function, the function can take effect. * - * @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version + * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version * - * @param[in] channel : LEDC channel(0-7), select from ledc_channel_t + * @param channel LEDC channel(0-7), select from ledc_channel_t * - * @param[in] duty : set the start of the gradient duty, the duty range is [0, (2**bit_num) - 1] + * @param duty Set the start of the gradient duty, the duty range is [0, (2**bit_num) - 1] * - * @param[in] gradule_direction : set the direction of the gradient + * @param gradule_direction Set the direction of the gradient * - * @param[in] step_num : set the number of the gradient + * @param step_num Set the number of the gradient * - * @param[in] duty_cyle_num : set how many LEDC tick each time the gradient lasts + * @param duty_cyle_num Set how many LEDC tick each time the gradient lasts * - * @param[in] duty_scale : set gradient change amplitude + * @param duty_scale Set gradient change amplitude * - * @return ESP_OK : success - * ESP_ERR_INVALID_ARG : parameter error + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG Parameter error */ esp_err_t ledc_set_fade(ledc_mode_t speed_mode, uint32_t channel, uint32_t duty, ledc_duty_direction_t gradule_direction, uint32_t step_num, uint32_t duty_cyle_num, uint32_t duty_scale); @@ -248,34 +249,37 @@ esp_err_t ledc_set_fade(ledc_mode_t speed_mode, uint32_t channel, uint32_t duty, /** * @brief register LEDC interrupt handler, the handler is an ISR. * The handler will be attached to the same CPU core that this function is running on. - * Users should know that which CPU is running and then pick a INUM that is not used by system. - * We can find the information of INUM and interrupt level in soc.h. - * TODO: to move INUM options to menu_config - * @param[in] uint32_t ledc_intr_num : LEDC interrupt number, check the info in soc.h, and please see the core-isa.h for more details - * @param[in] void (* fn)(void* ) : interrupt handler function. - * Note that the handler function MUST be defined with attribution of "IRAM_ATTR". - * @param[in] void * arg : parameter for handler function + * @note + * Users should know that which CPU is running and then pick a INUM that is not used by system. + * We can find the information of INUM and interrupt level in soc.h. + * @param ledc_intr_num LEDC interrupt number, check the info in soc.h, and please see the core-isa.h for more details + * @param fn Interrupt handler function. + * @note + * Note that the handler function MUST be defined with attribution of "IRAM_ATTR". + * @param arg Parameter for handler function * - * @return ESP_OK : success ; - * ESP_ERR_INVALID_ARG : function ptr error. + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG Function pointer error. */ esp_err_t ledc_isr_register(uint32_t ledc_intr_num, void (*fn)(void*), void * arg); /** * @brief configure LEDC settings * - * @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version + * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version * - * @param[in] timer_sel : timer index(0-3), there are 4 timers in LEDC module + * @param timer_sel Timer index(0-3), there are 4 timers in LEDC module * - * @param[in] div_num : timer clock divide number, the timer clock is divided from the selected clock source + * @param div_num Timer clock divide number, the timer clock is divided from the selected clock source * - * @param[in] bit_num : the count number of one period, counter range is 0 ~ ((2 ** bit_num) - 1) + * @param bit_num The count number of one period, counter range is 0 ~ ((2 ** bit_num) - 1) * - * @param[in] clk_src : select LEDC source clock. + * @param clk_src Select LEDC source clock. * - * @return -1: parameter error - * other value: current LEDC duty + * @return + * - (-1) Parameter error + * - Other Current LEDC duty * */ esp_err_t ledc_timer_set(ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t div_num, uint32_t bit_num, ledc_clk_src_t clk_src); @@ -283,13 +287,14 @@ esp_err_t ledc_timer_set(ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_ /** * @brief reset LEDC timer * - * @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version + * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version * - * @param[in] timer_sel : LEDC timer index(0-3), select from ledc_timer_t + * @param timer_sel LEDC timer index(0-3), select from ledc_timer_t * * - * @return ESP_ERR_INVALID_ARG: parameter error - * ESP_OK: success + * @return + * - ESP_ERR_INVALID_ARG Parameter error + * - ESP_OK Success * */ esp_err_t ledc_timer_rst(ledc_mode_t speed_mode, uint32_t timer_sel); @@ -297,13 +302,14 @@ esp_err_t ledc_timer_rst(ledc_mode_t speed_mode, uint32_t timer_sel); /** * @brief pause LEDC timer counter * - * @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version + * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version * - * @param[in] timer_sel : LEDC timer index(0-3), select from ledc_timer_t + * @param timer_sel LEDC timer index(0-3), select from ledc_timer_t * * - * @return ESP_ERR_INVALID_ARG: parameter error - * ESP_OK: success + * @return + * - ESP_ERR_INVALID_ARG Parameter error + * - ESP_OK Success * */ esp_err_t ledc_timer_pause(ledc_mode_t speed_mode, uint32_t timer_sel); @@ -311,13 +317,14 @@ esp_err_t ledc_timer_pause(ledc_mode_t speed_mode, uint32_t timer_sel); /** * @brief pause LEDC timer resume * - * @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version + * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version * - * @param[in] timer_sel : LEDC timer index(0-3), select from ledc_timer_t + * @param timer_sel LEDC timer index(0-3), select from ledc_timer_t * * - * @return ESP_ERR_INVALID_ARG: parameter error - * ESP_OK: success + * @return + * - ESP_ERR_INVALID_ARG Parameter error + * - ESP_OK Success * */ esp_err_t ledc_timer_resume(ledc_mode_t speed_mode, uint32_t timer_sel); @@ -325,15 +332,16 @@ esp_err_t ledc_timer_resume(ledc_mode_t speed_mode, uint32_t timer_sel); /** * @brief bind LEDC channel with the selected timer * - * @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version + * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version * - * @param[in] channel : LEDC channel index(0-7), select from ledc_channel_t + * @param channel LEDC channel index(0-7), select from ledc_channel_t * - * @param[in] timer_idx : LEDC timer index(0-3), select from ledc_timer_t + * @param timer_idx LEDC timer index(0-3), select from ledc_timer_t * * - * @return ESP_ERR_INVALID_ARG: parameter error - * ESP_OK: success + * @return + * - ESP_ERR_INVALID_ARG Parameter error + * - ESP_OK Success * */ esp_err_t ledc_bind_channel_timer(ledc_mode_t speed_mode, uint32_t channel, uint32_t timer_idx); @@ -342,44 +350,56 @@ esp_err_t ledc_bind_channel_timer(ledc_mode_t speed_mode, uint32_t channel, uint * * * ----------------EXAMPLE OF LEDC SETTING --------------------- - * //1. enable LEDC - * periph_module_enable(PERIPH_LEDC_MODULE); //enable LEDC module, or you can not set any register of it. + * @code{c} + * //1. enable LEDC + * //enable LEDC module, or you can not set any register of it. + * periph_module_enable(PERIPH_LEDC_MODULE); + * @endcode * - * //2. set LEDC timer - * ledc_timer_config_t timer_conf = { - * .bit_num = LEDC_TIMER_12_BIT, //set timer counter bit number - * .freq_hz = 1000, //set frequency of pwm, here, 1000Hz - * .speed_mode = LEDC_HIGH_SPEED_MODE //timer mode, - * .timer_num = LEDC_TIMER_0, //timer number - * }; - * ledc_timer_config(&timer_conf); //setup timer. + * @code{c} + * //2. set LEDC timer + * ledc_timer_config_t timer_conf = { + * .bit_num = LEDC_TIMER_12_BIT, //set timer counter bit number + * .freq_hz = 1000, //set frequency of pwm, here, 1000Hz + * .speed_mode = LEDC_HIGH_SPEED_MODE, //timer mode, + * .timer_num = LEDC_TIMER_0, //timer number + * }; + * ledc_timer_config(&timer_conf); //setup timer. + * @endcode * - * //3. set LEDC channel - * ledc_channel_config_t ledc_conf = { - * .channel = LEDC_CHANNEL_0; //set LEDC channel 0 - * .duty = 1000; //set the duty for initialization.(duty range is 0 ~ ((2**bit_num)-1) - * .gpio_num = 16; //GPIO number - * .intr_type = LEDC_INTR_FADE_END; //GPIO INTR TYPE, as an example, we enable fade_end interrupt here. - * .speed_mode = LEDC_HIGH_SPEED_MODE; //set LEDC mode, from ledc_mode_t - * .timer_sel = LEDC_TIMER_0; //set LEDC timer source, if different channel use one timer, the frequency and bit_num of these channels should be the same - * } - * ledc_channel_config(&ledc_conf); //setup the configuration + * @code{c} + * //3. set LEDC channel + * ledc_channel_config_t ledc_conf = { + * .channel = LEDC_CHANNEL_0; //set LEDC channel 0 + * .duty = 1000; //set the duty for initialization.(duty range is 0 ~ ((2**bit_num)-1) + * .gpio_num = 16; //GPIO number + * .intr_type = LEDC_INTR_FADE_END; //GPIO INTR TYPE, as an example, we enable fade_end interrupt here. + * .speed_mode = LEDC_HIGH_SPEED_MODE; //set LEDC mode, from ledc_mode_t + * .timer_sel = LEDC_TIMER_0; //set LEDC timer source, if different channel use one timer, the frequency and bit_num of these channels should be the same + * } + * ledc_channel_config(&ledc_conf); //setup the configuration * * ----------------EXAMPLE OF SETTING DUTY --- ----------------- - * uint32_t ledc_channel = LEDC_CHANNEL_0; //LEDC channel(0-73) - * uint32_t duty = 2000; //duty range is 0 ~ ((2**bit_num)-1) - * LEDC_set_duty(LEDC_HIGH_SPEED_MODE, ledc_channel, duty); //set speed mode, channel, and duty. - * ledc_update_duty(LEDC_HIGH_SPEED_MODE, ledc_channel); //after set duty, we need to call ledc_update_duty to update the settings. - * + * @code{c} + * uint32_t ledc_channel = LEDC_CHANNEL_0; //LEDC channel(0-73) + * uint32_t duty = 2000; //duty range is 0 ~ ((2**bit_num)-1) + * LEDC_set_duty(LEDC_HIGH_SPEED_MODE, ledc_channel, duty); //set speed mode, channel, and duty. + * ledc_update_duty(LEDC_HIGH_SPEED_MODE, ledc_channel); //after set duty, we need to call ledc_update_duty to update the settings. + * @endcode * * ----------------EXAMPLE OF LEDC INTERRUPT ------------------ - * //we have fade_end interrupt and counter overflow interrupt. we just give an example of fade_end interrupt here. - * ledc_isr_register(18, ledc_isr_handler, NULL); //hook the isr handler for LEDC interrupt - * //the first parameter is INUM, you can pick one form interrupt level 1/2 which is not used by the system. - * //NOTE1:user should arrange the INUMs that used, better not to use a same INUM for different interrupt source. - * //NOTE2:do not pick the INUM that already occupied by the system. - * //NOTE3:refer to soc.h to check which INUMs that can be used. + * @code{c} + * //we have fade_end interrupt and counter overflow interrupt. we just give an example of fade_end interrupt here. + * ledc_isr_register(18, ledc_isr_handler, NULL); //hook the isr handler for LEDC interrupt + * @endcode + * @note + * 1. the first parameter is INUM, you can pick one form interrupt level 1/2 which is not used by the system. + * 2. user should arrange the INUMs that used, better not to use a same INUM for different interrupt source. + * 3. do not pick the INUM that already occupied by the system. + * 4. refer to soc.h to check which INUMs that can be used. + * * ----------------EXAMPLE OF INTERRUPT HANDLER --------------- + * @code{c} * #include "esp_attr.h" * void IRAM_ATTR ledc_isr_handler(void* arg) //we should add 'IRAM_ATTR' attribution when we declare the isr function * { @@ -391,7 +411,7 @@ esp_err_t ledc_bind_channel_timer(ledc_mode_t speed_mode, uint32_t channel, uint * * LEDC.int_clr.val = intr_st; //clear LEDC interrupt status. * } - * + * @endcode * *--------------------------END OF EXAMPLE -------------------------- */ From f10cc7dc8eb09bcdd3075b7f8ef9303e3dc3da28 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 25 Oct 2016 14:55:35 +1100 Subject: [PATCH 237/343] bootloader: Refactor secure boot digest generation --- .../bootloader/src/main/bootloader_config.h | 4 +- .../bootloader/src/main/bootloader_start.c | 15 +- components/bootloader/src/main/secure_boot.c | 135 +++++++++++++----- 3 files changed, 114 insertions(+), 40 deletions(-) diff --git a/components/bootloader/src/main/bootloader_config.h b/components/bootloader/src/main/bootloader_config.h index 8a837693c2..1655280dc7 100644 --- a/components/bootloader/src/main/bootloader_config.h +++ b/components/bootloader/src/main/bootloader_config.h @@ -36,7 +36,6 @@ extern "C" #define RTC_DATA_LOW 0x50000000 #define RTC_DATA_HIGH 0x50002000 - #define PART_TYPE_APP 0x00 #define PART_SUBTYPE_FACTORY 0x00 #define PART_SUBTYPE_OTA_FLAG 0x10 @@ -66,8 +65,7 @@ void boot_cache_redirect( uint32_t pos, size_t size ); uint32_t get_bin_len(uint32_t pos); bool flash_encrypt(bootloader_state_t *bs); -bool secure_boot(void); - +bool secure_boot_generate_bootloader_digest(void); #ifdef __cplusplus } diff --git a/components/bootloader/src/main/bootloader_start.c b/components/bootloader/src/main/bootloader_start.c index 5b1e152070..a4b27702c4 100644 --- a/components/bootloader/src/main/bootloader_start.c +++ b/components/bootloader/src/main/bootloader_start.c @@ -256,6 +256,7 @@ void bootloader_main() bootloader_state_t bs; SpiFlashOpResult spiRet1,spiRet2; esp_ota_select_entry_t sa,sb; + memset(&bs, 0, sizeof(bs)); ESP_LOGI(TAG, "compile time " __TIME__ ); @@ -329,16 +330,20 @@ void bootloader_main() } ESP_LOGI(TAG, "Loading app partition at offset %08x", load_part_pos); + if(fhdr.secure_boot_flag == 0x01) { - /* protect the 2nd_boot */ - if(false == secure_boot()){ - ESP_LOGE(TAG, "secure boot failed"); - return; + /* Generate secure digest from this bootloader to protect future + modifications */ + if (secure_boot_generate_bootloader_digest() == false){ + ESP_LOGE(TAG, "Bootloader digest generation failed. SECURE BOOT IS NOT ENABLED."); + /* Allow booting to continue, as the failure is probably + due to user-configured EFUSEs for testing... + */ } } if(fhdr.encrypt_flag == 0x01) { - /* encrypt flash */ + /* encrypt flash */ if (false == flash_encrypt(&bs)) { ESP_LOGE(TAG, "flash encrypt failed"); return; diff --git a/components/bootloader/src/main/secure_boot.c b/components/bootloader/src/main/secure_boot.c index 3dfdbd1412..9247f2cbd9 100644 --- a/components/bootloader/src/main/secure_boot.c +++ b/components/bootloader/src/main/secure_boot.c @@ -40,7 +40,7 @@ static const char* TAG = "secure_boot"; * * @inputs: bool */ -bool secure_boot_generate(uint32_t bin_len){ +static bool secure_boot_generate(uint32_t bin_len){ SpiFlashOpResult spiRet; uint16_t i; uint32_t buf[32]; @@ -87,41 +87,112 @@ bool secure_boot_generate(uint32_t bin_len){ return true; } +/* Burn values written to the efuse write registers */ +static inline void burn_efuses() +{ + REG_WRITE(EFUSE_CONF_REG, 0x5A5A); /* efuse_pgm_op_ena, force no rd/wr disable */ + REG_WRITE(EFUSE_CMD_REG, 0x02); /* efuse_pgm_cmd */ + while (REG_READ(EFUSE_CMD_REG)); /* wait for efuse_pagm_cmd=0 */ + REG_WRITE(EFUSE_CONF_REG, 0x5AA5); /* efuse_read_op_ena, release force */ + REG_WRITE(EFUSE_CMD_REG, 0x01); /* efuse_read_cmd */ + while (REG_READ(EFUSE_CMD_REG)); /* wait for efuse_read_cmd=0 */ +} /** - * @function : secure_boot - * @description: protect boot code in flash + * @function : secure_boot_generate_bootloader_digest * - * @inputs: bool + * @description: Called if the secure boot flag is set on the + * bootloader image in flash. If secure boot is not yet enabled for + * bootloader, this will generate the secure boot digest and enable + * secure boot by blowing the EFUSE_RD_ABS_DONE_0 efuse. + * + * This function does not verify secure boot of the bootloader (the + * ROM bootloader does this.) + * + * @return true if secure boot is enabled (either was already enabled, + * or is freshly enabled as a result of calling this function.) */ -bool secure_boot(void){ - uint32_t bin_len = 0; - if (REG_READ(EFUSE_BLK0_RDATA6_REG) & EFUSE_RD_ABS_DONE_0) - { - ESP_LOGD(TAG, "already secure boot !"); - return true; - } else { - boot_cache_redirect( 0, 64*1024); - bin_len = get_bin_len((uint32_t)MEM_CACHE(0x1000)); - if (bin_len == 0) { - ESP_LOGE(TAG, "boot len is error"); - return false; - } - if (false == secure_boot_generate(bin_len)){ - ESP_LOGE(TAG, "secure boot generate failed"); - return false; - } - } +bool secure_boot_generate_bootloader_digest(void) { + uint32_t bin_len = 0; + if (REG_READ(EFUSE_BLK0_RDATA6_REG) & EFUSE_RD_ABS_DONE_0) + { + ESP_LOGI(TAG, "bootloader secure boot is already enabled, continuing.."); + return true; + } - REG_SET_BIT(EFUSE_BLK0_WDATA6_REG, EFUSE_RD_ABS_DONE_0); - REG_WRITE(EFUSE_CONF_REG, 0x5A5A); /* efuse_pgm_op_ena, force no rd/wr disable */ - REG_WRITE(EFUSE_CMD_REG, 0x02); /* efuse_pgm_cmd */ - while (REG_READ(EFUSE_CMD_REG)); /* wait for efuse_pagm_cmd=0 */ - ESP_LOGW(TAG, "burn abstract_done_0"); - REG_WRITE(EFUSE_CONF_REG, 0x5AA5); /* efuse_read_op_ena, release force */ - REG_WRITE(EFUSE_CMD_REG, 0x01); /* efuse_read_cmd */ - while (REG_READ(EFUSE_CMD_REG)); /* wait for efuse_read_cmd=0 */ - ESP_LOGI(TAG, "read EFUSE_BLK0_RDATA6 %x", REG_READ(EFUSE_BLK0_RDATA6_REG)); - return true; + boot_cache_redirect( 0, 64*1024); + bin_len = get_bin_len((uint32_t)MEM_CACHE(0x1000)); + if (bin_len == 0) { + ESP_LOGE(TAG, "Invalid bootloader image length zero."); + return false; + } + if (bin_len > 0x100000) { + ESP_LOGE(TAG, "Invalid bootloader image length %x", bin_len); + return false; + } + uint32_t dis_reg = REG_READ(EFUSE_BLK0_RDATA0_REG); + bool efuse_key_read_protected = dis_reg & EFUSE_RD_DIS_BLK2; + bool efuse_key_write_protected = dis_reg & EFUSE_WR_DIS_BLK2; + if (efuse_key_read_protected == false + && efuse_key_write_protected == false + && REG_READ(EFUSE_BLK2_RDATA0_REG) == 0 + && REG_READ(EFUSE_BLK2_RDATA1_REG) == 0 + && REG_READ(EFUSE_BLK2_RDATA2_REG) == 0 + && REG_READ(EFUSE_BLK2_RDATA3_REG) == 0 + && REG_READ(EFUSE_BLK2_RDATA4_REG) == 0 + && REG_READ(EFUSE_BLK2_RDATA5_REG) == 0 + && REG_READ(EFUSE_BLK2_RDATA6_REG) == 0 + && REG_READ(EFUSE_BLK2_RDATA7_REG) == 0) { + ESP_LOGI(TAG, "Generating new secure boot key..."); + /* reuse the secure boot IV generation function to generate + the key, as this generator uses the hardware RNG. */ + uint32_t buf[32]; + ets_secure_boot_rd_iv(buf); + for (int i = 0; i < 8; i++) { + ESP_LOGV(TAG, "EFUSE_BLK2_WDATA%d_REG = 0x%08x", i, buf[i]); + REG_WRITE(EFUSE_BLK2_WDATA0_REG + 4*i, buf[i]); + } + bzero(buf, sizeof(buf)); + burn_efuses(); + ESP_LOGI(TAG, "Read & write protecting new key..."); + REG_WRITE(EFUSE_BLK0_WDATA0_REG, EFUSE_WR_DIS_BLK2 | EFUSE_RD_DIS_BLK2); + burn_efuses(); + efuse_key_read_protected = true; + efuse_key_write_protected = true; + + } else { + ESP_LOGW(TAG, "Using pre-loaded secure boot key in EFUSE block 2"); + } + + ESP_LOGI(TAG, "Generating secure boot digest..."); + if (false == secure_boot_generate(bin_len)){ + ESP_LOGE(TAG, "secure boot generation failed"); + return false; + } + ESP_LOGI(TAG, "Digest generation complete."); + + if (!efuse_key_read_protected) { + ESP_LOGE(TAG, "Pre-loaded key is not read protected. Refusing to blow secure boot efuse."); + return false; + } + if (!efuse_key_write_protected) { + ESP_LOGE(TAG, "Pre-loaded key is not write protected. Refusing to blow secure boot efuse."); + return false; + } + + ESP_LOGI(TAG, "blowing secure boot efuse & disabling JTAG..."); + ESP_LOGD(TAG, "before updating, EFUSE_BLK0_RDATA6 %x", REG_READ(EFUSE_BLK0_RDATA6_REG)); + REG_WRITE(EFUSE_BLK0_WDATA6_REG, + EFUSE_RD_ABS_DONE_0 | EFUSE_RD_DISABLE_JTAG); + burn_efuses(); + uint32_t after = REG_READ(EFUSE_BLK0_RDATA6_REG); + ESP_LOGD(TAG, "after updating, EFUSE_BLK0_RDATA6 %x", after); + if (after & EFUSE_RD_ABS_DONE_0) { + ESP_LOGI(TAG, "secure boot is now enabled for bootloader image"); + return true; + } else { + ESP_LOGE(TAG, "secure boot not enabled for bootloader image, EFUSE_RD_ABS_DONE_0 is probably write protected!"); + return false; + } } From cf732bb663a4c8690107e354d958042ef3ea5bfb Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Mon, 31 Oct 2016 16:27:26 +1100 Subject: [PATCH 238/343] esp32: efuse_reg add bit values for read & write disable flags --- components/esp32/include/soc/efuse_reg.h | 26 ++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/components/esp32/include/soc/efuse_reg.h b/components/esp32/include/soc/efuse_reg.h index a0f0a07da6..291e3984ee 100644 --- a/components/esp32/include/soc/efuse_reg.h +++ b/components/esp32/include/soc/efuse_reg.h @@ -29,6 +29,16 @@ #define EFUSE_RD_EFUSE_RD_DIS_M ((EFUSE_RD_EFUSE_RD_DIS_V)<<(EFUSE_RD_EFUSE_RD_DIS_S)) #define EFUSE_RD_EFUSE_RD_DIS_V 0xF #define EFUSE_RD_EFUSE_RD_DIS_S 16 + +/* Read disable bits for efuse blocks 1-3 */ +#define EFUSE_RD_DIS_BLK1 (1<<16) +#define EFUSE_RD_DIS_BLK2 (1<<17) +#define EFUSE_RD_DIS_BLK3 (1<<18) +/* Read disable FLASH_CRYPT_CONFIG, CODING_SCHEME & KEY_STATUS + in efuse block 0 +*/ +#define EFUSE_RD_DIS_BLK0_PARTIAL (1<<19) + /* EFUSE_RD_EFUSE_WR_DIS : RO ;bitpos:[15:0] ;default: 16'b0 ; */ /*description: read for efuse_wr_disable*/ #define EFUSE_RD_EFUSE_WR_DIS 0x0000FFFF @@ -36,6 +46,22 @@ #define EFUSE_RD_EFUSE_WR_DIS_V 0xFFFF #define EFUSE_RD_EFUSE_WR_DIS_S 0 +/* Write disable bits */ +#define EFUSE_WR_DIS_RD_DIS (1<<0) /*< disable writing read disable reg */ +#define EFUSE_WR_DIS_WR_DIS (1<<1) /*< disable writing write disable reg */ +#define EFUSE_WR_DIS_FLASH_CRYPT_CNT (1<<2) +#define EFUSE_WR_DIS_MAC_SPI_CONFIG_HD (1<<3) /*< disable writing MAC & SPI config hd efuses */ +#define EFUSE_WR_DIS_XPD_SDIO (1<<5) /*< disable writing SDIO config efuses */ +#define EFUSE_WR_DIS_SPI_PAD_CONFIG (1<<6) /*< disable writing SPI_PAD_CONFIG efuses */ +#define EFUSE_WR_DIS_BLK1 (1<<7) /*< disable writing BLK1 efuses */ +#define EFUSE_WR_DIS_BLK2 (1<<8) /*< disable writing BLK2 efuses */ +#define EFUSE_WR_DIS_BLK3 (1<<9) /*< disable writing BLK3 efuses */ +#define EFUSE_WR_DIS_FLASH_CRYPT_CODING_SCHEME (1<<10) /*< disable writing FLASH_CRYPT_CONFIG and CODING_SCHEME efuses */ +#define EFUSE_WR_DIS_ABS_DONE_0 (1<<12) /*< disable writing ABS_DONE_0 efuse */ +#define EFUSE_WR_DIS_ABS_DONE_1 (1<<13) /*< disable writing ABS_DONE_1 efuse */ +#define EFUSE_WR_DIS_JTAG_DISABLE (1<<14) /*< disable writing JTAG_DISABLE efuse */ +#define EFUSE_WR_DIS_CONSOLE_DL_DISABLE (1<<15) /*< disable writing CONSOLE_DEBUG_DISABLE, DISABLE_DL_ENCRYPT, DISABLE_DL_DECRYPT and DISABLE_DL_CACHE efuses */ + #define EFUSE_BLK0_RDATA1_REG (DR_REG_EFUSE_BASE + 0x004) /* EFUSE_RD_WIFI_MAC_CRC_LOW : RO ;bitpos:[31:0] ;default: 32'b0 ; */ /*description: read for low 32bit WIFI_MAC_Address*/ From 4ba1b73eba78893d2117a94a6e65c6ad63e6705a Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 1 Nov 2016 10:50:16 +1100 Subject: [PATCH 239/343] build system: Add espefuse/espsecure support for secure boot --- components/bootloader/Kconfig.projbuild | 67 ++++++++++++++++++-- components/bootloader/Makefile.projbuild | 57 ++++++++++++++++- components/bootloader/src/main/secure_boot.c | 2 + components/esptool_py/Makefile.projbuild | 17 ++++- components/esptool_py/esptool | 2 +- make/project.mk | 23 +++++-- 6 files changed, 147 insertions(+), 21 deletions(-) diff --git a/components/bootloader/Kconfig.projbuild b/components/bootloader/Kconfig.projbuild index 394bcc1bd1..d6736b33db 100644 --- a/components/bootloader/Kconfig.projbuild +++ b/components/bootloader/Kconfig.projbuild @@ -20,12 +20,65 @@ config LOG_BOOTLOADER_LEVEL_VERBOSE endchoice config LOG_BOOTLOADER_LEVEL - int - default 0 if LOG_BOOTLOADER_LEVEL_NONE - default 1 if LOG_BOOTLOADER_LEVEL_ERROR - default 2 if LOG_BOOTLOADER_LEVEL_WARN - default 3 if LOG_BOOTLOADER_LEVEL_INFO - default 4 if LOG_BOOTLOADER_LEVEL_DEBUG - default 5 if LOG_BOOTLOADER_LEVEL_VERBOSE + int + default 0 if LOG_BOOTLOADER_LEVEL_NONE + default 1 if LOG_BOOTLOADER_LEVEL_ERROR + default 2 if LOG_BOOTLOADER_LEVEL_WARN + default 3 if LOG_BOOTLOADER_LEVEL_INFO + default 4 if LOG_BOOTLOADER_LEVEL_DEBUG + default 5 if LOG_BOOTLOADER_LEVEL_VERBOSE + +choice SECURE_BOOTLOADER + bool "Secure bootloader" + default SECURE_BOOTLOADER_DISABLED + help + Build a bootloader with the secure boot flag enabled. + + Secure bootloader can be one-time-flash (chip will only ever + boot that particular bootloader), or a digest key can be used + to allow the secure bootloader to be re-flashed with + modifications. Secure boot also permanently disables JTAG. + + See docs/security/secure-boot.rst for details. + +config SECURE_BOOTLOADER_DISABLED + bool "Disabled" + +config SECURE_BOOTLOADER_ONE_TIME_FLASH + bool "One-time flash" + help + On first boot, the bootloader will generate a key which is not readable externally or by software. A digest is generated from the bootloader image itself. This digest will be verified on each subsequent boot. + + Enabling this option means that the bootloader cannot be changed after the first time it is booted. + +config SECURE_BOOTLOADER_REFLASHABLE + bool "Reflashable" + help + Generate the bootloader digest key on the computer instead of inside + the chip. Allows the secure bootloader to be re-flashed by using the + same key. + + This option is less secure than one-time flash, because a leak of the digest key allows reflashing of any device that uses it. + +endchoice + +config SECURE_BOOTLOADER_KEY_FILE + string "Secure bootloader digest key file" + depends on SECURE_BOOTLOADER_REFLASHABLE + default secure_boot_key.bin + help + Path to the key file for a reflashable secure boot digest. + File must contain 32 randomly generated bytes. + + Path is evaluated relative to the project directory. + + You can generate a new key by running the following command: + espsecure.py generate_key secure_boot_key.bin + + See docs/security/secure-boot.rst for details. + +config SECURE_BOOTLOADER_ENABLED + bool + default SECURE_BOOTLOADER_ONE_TIME_FLASH || SECURE_BOOTLOADER_REFLASHABLE endmenu diff --git a/components/bootloader/Makefile.projbuild b/components/bootloader/Makefile.projbuild index 50c95f9fec..8edabdb6ef 100644 --- a/components/bootloader/Makefile.projbuild +++ b/components/bootloader/Makefile.projbuild @@ -15,6 +15,8 @@ BOOTLOADER_BUILD_DIR=$(abspath $(BUILD_DIR_BASE)/bootloader) BOOTLOADER_BIN=$(BOOTLOADER_BUILD_DIR)/bootloader.bin BOOTLOADER_SDKCONFIG=$(BOOTLOADER_BUILD_DIR)/sdkconfig +SECURE_BOOT_KEYFILE=$(abspath $(call dequote,$(CONFIG_SECURE_BOOTLOADER_KEY_FILE))) + # Custom recursive make for bootloader sub-project BOOTLOADER_MAKE=+$(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src \ V=$(V) SDKCONFIG=$(BOOTLOADER_SDKCONFIG) \ @@ -31,18 +33,67 @@ bootloader-clean: clean: bootloader-clean +ifdef CONFIG_SECURE_BOOTLOADER_DISABLED +# If secure boot disabled, bootloader flashing is integrated +# with 'make flash' and no warnings are printed. + bootloader: $(BOOTLOADER_BIN) + @echo "$(SEPARATOR)" @echo "Bootloader built. Default flash command is:" @echo "$(ESPTOOLPY_WRITE_FLASH) 0x1000 $(BOOTLOADER_BIN)" -all_binaries: $(BOOTLOADER_BIN) - ESPTOOL_ALL_FLASH_ARGS += 0x1000 $(BOOTLOADER_BIN) -# bootloader-flash calls flash in the bootloader dummy project bootloader-flash: $(BOOTLOADER_BIN) $(BOOTLOADER_MAKE) flash +else ifdef CONFIG_SECURE_BOOTLOADER_ONE_TIME_FLASH +# One time flashing requires user to run esptool.py command themselves, +# and warning is printed about inability to reflash. + +bootloader: $(BOOTLOADER_BIN) + @echo $(SEPARATOR) + @echo "Bootloader built. One-time flash command is:" + @echo "$(ESPTOOLPY_WRITE_FLASH) 0x1000 $(BOOTLOADER_BIN)" + @echo $(SEPARATOR) + @echo "* IMPORTANT: After first boot, BOOTLOADER CANNOT BE RE-FLASHED on same device" + +else ifdef CONFIG_SECURE_BOOTLOADER_REFLASHABLE +# Reflashable secure bootloader (recommended for testing only) +# generates a digest binary (bootloader + digest) and prints +# instructions for reflashing. User must run commands manually. + +BOOTLOADER_DIGEST_BIN=$(BOOTLOADER_BUILD_DIR)/bootloader-reflash-digest.bin + +bootloader: $(BOOTLOADER_DIGEST_BIN) + @echo $(SEPARATOR) + @echo "Bootloader built and secure digest generated. First time flash command is:" + @echo "$(ESPEFUSEPY) burn_key secure_boot $(SECURE_BOOT_KEYFILE)" + @echo "$(ESPTOOLPY_WRITE_FLASH) 0x1000 $(BOOTLOADER_BIN)" + @echo $(SEPARATOR) + @echo "To reflash the bootloader after initial flash:" + @echo "$(ESPTOOLPY_WRITE_FLASH) 0x0 $(BOOTLOADER_DIGEST_BIN)" + @echo $(SEPARATOR) + @echo "* After first boot, only re-flashes of this kind (with same key) will be accepted." + @echo "* NOT RECOMMENDED TO RE-FLASH the same bootloader-reflash-digest.bin to multiple production devices" + +$(BOOTLOADER_DIGEST_BIN): $(BOOTLOADER_BIN) $(SECURE_BOOT_KEYFILE) + @echo "DIGEST $< + $(SECURE_BOOT_KEYFILE) -> $@" + $(Q) $(ESPSECUREPY) digest_secure_bootloader -k $(SECURE_BOOT_KEYFILE) -o $@ $< + +$(SECURE_BOOT_KEYFILE): + @echo $(SEPARATOR) + @echo "Need to generate secure boot digest key first. Run following command:" + @echo "$(ESPSECUREPY) generate_key $@" + @echo "Keep key file safe after generating." + @exit 1 + +else +$(error Bad sdkconfig - one of CONFIG_SECURE_BOOTLOADER_DISABLED, CONFIG_SECURE_BOOTLOADER_ONE_TIME_FLASH, CONFIG_SECURE_BOOTLOADER_REFLASHABLE must be set) +endif + +all_binaries: $(BOOTLOADER_BIN) + # synchronise the project level config to the bootloader's # config $(BOOTLOADER_SDKCONFIG): $(PROJECT_PATH)/sdkconfig | $(BOOTLOADER_BUILD_DIR) diff --git a/components/bootloader/src/main/secure_boot.c b/components/bootloader/src/main/secure_boot.c index 9247f2cbd9..070fbf24d3 100644 --- a/components/bootloader/src/main/secure_boot.c +++ b/components/bootloader/src/main/secure_boot.c @@ -148,7 +148,9 @@ bool secure_boot_generate_bootloader_digest(void) { /* reuse the secure boot IV generation function to generate the key, as this generator uses the hardware RNG. */ uint32_t buf[32]; + ets_secure_boot_start(); ets_secure_boot_rd_iv(buf); + ets_secure_boot_finish(); for (int i = 0; i < 8; i++) { ESP_LOGV(TAG, "EFUSE_BLK2_WDATA%d_REG = 0x%08x", i, buf[i]); REG_WRITE(EFUSE_BLK2_WDATA0_REG + 4*i, buf[i]); diff --git a/components/esptool_py/Makefile.projbuild b/components/esptool_py/Makefile.projbuild index 69c01e1e7f..dfb9dfc4c2 100644 --- a/components/esptool_py/Makefile.projbuild +++ b/components/esptool_py/Makefile.projbuild @@ -11,23 +11,34 @@ PYTHON ?= $(call dequote,$(CONFIG_PYTHON)) # two commands that can be used from other components # to invoke esptool.py (with or without serial port args) # -# NB: esptool.py lives in the sdk/bin directory not the component directory ESPTOOLPY_SRC := $(COMPONENT_PATH)/esptool/esptool.py ESPTOOLPY := $(PYTHON) $(ESPTOOLPY_SRC) --chip esp32 ESPTOOLPY_SERIAL := $(ESPTOOLPY) --port $(ESPPORT) --baud $(ESPBAUD) +# Supporting esptool command line tools +ESPEFUSEPY := $(PYTHON) $(COMPONENT_PATH)/esptool/espefuse.py +ESPSECUREPY := $(PYTHON) $(COMPONENT_PATH)/esptool/espsecure.py + ESPTOOL_FLASH_OPTIONS := --flash_mode $(ESPFLASHMODE) --flash_freq $(ESPFLASHFREQ) --flash_size $(ESPFLASHSIZE) -# the no-stub argument is temporary until esptool.py fully supports compressed uploads +ESPTOOL_ELF2IMAGE_OPTIONS := + +ifdef CONFIG_SECURE_BOOTLOADER_ENABLED +ESPTOOL_ELF2IMAGE_OPTIONS += "--set-secure-boot-flag" +endif + ESPTOOLPY_WRITE_FLASH=$(ESPTOOLPY_SERIAL) write_flash $(if $(CONFIG_ESPTOOLPY_COMPRESSED),-z) $(ESPTOOL_FLASH_OPTIONS) ESPTOOL_ALL_FLASH_ARGS += $(CONFIG_APP_OFFSET) $(APP_BIN) $(APP_BIN): $(APP_ELF) $(ESPTOOLPY_SRC) - $(Q) $(ESPTOOLPY) elf2image $(ESPTOOL_FLASH_OPTIONS) -o $@ $< + $(Q) $(ESPTOOLPY) elf2image $(ESPTOOL_FLASH_OPTIONS) $(ESPTOOL_ELF2IMAGE_OPTIONS) -o $@ $< flash: all_binaries $(ESPTOOLPY_SRC) @echo "Flashing binaries to serial port $(ESPPORT) (app at offset $(CONFIG_APP_OFFSET))..." +ifdef CONFIG_SECURE_BOOTLOADER_ENABLED + @echo "(Secure boot enabled, so bootloader not flashed automatically. See 'make bootloader' output)" +endif $(Q) $(ESPTOOLPY_WRITE_FLASH) $(ESPTOOL_ALL_FLASH_ARGS) app-flash: $(APP_BIN) $(ESPTOOLPY_SRC) diff --git a/components/esptool_py/esptool b/components/esptool_py/esptool index 5c6962e894..95dae1651e 160000 --- a/components/esptool_py/esptool +++ b/components/esptool_py/esptool @@ -1 +1 @@ -Subproject commit 5c6962e894e0a118c9a4b5760876433493449260 +Subproject commit 95dae1651e5aea1adb2b6018b23f65a305f67387 diff --git a/make/project.mk b/make/project.mk index 67e2e92bdb..17fb83e0d8 100644 --- a/make/project.mk +++ b/make/project.mk @@ -11,13 +11,13 @@ # .PHONY: build-components menuconfig defconfig all build clean all_binaries -all: all_binaries # other components will add dependencies to 'all_binaries' - @echo "To flash all build output, run 'make flash' or:" - @echo $(ESPTOOLPY_WRITE_FLASH) $(ESPTOOL_ALL_FLASH_ARGS) - -# (the reason all_binaries is used instead of 'all' is so that the flash target -# can build everything without triggering the per-component "to flash..." -# output targets.) +all: all_binaries +# see below for recipe of 'all' target +# +# # other components will add dependencies to 'all_binaries'. The +# reason all_binaries is used instead of 'all' is so that the flash +# target can build everything without triggering the per-component "to +# flash..." output targets.) help: @echo "Welcome to Espressif IDF build system. Some useful make targets:" @@ -135,6 +135,15 @@ export PROJECT_PATH #Include functionality common to both project & component -include $(IDF_PATH)/make/common.mk +all: +ifdef CONFIG_SECURE_BOOTLOADER_ENABLED + @echo "(Secure boot enabled, so bootloader not flashed automatically. See 'make bootloader' output)" + @echo "To flash app & partition table, run 'make flash' or:" +else + @echo "To flash all build output, run 'make flash' or:" +endif + @echo $(ESPTOOLPY_WRITE_FLASH) $(ESPTOOL_ALL_FLASH_ARGS) + # Set default LDFLAGS LDFLAGS ?= -nostdlib \ From 04beb8baba3c087622558851285ccd038f8b59d0 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 1 Nov 2016 17:41:27 +1100 Subject: [PATCH 240/343] Add documentation for bootloader secure boot stage --- components/bootloader/Kconfig.projbuild | 4 +- components/bootloader/Makefile.projbuild | 2 +- docs/security/secure-boot.rst | 146 +++++++++++++++++++++++ 3 files changed, 149 insertions(+), 3 deletions(-) create mode 100644 docs/security/secure-boot.rst diff --git a/components/bootloader/Kconfig.projbuild b/components/bootloader/Kconfig.projbuild index d6736b33db..55c2eebd14 100644 --- a/components/bootloader/Kconfig.projbuild +++ b/components/bootloader/Kconfig.projbuild @@ -63,11 +63,11 @@ config SECURE_BOOTLOADER_REFLASHABLE endchoice config SECURE_BOOTLOADER_KEY_FILE - string "Secure bootloader digest key file" + string "Secure bootloader key file" depends on SECURE_BOOTLOADER_REFLASHABLE default secure_boot_key.bin help - Path to the key file for a reflashable secure boot digest. + Path to the key file for a reflashable secure bootloader digest. File must contain 32 randomly generated bytes. Path is evaluated relative to the project directory. diff --git a/components/bootloader/Makefile.projbuild b/components/bootloader/Makefile.projbuild index 8edabdb6ef..b9dab3e093 100644 --- a/components/bootloader/Makefile.projbuild +++ b/components/bootloader/Makefile.projbuild @@ -75,7 +75,7 @@ bootloader: $(BOOTLOADER_DIGEST_BIN) @echo "$(ESPTOOLPY_WRITE_FLASH) 0x0 $(BOOTLOADER_DIGEST_BIN)" @echo $(SEPARATOR) @echo "* After first boot, only re-flashes of this kind (with same key) will be accepted." - @echo "* NOT RECOMMENDED TO RE-FLASH the same bootloader-reflash-digest.bin to multiple production devices" + @echo "* Not recommended to re-use the same secure boot keyfile on multiple production devices." $(BOOTLOADER_DIGEST_BIN): $(BOOTLOADER_BIN) $(SECURE_BOOT_KEYFILE) @echo "DIGEST $< + $(SECURE_BOOT_KEYFILE) -> $@" diff --git a/docs/security/secure-boot.rst b/docs/security/secure-boot.rst new file mode 100644 index 0000000000..5e33367b49 --- /dev/null +++ b/docs/security/secure-boot.rst @@ -0,0 +1,146 @@ +Secure Boot +=========== + +Secure Boot is a feature for ensuring only your code can run on the chip. Data loaded from flash is verified on each reset. + +Secure Boot is separate from the Encrypted Flash feature, and you can use secure boot without encrypting the flash contents. However for maximum protection we recommend using both features together. + +Background +---------- + +- Most data is stored in flash. Flash access does not need to protected for secure boot to function, because critical data is stored in Efuses internal to the chip. + +- Efuses are used to store the secure bootloader key (in efuse block 2), and also a single Efuse (ABS_DONE_0) is burned (written to 1) to permanently enable secure boot on the chip. For more details about efuse, see the (forthcoming) chapter in the Technical Reference Manual. + +- To understand the secure boot process, first familiarise yourself with the standard `esp-idf boot process`. + +Secure Boot Process Overview +---------------------------- + +This is a high level overview of the secure boot process. Step by step instructions are supplied under `How To Enable Secure Boot`. Further in-depth details are supplied under `Technical Details`: + +1. The options to enable secure boot are provided in the ``make menuconfig`` hierarchy, under "Bootloader Config". + +2. Bootloader Config includes the path to a ECDSA public key. This "image public key" is compiled into the software bootloader. + +2. The software bootloader image is built by esp-idf with the public key embedded, and with a secure boot flag set in its header. This software bootloader image is flashed at offset 0x1000. + +3. On first boot, the software bootloader tests the secure boot flag. If it is set, the following process is followed to enable secure boot: + - Hardware secure boot support generates a device secure bootloader key (stored read/write protected in efuse), and a secure digest. The digest is derived from the key, an IV, and the bootloader image contents. + - The secure digest is flashed at offset 0x0 in the flash. + - Bootloader permanently enables secure boot by burning the ABS_DONE_0 efuse. The software bootloader then becomes protected (the chip will only boot this bootloader image.) + - Bootloader also disables JTAG via efuse. + +4. On subsequent boots the ROM bootloader sees that the secure boot efuse is burned, reads the saved digest at 0x0 and uses hardware secure boot support to compare it with a newly calculated digest. If the digest does not match then booting will not continue. + +5. When running in secure boot mode, the software bootloader uses the image public key (embedded in the bootloader itself) to verify all subsequent partition tables and app images before they are booted. + +Keys +---- + +The following keys are used by the secure boot process: + +- "secure bootloader key" is a 256-bit AES key that is stored in Efuse block 2. The bootloader can generate this key itself from hardware, the user does not need to supply it. The Efuse holding this key must be read & write protected (preventing software access) before secure boot is enabled. + +- "image public key" is a ECDSA public key (curve TBD) in format TBD. This public key is flashed into the software bootloader and used to verify the remaining parts of the flash (partition table, app image) before booting continues. The public key can be freely distributed, it does not need to be kept secret. + +- "image private key" is a ECDSA private key, a matching pair with "image public key". This private key is used to sign partition tables and app images for the secure boot process. **This private key must be securely kept private** as anyone who has this key can authenticate to the secure boot process. It is acceptable to use the same private key across multiple production devices. + +How To Enable Secure Boot +------------------------- + +1. Run ``make menuconfig``, navigate to "Bootloader Config" -> "Secure Boot" and select the option "One-time Flash". (For the alternative "Reflashable" choice, see `Re-Flashable Software Bootloader`.) + +2. Select names for public & private image key files "Image Public Key File" and "Image Private Key File". These options will appear after secure boot is enabled. The files can be anywhere on your system. Relative paths are evaluated from the project directory. The files don't need to exist yet. + +3. Set other config options (as desired). Pay particular attention to the "Bootloader Config" options, as you can only flash the bootloader once. Then exit menuconfig and save your configuration + +4. Run ``make generate_image_keypair`` to generate an image public key and a matching image private key. + + **IMPORTANT** The key pair is generated using the best random number source available via the OS and its Python installation (`/dev/urandom` on OSX/Linux and `CryptGenRandom()` on Windows). If this random number source is weak, then the private key will be weak. + +5. Run ``make bootloader`` to build a secure boot enabled bootloader. The output of `make` will include a prompt for a flashing command, using `esptool.py write_flash`. + +6. When you're ready to flash the bootloader, run the specified command (you have to enter it yourself, this step is not automated) and then wait for flashing to complete. **Remember this is a one time flash, you can't change the bootloader after this!**. + +7. Run `make flash` to build and flash the partition table and the just-built app image. The app image will be signed using the private key you generated in step 4. + + *NOTE*: `make flash` doesn't flash the bootloader if secure boot is enabled. + +8. Reset the ESP32 and it will boot the software bootloader you flashed. The software bootloader will enable secure boot on the chip, and then it verifies the app image signature and boots the app. You should watch the serial console output from the ESP32 to verify that secure boot is enabled and no errors have occured due to the build configuration. + +**IMPORTANT** Secure boot won't ever be enabled until after a valid partition table and app image have been flashed. This is to prevent accidents before the system is fully configured. + +9. On subsequent boots, the secure boot hardware will verify the software bootloader (using the secure bootloader key) and then the software bootloader will verify the partition table and app image (using the image public key). + +Re-Flashable Software Bootloader +-------------------------------- + +The "Secure Boot: One-Time Flash" is the recommended software bootloader configuration for production devices. In this mode, each device gets a unique key that is never stored outside the device. + +However, an alternative mode "Secure Boot: Reflashable" is also available. This mode allows you to supply a 256-bit key file that is used for the secure bootloader key. As you have the key file, you can generate new bootloader images and secure boot digests for them. + +*NOTE*: Although it's possible, we strongly recommend not generating one secure boot key and flashing it to every device in a production environment. + +1. In the ``make menuconfig`` step, select "Bootloader Config" -> "Secure Boot" -> "Reflashable". + +2. Select a name for the "Secure bootloader key file". The file can be anywhere on your system, and does not have to exist yet. A path is evaluated relative to the project directory. The file doesn't have to exist yet. + +3. The first time you run ``make bootloader``, the system will prompt you with a ``espsecure.py generate_key`` command that can be used to generate the secure bootloader key. + + **IMPORTANT** The new key is generated using the best random number source available via the OS and its Python installation (`/dev/urandom` on OSX/Linux and `CryptGenRandom()` on Windows). If this random number source is weak, then the secure bootloader key will be weak. + +4. Run ``make bootloader`` again. Two sets of flashing steps will be printed - the first set of steps includes an ``espefuse.py burn_key`` command which is used to write the secure bootloader key to efuse. (Flashing this key is a one-time-only process.) The second set of steps can be used to reflash the bootloader with a pre-generated digest (generated during the build process, using the secure bootloader key file). + +5. Resume from `Step 6` of the one-time process, to flash the bootloader and enable secure boot. Watch the console log output closely to ensure there were no errors in the secure boot configuration. + + +Technical Details +----------------- + +The following sections contain low-level descriptions of various technical functions: + +Hardware Secure Boot Support +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The Secure Boot support hardware can perform three basic operations: + +1. Generate a random sequence of bytes from a hardware random number generator. + +2. Generate a digest from data (usually the bootloader image from flash) using a key stored in Efuse block 2. The key in Efuse can (& should) be read/write protected, which prevents software access. For full details of this algorithm see `Secure Bootloader Digest Algorithm`. The digest can only be read from hardware if Efuse ABS_DONE_0 is *not* burned (ie still 0), to prevent new digests from being calculated on the device after secure boot is enabled. + +3. Verify a digest from data (usually the bootloader image from flash), and compare it to a pre-existing digest (usually read from flash offset 0x0). The hardware returns a true/false comparison without making the digest available to software. + +Secure Bootloader Digest Algorithm +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Starting with an "image" of binary data as input, this algorithm generates a digest as output. + +For a Python version of this algorithm, see the `espsecure.py` tool in the components/esptool_py directory. + +Items marked with (^) are to fulfill hardware restrictions, as opposed to cryptographic restrictions. + +1. Prefix the image with a 128 byte randomly generated IV. +2. If the image is not modulo 128, pad the image to a 128 byte boundary with 0xFF. (^) +3. For each 16 byte block of the input image: + - Reverse the byte order of the block (^) + - Use the AES256 algorithm in ECB mode to encrypt the block. + - Reverse the byte order of the 16 bytes of ciphertext output. (^) + - Append to the overall ciphertext output. +4. Byte-swap each 4 byte word of the ciphertext (^) +5. Calculate SHA-512 of the ciphertext. + +Output digest is 192 bytes of data: The 128 byte IV, followed by the 64 byte SHA-512 digest. + +Image Signing Algorithm +~~~~~~~~~~~~~~~~~~~~~~~ + +Deterministic ECDSA as specified by `RFC6979`. + +Curve is TBD. +Key format is TBD. +Output format is TBD. + + +.. _esp-idf boot process: ../boot-process.rst +.. _RFC6979: https://tools.ietf.org/html/rfc6979 From d0fac3c39566d819022b569f2f2f26b3552c2166 Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Wed, 2 Nov 2016 10:26:02 +0800 Subject: [PATCH 241/343] Language tweaking --- docs/openocd.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/openocd.rst b/docs/openocd.rst index cf1d25e60b..9e2aeff459 100644 --- a/docs/openocd.rst +++ b/docs/openocd.rst @@ -1,7 +1,7 @@ OpenOCD setup for ESP32 ----------------------- -The ESP31 and ESP32 have two powerful Xtensa cores, allowing for a great deal of variety of program architectures. The FreeRTOS +The ESP31 and ESP32 have two powerful Xtensa cores, allowing for a great variety of program architectures. The FreeRTOS OS that comes with ESP-IDF is capable of multi-core pre-emptive multithreading, allowing for an intuitive way of writing software. The downside of the ease of programming is that debugging without the right tools is harder: figuring out a bug that is caused From aceb6517c05e807c7f9ad27d31e9b8aa12568172 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 2 Nov 2016 10:41:58 +1100 Subject: [PATCH 242/343] Refactor existing bootloader common functionality into bootloader_support component --- components/bootloader/Makefile.projbuild | 6 +- components/bootloader/src/Makefile | 2 +- .../bootloader/src/main/bootloader_config.h | 5 - .../bootloader/src/main/bootloader_start.c | 276 ++++++++---------- .../bootloader/src/main/flash_encrypt.c | 158 +++++----- components/bootloader/src/main/secure_boot.c | 72 +++-- components/bootloader_support/README.rst | 9 + components/bootloader_support/component.mk | 11 + .../include/esp_image_format.h | 133 +++++++++ .../include/esp_secureboot.h | 51 ++++ .../include_priv/bootloader_flash.h | 69 +++++ .../bootloader_support/src/bootloader_flash.c | 122 ++++++++ .../bootloader_support/src/esp_image_format.c | 155 ++++++++++ .../bootloader_support/src/secureboot.c | 7 + .../esp32/include/esp_flash_data_types.h | 48 --- components/esp32/include/rom/secure_boot.h | 2 +- components/log/include/esp_log.h | 4 + make/project.mk | 2 +- 18 files changed, 813 insertions(+), 319 deletions(-) create mode 100644 components/bootloader_support/README.rst create mode 100755 components/bootloader_support/component.mk create mode 100644 components/bootloader_support/include/esp_image_format.h create mode 100644 components/bootloader_support/include/esp_secureboot.h create mode 100644 components/bootloader_support/include_priv/bootloader_flash.h create mode 100644 components/bootloader_support/src/bootloader_flash.c create mode 100644 components/bootloader_support/src/esp_image_format.c create mode 100644 components/bootloader_support/src/secureboot.c diff --git a/components/bootloader/Makefile.projbuild b/components/bootloader/Makefile.projbuild index b9dab3e093..3799e913c8 100644 --- a/components/bootloader/Makefile.projbuild +++ b/components/bootloader/Makefile.projbuild @@ -20,7 +20,7 @@ SECURE_BOOT_KEYFILE=$(abspath $(call dequote,$(CONFIG_SECURE_BOOTLOADER_KEY_FILE # Custom recursive make for bootloader sub-project BOOTLOADER_MAKE=+$(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src \ V=$(V) SDKCONFIG=$(BOOTLOADER_SDKCONFIG) \ - BUILD_DIR_BASE=$(BOOTLOADER_BUILD_DIR) \ + BUILD_DIR_BASE=$(BOOTLOADER_BUILD_DIR) IS_BOOTLOADER_BUILD=1 .PHONY: bootloader-clean bootloader-flash bootloader $(BOOTLOADER_BIN) @@ -89,7 +89,9 @@ $(SECURE_BOOT_KEYFILE): @exit 1 else -$(error Bad sdkconfig - one of CONFIG_SECURE_BOOTLOADER_DISABLED, CONFIG_SECURE_BOOTLOADER_ONE_TIME_FLASH, CONFIG_SECURE_BOOTLOADER_REFLASHABLE must be set) +bootloader: + @echo "Invalid bootloader target: bad sdkconfig?" + @exit 1 endif all_binaries: $(BOOTLOADER_BIN) diff --git a/components/bootloader/src/Makefile b/components/bootloader/src/Makefile index add9c15d61..278e0e9afb 100644 --- a/components/bootloader/src/Makefile +++ b/components/bootloader/src/Makefile @@ -4,7 +4,7 @@ # PROJECT_NAME := bootloader -COMPONENTS := esptool_py bootloader log spi_flash +COMPONENTS := esptool_py bootloader bootloader_support log spi_flash # The bootloader pseudo-component is also included in this build, for its Kconfig.projbuild to be included. # diff --git a/components/bootloader/src/main/bootloader_config.h b/components/bootloader/src/main/bootloader_config.h index 1655280dc7..0823581824 100644 --- a/components/bootloader/src/main/bootloader_config.h +++ b/components/bootloader/src/main/bootloader_config.h @@ -25,8 +25,6 @@ extern "C" #define BOOT_VERSION "V0.1" #define SPI_SEC_SIZE 0x1000 -#define MEM_CACHE(offset) (uint8_t *)(0x3f400000 + (offset)) -#define CACHE_READ_32(offset) ((uint32_t *)(0x3f400000 + (offset))) #define IROM_LOW 0x400D0000 #define IROM_HIGH 0x40400000 #define DROM_LOW 0x3F400000 @@ -61,9 +59,6 @@ typedef struct { uint32_t selected_subtype; } bootloader_state_t; -void boot_cache_redirect( uint32_t pos, size_t size ); -uint32_t get_bin_len(uint32_t pos); - bool flash_encrypt(bootloader_state_t *bs); bool secure_boot_generate_bootloader_digest(void); diff --git a/components/bootloader/src/main/bootloader_start.c b/components/bootloader/src/main/bootloader_start.c index a4b27702c4..3bc2696a4b 100644 --- a/components/bootloader/src/main/bootloader_start.c +++ b/components/bootloader/src/main/bootloader_start.c @@ -33,6 +33,8 @@ #include "soc/timer_group_reg.h" #include "sdkconfig.h" +#include "esp_image_format.h" +#include "bootloader_flash.h" #include "bootloader_config.h" @@ -49,7 +51,7 @@ flash cache is down and the app CPU is in reset. We do have a stack, so we can d extern void Cache_Flush(int); void bootloader_main(); -void unpack_load_app(const esp_partition_pos_t *app_node); +static void unpack_load_app(const esp_partition_pos_t *app_node); void print_flash_info(const esp_image_header_t* pfhdr); void IRAM_ATTR set_cache_and_start_app(uint32_t drom_addr, uint32_t drom_load_addr, @@ -94,53 +96,6 @@ void IRAM_ATTR call_start_cpu0() bootloader_main(); } -/** - * @function : get_bin_len - * @description: get bin's length - * - * @inputs: pos bin locate address in flash - * @return: uint32 length of bin,if bin MAGIC error return 0 - */ - -uint32_t get_bin_len(uint32_t pos) -{ - uint32_t len = 8 + 16; - uint8_t i; - ESP_LOGD(TAG, "pos %d %x",pos,*(uint8_t *)pos); - if(0xE9 != *(uint8_t *)pos) { - return 0; - } - for (i = 0; i < *(uint8_t *)(pos + 1); i++) { - len += *(uint32_t *)(pos + len + 4) + 8; - } - if (len % 16 != 0) { - len = (len / 16 + 1) * 16; - } else { - len += 16; - } - ESP_LOGD(TAG, "bin length = %d", len); - return len; -} - -/** - * @function : boot_cache_redirect - * @description: Configure several pages in flash map so that `size` bytes - * starting at `pos` are mapped to 0x3f400000. - * This sets up mapping only for PRO CPU. - * - * @inputs: pos address in flash - * size size of the area to map, in bytes - */ -void boot_cache_redirect( uint32_t pos, size_t size ) -{ - uint32_t pos_aligned = pos & 0xffff0000; - uint32_t count = (size + 0xffff) / 0x10000; - Cache_Read_Disable( 0 ); - Cache_Flush( 0 ); - ESP_LOGD(TAG, "mmu set paddr=%08x count=%d", pos_aligned, count ); - cache_flash_mmu_set( 0, 0, 0x3f400000, pos_aligned, 64, count ); - Cache_Read_Enable( 0 ); -} /** * @function : load_partition_table @@ -154,79 +109,86 @@ void boot_cache_redirect( uint32_t pos, size_t size ) */ bool load_partition_table(bootloader_state_t* bs, uint32_t addr) { - esp_partition_info_t partition; - uint32_t end = addr + 0x1000; - int index = 0; + const esp_partition_info_t *partitions; + const int PARTITION_TABLE_SIZE = 0x1000; + const int MAX_PARTITIONS = PARTITION_TABLE_SIZE / sizeof(esp_partition_info_t); char *partition_usage; ESP_LOGI(TAG, "Partition Table:"); ESP_LOGI(TAG, "## Label Usage Type ST Offset Length"); - while (addr < end) { - ESP_LOGD(TAG, "load partition table entry from %x(%08x)", addr, MEM_CACHE(addr)); - memcpy(&partition, MEM_CACHE(addr), sizeof(partition)); - ESP_LOGD(TAG, "type=%x subtype=%x", partition.type, partition.subtype); + partitions = bootloader_mmap(addr, 0x1000); + if (!partitions) { + ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", addr, 0x1000); + return false; + } + ESP_LOGD(TAG, "mapped partition table 0x%x at 0x%x", addr, (intptr_t)partitions); + + for(int i = 0; i < MAX_PARTITIONS; i++) { + const esp_partition_info_t *partition = &partitions[i]; + ESP_LOGD(TAG, "load partition table entry 0x%x", (intptr_t)partition); + ESP_LOGD(TAG, "type=%x subtype=%x", partition->type, partition->subtype); partition_usage = "unknown"; - if (partition.magic == ESP_PARTITION_MAGIC) { /* valid partition definition */ - switch(partition.type) { - case PART_TYPE_APP: /* app partition */ - switch(partition.subtype) { - case PART_SUBTYPE_FACTORY: /* factory binary */ - bs->factory = partition.pos; - partition_usage = "factory app"; - break; - case PART_SUBTYPE_TEST: /* test binary */ - bs->test = partition.pos; - partition_usage = "test app"; - break; - default: - /* OTA binary */ - if ((partition.subtype & ~PART_SUBTYPE_OTA_MASK) == PART_SUBTYPE_OTA_FLAG) { - bs->ota[partition.subtype & PART_SUBTYPE_OTA_MASK] = partition.pos; - ++bs->app_count; - partition_usage = "OTA app"; - } - else { - partition_usage = "Unknown app"; - } - break; + if (partition->magic != ESP_PARTITION_MAGIC) { + /* invalid partition definition indicates end-of-table */ + break; + } + + /* valid partition table */ + switch(partition->type) { + case PART_TYPE_APP: /* app partition */ + switch(partition->subtype) { + case PART_SUBTYPE_FACTORY: /* factory binary */ + bs->factory = partition->pos; + partition_usage = "factory app"; + break; + case PART_SUBTYPE_TEST: /* test binary */ + bs->test = partition->pos; + partition_usage = "test app"; + break; + default: + /* OTA binary */ + if ((partition->subtype & ~PART_SUBTYPE_OTA_MASK) == PART_SUBTYPE_OTA_FLAG) { + bs->ota[partition->subtype & PART_SUBTYPE_OTA_MASK] = partition->pos; + ++bs->app_count; + partition_usage = "OTA app"; } - break; /* PART_TYPE_APP */ - case PART_TYPE_DATA: /* data partition */ - switch(partition.subtype) { - case PART_SUBTYPE_DATA_OTA: /* ota data */ - bs->ota_info = partition.pos; - partition_usage = "OTA data"; - break; - case PART_SUBTYPE_DATA_RF: - partition_usage = "RF data"; - break; - case PART_SUBTYPE_DATA_WIFI: - partition_usage = "WiFi data"; - break; - default: - partition_usage = "Unknown data"; - break; + else { + partition_usage = "Unknown app"; } - break; /* PARTITION_USAGE_DATA */ - default: /* other partition type */ break; } - } - /* invalid partition magic number */ - else { - break; /* todo: validate md5 */ + break; /* PART_TYPE_APP */ + case PART_TYPE_DATA: /* data partition */ + switch(partition->subtype) { + case PART_SUBTYPE_DATA_OTA: /* ota data */ + bs->ota_info = partition->pos; + partition_usage = "OTA data"; + break; + case PART_SUBTYPE_DATA_RF: + partition_usage = "RF data"; + break; + case PART_SUBTYPE_DATA_WIFI: + partition_usage = "WiFi data"; + break; + default: + partition_usage = "Unknown data"; + break; + } + break; /* PARTITION_USAGE_DATA */ + default: /* other partition type */ + break; } /* print partition type info */ - ESP_LOGI(TAG, "%2d %-16s %-16s %02x %02x %08x %08x", index, partition.label, partition_usage, - partition.type, partition.subtype, - partition.pos.offset, partition.pos.size); - index++; - addr += sizeof(partition); + ESP_LOGI(TAG, "%2d %-16s %-16s %02x %02x %08x %08x", i, partition->label, partition_usage, + partition->type, partition->subtype, + partition->pos.offset, partition->pos.size); } + bootloader_unmap(partitions); + ESP_LOGI(TAG,"End of partition table"); return true; } @@ -254,8 +216,9 @@ void bootloader_main() esp_image_header_t fhdr; bootloader_state_t bs; - SpiFlashOpResult spiRet1,spiRet2; + SpiFlashOpResult spiRet1,spiRet2; esp_ota_select_entry_t sa,sb; + const esp_ota_select_entry_t *ota_select_map; memset(&bs, 0, sizeof(bs)); @@ -264,10 +227,11 @@ void bootloader_main() REG_CLR_BIT( RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_FLASHBOOT_MOD_EN ); REG_CLR_BIT( TIMG_WDTCONFIG0_REG(0), TIMG_WDT_FLASHBOOT_MOD_EN ); SPIUnlock(); - /*register first sector in drom0 page 0 */ - boot_cache_redirect( 0, 0x5000 ); - memcpy((unsigned int *) &fhdr, MEM_CACHE(0x1000), sizeof(esp_image_header_t) ); + if(esp_image_load_header(0x1000, &fhdr) != ESP_OK) { + ESP_LOGE(TAG, "failed to load bootloader header!"); + return; + } print_flash_info(&fhdr); @@ -282,9 +246,19 @@ void bootloader_main() if (bs.ota_info.offset != 0) { // check if partition table has OTA info partition //ESP_LOGE("OTA info sector handling is not implemented"); - boot_cache_redirect(bs.ota_info.offset, bs.ota_info.size ); - memcpy(&sa,MEM_CACHE(bs.ota_info.offset & 0x0000ffff),sizeof(sa)); - memcpy(&sb,MEM_CACHE((bs.ota_info.offset + 0x1000)&0x0000ffff) ,sizeof(sb)); + if (bs.ota_info.size < 2 * sizeof(esp_ota_select_entry_t)) { + ESP_LOGE(TAG, "ERROR: ota_info partition size %d is too small (minimum %d bytes)", bs.ota_info.size, sizeof(esp_ota_select_entry_t)); + return; + } + ota_select_map = bootloader_mmap(bs.ota_info.offset, bs.ota_info.size); + if (!ota_select_map) { + ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", bs.ota_info.offset, bs.ota_info.size); + return; + } + sa = ota_select_map[0]; + sb = ota_select_map[1]; + bootloader_unmap(ota_select_map); + if(sa.ota_seq == 0xFFFFFFFF && sb.ota_seq == 0xFFFFFFFF) { // init status flash load_part_pos = bs.ota[0]; @@ -355,14 +329,14 @@ void bootloader_main() } -void unpack_load_app(const esp_partition_pos_t* partition) +static void unpack_load_app(const esp_partition_pos_t* partition) { - boot_cache_redirect(partition->offset, partition->size); - - uint32_t pos = 0; esp_image_header_t image_header; - memcpy(&image_header, MEM_CACHE(pos), sizeof(image_header)); - pos += sizeof(image_header); + + if (esp_image_load_header(partition->offset, &image_header) != ESP_OK) { + ESP_LOGE(TAG, "Failed to load app image header @ 0x%x", partition->offset); + return; + } uint32_t drom_addr = 0; uint32_t drom_load_addr = 0; @@ -376,19 +350,22 @@ void unpack_load_app(const esp_partition_pos_t* partition) bool load_rtc_memory = rtc_get_reset_reason(0) != DEEPSLEEP_RESET; ESP_LOGD(TAG, "bin_header: %u %u %u %u %08x", image_header.magic, - image_header.blocks, + image_header.segment_count, image_header.spi_mode, image_header.spi_size, (unsigned)image_header.entry_addr); - for (uint32_t section_index = 0; - section_index < image_header.blocks; - ++section_index) { - esp_image_section_header_t section_header = {0}; - memcpy(§ion_header, MEM_CACHE(pos), sizeof(section_header)); - pos += sizeof(section_header); + for (int segment = 0; segment < image_header.segment_count; segment++) { + esp_image_segment_header_t segment_header; + uint32_t data_offs; + if(esp_image_load_segment_header(segment, partition->offset, + &image_header, &segment_header, + &data_offs) != ESP_OK) { + ESP_LOGE(TAG, "failed to load segment header #%d", segment); + return; + } - const uint32_t address = section_header.load_addr; + const uint32_t address = segment_header.load_addr; bool load = true; bool map = false; if (address == 0x00000000) { // padding, ignore block @@ -400,47 +377,50 @@ void unpack_load_app(const esp_partition_pos_t* partition) } if (address >= DROM_LOW && address < DROM_HIGH) { - ESP_LOGD(TAG, "found drom section, map from %08x to %08x", pos, - section_header.load_addr); - drom_addr = partition->offset + pos - sizeof(section_header); - drom_load_addr = section_header.load_addr; - drom_size = section_header.data_len + sizeof(section_header); + ESP_LOGD(TAG, "found drom section, map from %08x to %08x", data_offs, + segment_header.load_addr); + drom_addr = data_offs; + drom_load_addr = segment_header.load_addr; + drom_size = segment_header.data_len + sizeof(segment_header); load = false; map = true; } if (address >= IROM_LOW && address < IROM_HIGH) { - ESP_LOGD(TAG, "found irom section, map from %08x to %08x", pos, - section_header.load_addr); - irom_addr = partition->offset + pos - sizeof(section_header); - irom_load_addr = section_header.load_addr; - irom_size = section_header.data_len + sizeof(section_header); + ESP_LOGD(TAG, "found irom section, map from %08x to %08x", data_offs, + segment_header.load_addr); + irom_addr = data_offs; + irom_load_addr = segment_header.load_addr; + irom_size = segment_header.data_len + sizeof(segment_header); load = false; map = true; } if (!load_rtc_memory && address >= RTC_IRAM_LOW && address < RTC_IRAM_HIGH) { - ESP_LOGD(TAG, "Skipping RTC code section at %08x\n", pos); + ESP_LOGD(TAG, "Skipping RTC code section at %08x\n", data_offs); load = false; } if (!load_rtc_memory && address >= RTC_DATA_LOW && address < RTC_DATA_HIGH) { - ESP_LOGD(TAG, "Skipping RTC data section at %08x\n", pos); + ESP_LOGD(TAG, "Skipping RTC data section at %08x\n", data_offs); load = false; } - ESP_LOGI(TAG, "section %d: paddr=0x%08x vaddr=0x%08x size=0x%05x (%6d) %s", section_index, pos, - section_header.load_addr, section_header.data_len, section_header.data_len, (load)?"load":(map)?"map":""); + ESP_LOGI(TAG, "segment %d: paddr=0x%08x vaddr=0x%08x size=0x%05x (%6d) %s", segment, data_offs - sizeof(esp_image_segment_header_t), + segment_header.load_addr, segment_header.data_len, segment_header.data_len, (load)?"load":(map)?"map":""); - if (!load) { - pos += section_header.data_len; - continue; + if (load) { + const void *data = bootloader_mmap(data_offs, segment_header.data_len); + if(!data) { + ESP_LOGE(TAG, "bootloader_mmap(0x%xc, 0x%x) failed", + data_offs, segment_header.data_len); + return; + } + memcpy((void *)segment_header.load_addr, data, segment_header.data_len); + bootloader_unmap(data); } - - memcpy((void*) section_header.load_addr, MEM_CACHE(pos), section_header.data_len); - pos += section_header.data_len; } - + set_cache_and_start_app(drom_addr, drom_load_addr, drom_size, @@ -526,7 +506,7 @@ void print_flash_info(const esp_image_header_t* phdr) #if (BOOT_LOG_LEVEL >= BOOT_LOG_LEVEL_NOTICE) ESP_LOGD(TAG, "magic %02x", phdr->magic ); - ESP_LOGD(TAG, "blocks %02x", phdr->blocks ); + ESP_LOGD(TAG, "segments %02x", phdr->segment_count ); ESP_LOGD(TAG, "spi_mode %02x", phdr->spi_mode ); ESP_LOGD(TAG, "spi_speed %02x", phdr->spi_speed ); ESP_LOGD(TAG, "spi_size %02x", phdr->spi_size ); diff --git a/components/bootloader/src/main/flash_encrypt.c b/components/bootloader/src/main/flash_encrypt.c index 2fb57a987d..2b1479097d 100644 --- a/components/bootloader/src/main/flash_encrypt.c +++ b/components/bootloader/src/main/flash_encrypt.c @@ -17,6 +17,7 @@ #include "esp_types.h" #include "esp_attr.h" #include "esp_log.h" +#include "esp_err.h" #include "rom/cache.h" #include "rom/ets_sys.h" @@ -30,6 +31,7 @@ #include "sdkconfig.h" #include "bootloader_config.h" +#include "esp_image_format.h" static const char* TAG = "flash_encrypt"; @@ -90,103 +92,97 @@ bool flash_encrypt_write(uint32_t pos, uint32_t len) Cache_Read_Enable(0); return true; } + + /** * @function : flash_encrypt * @description: encrypt 2nd boot ,partition table ,factory bin ��test bin (if use)��ota bin * ��OTA info sector. * * @inputs: bs bootloader state structure used to save the data - * + * * @return: return true, if the encrypt flash success - * + * */ bool flash_encrypt(bootloader_state_t *bs) { - uint32_t bin_len = 0; - uint32_t flash_crypt_cnt = REG_GET_FIELD(EFUSE_BLK0_RDATA0_REG, EFUSE_FLASH_CRYPT_CNT); - uint8_t count = bitcount(flash_crypt_cnt); - int i = 0; - ESP_LOGD(TAG, "flash encrypt cnt %x, bitcount %d", flash_crypt_cnt, count); + esp_err_t err; + uint32_t image_len = 0; + uint32_t flash_crypt_cnt = REG_GET_FIELD(EFUSE_BLK0_RDATA0_REG, EFUSE_FLASH_CRYPT_CNT); + uint8_t count = bitcount(flash_crypt_cnt); + ESP_LOGD(TAG, "flash encrypt cnt %x, bitcount %d", flash_crypt_cnt, count); - if ((count % 2) == 0) { - boot_cache_redirect( 0, 64*1024); - /* encrypt iv and abstruct */ - if (false == flash_encrypt_write(0, SPI_SEC_SIZE)) { - ESP_LOGE(TAG, "encrypt iv and abstract error"); - return false; - } + if ((count % 2) == 0) { + /* encrypt iv and abstract */ + if (false == flash_encrypt_write(0, SPI_SEC_SIZE)) { + ESP_LOGE(TAG, "encrypt iv and abstract error"); + return false; + } + + /* encrypt bootloader image */ + err = esp_image_basic_verify(0x1000, &image_len); + if(err == ESP_OK && image_len != 0) { + if (false == flash_encrypt_write(0x1000, image_len)) { + ESP_LOGE(TAG, "encrypt 2nd boot error"); + return false; + } + } else { + ESP_LOGE(TAG, "2nd boot len error"); + return false; + } - /* encrypt write boot bin*/ - bin_len = get_bin_len((uint32_t)MEM_CACHE(0x1000)); - if(bin_len != 0) { - if (false == flash_encrypt_write(0x1000, bin_len)) { - ESP_LOGE(TAG, "encrypt 2nd boot error"); - return false; - } - } else { - ESP_LOGE(TAG, "2nd boot len error"); - return false; - } /* encrypt partition table */ - if (false == flash_encrypt_write(ESP_PARTITION_TABLE_ADDR, SPI_SEC_SIZE)) { - ESP_LOGE(TAG, "encrypt partition table error"); - return false; - } + if (false == flash_encrypt_write(ESP_PARTITION_TABLE_ADDR, SPI_SEC_SIZE)) { + ESP_LOGE(TAG, "encrypt partition table error"); + return false; + } /* encrypt write factory bin */ - if(bs->factory.offset != 0x00) { - ESP_LOGD(TAG, "have factory bin"); - boot_cache_redirect(bs->factory.offset, bs->factory.size); - bin_len = get_bin_len((uint32_t)MEM_CACHE(bs->factory.offset&0xffff)); - if(bin_len != 0) { - if (false == flash_encrypt_write(bs->factory.offset, bin_len)) { - ESP_LOGE(TAG, "encrypt factory bin error"); - return false; - } - } - } + if(bs->factory.offset != 0 && bs->factory.size != 0) { + ESP_LOGD(TAG, "have factory bin"); + if (false == flash_encrypt_write(bs->factory.offset, bs->factory.size)) { + ESP_LOGE(TAG, "encrypt factory bin error"); + return false; + } + } + /* encrypt write test bin */ - if(bs->test.offset != 0x00) { - ESP_LOGD(TAG, "have test bin"); - boot_cache_redirect(bs->test.offset, bs->test.size); - bin_len = get_bin_len((uint32_t)MEM_CACHE(bs->test.offset&0xffff)); - if(bin_len != 0) { - if (false == flash_encrypt_write(bs->test.offset, bin_len)) { - ESP_LOGE(TAG, "encrypt test bin error"); - return false; - } - } - } + if(bs->test.offset != 0 && bs->test.size != 0) { + ESP_LOGD(TAG, "have test bin"); + if (false == flash_encrypt_write(bs->test.offset, bs->test.size)) { + ESP_LOGE(TAG, "encrypt test bin error"); + return false; + } + } + /* encrypt write ota bin */ - for (i = 0;i<16;i++) { - if(bs->ota[i].offset != 0x00) { - ESP_LOGD(TAG, "have ota[%d] bin",i); - boot_cache_redirect(bs->ota[i].offset, bs->ota[i].size); - bin_len = get_bin_len((uint32_t)MEM_CACHE(bs->ota[i].offset&0xffff)); - if(bin_len != 0) { - if (false == flash_encrypt_write(bs->ota[i].offset, bin_len)) { - ESP_LOGE(TAG, "encrypt ota bin error"); - return false; - } - } - } - } + for (int i = 0; i < 16; i++) { + if(bs->ota[i].offset != 0 && bs->ota[i].size != 0) { + ESP_LOGD(TAG, "have ota[%d] bin",i); + if (false == flash_encrypt_write(bs->ota[i].offset, bs->ota[i].size)) { + ESP_LOGE(TAG, "encrypt ota bin error"); + return false; + } + } + } + /* encrypt write ota info bin */ - if (false == flash_encrypt_write(bs->ota_info.offset, 2*SPI_SEC_SIZE)) { - ESP_LOGE(TAG, "encrypt ota info error"); - return false; - } - REG_SET_FIELD(EFUSE_BLK0_WDATA0_REG, EFUSE_FLASH_CRYPT_CNT, 0x04); - REG_WRITE(EFUSE_CONF_REG, 0x5A5A); /* efuse_pgm_op_ena, force no rd/wr disable */ - REG_WRITE(EFUSE_CMD_REG, 0x02); /* efuse_pgm_cmd */ - while (REG_READ(EFUSE_CMD_REG)); /* wait for efuse_pagm_cmd=0 */ - ESP_LOGW(TAG, "burn flash_crypt_cnt"); - REG_WRITE(EFUSE_CONF_REG, 0x5AA5); /* efuse_read_op_ena, release force */ - REG_WRITE(EFUSE_CMD_REG, 0x01); /* efuse_read_cmd */ - while (REG_READ(EFUSE_CMD_REG)); /* wait for efuse_read_cmd=0 */ - return true; - } else { - ESP_LOGI(TAG, "flash already encrypted."); - return true; - } + if (false == flash_encrypt_write(bs->ota_info.offset, 2*SPI_SEC_SIZE)) { + ESP_LOGE(TAG, "encrypt ota info error"); + return false; + } + + REG_SET_FIELD(EFUSE_BLK0_WDATA0_REG, EFUSE_FLASH_CRYPT_CNT, 0x04); + REG_WRITE(EFUSE_CONF_REG, 0x5A5A); /* efuse_pgm_op_ena, force no rd/wr disable */ + REG_WRITE(EFUSE_CMD_REG, 0x02); /* efuse_pgm_cmd */ + while (REG_READ(EFUSE_CMD_REG)); /* wait for efuse_pagm_cmd=0 */ + ESP_LOGW(TAG, "burn flash_crypt_cnt"); + REG_WRITE(EFUSE_CONF_REG, 0x5AA5); /* efuse_read_op_ena, release force */ + REG_WRITE(EFUSE_CMD_REG, 0x01); /* efuse_read_cmd */ + while (REG_READ(EFUSE_CMD_REG)); /* wait for efuse_read_cmd=0 */ + return true; + } else { + ESP_LOGI(TAG, "flash already encrypted."); + return true; + } } diff --git a/components/bootloader/src/main/secure_boot.c b/components/bootloader/src/main/secure_boot.c index 070fbf24d3..2b1b8573fc 100644 --- a/components/bootloader/src/main/secure_boot.c +++ b/components/bootloader/src/main/secure_boot.c @@ -31,6 +31,8 @@ #include "sdkconfig.h" #include "bootloader_config.h" +#include "bootloader_flash.h" +#include "esp_image_format.h" static const char* TAG = "secure_boot"; @@ -40,43 +42,52 @@ static const char* TAG = "secure_boot"; * * @inputs: bool */ -static bool secure_boot_generate(uint32_t bin_len){ +static bool secure_boot_generate(uint32_t image_len){ SpiFlashOpResult spiRet; - uint16_t i; uint32_t buf[32]; - if (bin_len % 128 != 0) { - bin_len = (bin_len / 128 + 1) * 128; - } + const void *image; + + if (image_len % 128 != 0) { + image_len = (image_len / 128 + 1) * 128; + } ets_secure_boot_start(); ets_secure_boot_rd_iv(buf); ets_secure_boot_hash(NULL); Cache_Read_Disable(0); - /* iv stored in sec 0 */ + /* iv stored in sec 0 */ spiRet = SPIEraseSector(0); if (spiRet != SPI_FLASH_RESULT_OK) - { - ESP_LOGE(TAG, SPI_ERROR_LOG); - return false; - } - /* write iv to flash, 0x0000, 128 bytes (1024 bits) */ - spiRet = SPIWrite(0, buf, 128); - if (spiRet != SPI_FLASH_RESULT_OK) { ESP_LOGE(TAG, SPI_ERROR_LOG); return false; } - ESP_LOGD(TAG, "write iv to flash."); Cache_Read_Enable(0); - /* read 4K code image from flash, for test */ - for (i = 0; i < bin_len; i+=128) { - ets_secure_boot_hash((uint32_t *)(0x3f400000 + 0x1000 + i)); + + /* write iv to flash, 0x0000, 128 bytes (1024 bits) */ + ESP_LOGD(TAG, "write iv to flash."); + spiRet = SPIWrite(0, buf, 128); + if (spiRet != SPI_FLASH_RESULT_OK) + { + ESP_LOGE(TAG, SPI_ERROR_LOG); + return false; } + /* generate digest from image contents */ + image = bootloader_mmap(0x1000, image_len); + if (!image) { + ESP_LOGE(TAG, "bootloader_mmap(0x1000, 0x%x) failed", image_len); + return false; + } + for (int i = 0; i < image_len; i+=128) { + ets_secure_boot_hash(image + i/sizeof(void *)); + } + bootloader_unmap(image); + ets_secure_boot_obtain(); ets_secure_boot_rd_abstract(buf); ets_secure_boot_finish(); - Cache_Read_Disable(0); - /* write abstract to flash, 0x0080, 64 bytes (512 bits) */ + + ESP_LOGD(TAG, "write abstract to flash."); spiRet = SPIWrite(0x80, buf, 64); if (spiRet != SPI_FLASH_RESULT_OK) { ESP_LOGE(TAG, SPI_ERROR_LOG); @@ -99,9 +110,9 @@ static inline void burn_efuses() } /** - * @function : secure_boot_generate_bootloader_digest + * @brief Enable secure boot if it is not already enabled. * - * @description: Called if the secure boot flag is set on the + * Called if the secure boot flag is set on the * bootloader image in flash. If secure boot is not yet enabled for * bootloader, this will generate the secure boot digest and enable * secure boot by blowing the EFUSE_RD_ABS_DONE_0 efuse. @@ -110,24 +121,21 @@ static inline void burn_efuses() * ROM bootloader does this.) * * @return true if secure boot is enabled (either was already enabled, - * or is freshly enabled as a result of calling this function.) + * or is freshly enabled as a result of calling this function.) false + * implies an error occured (possibly secure boot is part-enabled.) */ bool secure_boot_generate_bootloader_digest(void) { - uint32_t bin_len = 0; + esp_err_t err; + uint32_t image_len = 0; if (REG_READ(EFUSE_BLK0_RDATA6_REG) & EFUSE_RD_ABS_DONE_0) { ESP_LOGI(TAG, "bootloader secure boot is already enabled, continuing.."); return true; } - boot_cache_redirect( 0, 64*1024); - bin_len = get_bin_len((uint32_t)MEM_CACHE(0x1000)); - if (bin_len == 0) { - ESP_LOGE(TAG, "Invalid bootloader image length zero."); - return false; - } - if (bin_len > 0x100000) { - ESP_LOGE(TAG, "Invalid bootloader image length %x", bin_len); + err = esp_image_basic_verify(0x1000, &image_len); + if (err != ESP_OK) { + ESP_LOGE(TAG, "bootloader image appears invalid! error %d", err); return false; } @@ -168,7 +176,7 @@ bool secure_boot_generate_bootloader_digest(void) { } ESP_LOGI(TAG, "Generating secure boot digest..."); - if (false == secure_boot_generate(bin_len)){ + if (false == secure_boot_generate(image_len)){ ESP_LOGE(TAG, "secure boot generation failed"); return false; } diff --git a/components/bootloader_support/README.rst b/components/bootloader_support/README.rst new file mode 100644 index 0000000000..54ac861c9b --- /dev/null +++ b/components/bootloader_support/README.rst @@ -0,0 +1,9 @@ +Bootloader Support Component +============================ + +Overview +-------- + +"Bootloader support" contains APIs which are used by the bootloader but are also needed for the main app. + +Code in this component needs to be aware of being executed in a bootloader environment (no RTOS available, BOOTLOADER_BUILD macro set) or in an esp-idf app environment (RTOS running, need locking support.) diff --git a/components/bootloader_support/component.mk b/components/bootloader_support/component.mk new file mode 100755 index 0000000000..2988fe287e --- /dev/null +++ b/components/bootloader_support/component.mk @@ -0,0 +1,11 @@ +COMPONENT_ADD_INCLUDEDIRS := include +COMPONENT_PRIV_INCLUDEDIRS := include_priv + +ifdef IS_BOOTLOADER_BUILD +# share "private" headers with the bootloader component +COMPONENT_ADD_INCLUDEDIRS += include_priv +endif + +COMPONENT_SRCDIRS := src + +include $(IDF_PATH)/make/component_common.mk diff --git a/components/bootloader_support/include/esp_image_format.h b/components/bootloader_support/include/esp_image_format.h new file mode 100644 index 0000000000..a8b1739d73 --- /dev/null +++ b/components/bootloader_support/include/esp_image_format.h @@ -0,0 +1,133 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#ifndef __ESP32_IMAGE_FORMAT_H +#define __ESP32_IMAGE_FORMAT_H + +#include +#include + +#define ESP_ERR_IMAGE_BASE 0x2000 +#define ESP_ERR_IMAGE_FLASH_FAIL (ESP_ERR_IMAGE_BASE + 1) +#define ESP_ERR_IMAGE_INVALID (ESP_ERR_IMAGE_BASE + 2) + +/* Support for app/bootloader image parsing + Can be compiled as part of app or bootloader code. +*/ + +/* SPI flash mode, used in esp_image_header_t */ +typedef enum { + ESP_IMAGE_SPI_MODE_QIO, + ESP_IMAGE_SPI_MODE_QOUT, + ESP_IMAGE_SPI_MODE_DIO, + ESP_IMAGE_SPI_MODE_DOUT, + ESP_IMAGE_SPI_MODE_FAST_READ, + ESP_IMAGE_SPI_MODE_SLOW_READ +} esp_image_spi_mode_t; + +/* SPI flash clock frequency */ +enum { + ESP_IMAGE_SPI_SPEED_40M, + ESP_IMAGE_SPI_SPEED_26M, + ESP_IMAGE_SPI_SPEED_20M, + ESP_IMAGE_SPI_SPEED_80M = 0xF +} esp_image_spi_freq_t; + +/* Supported SPI flash sizes */ +typedef enum { + ESP_IMAGE_FLASH_SIZE_1MB = 0, + ESP_IMAGE_FLASH_SIZE_2MB, + ESP_IMAGE_FLASH_SIZE_4MB, + ESP_IMAGE_FLASH_SIZE_8MB, + ESP_IMAGE_FLASH_SIZE_16MB, + ESP_IMAGE_FLASH_SIZE_MAX +} esp_image_flash_size_t; + +#define ESP_IMAGE_HEADER_MAGIC 0xE9 + +/* Main header of binary image */ +typedef struct { + uint8_t magic; + uint8_t segment_count; + uint8_t spi_mode; /* flash read mode (esp_image_spi_mode_t as uint8_t) */ + uint8_t spi_speed: 4; /* flash frequency (esp_image_spi_freq_t as uint8_t) */ + uint8_t spi_size: 4; /* flash chip size (esp_image_flash_size_t as uint8_t) */ + uint32_t entry_addr; + uint8_t encrypt_flag; /* encrypt flag */ + uint8_t secure_boot_flag; /* secure boot flag */ + uint8_t extra_header[14]; /* ESP32 additional header, unused by second bootloader */ +} esp_image_header_t; + +/* Header of binary image segment */ +typedef struct { + uint32_t load_addr; + uint32_t data_len; +} esp_image_segment_header_t; + + +/** + * @brief Read an ESP image header from flash. + * + * @param src_addr Address in flash to load image header. Must be 4 byte aligned. + * @param[out] image_header Pointer to an esp_image_header_t struture to be filled with data. If the function fails, contents are undefined. + * + * @return ESP_OK if image header was loaded, ESP_ERR_IMAGE_FLASH_FAIL + * if a SPI flash error occurs, ESP_ERR_IMAGE_INVALID if the image header + * appears invalid. + */ +esp_err_t esp_image_load_header(uint32_t src_addr, esp_image_header_t *image_header); + +/** + * @brief Read the segment header and data offset of a segment in the image. + * + * @param index Index of the segment to load information for. + * @param src_addr Base address in flash of the image. + * @param[in] image_header Pointer to the flash image header, already loaded by @ref esp_image_load_header(). + * @param[out] segment_header Pointer to a segment header structure to be filled with data. If the function fails, contents are undefined. + * @param[out] segment_data_offset Pointer to the data offset of the segment. + * + * @return ESP_OK if segment_header & segment_data_offset were loaded successfully, ESP_ERR_IMAGE_FLASH_FAIL if a SPI flash error occurs, ESP_ERR_IMAGE_INVALID if the image header appears invalid, ESP_ERR_INVALID_ARG if the index is invalid. + */ +esp_err_t esp_image_load_segment_header(uint8_t index, uint32_t src_addr, const esp_image_header_t *image_header, esp_image_segment_header_t *segment_header, uint32_t *segment_data_offset); + + +/** + * @brief Return length of an image in flash. Non-cryptographically validates image integrity in the process. + * + * If the image has a secure boot signature appended, the signature is not checked and this length is not included in the result. + * + * Image validation checks: + * - Magic byte + * - No single section longer than 16MB + * - Total image no longer than 16MB + * - 8 bit image checksum is valid + * + * @param src_addr Offset of the start of the image in flash. Must be 4 byte aligned. + * @param[out] length Length of the image, set to a value if the image is valid. Can be null. + * + * @return ESP_OK if image is valid, ESP_FAIL or ESP_ERR_IMAGE_INVALID on errors. + * + */ +esp_err_t esp_image_basic_verify(uint32_t src_addr, uint32_t *length); + + +typedef struct { + uint32_t drom_addr; + uint32_t drom_load_addr; + uint32_t drom_size; + uint32_t irom_addr; + uint32_t irom_load_addr; + uint32_t irom_size; +} esp_image_flash_mapping_t; + +#endif diff --git a/components/bootloader_support/include/esp_secureboot.h b/components/bootloader_support/include/esp_secureboot.h new file mode 100644 index 0000000000..b0097df8a6 --- /dev/null +++ b/components/bootloader_support/include/esp_secureboot.h @@ -0,0 +1,51 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#ifndef __ESP32_SECUREBOOT_H +#define __ESP32_SECUREBOOT_H + +#include +#include + +/* Support functions for secure boot features. + + Can be compiled as part of app or bootloader code. +*/ + +/** @brief Is secure boot currently enabled in hardware? + * + * Secure boot is enabled if the ABS_DONE_0 efuse is blown. This means + * that the ROM bootloader code will only boot a verified secure + * bootloader digest from now on. + * + * @return true if secure boot is enabled. + */ +bool esp_secure_boot_enabled(void); + + +/** @brief Enable secure boot if it isw not already enabled. + * + * @important If this function succeeds, secure boot is permanentl + * enabled on the chip via efuse. + * + * This function is intended to be called from bootloader code. + * + * @return ESP_ERR_INVALID_STATE if efuse state doesn't allow + * secure boot to be enabled cleanly. ESP_OK if secure boot + * is enabled on this chip from now on. + */ +esp_err_t esp_secure_boot_enable(void); + + + +#endif diff --git a/components/bootloader_support/include_priv/bootloader_flash.h b/components/bootloader_support/include_priv/bootloader_flash.h new file mode 100644 index 0000000000..d70ec22d56 --- /dev/null +++ b/components/bootloader_support/include_priv/bootloader_flash.h @@ -0,0 +1,69 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#ifndef __BOOTLOADER_FLASH_H +#define __BOOTLOADER_FLASH_H + +#include +#include +#include +#include + +/* Provide a Flash API for bootloader_support code, + that can be used from bootloader or app code. + + This header is available to source code in the bootloader & + bootloader_support components only. +*/ + +/** + * @brief Map a region of flash to data memory + * + * @important In bootloader code, only one region can be bootloader_mmaped at once. The previous region must be bootloader_unmapped before another region is mapped. + * + * @important In app code, these functions are not thread safe. + * + * Call bootloader_unmap once for each successful call to bootloader_mmap. + * + * In esp-idf app, this function maps directly to spi_flash_mmap. + * + * @param offset - Starting flash offset to map to memory. + * @param length - Length of data to map. + * + * @return Pointer to mapped data memory (at src_addr), or NULL + * if an allocation error occured. + */ +const void *bootloader_mmap(uint32_t src_addr, uint32_t size); + + +/** + * @brief Unmap a previously mapped region of flash + * + * Call bootloader_unmap once for each successful call to bootloader_mmap. + */ +void bootloader_unmap(const void *mapping); + +/** + * @brief Read data from Flash. + * + * @note Both src and dest have to be 4-byte aligned. + * + * @param src source address of the data in Flash. + * @param dest pointer to the destination buffer + * @param size length of data + * + * @return esp_err_t + */ +esp_err_t bootloader_flash_read(size_t src_addr, void *dest, size_t size); + +#endif diff --git a/components/bootloader_support/src/bootloader_flash.c b/components/bootloader_support/src/bootloader_flash.c new file mode 100644 index 0000000000..a50cd157e9 --- /dev/null +++ b/components/bootloader_support/src/bootloader_flash.c @@ -0,0 +1,122 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include + +#include +#include +#include /* including in bootloader for error values */ + +#ifndef BOOTLOADER_BUILD +/* Normal app version maps to esp_spi_flash.h operations... + */ +static const char *TAG = "bootloader_mmap"; + +static spi_flash_mmap_memory_t map; + +const void *bootloader_mmap(uint32_t src_addr, uint32_t size) +{ + if (map) { + ESP_LOGE(TAG, "tried to bootloader_mmap twice"); + return NULL; /* existing mapping in use... */ + } + const void *result = NULL; + esp_err_t err = spi_flash_mmap(src_addr, size, SPI_FLASH_MMAP_DATA, &result, &map); + if (err != ESP_OK) { + result = NULL; + } + return result; +} + +void bootloader_unmap(const void *mapping) +{ + if(mapping && map) { + spi_flash_munmap(map); + } + map = 0; +} + +esp_err_t bootloader_flash_read(size_t src, void *dest, size_t size) +{ + return spi_flash_read(src, dest, size); +} + +#else +/* Bootloader version, uses ROM functions only */ +#include +#include + +static const char *TAG = "bootloader_flash"; + +static bool mapped; + +const void *bootloader_mmap(uint32_t src_addr, uint32_t size) +{ + if (mapped) { + ESP_LOGE(TAG, "tried to bootloader_mmap twice"); + return NULL; /* can't map twice */ + } + + uint32_t src_addr_aligned = src_addr & 0xffff0000; + uint32_t count = (size + 0xffff) / 0x10000; + Cache_Read_Disable(0); + Cache_Flush(0); + ESP_LOGD(TAG, "mmu set paddr=%08x count=%d", src_addr_aligned, count ); + cache_flash_mmu_set( 0, 0, 0x3f400000, src_addr_aligned, 64, count ); + Cache_Read_Enable( 0 ); + + mapped = true; + + return (void *)(0x3f400000 + (src_addr - src_addr_aligned)); +} + +void bootloader_unmap(const void *mapping) +{ + if (mapped) { + /* Full MMU reset */ + Cache_Read_Disable(0); + Cache_Flush(0); + mmu_init(0); + mapped = false; + } +} + +esp_err_t bootloader_flash_read(size_t src_addr, void *dest, size_t size) +{ + if(src_addr & 3) { + ESP_LOGE(TAG, "bootloader_flash_read src_addr not 4-byte aligned"); + return ESP_FAIL; + } + if((intptr_t)dest & 3) { + ESP_LOGE(TAG, "bootloader_flash_read dest not 4-byte aligned"); + return ESP_FAIL; + } + + Cache_Read_Disable(0); + Cache_Flush(0); + SpiFlashOpResult r = SPIRead(src_addr, dest, size); + Cache_Read_Enable(0); + + switch(r) { + case SPI_FLASH_RESULT_OK: + return ESP_OK; + case SPI_FLASH_RESULT_ERR: + return ESP_ERR_FLASH_OP_FAIL; + case SPI_FLASH_RESULT_TIMEOUT: + return ESP_ERR_FLASH_OP_TIMEOUT; + default: + return ESP_FAIL; + } +} + +#endif diff --git a/components/bootloader_support/src/esp_image_format.c b/components/bootloader_support/src/esp_image_format.c new file mode 100644 index 0000000000..ad3cd33f13 --- /dev/null +++ b/components/bootloader_support/src/esp_image_format.c @@ -0,0 +1,155 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include + +#include +#include +#include + +const static char *TAG = "esp_image"; + +#define SIXTEEN_MB 0x1000000 +#define ESP_ROM_CHECKSUM_INITIAL 0xEF + +esp_err_t esp_image_load_header(uint32_t src_addr, esp_image_header_t *image_header) +{ + esp_err_t err; + ESP_LOGD(TAG, "reading image header @ 0x%x", src_addr); + + err = bootloader_flash_read(src_addr, image_header, sizeof(esp_image_header_t)); + + if (err == ESP_OK) { + if (image_header->magic != ESP_IMAGE_HEADER_MAGIC) { + ESP_LOGE(TAG, "image at 0x%x has invalid magic byte", src_addr); + err = ESP_ERR_IMAGE_INVALID; + } + if (image_header->spi_mode > ESP_IMAGE_SPI_MODE_SLOW_READ) { + ESP_LOGW(TAG, "image at 0x%x has invalid SPI mode %d", src_addr, image_header->spi_mode); + } + if (image_header->spi_speed > ESP_IMAGE_SPI_SPEED_80M) { + ESP_LOGW(TAG, "image at 0x%x has invalid SPI speed %d", src_addr, image_header->spi_speed); + } + if (image_header->spi_size > ESP_IMAGE_FLASH_SIZE_MAX) { + ESP_LOGW(TAG, "image at 0x%x has invalid SPI size %d", src_addr, image_header->spi_size); + } + } + + if (err != ESP_OK) { + bzero(image_header, sizeof(esp_image_header_t)); + } + return err; +} + +esp_err_t esp_image_load_segment_header(uint8_t index, uint32_t src_addr, const esp_image_header_t *image_header, esp_image_segment_header_t *segment_header, uint32_t *segment_data_offset) +{ + esp_err_t err = ESP_OK; + uint32_t next_addr = src_addr + sizeof(esp_image_header_t); + + if(index >= image_header->segment_count) { + ESP_LOGE(TAG, "index %d higher than segment count %d", index, image_header->segment_count); + return ESP_ERR_INVALID_ARG; + } + + for(int i = 0; i <= index && err == ESP_OK; i++) { + err = bootloader_flash_read(next_addr, segment_header, sizeof(esp_image_segment_header_t)); + if (err == ESP_OK) { + if ((segment_header->data_len & 3) != 0 + || segment_header->data_len >= SIXTEEN_MB) { + ESP_LOGE(TAG, "invalid segment length 0x%x", segment_header->data_len); + err = ESP_ERR_IMAGE_INVALID; + } + next_addr += sizeof(esp_image_segment_header_t); + *segment_data_offset = next_addr; + next_addr += segment_header->data_len; + } + } + + if (err != ESP_OK) { + *segment_data_offset = 0; + bzero(segment_header, sizeof(esp_image_segment_header_t)); + } + + return err; +} + +esp_err_t esp_image_basic_verify(uint32_t src_addr, uint32_t *p_length) +{ + esp_err_t err; + uint8_t buf[16]; + uint8_t checksum = ESP_ROM_CHECKSUM_INITIAL; + esp_image_header_t image_header; + esp_image_segment_header_t segment_header = { 0 }; + uint32_t segment_data_offs = 0; + const uint8_t *segment_data; + uint32_t end_addr; + uint32_t length; + + if (p_length != NULL) { + *p_length = 0; + } + + err = esp_image_load_header(src_addr, &image_header); + if (err != ESP_OK) { + return err; + } + + ESP_LOGD(TAG, "reading %d image segments", image_header.segment_count); + + /* Checksum each segment's data */ + for (int i = 0; i < image_header.segment_count; i++) { + err = esp_image_load_segment_header(i, src_addr, &image_header, + &segment_header, &segment_data_offs); + if (err != ESP_OK) { + return err; + } + + segment_data = bootloader_mmap(segment_data_offs, segment_header.data_len); + if (segment_data == NULL) { + ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", segment_data_offs, segment_header.data_len); + return ESP_FAIL; + } + for(int i = 0; i < segment_header.data_len; i++) { + checksum ^= segment_data[i]; + } + bootloader_unmap(segment_data); + } + + /* End of image, verify checksum */ + end_addr = segment_data_offs + segment_header.data_len; + + if (end_addr < src_addr) { + ESP_LOGE(TAG, "image offset has wrapped"); + return ESP_ERR_IMAGE_INVALID; + } + + length = end_addr - src_addr; + if (length >= SIXTEEN_MB) { + ESP_LOGE(TAG, "invalid total length 0x%x", length); + return ESP_ERR_IMAGE_INVALID; + } + + /* image padded to next full 16 byte block, with checksum byte at very end */ + length += 15 - (length % 16); + bootloader_flash_read(src_addr + length - 16, buf, 16); + if (checksum != buf[15]) { + ESP_LOGE(TAG, "checksum failed. Calculated 0x%x read 0x%x", + checksum, buf[15]); + return ESP_ERR_IMAGE_INVALID; + } + + if (p_length != NULL) { + *p_length = length; + } + return ESP_OK; +} diff --git a/components/bootloader_support/src/secureboot.c b/components/bootloader_support/src/secureboot.c new file mode 100644 index 0000000000..e55c1f33fa --- /dev/null +++ b/components/bootloader_support/src/secureboot.c @@ -0,0 +1,7 @@ +#include +#include + +#include "esp_log.h" + + + diff --git a/components/esp32/include/esp_flash_data_types.h b/components/esp32/include/esp_flash_data_types.h index 4bf886c842..ce4acb7bc9 100644 --- a/components/esp32/include/esp_flash_data_types.h +++ b/components/esp32/include/esp_flash_data_types.h @@ -24,54 +24,6 @@ extern "C" #define ESP_PARTITION_TABLE_ADDR 0x4000 #define ESP_PARTITION_MAGIC 0x50AA -/* SPI flash mode, used in esp_image_header_t */ -typedef enum { - ESP_IMAGE_SPI_MODE_QIO, - ESP_IMAGE_SPI_MODE_QOUT, - ESP_IMAGE_SPI_MODE_DIO, - ESP_IMAGE_SPI_MODE_DOUT, - ESP_IMAGE_SPI_MODE_FAST_READ, - ESP_IMAGE_SPI_MODE_SLOW_READ -} esp_image_spi_mode_t; - -/* SPI flash clock frequency */ -enum { - ESP_IMAGE_SPI_SPEED_40M, - ESP_IMAGE_SPI_SPEED_26M, - ESP_IMAGE_SPI_SPEED_20M, - ESP_IMAGE_SPI_SPEED_80M = 0xF -} esp_image_spi_freq_t; - -/* Supported SPI flash sizes */ -typedef enum { - ESP_IMAGE_FLASH_SIZE_1MB = 0, - ESP_IMAGE_FLASH_SIZE_2MB, - ESP_IMAGE_FLASH_SIZE_4MB, - ESP_IMAGE_FLASH_SIZE_8MB, - ESP_IMAGE_FLASH_SIZE_16MB, - ESP_IMAGE_FLASH_SIZE_MAX -} esp_image_flash_size_t; - -/* Main header of binary image */ -typedef struct { - uint8_t magic; - uint8_t blocks; - uint8_t spi_mode; /* flash read mode (esp_image_spi_mode_t as uint8_t) */ - uint8_t spi_speed: 4; /* flash frequency (esp_image_spi_freq_t as uint8_t) */ - uint8_t spi_size: 4; /* flash chip size (esp_image_flash_size_t as uint8_t) */ - uint32_t entry_addr; - uint8_t encrypt_flag; /* encrypt flag */ - uint8_t secure_boot_flag; /* secure boot flag */ - uint8_t extra_header[14]; /* ESP32 additional header, unused by second bootloader */ -} esp_image_header_t; - -/* Header of binary image segment */ -typedef struct { - uint32_t load_addr; - uint32_t data_len; -} esp_image_section_header_t; - - /* OTA selection structure (two copies in the OTA data partition.) Size of 32 bytes is friendly to flash encryption */ typedef struct { diff --git a/components/esp32/include/rom/secure_boot.h b/components/esp32/include/rom/secure_boot.h index cfeda08933..bd4f32ed95 100644 --- a/components/esp32/include/rom/secure_boot.h +++ b/components/esp32/include/rom/secure_boot.h @@ -25,7 +25,7 @@ void ets_secure_boot_start(void); void ets_secure_boot_finish(void); -void ets_secure_boot_hash(uint32_t *buf); +void ets_secure_boot_hash(const uint32_t *buf); void ets_secure_boot_obtain(void); diff --git a/components/log/include/esp_log.h b/components/log/include/esp_log.h index 6716f6e10f..f4b9aa2885 100644 --- a/components/log/include/esp_log.h +++ b/components/log/include/esp_log.h @@ -19,6 +19,10 @@ #include #include "sdkconfig.h" +#ifdef BOOTLOADER_BUILD +#include +#endif + #ifdef __cplusplus extern "C" { #endif diff --git a/make/project.mk b/make/project.mk index 17fb83e0d8..7e8dc46d54 100644 --- a/make/project.mk +++ b/make/project.mk @@ -100,7 +100,7 @@ COMPONENT_LDFLAGS := # # Debugging this? Replace $(shell with $(error and you'll see the full command as-run. define GetVariable -$(shell "$(MAKE)" -s --no-print-directory -C $(1) -f component.mk get_variable PROJECT_PATH=$(PROJECT_PATH) GET_VARIABLE=$(2) | sed -En "s/^$(2)=(.+)/\1/p" ) +$(shell "$(MAKE)" -s --no-print-directory -C $(1) -f component.mk get_variable PROJECT_PATH=$(PROJECT_PATH) GET_VARIABLE=$(2) IS_BOOTLOADER_BUILD=$(IS_BOOTLOADER_BUILD) | sed -En "s/^$(2)=(.+)/\1/p" ) endef COMPONENT_INCLUDES := $(abspath $(foreach comp,$(COMPONENT_PATHS_BUILDABLE),$(addprefix $(comp)/, \ From c534dedf2d2a720fa748a57ce60b823d7a8069fe Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Wed, 2 Nov 2016 17:17:28 +0800 Subject: [PATCH 243/343] newlib: implement time syscalls --- components/esp32/Kconfig | 29 +++++ components/esp32/cpu_start.c | 3 +- components/esp32/include/soc/frc_timer_reg.h | 49 ++++++++ components/esp32/include/soc/rtc_cntl_reg.h | 3 + components/esp32/include/soc/soc.h | 9 +- .../newlib/platform_include/esp_newlib.h | 8 +- components/newlib/syscall_table.c | 3 +- components/newlib/time.c | 118 +++++++++++++++++- 8 files changed, 211 insertions(+), 11 deletions(-) create mode 100644 components/esp32/include/soc/frc_timer_reg.h diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig index b5a8d2f2dd..928b190321 100644 --- a/components/esp32/Kconfig +++ b/components/esp32/Kconfig @@ -319,6 +319,35 @@ config BROWNOUT_DET_RESETDELAY before trying to restart the chip. You can set the delay here. +choice ESP32_TIME_SYSCALL + prompt "Timers used for gettimeofday function" + default ESP32_TIME_SYSCALL_USE_RTC_FRC1 + help + This setting defines which hardware timers are used to + implement 'gettimeofday' function in C library. + + - If only FRC1 timer is used, gettimeofday will provide time at + microsecond resolution. Time will not be preserved when going + into deep sleep mode. + - If both FRC1 and RTC timers are used, timekeeping will + continue in deep sleep. Time will be reported at 1 microsecond + resolution. + - If only RTC timer is used, timekeeping will continue in + deep sleep, but time will be measured at 6.(6) microsecond + resolution. Also the gettimeofday function itself may take + longer to run. + - If no timers are used, gettimeofday function return -1 and + set errno to ENOSYS. + +config ESP32_TIME_SYSCALL_USE_RTC + bool "RTC" +config ESP32_TIME_SYSCALL_USE_RTC_FRC1 + bool "RTC and FRC1" +config ESP32_TIME_SYSCALL_USE_FRC1 + bool "FRC1" +config ESP32_TIME_SYSCALL_USE_NONE + bool "None" +endchoice endmenu diff --git a/components/esp32/cpu_start.c b/components/esp32/cpu_start.c index 8d56e2c12d..c82c528597 100644 --- a/components/esp32/cpu_start.c +++ b/components/esp32/cpu_start.c @@ -169,7 +169,8 @@ void start_cpu0_default(void) #if CONFIG_TASK_WDT esp_task_wdt_init(); #endif - esp_setup_syscalls(); + esp_setup_syscall_table(); + esp_setup_time_syscalls(); esp_vfs_dev_uart_register(); esp_reent_init(_GLOBAL_REENT); const char* default_uart_dev = "/dev/uart/0"; diff --git a/components/esp32/include/soc/frc_timer_reg.h b/components/esp32/include/soc/frc_timer_reg.h new file mode 100644 index 0000000000..24b942c0bb --- /dev/null +++ b/components/esp32/include/soc/frc_timer_reg.h @@ -0,0 +1,49 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef _SOC_FRC_TIMER_REG_H_ +#define _SOC_FRC_TIMER_REG_H_ + +#include "soc.h" + +/** + * These are the register definitions for "legacy" timers + */ + +#define REG_FRC_TIMER_BASE(i) (DR_REG_FRC_TIMER_BASE + i*0x20) + +#define FRC_TIMER_LOAD_REG(i) (REG_FRC_TIMER_BASE(i) + 0x0) // timer load value (23 bit for i==0, 32 bit for i==1) +#define FRC_TIMER_LOAD_VALUE(i) ((i == 0)?0x007FFFFF:0xffffffff) +#define FRC_TIMER_LOAD_VALUE_S 0 + +#define FRC_TIMER_COUNT_REG(i) (REG_FRC_TIMER_BASE(i) + 0x4) // timer count value (23 bit for i==0, 32 bit for i==1) +#define FRC_TIMER_COUNT ((i == 0)?0x007FFFFF:0xffffffff) +#define FRC_TIMER_COUNT_S 0 + +#define FRC_TIMER_CTRL_REG(i) (REG_FRC_TIMER_BASE(i) + 0x8) +#define FRC_TIMER_INT_ENABLE (BIT(8)) // enable interrupt +#define FRC_TIMER_ENABLE (BIT(7)) // enable timer +#define FRC_TIMER_AUTOLOAD (BIT(6)) // enable autoload +#define FRC_TIMER_PRESCALER 0x00000007 // 0: divide by 1, 2: divide by 16, 4: divide by 256 +#define FRC_TIMER_PRESCALER_S 1 +#define FRC_TIMER_EDGE_INT (BIT(0)) // 0: level, 1: edge + +#define FRC_TIMER_INT_REG(i) (REG_FRC_TIMER_BASE(i) + 0xC) +#define FRC_TIMER_INT_CLR (BIT(0)) // clear interrupt + +#define FRC_TIMER_ALARM_REG(i) (REG_FRC_TIMER_BASE(i) + 0x10) // timer alarm value; register only present for i == 1 +#define FRC_TIMER_ALARM 0xFFFFFFFF +#define FRC_TIMER_ALARM_S 0 + +#endif //_SOC_FRC_TIMER_REG_H_ diff --git a/components/esp32/include/soc/rtc_cntl_reg.h b/components/esp32/include/soc/rtc_cntl_reg.h index bb4e2afced..d99cec1864 100644 --- a/components/esp32/include/soc/rtc_cntl_reg.h +++ b/components/esp32/include/soc/rtc_cntl_reg.h @@ -239,6 +239,9 @@ #define RTC_CNTL_TIME_VALID_V 0x1 #define RTC_CNTL_TIME_VALID_S 30 +/* frequency of RTC slow clock, Hz */ +#define RTC_CTNL_SLOWCLK_FREQ 150000 + #define RTC_CNTL_TIME0_REG (DR_REG_RTCCNTL_BASE + 0x10) /* RTC_CNTL_TIME_LO : RO ;bitpos:[31:0] ;default: 32'h0 ; */ /*description: RTC timer low 32 bits*/ diff --git a/components/esp32/include/soc/soc.h b/components/esp32/include/soc/soc.h index 4ffdfb069e..8ab9f027c5 100755 --- a/components/esp32/include/soc/soc.h +++ b/components/esp32/include/soc/soc.h @@ -148,6 +148,7 @@ #define DR_REG_GPIO_SD_BASE 0x3ff44f00 #define DR_REG_FE2_BASE 0x3ff45000 #define DR_REG_FE_BASE 0x3ff46000 +#define DR_REG_FRC_TIMER_BASE 0x3ff47000 #define DR_REG_RTCCNTL_BASE 0x3ff48000 #define DR_REG_RTCIO_BASE 0x3ff48400 #define DR_REG_SARADC_BASE 0x3ff48800 @@ -281,9 +282,9 @@ * 19 2 extern level * 20 2 extern level * 21 2 extern level - * 22 3 extern edge + * 22 3 extern edge FRC1 timer * 23 3 extern level - * 24 4 extern level + * 24 4 extern level TG1_WDT * 25 4 extern level Reserved Reserved * 26 5 extern level Reserved Reserved * 27 3 extern level Reserved Reserved @@ -301,8 +302,10 @@ #define ETS_T0_WDT_INUM 3 #define ETS_WBB_INUM 4 #define ETS_TG0_T1_INUM 10 /**< use edge interrupt*/ +#define ETS_FRC1_INUM 22 +#define ETS_T1_WDT_INUM 24 -//CPU0 Intrrupt number used in ROM, should be cancelled in SDK +//CPU0 Interrupt number used in ROM, should be cancelled in SDK #define ETS_SLC_INUM 1 #define ETS_UART0_INUM 5 #define ETS_UART1_INUM 5 diff --git a/components/newlib/platform_include/esp_newlib.h b/components/newlib/platform_include/esp_newlib.h index 468f2ae34f..eac3544259 100644 --- a/components/newlib/platform_include/esp_newlib.h +++ b/components/newlib/platform_include/esp_newlib.h @@ -31,7 +31,13 @@ void esp_reent_init(struct _reent* r); * Called from the startup code, not intended to be called from application * code. */ -void esp_setup_syscalls(); +void esp_setup_syscall_table(); +/** + * Initialize hardware timer used as time source for newlib time functions. + * + * Called from the startup code, not intended to be called from application. + */ +void esp_setup_time_syscalls(); #endif //__ESP_NEWLIB_H__ diff --git a/components/newlib/syscall_table.c b/components/newlib/syscall_table.c index b6414af554..feed768172 100644 --- a/components/newlib/syscall_table.c +++ b/components/newlib/syscall_table.c @@ -24,6 +24,7 @@ #include #include "rom/libc_stubs.h" #include "esp_vfs.h" +#include "esp_newlib.h" static struct _reent s_reent; @@ -79,7 +80,7 @@ static struct syscall_stub_table s_stub_table = { ._scanf_float = &_scanf_float, }; -void esp_setup_syscalls() +void esp_setup_syscall_table() { syscall_table_ptr_pro = &s_stub_table; syscall_table_ptr_app = &s_stub_table; diff --git a/components/newlib/time.c b/components/newlib/time.c index 021b295451..83645aa4cc 100644 --- a/components/newlib/time.c +++ b/components/newlib/time.c @@ -14,22 +14,130 @@ #include #include +#include +#include #include #include #include #include #include "esp_attr.h" +#include "soc/soc.h" +#include "soc/rtc_cntl_reg.h" +#include "soc/frc_timer_reg.h" +#include "rom/ets_sys.h" +#include "freertos/FreeRTOS.h" +#include "freertos/xtensa_api.h" +#include "freertos/task.h" +#include "sdkconfig.h" +#if defined( CONFIG_ESP32_TIME_SYSCALL_USE_RTC ) || defined( CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1 ) +#define WITH_RTC 1 +#endif -clock_t _times_r(struct _reent *r, struct tms *ptms) +#if defined( CONFIG_ESP32_TIME_SYSCALL_USE_FRC1 ) || defined( CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1 ) +#define WITH_FRC1 1 +#endif + +#ifdef WITH_RTC +static uint64_t get_rtc_time_us() { - __errno_r(r) = ENOSYS; - return (clock_t) -1; + SET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_UPDATE_M); + while (GET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_VALID_M) == 0) { + ; + } + CLEAR_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_UPDATE_M); + uint64_t low = READ_PERI_REG(RTC_CNTL_TIME0_REG); + uint64_t high = READ_PERI_REG(RTC_CNTL_TIME1_REG); + uint64_t ticks = (high << 32) | low; + return ticks * 100 / (RTC_CTNL_SLOWCLK_FREQ / 10000); // scale RTC_CTNL_SLOWCLK_FREQ to avoid overflow +} +#endif // WITH_RTC + + +#ifdef WITH_FRC1 +#define FRC1_PRESCALER 16 +#define FRC1_PRESCALER_CTL 2 +#define FRC1_TICK_FREQ (APB_CLK_FREQ / FRC1_PRESCALER) +#define FRC1_TICKS_PER_US (FRC1_TICK_FREQ / 1000000) +#define FRC1_ISR_PERIOD_US (FRC_TIMER_LOAD_VALUE(0) / FRC1_TICKS_PER_US) +// Counter frequency will be APB_CLK_FREQ / 16 = 5 MHz +// 1 tick = 0.2 us +// Timer has 23 bit counter, so interrupt will fire each 1677721.6 microseconds. +// This is not a whole number, so timer will drift by 0.3 ppm due to rounding error. + +static volatile uint64_t s_microseconds = 0; + +static void IRAM_ATTR frc_timer_isr() +{ + WRITE_PERI_REG(FRC_TIMER_INT_REG(0), FRC_TIMER_INT_CLR); + s_microseconds += FRC1_ISR_PERIOD_US; } -// TODO: read time from RTC -int _gettimeofday_r(struct _reent *r, struct timeval *tv, void *tz) +#endif // WITH_FRC1 + +void esp_setup_time_syscalls() { +#if defined( WITH_FRC1 ) +#if defined( WITH_RTC ) + // initialize time from RTC clock + s_microseconds = get_rtc_time_us(); +#endif //WITH_RTC + + + // set up timer + WRITE_PERI_REG(FRC_TIMER_CTRL_REG(0), \ + FRC_TIMER_AUTOLOAD | \ + (FRC1_PRESCALER_CTL << FRC_TIMER_PRESCALER_S) | \ + FRC_TIMER_EDGE_INT); + + WRITE_PERI_REG(FRC_TIMER_LOAD_REG(0), FRC_TIMER_LOAD_VALUE(0)); + SET_PERI_REG_MASK(FRC_TIMER_CTRL_REG(0), + FRC_TIMER_ENABLE | \ + FRC_TIMER_INT_ENABLE); + intr_matrix_set(xPortGetCoreID(), ETS_TIMER1_INTR_SOURCE, ETS_FRC1_INUM); + xt_set_interrupt_handler(ETS_FRC1_INUM, &frc_timer_isr, NULL); + xt_ints_on(1 << ETS_FRC1_INUM); +#endif // WITH_FRC1 +} + +clock_t IRAM_ATTR _times_r(struct _reent *r, struct tms *ptms) +{ + clock_t t = xTaskGetTickCount() * (portTICK_PERIOD_MS * CLK_TCK / 1000); + ptms->tms_cstime = t; + ptms->tms_cutime = 0; + ptms->tms_stime = t; + ptms->tms_utime = 0; + struct timeval tv = {0, 0}; + _gettimeofday_r(r, &tv, NULL); + return (clock_t) tv.tv_sec; +} + +int IRAM_ATTR _gettimeofday_r(struct _reent *r, struct timeval *tv, void *tz) +{ + (void) tz; +#ifdef WITH_FRC1 + uint32_t timer_ticks_before = READ_PERI_REG(FRC_TIMER_COUNT_REG(0)); + uint64_t microseconds = s_microseconds; + uint32_t timer_ticks_after = READ_PERI_REG(FRC_TIMER_COUNT_REG(0)); + if (timer_ticks_after > timer_ticks_before) { + // overflow happened at some point between getting + // timer_ticks_before and timer_ticks_after + // microseconds value is ambiguous, get a new one + microseconds = s_microseconds; + } + microseconds += (FRC_TIMER_LOAD_VALUE(0) - timer_ticks_after) / FRC1_TICKS_PER_US; +#elif defined(WITH_RTC) + uint64_t microseconds = get_rtc_time_us(); +#endif + +#if defined( WITH_FRC1 ) || defined( WITH_RTC ) + if (tv) { + tv->tv_sec = microseconds / 1000000; + tv->tv_usec = microseconds % 1000000; + } + return 0; +#else __errno_r(r) = ENOSYS; return -1; +#endif // defined( WITH_FRC1 ) || defined( WITH_RTC ) } From fdff6b2b012ac29f6aa6218ebfcc37b881d8ad9c Mon Sep 17 00:00:00 2001 From: Yinling Date: Wed, 2 Nov 2016 19:08:55 +0800 Subject: [PATCH 244/343] run unit test case by case name --- .../idf_test/integration_test/TestEnvAll.yml | 6 + .../CIConfigs/UT_Function_SYS_01.yml | 2 +- components/idf_test/unit_test/TestCaseAll.yml | 103 +++++++----------- .../TestCaseScript/IDFUnitTest/UnitTest.py | 14 ++- components/idf_test/unit_test/TestEnvAll.yml | 6 + 5 files changed, 61 insertions(+), 70 deletions(-) diff --git a/components/idf_test/integration_test/TestEnvAll.yml b/components/idf_test/integration_test/TestEnvAll.yml index 6b21760150..b8a2a497c6 100644 --- a/components/idf_test/integration_test/TestEnvAll.yml +++ b/components/idf_test/integration_test/TestEnvAll.yml @@ -202,6 +202,12 @@ test environment: SSC2', additional param list: '', basic param list: '', script path: EnvBase.py, tag: SSC_T2_GPIO3, test environment detail: '[TBD] 2个ESP_8266通过UART连到PC, ESP_8266之间需要测试的Target_GPIO相连', test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 2.0, script path: EnvBase.py, tag: SSC_T2_JAP, + test environment detail: 'PC has 1 wired NIC connected to APC. + + APC control the power supply of multiple APs. + + 2 SSC target connect with PC by UART.', test script: EnvBase} - {PC OS: '', Special: N, Target Count: 2.0, script path: EnvBase.py, tag: SSC_T2_PhyMode, test environment detail: '2 SSC target connect with PC by UART. diff --git a/components/idf_test/unit_test/CIConfigs/UT_Function_SYS_01.yml b/components/idf_test/unit_test/CIConfigs/UT_Function_SYS_01.yml index 86e191cedf..c3561aa0c5 100644 --- a/components/idf_test/unit_test/CIConfigs/UT_Function_SYS_01.yml +++ b/components/idf_test/unit_test/CIConfigs/UT_Function_SYS_01.yml @@ -2,7 +2,7 @@ Config: {execute count: 1, execute order: in order} DUT: [UT1] Filter: - Add: - ID: [SYS_OS_0101, SYS_OS_0102, SYS_MISC_0103, SYS_MISC_0102, SYS_MISC_0105, SYS_MISC_0104, + ID: [SYS_OS_0102, SYS_MISC_0103, SYS_MISC_0102, SYS_MISC_0105, SYS_MISC_0104, SYS_MISC_0107, SYS_MISC_0106, SYS_MISC_0109, SYS_MISC_0108, SYS_MISC_0112, SYS_MISC_0113, SYS_MISC_0110, SYS_MISC_0111, SYS_MISC_0115, SYS_LIB_0103, SYS_LIB_0102, SYS_LIB_0101, SYS_LIB_0106, SYS_LIB_0105, SYS_LIB_0104] diff --git a/components/idf_test/unit_test/TestCaseAll.yml b/components/idf_test/unit_test/TestCaseAll.yml index 8732296bfc..6f974e0bf5 100644 --- a/components/idf_test/unit_test/TestCaseAll.yml +++ b/components/idf_test/unit_test/TestCaseAll.yml @@ -2,12 +2,12 @@ test cases: - CI ready: 'Yes' ID: SYS_LIB_0101 SDK: ESP32_IDF - Test App: testje + Test App: UT auto test: 'Yes' category: Function cmd set: - IDFUnitTest/UnitTest - - - test_case = "12" + - - test_case = "check if ROM is used for functions" - [dummy] comment: check if ROM is used for functions execution time: 0 @@ -25,12 +25,12 @@ test cases: - CI ready: 'Yes' ID: SYS_LIB_0102 SDK: ESP32_IDF - Test App: testje + Test App: UT auto test: 'Yes' category: Function cmd set: - IDFUnitTest/UnitTest - - - test_case = "13" + - - test_case = "test time functions" - [dummy] comment: test time functions execution time: 0 @@ -48,12 +48,12 @@ test cases: - CI ready: 'Yes' ID: SYS_LIB_0103 SDK: ESP32_IDF - Test App: testje + Test App: UT auto test: 'Yes' category: Function cmd set: - IDFUnitTest/UnitTest - - - test_case = "14" + - - test_case = "test sscanf function" - [dummy] comment: test sscanf function execution time: 0 @@ -71,12 +71,12 @@ test cases: - CI ready: 'Yes' ID: SYS_LIB_0104 SDK: ESP32_IDF - Test App: testje + Test App: UT auto test: 'Yes' category: Function cmd set: - IDFUnitTest/UnitTest - - - test_case = "15" + - - test_case = "test sprintf function" - [dummy] comment: test sprintf function execution time: 0 @@ -94,12 +94,12 @@ test cases: - CI ready: 'Yes' ID: SYS_LIB_0105 SDK: ESP32_IDF - Test App: testje + Test App: UT auto test: 'Yes' category: Function cmd set: - IDFUnitTest/UnitTest - - - test_case = "16" + - - test_case = "test atoX functions" - [dummy] comment: test atoX functions execution time: 0 @@ -117,12 +117,12 @@ test cases: - CI ready: 'Yes' ID: SYS_LIB_0106 SDK: ESP32_IDF - Test App: testje + Test App: UT auto test: 'Yes' category: Function cmd set: - IDFUnitTest/UnitTest - - - test_case = "17" + - - test_case = "test ctype functions" - [dummy] comment: test ctype functions execution time: 0 @@ -140,12 +140,12 @@ test cases: - CI ready: 'Yes' ID: SYS_MISC_0102 SDK: ESP32_IDF - Test App: testje + Test App: UT auto test: 'Yes' category: Function cmd set: - IDFUnitTest/UnitTest - - - test_case = "21" + - - test_case = "mbedtls MPI self-tests" - [dummy] comment: mbedtls MPI self-tests execution time: 0 @@ -163,12 +163,12 @@ test cases: - CI ready: 'Yes' ID: SYS_MISC_0103 SDK: ESP32_IDF - Test App: testje + Test App: UT auto test: 'Yes' category: Function cmd set: - IDFUnitTest/UnitTest - - - test_case = "25" + - - test_case = "test AES thread safety" - [dummy] comment: test AES thread safety execution time: 0 @@ -186,12 +186,12 @@ test cases: - CI ready: 'Yes' ID: SYS_MISC_0104 SDK: ESP32_IDF - Test App: testje + Test App: UT auto test: 'Yes' category: Function cmd set: - IDFUnitTest/UnitTest - - - test_case = "26" + - - test_case = "test AES acceleration" - [dummy] comment: test AES acceleration execution time: 0 @@ -209,12 +209,12 @@ test cases: - CI ready: 'Yes' ID: SYS_MISC_0105 SDK: ESP32_IDF - Test App: testje + Test App: UT auto test: 'Yes' category: Function cmd set: - IDFUnitTest/UnitTest - - - test_case = "27" + - - test_case = "test SHA thread safety" - [dummy] comment: test SHA thread safety execution time: 0 @@ -232,12 +232,12 @@ test cases: - CI ready: 'Yes' ID: SYS_MISC_0106 SDK: ESP32_IDF - Test App: testje + Test App: UT auto test: 'Yes' category: Function cmd set: - IDFUnitTest/UnitTest - - - test_case = "33" + - - test_case = "context switch saves FP registers" - [dummy] comment: context switch saves FP registers execution time: 0 @@ -255,12 +255,12 @@ test cases: - CI ready: 'Yes' ID: SYS_MISC_0107 SDK: ESP32_IDF - Test App: testje + Test App: UT auto test: 'Yes' category: Function cmd set: - IDFUnitTest/UnitTest - - - test_case = "34" + - - test_case = "test FP sqrt" - [dummy] comment: test FP sqrt execution time: 0 @@ -278,12 +278,12 @@ test cases: - CI ready: 'Yes' ID: SYS_MISC_0108 SDK: ESP32_IDF - Test App: testje + Test App: UT auto test: 'Yes' category: Function cmd set: - IDFUnitTest/UnitTest - - - test_case = "35" + - - test_case = "test FP div" - [dummy] comment: test FP div execution time: 0 @@ -301,12 +301,12 @@ test cases: - CI ready: 'Yes' ID: SYS_MISC_0109 SDK: ESP32_IDF - Test App: testje + Test App: UT auto test: 'Yes' category: Function cmd set: - IDFUnitTest/UnitTest - - - test_case = "36" + - - test_case = "test FP mul" - [dummy] comment: test FP mul execution time: 0 @@ -324,12 +324,12 @@ test cases: - CI ready: 'Yes' ID: SYS_MISC_0110 SDK: ESP32_IDF - Test App: testje + Test App: UT auto test: 'Yes' category: Function cmd set: - IDFUnitTest/UnitTest - - - test_case = "37" + - - test_case = "test FP add" - [dummy] comment: test FP add execution time: 0 @@ -347,12 +347,12 @@ test cases: - CI ready: 'Yes' ID: SYS_MISC_0111 SDK: ESP32_IDF - Test App: testje + Test App: UT auto test: 'Yes' category: Function cmd set: - IDFUnitTest/UnitTest - - - test_case = "3" + - - test_case = "Test JPEG decompression library" - [dummy] comment: Test JPEG decompression library execution time: 0 @@ -370,12 +370,12 @@ test cases: - CI ready: 'Yes' ID: SYS_MISC_0112 SDK: ESP32_IDF - Test App: testje + Test App: UT auto test: 'Yes' category: Function cmd set: - IDFUnitTest/UnitTest - - - test_case = "22" + - - test_case = "mbedtls AES self-tests" - [dummy] comment: mbedtls AES self-tests execution time: 0 @@ -393,12 +393,12 @@ test cases: - CI ready: 'Yes' ID: SYS_MISC_0113 SDK: ESP32_IDF - Test App: testje + Test App: UT auto test: 'Yes' category: Function cmd set: - IDFUnitTest/UnitTest - - - test_case = "17" + - - test_case = "mbedtls SHA self-tests" - [dummy] comment: mbedtls SHA self-tests execution time: 0 @@ -416,12 +416,12 @@ test cases: - CI ready: 'Yes' ID: SYS_MISC_0115 SDK: ESP32_IDF - Test App: testje + Test App: UT auto test: 'Yes' category: Function cmd set: - IDFUnitTest/UnitTest - - - test_case = "28" + - - test_case = "test SHA acceleration" - [dummy] comment: test SHA acceleration execution time: 0 @@ -436,38 +436,15 @@ test cases: test point 1: basic function test point 2: SHA acceleration version: v1 (2016-10-31) -- CI ready: 'Yes' - ID: SYS_OS_0101 - SDK: ESP32_IDF - Test App: testje - auto test: 'Yes' - category: Function - cmd set: - - IDFUnitTest/UnitTest - - - test_case = "31" - - [dummy] - comment: FreeRTOS Event Groups - execution time: 0 - expected result: 1. set succeed - initial condition: UTINIT1 - level: Unit - module: System - steps: 1. run freertos test - sub module: OS - summary: freertos unit test - test environment: UT_T1_1 - test point 1: basic function - test point 2: freertos - version: v1 (2016-10-26) - CI ready: 'Yes' ID: SYS_OS_0102 SDK: ESP32_IDF - Test App: testje + Test App: UT auto test: 'Yes' category: Function cmd set: - IDFUnitTest/UnitTest - - - test_case = "2" + - - test_case = "Freertos TLS delete cb" - [dummy] comment: Freertos TLS delete cb execution time: 0 diff --git a/components/idf_test/unit_test/TestCaseScript/IDFUnitTest/UnitTest.py b/components/idf_test/unit_test/TestCaseScript/IDFUnitTest/UnitTest.py index 6e7cac4109..2af4747e5d 100644 --- a/components/idf_test/unit_test/TestCaseScript/IDFUnitTest/UnitTest.py +++ b/components/idf_test/unit_test/TestCaseScript/IDFUnitTest/UnitTest.py @@ -11,7 +11,7 @@ class UnitTest(PerformanceTCBase.PerformanceTCBase): timeout=timeout, log_path=log_path) self.test_case = None - self.test_timeout = 6 + self.test_timeout = 20 # load param from excel for i in range(1, len(cmd_set)): @@ -26,12 +26,14 @@ class UnitTest(PerformanceTCBase.PerformanceTCBase): try: self.serial_write_line("UT1", self.test_case) - time.sleep(self.test_timeout) #wait for test to run before reading result - data = self.serial_read_data("UT1") - if re.search('[^0] Tests 0 F', data): #check that number of tests run != 0 and number of tests failed == 0 - self.set_result("Success") + data = "" + for _ in range(self.timeout): + time.sleep(1) #wait for test to run before reading result + data += self.serial_read_data("UT1") + if re.search('[^0] Tests 0 F', data): #check that number of tests run != 0 and number of tests failed == 0 + self.set_result("Success") else: - self.set_result("Fail") + self.set_result("Fail") except StandardError,e: NativeLog.add_exception_log(e) diff --git a/components/idf_test/unit_test/TestEnvAll.yml b/components/idf_test/unit_test/TestEnvAll.yml index 6b21760150..b8a2a497c6 100644 --- a/components/idf_test/unit_test/TestEnvAll.yml +++ b/components/idf_test/unit_test/TestEnvAll.yml @@ -202,6 +202,12 @@ test environment: SSC2', additional param list: '', basic param list: '', script path: EnvBase.py, tag: SSC_T2_GPIO3, test environment detail: '[TBD] 2个ESP_8266通过UART连到PC, ESP_8266之间需要测试的Target_GPIO相连', test script: EnvBase} +- {PC OS: '', Special: N, Target Count: 2.0, script path: EnvBase.py, tag: SSC_T2_JAP, + test environment detail: 'PC has 1 wired NIC connected to APC. + + APC control the power supply of multiple APs. + + 2 SSC target connect with PC by UART.', test script: EnvBase} - {PC OS: '', Special: N, Target Count: 2.0, script path: EnvBase.py, tag: SSC_T2_PhyMode, test environment detail: '2 SSC target connect with PC by UART. From 2e319705ecfd6e2b3c159a771911ff0968652396 Mon Sep 17 00:00:00 2001 From: Yinling Date: Wed, 2 Nov 2016 19:41:33 +0800 Subject: [PATCH 245/343] forget to break when test succeed --- .../idf_test/unit_test/TestCaseScript/IDFUnitTest/UnitTest.py | 1 + 1 file changed, 1 insertion(+) diff --git a/components/idf_test/unit_test/TestCaseScript/IDFUnitTest/UnitTest.py b/components/idf_test/unit_test/TestCaseScript/IDFUnitTest/UnitTest.py index 2af4747e5d..ab29a97f9b 100644 --- a/components/idf_test/unit_test/TestCaseScript/IDFUnitTest/UnitTest.py +++ b/components/idf_test/unit_test/TestCaseScript/IDFUnitTest/UnitTest.py @@ -32,6 +32,7 @@ class UnitTest(PerformanceTCBase.PerformanceTCBase): data += self.serial_read_data("UT1") if re.search('[^0] Tests 0 F', data): #check that number of tests run != 0 and number of tests failed == 0 self.set_result("Success") + break else: self.set_result("Fail") From c12aeb11279b9deecdd43e3259d6e52d66fe3661 Mon Sep 17 00:00:00 2001 From: He Yin Ling Date: Wed, 2 Nov 2016 20:12:43 +0800 Subject: [PATCH 246/343] add case select by name mark " before case name --- .../idf_test/unit_test/TestCaseScript/IDFUnitTest/UnitTest.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/idf_test/unit_test/TestCaseScript/IDFUnitTest/UnitTest.py b/components/idf_test/unit_test/TestCaseScript/IDFUnitTest/UnitTest.py index ab29a97f9b..3ec87d24bc 100644 --- a/components/idf_test/unit_test/TestCaseScript/IDFUnitTest/UnitTest.py +++ b/components/idf_test/unit_test/TestCaseScript/IDFUnitTest/UnitTest.py @@ -25,7 +25,8 @@ class UnitTest(PerformanceTCBase.PerformanceTCBase): self.flush_data("UT1") try: - self.serial_write_line("UT1", self.test_case) + # add case select by name mark " before case name + self.serial_write_line("UT1", "/"" + self.test_case) data = "" for _ in range(self.timeout): time.sleep(1) #wait for test to run before reading result From e56b745527a96ab41765e8bbe2316920e2d7b602 Mon Sep 17 00:00:00 2001 From: He Yin Ling Date: Wed, 2 Nov 2016 20:21:46 +0800 Subject: [PATCH 247/343] incorrect "/", should be "\" --- .../idf_test/unit_test/TestCaseScript/IDFUnitTest/UnitTest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/idf_test/unit_test/TestCaseScript/IDFUnitTest/UnitTest.py b/components/idf_test/unit_test/TestCaseScript/IDFUnitTest/UnitTest.py index 3ec87d24bc..35bb62c6d8 100644 --- a/components/idf_test/unit_test/TestCaseScript/IDFUnitTest/UnitTest.py +++ b/components/idf_test/unit_test/TestCaseScript/IDFUnitTest/UnitTest.py @@ -26,7 +26,7 @@ class UnitTest(PerformanceTCBase.PerformanceTCBase): try: # add case select by name mark " before case name - self.serial_write_line("UT1", "/"" + self.test_case) + self.serial_write_line("UT1", "\"" + self.test_case) data = "" for _ in range(self.timeout): time.sleep(1) #wait for test to run before reading result From 47910466ce3b646fcbff677f2a8035f30ae8f183 Mon Sep 17 00:00:00 2001 From: He Yin Ling Date: Wed, 2 Nov 2016 20:54:22 +0800 Subject: [PATCH 248/343] Set result "Succeed" for passed cases --- .../idf_test/unit_test/TestCaseScript/IDFUnitTest/UnitTest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/idf_test/unit_test/TestCaseScript/IDFUnitTest/UnitTest.py b/components/idf_test/unit_test/TestCaseScript/IDFUnitTest/UnitTest.py index 35bb62c6d8..bfc8edeaa9 100644 --- a/components/idf_test/unit_test/TestCaseScript/IDFUnitTest/UnitTest.py +++ b/components/idf_test/unit_test/TestCaseScript/IDFUnitTest/UnitTest.py @@ -32,7 +32,7 @@ class UnitTest(PerformanceTCBase.PerformanceTCBase): time.sleep(1) #wait for test to run before reading result data += self.serial_read_data("UT1") if re.search('[^0] Tests 0 F', data): #check that number of tests run != 0 and number of tests failed == 0 - self.set_result("Success") + self.set_result("Succeed") break else: self.set_result("Fail") From eb2c633cbf4acabbb5822a294d39458ea6c8c81f Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Thu, 3 Nov 2016 12:46:46 +0800 Subject: [PATCH 249/343] newlib: implement settimeofday, integrate LwIP SNTP, add SNTP example --- components/esp32/Kconfig | 6 +- components/lwip/Kconfig | 9 + components/lwip/include/lwip/port/lwipopts.h | 17 ++ components/newlib/time.c | 51 +++++- examples/06_sntp/Makefile | 9 + examples/06_sntp/README.md | 41 +++++ examples/06_sntp/main/Kconfig.projbuild | 17 ++ examples/06_sntp/main/component.mk | 10 ++ examples/06_sntp/main/sntp_main.c | 163 +++++++++++++++++++ 9 files changed, 314 insertions(+), 9 deletions(-) create mode 100644 examples/06_sntp/Makefile create mode 100644 examples/06_sntp/README.md create mode 100644 examples/06_sntp/main/Kconfig.projbuild create mode 100644 examples/06_sntp/main/component.mk create mode 100644 examples/06_sntp/main/sntp_main.c diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig index 928b190321..65cac4ee9f 100644 --- a/components/esp32/Kconfig +++ b/components/esp32/Kconfig @@ -324,7 +324,7 @@ choice ESP32_TIME_SYSCALL default ESP32_TIME_SYSCALL_USE_RTC_FRC1 help This setting defines which hardware timers are used to - implement 'gettimeofday' function in C library. + implement 'gettimeofday' and 'time' functions in C library. - If only FRC1 timer is used, gettimeofday will provide time at microsecond resolution. Time will not be preserved when going @@ -336,8 +336,8 @@ choice ESP32_TIME_SYSCALL deep sleep, but time will be measured at 6.(6) microsecond resolution. Also the gettimeofday function itself may take longer to run. - - If no timers are used, gettimeofday function return -1 and - set errno to ENOSYS. + - If no timers are used, gettimeofday and time functions + return -1 and set errno to ENOSYS. config ESP32_TIME_SYSCALL_USE_RTC bool "RTC" diff --git a/components/lwip/Kconfig b/components/lwip/Kconfig index 15c94c66ba..801fa0b51c 100644 --- a/components/lwip/Kconfig +++ b/components/lwip/Kconfig @@ -24,6 +24,15 @@ config LWIP_SO_REUSE Enabling this option allows binding to a port which remains in TIME_WAIT. +config LWIP_DHCP_MAX_NTP_SERVERS + int "Maximum number of NTP servers" + default 1 + range 1 16 + help + Set maxumum number of NTP servers used by LwIP SNTP module. + First argument of sntp_setserver/sntp_setservername functions + is limited to this value. + endmenu diff --git a/components/lwip/include/lwip/port/lwipopts.h b/components/lwip/include/lwip/port/lwipopts.h index b970ae5539..f705887508 100755 --- a/components/lwip/include/lwip/port/lwipopts.h +++ b/components/lwip/include/lwip/port/lwipopts.h @@ -33,6 +33,8 @@ #define __LWIPOPTS_H__ #include +#include +#include #include "esp_task.h" #include "sdkconfig.h" @@ -552,7 +554,22 @@ extern unsigned char misc_prof_get_tcp_snd_buf(void); #define LWIP_NETCONN_FULLDUPLEX 1 #define LWIP_NETCONN_SEM_PER_THREAD 1 +#define LWIP_DHCP_MAX_NTP_SERVERS CONFIG_LWIP_DHCP_MAX_NTP_SERVERS +#define LWIP_TIMEVAL_PRIVATE 0 +#define SNTP_SET_SYSTEM_TIME_US(sec, us) \ + do { \ + struct timeval tv = { .tv_sec = sec, .tv_usec = us }; \ + settimeofday(&tv, NULL); \ + } while (0); + +#define SNTP_GET_SYSTEM_TIME(sec, us) \ + do { \ + struct timeval tv = { .tv_sec = 0, .tv_usec = 0 }; \ + gettimeofday(&tv, NULL); \ + (sec) = tv.tv_sec; \ + (us) = tv.tv_usec; \ + } while (0); #define SOC_SEND_LOG //printf diff --git a/components/newlib/time.c b/components/newlib/time.c index 83645aa4cc..5f60e1d7b2 100644 --- a/components/newlib/time.c +++ b/components/newlib/time.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "esp_attr.h" #include "soc/soc.h" #include "soc/rtc_cntl_reg.h" @@ -54,6 +55,15 @@ static uint64_t get_rtc_time_us() #endif // WITH_RTC +// time from Epoch to the first boot time +#ifdef WITH_RTC +static RTC_DATA_ATTR struct timeval s_boot_time; +#else +static struct timeval s_boot_time; +#endif +static _lock_t s_boot_time_lock; + + #ifdef WITH_FRC1 #define FRC1_PRESCALER 16 #define FRC1_PRESCALER_CTL 2 @@ -83,7 +93,6 @@ void esp_setup_time_syscalls() s_microseconds = get_rtc_time_us(); #endif //WITH_RTC - // set up timer WRITE_PERI_REG(FRC_TIMER_CTRL_REG(0), \ FRC_TIMER_AUTOLOAD | \ @@ -112,12 +121,12 @@ clock_t IRAM_ATTR _times_r(struct _reent *r, struct tms *ptms) return (clock_t) tv.tv_sec; } -int IRAM_ATTR _gettimeofday_r(struct _reent *r, struct timeval *tv, void *tz) +static uint64_t get_time_since_boot() { - (void) tz; + uint64_t microseconds = 0; #ifdef WITH_FRC1 uint32_t timer_ticks_before = READ_PERI_REG(FRC_TIMER_COUNT_REG(0)); - uint64_t microseconds = s_microseconds; + microseconds = s_microseconds; uint32_t timer_ticks_after = READ_PERI_REG(FRC_TIMER_COUNT_REG(0)); if (timer_ticks_after > timer_ticks_before) { // overflow happened at some point between getting @@ -127,13 +136,22 @@ int IRAM_ATTR _gettimeofday_r(struct _reent *r, struct timeval *tv, void *tz) } microseconds += (FRC_TIMER_LOAD_VALUE(0) - timer_ticks_after) / FRC1_TICKS_PER_US; #elif defined(WITH_RTC) - uint64_t microseconds = get_rtc_time_us(); + microseconds = get_rtc_time_us(); #endif + return microseconds; +} +int IRAM_ATTR _gettimeofday_r(struct _reent *r, struct timeval *tv, void *tz) +{ + (void) tz; #if defined( WITH_FRC1 ) || defined( WITH_RTC ) + uint64_t microseconds = get_time_since_boot(); if (tv) { - tv->tv_sec = microseconds / 1000000; + _lock_acquire(&s_boot_time_lock); + microseconds += s_boot_time.tv_usec; + tv->tv_sec = s_boot_time.tv_sec + microseconds / 1000000; tv->tv_usec = microseconds % 1000000; + _lock_release(&s_boot_time_lock); } return 0; #else @@ -141,3 +159,24 @@ int IRAM_ATTR _gettimeofday_r(struct _reent *r, struct timeval *tv, void *tz) return -1; #endif // defined( WITH_FRC1 ) || defined( WITH_RTC ) } + +int settimeofday(const struct timeval *tv, const struct timezone *tz) +{ + (void) tz; +#if defined( WITH_FRC1 ) || defined( WITH_RTC ) + if (tv) { + _lock_acquire(&s_boot_time_lock); + uint64_t now = ((uint64_t) tv->tv_sec) * 1000000LL + tv->tv_usec; + uint64_t since_boot = get_time_since_boot(); + uint64_t boot_time = now - since_boot; + + s_boot_time.tv_sec = boot_time / 1000000; + s_boot_time.tv_usec = boot_time % 1000000; + _lock_release(&s_boot_time_lock); + } + return 0; +#else + __errno_r(r) = ENOSYS; + return -1; +#endif +} diff --git a/examples/06_sntp/Makefile b/examples/06_sntp/Makefile new file mode 100644 index 0000000000..e6ef17be14 --- /dev/null +++ b/examples/06_sntp/Makefile @@ -0,0 +1,9 @@ +# +# This is a project Makefile. It is assumed the directory this Makefile resides in is a +# project subdirectory. +# + +PROJECT_NAME := sntp + +include $(IDF_PATH)/make/project.mk + diff --git a/examples/06_sntp/README.md b/examples/06_sntp/README.md new file mode 100644 index 0000000000..c5a153bbb2 --- /dev/null +++ b/examples/06_sntp/README.md @@ -0,0 +1,41 @@ +# Example: using LwIP SNTP module and time functions + +This example demonstrates the use of LwIP SNTP module to obtain time from Internet servers. See the README.md file in the upper level 'examples' directory for more information about examples. + +## Obtaining time using LwIP SNTP module + +When this example boots first time after ESP32 is reset, it connects to WiFi and obtains time using SNTP. +See `initialize_sntp` function for details. + +## Timekeeping + +Once time is synchronized, ESP32 will perform timekeeping using built-in timers. + +- RTC clock is used to maintain accurate time when chip is in deep sleep mode + +- FRC1 timer is used to provide time at microsecond accuracy when ESP32 is running. + +Timekeeping using RTC timer is demonstrated in this example by going into deep sleep mode. After wake up, ESP32 will print current time without connecting to WiFi. + +To use this functionality, make sure "Timers used for gettimeofday function" option in "ESP32-specific config" menu of menuconfig is set to "RTC and FRC1" or "RTC". + +## Working with time + +To get current time, [`gettimeofday`](http://man7.org/linux/man-pages/man2/gettimeofday.2.html) function may be used. Additionally the following [standard C library functions](http://en.cppreference.com/w/cpp/header/ctime) can be used to obtain time and manipulate it: + + gettimeofday + time + asctime + clock + ctime + difftime + gmtime + localtime + mktime + strftime + +To set time, [`settimeofday`](http://man7.org/linux/man-pages/man2/settimeofday.2.html) POSIX function can be used. It is used internally in LwIP SNTP library to set current time when response from NTP server is received. + +## Timezones + +To set local timezone, use [`setenv`](http://man7.org/linux/man-pages/man3/setenv.3.html) and [`tzset`](http://man7.org/linux/man-pages/man3/tzset.3.html) POSIX functions. First, call `setenv` to set `TZ` environment variable to the correct value depending on device location. Format of the time string is described in [libc documentation](https://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html). Next, call `tzset` to update C library runtime data for the new time zone. Once these steps are done, `localtime` function will return correct local time, taking time zone offset and daylight saving time into account. diff --git a/examples/06_sntp/main/Kconfig.projbuild b/examples/06_sntp/main/Kconfig.projbuild new file mode 100644 index 0000000000..c5d5523a9f --- /dev/null +++ b/examples/06_sntp/main/Kconfig.projbuild @@ -0,0 +1,17 @@ +menu "Example Configuration" + +config WIFI_SSID + string "WiFi SSID" + default "myssid" + help + SSID (network name) for the example to connect to. + +config WIFI_PASSWORD + string "WiFi Password" + default "myssid" + help + WiFi password (WPA or WPA2) for the example to use. + + Can be left blank if the network has no security set. + +endmenu \ No newline at end of file diff --git a/examples/06_sntp/main/component.mk b/examples/06_sntp/main/component.mk new file mode 100644 index 0000000000..24356f23ed --- /dev/null +++ b/examples/06_sntp/main/component.mk @@ -0,0 +1,10 @@ +# +# Main Makefile. This is basically the same as a component makefile. +# +# This Makefile should, at the very least, just include $(SDK_PATH)/make/component_common.mk. By default, +# this will take the sources in the src/ directory, compile them and link them into +# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable, +# please read the ESP-IDF documents if you need to do this. +# + +include $(IDF_PATH)/make/component_common.mk diff --git a/examples/06_sntp/main/sntp_main.c b/examples/06_sntp/main/sntp_main.c new file mode 100644 index 0000000000..7f516625e3 --- /dev/null +++ b/examples/06_sntp/main/sntp_main.c @@ -0,0 +1,163 @@ +/* LwIP SNTP example + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/event_groups.h" +#include "esp_system.h" +#include "esp_wifi.h" +#include "esp_event_loop.h" +#include "esp_log.h" +#include "esp_attr.h" +#include "esp_deepsleep.h" +#include "nvs_flash.h" + +#include "lwip/err.h" +#include "apps/sntp/sntp.h" + +/* The examples use simple WiFi configuration that you can set via + 'make menuconfig'. + + If you'd rather not, just change the below entries to strings with + the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" +*/ +#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID +#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD + +/* FreeRTOS event group to signal when we are connected & ready to make a request */ +static EventGroupHandle_t wifi_event_group; + +/* The event group allows multiple bits for each event, + but we only care about one event - are we connected + to the AP with an IP? */ +const int CONNECTED_BIT = BIT0; + +static const char *TAG = "example"; + +/* Variable holding number of times ESP32 restarted since first boot. + * It is placed into RTC memory using RTC_DATA_ATTR and + * maintains its value when ESP32 wakes from deep sleep. + */ +RTC_DATA_ATTR static int boot_count = 0; + +static void obtain_time(void); +static void initialize_sntp(void); +static void initialise_wifi(void); +static esp_err_t event_handler(void *ctx, system_event_t *event); + + +void app_main() +{ + ++boot_count; + ESP_LOGI(TAG, "Boot count: %d", boot_count); + + time_t now; + struct tm timeinfo; + time(&now); + localtime_r(&now, &timeinfo); + // Is time set? If not, tm_year will be (1970 - 1900). + if (timeinfo.tm_year < (2016 - 1900)) { + ESP_LOGI(TAG, "Time is not set yet. Connecting to WiFi and getting time over NTP."); + obtain_time(); + // update 'now' variable with current time + time(&now); + } + char strftime_buf[64]; + + // Set timezone to Eastern Standard Time and print local time + setenv("TZ", "EST5EDT,M3.2.0/2,M11.1.0", 1); + tzset(); + localtime_r(&now, &timeinfo); + strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo); + ESP_LOGI(TAG, "The current date/time in New York is: %s", strftime_buf); + + // Set timezone to China Standard Time + setenv("TZ", "CST-8CDT-9,M4.2.0/2,M9.2.0/3", 1); + tzset(); + localtime_r(&now, &timeinfo); + strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo); + ESP_LOGI(TAG, "The current date/time in Shanghai is: %s", strftime_buf); + + const int deep_sleep_sec = 10; + ESP_LOGI(TAG, "Entering deep sleep for %d seconds", deep_sleep_sec); + system_deep_sleep(1000000LL * deep_sleep_sec); +} + +static void obtain_time(void) +{ + nvs_flash_init(); + system_init(); + initialise_wifi(); + xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, + false, true, portMAX_DELAY); + initialize_sntp(); + + // wait for time to be set + time_t now = 0; + struct tm timeinfo = { 0 }; + int retry = 0; + const int retry_count = 10; + while(timeinfo.tm_year < (2016 - 1900) && ++retry < retry_count) { + ESP_LOGI(TAG, "Waiting for system time to be set... (%d/%d)", retry, retry_count); + vTaskDelay(2000 / portTICK_PERIOD_MS); + time(&now); + localtime_r(&now, &timeinfo); + } +} + +static void initialize_sntp(void) +{ + ESP_LOGI(TAG, "Initializing SNTP"); + sntp_setoperatingmode(SNTP_OPMODE_POLL); + sntp_setservername(0, "pool.ntp.org"); + sntp_init(); +} + +static void initialise_wifi(void) +{ + tcpip_adapter_init(); + wifi_event_group = xEventGroupCreate(); + ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) ); + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); + ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); + wifi_config_t wifi_config = { + .sta = { + .ssid = EXAMPLE_WIFI_SSID, + .password = EXAMPLE_WIFI_PASS, + }, + }; + ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid); + ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) ); + ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &wifi_config) ); + ESP_ERROR_CHECK( esp_wifi_start() ); +} + +static esp_err_t event_handler(void *ctx, system_event_t *event) +{ + switch(event->event_id) { + case SYSTEM_EVENT_STA_START: + esp_wifi_connect(); + break; + case SYSTEM_EVENT_STA_GOT_IP: + xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); + break; + case SYSTEM_EVENT_STA_DISCONNECTED: + /* This is a workaround as ESP32 WiFi libs don't currently + auto-reassociate. */ + esp_wifi_connect(); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + break; + default: + break; + } + return ESP_OK; +} From 299655e3be68212bd2317cce9c1d8f11bb6ffbf7 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Thu, 3 Nov 2016 14:49:05 +0800 Subject: [PATCH 250/343] esp32: add choice for RTC clock source For now only one option is supported: internal RC oscillator --- components/esp32/Kconfig | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig index 65cac4ee9f..1f04cf4bb7 100644 --- a/components/esp32/Kconfig +++ b/components/esp32/Kconfig @@ -349,5 +349,19 @@ config ESP32_TIME_SYSCALL_USE_NONE bool "None" endchoice +choice ESP32_RTC_CLOCK_SOURCE + prompt "RTC clock source" + default ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC + help + Choose which clock is used as RTC clock source. + The only available option for now is to use internal + 150kHz RC oscillator. + +config ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC + bool "Internal RC" +config ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL + bool "External 32kHz crystal" + depends on DOCUMENTATION_FOR_RTC_CNTL +endchoice endmenu From bc4f1c90a7cbf8f457df9cc97dc89d2e3e8d5a85 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Thu, 3 Nov 2016 17:44:23 +0800 Subject: [PATCH 251/343] conver tabs to spaces in frc_timer_reg.h --- components/esp32/include/soc/frc_timer_reg.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/components/esp32/include/soc/frc_timer_reg.h b/components/esp32/include/soc/frc_timer_reg.h index 24b942c0bb..d76199c4f3 100644 --- a/components/esp32/include/soc/frc_timer_reg.h +++ b/components/esp32/include/soc/frc_timer_reg.h @@ -23,26 +23,26 @@ #define REG_FRC_TIMER_BASE(i) (DR_REG_FRC_TIMER_BASE + i*0x20) -#define FRC_TIMER_LOAD_REG(i) (REG_FRC_TIMER_BASE(i) + 0x0) // timer load value (23 bit for i==0, 32 bit for i==1) +#define FRC_TIMER_LOAD_REG(i) (REG_FRC_TIMER_BASE(i) + 0x0) // timer load value (23 bit for i==0, 32 bit for i==1) #define FRC_TIMER_LOAD_VALUE(i) ((i == 0)?0x007FFFFF:0xffffffff) #define FRC_TIMER_LOAD_VALUE_S 0 -#define FRC_TIMER_COUNT_REG(i) (REG_FRC_TIMER_BASE(i) + 0x4) // timer count value (23 bit for i==0, 32 bit for i==1) +#define FRC_TIMER_COUNT_REG(i) (REG_FRC_TIMER_BASE(i) + 0x4) // timer count value (23 bit for i==0, 32 bit for i==1) #define FRC_TIMER_COUNT ((i == 0)?0x007FFFFF:0xffffffff) #define FRC_TIMER_COUNT_S 0 #define FRC_TIMER_CTRL_REG(i) (REG_FRC_TIMER_BASE(i) + 0x8) -#define FRC_TIMER_INT_ENABLE (BIT(8)) // enable interrupt -#define FRC_TIMER_ENABLE (BIT(7)) // enable timer -#define FRC_TIMER_AUTOLOAD (BIT(6)) // enable autoload -#define FRC_TIMER_PRESCALER 0x00000007 // 0: divide by 1, 2: divide by 16, 4: divide by 256 -#define FRC_TIMER_PRESCALER_S 1 -#define FRC_TIMER_EDGE_INT (BIT(0)) // 0: level, 1: edge +#define FRC_TIMER_INT_ENABLE (BIT(8)) // enable interrupt +#define FRC_TIMER_ENABLE (BIT(7)) // enable timer +#define FRC_TIMER_AUTOLOAD (BIT(6)) // enable autoload +#define FRC_TIMER_PRESCALER 0x00000007 // 0: divide by 1, 2: divide by 16, 4: divide by 256 +#define FRC_TIMER_PRESCALER_S 1 +#define FRC_TIMER_EDGE_INT (BIT(0)) // 0: level, 1: edge #define FRC_TIMER_INT_REG(i) (REG_FRC_TIMER_BASE(i) + 0xC) -#define FRC_TIMER_INT_CLR (BIT(0)) // clear interrupt +#define FRC_TIMER_INT_CLR (BIT(0)) // clear interrupt -#define FRC_TIMER_ALARM_REG(i) (REG_FRC_TIMER_BASE(i) + 0x10) // timer alarm value; register only present for i == 1 +#define FRC_TIMER_ALARM_REG(i) (REG_FRC_TIMER_BASE(i) + 0x10) // timer alarm value; register only present for i == 1 #define FRC_TIMER_ALARM 0xFFFFFFFF #define FRC_TIMER_ALARM_S 0 From 8282c73ac25a3b6e8895719eadab0eec92f1e1b3 Mon Sep 17 00:00:00 2001 From: Wangjialin Date: Thu, 3 Nov 2016 18:28:36 +0800 Subject: [PATCH 252/343] debug ring buffer error. --- components/driver/include/driver/uart.h | 2 +- components/driver/uart.c | 205 +++++++++++++++++------- components/freertos/ringbuf.c | 29 +++- 3 files changed, 177 insertions(+), 59 deletions(-) diff --git a/components/driver/include/driver/uart.h b/components/driver/include/driver/uart.h index 3ea77b2d02..445d71b685 100644 --- a/components/driver/include/driver/uart.h +++ b/components/driver/include/driver/uart.h @@ -530,7 +530,7 @@ int uart_read_char(uart_port_t uart_num, TickType_t ticks_to_wait); * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 * @param buf pointer to the buffer. * @param length data length - * @param ticks_to_wait: Timeout, count in RTOS ticks + * @param ticks_to_wait sTimeout, count in RTOS ticks * * @return * - (-1) Error diff --git a/components/driver/uart.c b/components/driver/uart.c index eeb2c64208..d6585405f2 100644 --- a/components/driver/uart.c +++ b/components/driver/uart.c @@ -37,8 +37,6 @@ const char* UART_TAG = "UART"; #define UART_EMPTY_THRESH_DEFAULT (10) #define UART_FULL_THRESH_DEFAULT (120) #define UART_TOUT_THRESH_DEFAULT (10) -#define UART_TX_TASK_DEPTH_DEFAULT (256*2+64) -#define UART_TX_TASK_PRIO_DEFAULT (10) #define UART_ENTER_CRITICAL_ISR(mux) portENTER_CRITICAL_ISR(mux) #define UART_EXIT_CRITICAL_ISR(mux) portEXIT_CRITICAL_ISR(mux) #define UART_ENTER_CRITICAL(mux) portENTER_CRITICAL(mux) @@ -60,7 +58,6 @@ typedef struct { RingbufHandle_t rx_ring_buf; int tx_buf_size; RingbufHandle_t tx_ring_buf; - TaskHandle_t tx_task_handle; bool buffer_full_flg; bool tx_waiting; int cur_remain; @@ -439,8 +436,17 @@ static void IRAM_ATTR uart_rx_intr_handler_default(void *param) uart_dev_t* uart_reg = UART[uart_num]; uint8_t buf_idx = 0; uint32_t uart_intr_status = UART[uart_num]->int_st.val; - static int rx_fifo_len = 0; + int rx_fifo_len = 0; uart_event_t uart_event; + + static uint8_t * tx_ptr; + static uart_event_t* tx_head; + static int tx_len_tot = 0; + static int brk_flg = 0; + static int tx_brk_len = 0; + static int wait_brk = 0; + + portBASE_TYPE HPTaskAwoken = 0; while(uart_intr_status != 0x0) { buf_idx = 0; @@ -450,14 +456,99 @@ static void IRAM_ATTR uart_rx_intr_handler_default(void *param) uart_reg->int_ena.txfifo_empty = 0; uart_reg->int_clr.txfifo_empty = 1; UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); + if(wait_brk) { + return; + } if(p_uart->tx_waiting == true) { p_uart->tx_waiting = false; xSemaphoreGiveFromISR(p_uart->tx_fifo_sem, NULL); } + else { + int tx_fifo_rem = UART_FIFO_LEN - UART[uart_num]->status.txfifo_cnt; + bool en_tx_flg = false; + if(tx_len_tot == 0) { + size_t size; +// ets_printf("dbg1,tot=0,get 1st head\n"); +// xRingbufferPrintInfo(p_uart->tx_ring_buf); + tx_head = (uart_event_t*) xRingbufferReceiveFromISR(p_uart->tx_ring_buf, &size); +// xRingbufferPrintInfo(p_uart->tx_ring_buf); + if(tx_head) { //enable empty intr +// tx_ptr = (uint8_t*)tx_head + sizeof(uart_event_t); + tx_ptr = NULL; +// en_tx_flg = true; + tx_len_tot = tx_head->data.size; + if(tx_head->type == UART_DATA_BREAK) { + tx_len_tot = tx_head->data.size; + brk_flg = 1; + tx_brk_len = tx_head->data.brk_len; + } +// ets_printf("ret1,tot: %d\n", tx_len_tot); + vRingbufferReturnItemFromISR(p_uart->tx_ring_buf, tx_head, &HPTaskAwoken); +// xRingbufferPrintInfo(p_uart->tx_ring_buf); +// xRingbufferPrintInfo(p_uart->tx_ring_buf); + } + else { + return; + } + } + if(tx_ptr == NULL) { + size_t size; +// ets_printf("dbg2, tx ptr null, get 2nd tx ptr\n"); +// xRingbufferPrintInfo(p_uart->tx_ring_buf); + tx_ptr = (uint8_t*) xRingbufferReceiveFromISR(p_uart->tx_ring_buf, &size); + +// xRingbufferPrintInfo(p_uart->tx_ring_buf); + if(tx_ptr) { + tx_head = (void*) tx_ptr; +// ets_printf("get size: %d ; h size: %d\n", size, tx_len_tot); + en_tx_flg = true; + } else { + return; + } + } +// else + if(tx_len_tot > 0 && tx_ptr) { //tx + int send_len = tx_len_tot > tx_fifo_rem ? tx_fifo_rem : tx_len_tot; + for(buf_idx = 0; buf_idx < send_len; buf_idx++) { + WRITE_PERI_REG(UART_FIFO_AHB_REG(uart_num), *(tx_ptr++) & 0xff); + } + tx_len_tot -= send_len; +// ets_printf("tot: %d\n", tx_len_tot); + if(tx_len_tot == 0) { + if(brk_flg == 1) { + UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); + uart_reg->int_ena.tx_brk_done = 0; + uart_reg->idle_conf.tx_brk_num = tx_brk_len; + uart_reg->conf0.txd_brk = 1; + uart_reg->int_clr.tx_brk_done = 1; + uart_reg->int_ena.tx_brk_done = 1; + UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); + wait_brk = 1; + } else { + en_tx_flg = true; + } +// ets_printf("ret2\n"); + vRingbufferReturnItemFromISR(p_uart->tx_ring_buf, tx_head, &HPTaskAwoken); +// xRingbufferPrintInfo(p_uart->tx_ring_buf); +// xRingbufferPrintInfo(p_uart->tx_ring_buf); + tx_head = NULL; + tx_ptr = NULL; + } else { + en_tx_flg = true; + } + } + if(en_tx_flg) { + UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); + uart_reg->int_clr.txfifo_empty = 1; + uart_reg->int_ena.txfifo_empty = 1; + UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); + } + } } else if((uart_intr_status & UART_RXFIFO_TOUT_INT_ST_M) || (uart_intr_status & UART_RXFIFO_FULL_INT_ST_M)) { if(p_uart->buffer_full_flg == false) { //Get the buffer from the FIFO +// ESP_LOGE(UART_TAG, "FULL\n"); rx_fifo_len = uart_reg->status.rxfifo_cnt; p_uart->data_len = rx_fifo_len; memset(p_uart->data_buf, 0, sizeof(p_uart->data_buf)); @@ -506,12 +597,22 @@ static void IRAM_ATTR uart_rx_intr_handler_default(void *param) uart_reg->int_clr.frm_err = 1; uart_event.type = UART_PARITY_ERR; } else if(uart_intr_status & UART_TX_BRK_DONE_INT_ST_M) { +// ESP_LOGE(UART_TAG, "UART TX BRK DONE\n"); + ets_printf("tx brk done\n"); UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); uart_reg->conf0.txd_brk = 0; uart_reg->int_ena.tx_brk_done = 0; uart_reg->int_clr.tx_brk_done = 1; + if(brk_flg == 1) { + uart_reg->int_ena.txfifo_empty = 1; + } UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); - xSemaphoreGiveFromISR(p_uart->tx_brk_sem, &HPTaskAwoken); + if(brk_flg == 1) { + brk_flg = 0; + wait_brk = 0; + } else { + xSemaphoreGiveFromISR(p_uart->tx_brk_sem, &HPTaskAwoken); + } } else if(uart_intr_status & UART_TX_BRK_IDLE_DONE_INT_ST_M) { UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); uart_reg->int_ena.tx_brk_idle_done = 0; @@ -638,26 +739,26 @@ static int uart_tx_all(uart_port_t uart_num, const char* src, size_t size, bool return original_size; } -static void uart_tx_task(void* arg) -{ - uart_obj_t* p_uart = (uart_obj_t*) arg; - size_t size; - uart_event_t evt; - for(;;) { - char* data = (char*) xRingbufferReceive(p_uart->tx_ring_buf, &size, portMAX_DELAY); - if(data == NULL) { - continue; - } - memcpy(&evt, data, sizeof(evt)); - if(evt.type == UART_DATA) { - uart_tx_all(p_uart->uart_num, (const char*) data + sizeof(uart_event_t), evt.data.size, 0, 0); - } else if(evt.type == UART_DATA_BREAK) { - uart_tx_all(p_uart->uart_num, (const char*) data + sizeof(uart_event_t), evt.data.size, 1, evt.data.brk_len); - } - vRingbufferReturnItem(p_uart->tx_ring_buf, data); - } - vTaskDelete(NULL); -} +//static void uart_tx_task(void* arg) +//{ +// uart_obj_t* p_uart = (uart_obj_t*) arg; +// size_t size; +// uart_event_t evt; +// for(;;) { +// char* data = (char*) xRingbufferReceive(p_uart->tx_ring_buf, &size, portMAX_DELAY); +// if(data == NULL) { +// continue; +// } +// memcpy(&evt, data, sizeof(evt)); +// if(evt.type == UART_DATA) { +// uart_tx_all(p_uart->uart_num, (const char*) data + sizeof(uart_event_t), evt.data.size, 0, 0); +// } else if(evt.type == UART_DATA_BREAK) { +// uart_tx_all(p_uart->uart_num, (const char*) data + sizeof(uart_event_t), evt.data.size, 1, evt.data.brk_len); +// } +// vRingbufferReturnItem(p_uart->tx_ring_buf, data); +// } +// vTaskDelete(NULL); +//} int uart_tx_all_chars(uart_port_t uart_num, const char* src, size_t size) { @@ -666,19 +767,18 @@ int uart_tx_all_chars(uart_port_t uart_num, const char* src, size_t size) UART_CHECK(src, "buffer null"); if(p_uart_obj[uart_num]->tx_buf_size > 0) { if(xRingbufferGetMaxItemSize(p_uart_obj[uart_num]->tx_ring_buf) > (size + sizeof(uart_event_t))) { - uart_event_t *evt = (uart_event_t*) malloc(sizeof(uart_event_t) + size); - if(evt == NULL) { - ESP_LOGE(UART_TAG, "UART EVT MALLOC ERROR\n"); - return -1; - } + uart_event_t evt; xSemaphoreTake(p_uart_obj[uart_num]->tx_buffer_mutex, (portTickType)portMAX_DELAY); - evt->type = UART_DATA; - evt->data.size = size; - memcpy(evt->data.data, src, size); - xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void*) evt, sizeof(uart_event_t) + size, portMAX_DELAY); - free(evt); - evt = NULL; + evt.type = UART_DATA; + evt.data.size = size; + ets_printf("-----1st send-----\n"); + xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void*) &evt, sizeof(uart_event_t), portMAX_DELAY); + xRingbufferPrintInfo(p_uart_obj[uart_num]->tx_ring_buf); + ets_printf("====2nd send====\n"); + xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void*) src, size, portMAX_DELAY); + xRingbufferPrintInfo(p_uart_obj[uart_num]->tx_ring_buf); xSemaphoreGive(p_uart_obj[uart_num]->tx_buffer_mutex); + uart_enable_tx_intr(uart_num, 1, UART_EMPTY_THRESH_DEFAULT); return size; } else { ESP_LOGW(UART_TAG, "UART TX BUFFER TOO SMALL[0], SEND DIRECTLY\n"); @@ -698,19 +798,15 @@ int uart_tx_all_chars_with_break(uart_port_t uart_num, const char* src, size_t s UART_CHECK((brk_len > 0 && brk_len < 256), "break_num error"); if(p_uart_obj[uart_num]->tx_buf_size > 0) { if(xRingbufferGetMaxItemSize(p_uart_obj[uart_num]->tx_ring_buf) > (size)) { - uart_event_t *evt = (uart_event_t*) malloc(sizeof(uart_event_t) + size); - if(evt == NULL) { - return -1; - } + uart_event_t evt; xSemaphoreTake(p_uart_obj[uart_num]->tx_buffer_mutex, (portTickType)portMAX_DELAY); - evt->type = UART_DATA_BREAK; - evt->data.size = size; - evt->data.brk_len = brk_len; - memcpy(evt->data.data, src, size); - xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void*) evt, sizeof(uart_event_t) + size, portMAX_DELAY); - free(evt); - evt = NULL; + evt.type = UART_DATA_BREAK; + evt.data.size = size; + evt.data.brk_len = brk_len; + xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void*) &evt, sizeof(uart_event_t), portMAX_DELAY); + xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void*) src, size, portMAX_DELAY); xSemaphoreGive(p_uart_obj[uart_num]->tx_buffer_mutex); + uart_enable_tx_intr(uart_num, 1, UART_EMPTY_THRESH_DEFAULT); return size; } else { ESP_LOGW(UART_TAG, "UART TX BUFFER TOO SMALL[1], SEND DIRECTLY\n"); @@ -782,8 +878,10 @@ int uart_read_bytes(uart_port_t uart_num, uint8_t* buf, uint32_t length, TickTyp p_uart_obj[uart_num]->head_ptr = data; p_uart_obj[uart_num]->rd_ptr = data; p_uart_obj[uart_num]->cur_remain = size; +// ets_printf("dbg0\n"); } else { xSemaphoreGive(p_uart_obj[uart_num]->rx_mux); +// ets_printf("dbg1\n"); return copy_len; } } @@ -792,17 +890,20 @@ int uart_read_bytes(uart_port_t uart_num, uint8_t* buf, uint32_t length, TickTyp } else { len_tmp = p_uart_obj[uart_num]->cur_remain; } +// ets_printf("dbga\n"); memcpy(buf + copy_len, p_uart_obj[uart_num]->rd_ptr, len_tmp); p_uart_obj[uart_num]->rd_ptr += len_tmp; p_uart_obj[uart_num]->cur_remain -= len_tmp; copy_len += len_tmp; length -= len_tmp; +// ets_printf("dbgb\n"); if(p_uart_obj[uart_num]->cur_remain == 0) { vRingbufferReturnItem(p_uart_obj[uart_num]->rx_ring_buf, p_uart_obj[uart_num]->head_ptr); p_uart_obj[uart_num]->head_ptr = NULL; p_uart_obj[uart_num]->rd_ptr = NULL; if(p_uart_obj[uart_num]->buffer_full_flg) { BaseType_t res = xRingbufferSend(p_uart_obj[uart_num]->rx_ring_buf, p_uart_obj[uart_num]->data_buf, p_uart_obj[uart_num]->data_len, 1); +// ets_printf("dbg2\n"); if(res == pdTRUE) { p_uart_obj[uart_num]->buffer_full_flg = false; uart_enable_rx_intr(p_uart_obj[uart_num]->uart_num); @@ -810,6 +911,7 @@ int uart_read_bytes(uart_port_t uart_num, uint8_t* buf, uint32_t length, TickTyp } } } +// ets_printf("dbg3\n"); xSemaphoreGive(p_uart_obj[uart_num]->rx_mux); return copy_len; } @@ -944,14 +1046,11 @@ esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_b p_uart_obj[uart_num]->rx_buf_type = rx_buf_type; p_uart_obj[uart_num]->rx_ring_buf = xRingbufferCreate(rx_buffer_size, rx_buf_type); if(tx_buffer_size > 0) { - p_uart_obj[uart_num]->tx_ring_buf = xRingbufferCreate(tx_buffer_size, RINGBUF_TYPE_NOSPLIT); + p_uart_obj[uart_num]->tx_ring_buf = xRingbufferCreate(tx_buffer_size, RINGBUF_TYPE_NOSPLIT);//RINGBUF_TYPE_BYTEBUF);//RINGBUF_TYPE_NOSPLIT); p_uart_obj[uart_num]->tx_buf_size = tx_buffer_size; - xTaskCreate(uart_tx_task, "uart_tx_task", UART_TX_TASK_DEPTH_DEFAULT, (void*)p_uart_obj[uart_num], UART_TX_TASK_PRIO_DEFAULT, &p_uart_obj[uart_num]->tx_task_handle); - } else { p_uart_obj[uart_num]->tx_ring_buf = NULL; p_uart_obj[uart_num]->tx_buf_size = 0; - p_uart_obj[uart_num]->tx_task_handle = NULL; } } else { ESP_LOGE(UART_TAG, "UART driver already installed\n"); @@ -986,10 +1085,6 @@ esp_err_t uart_driver_delete(uart_port_t uart_num) uart_disable_tx_intr(uart_num); uart_isr_register(uart_num, p_uart_obj[uart_num]->intr_num, NULL, NULL); - if(p_uart_obj[uart_num]->tx_task_handle) { - vTaskDelete(p_uart_obj[uart_num]->tx_task_handle); - p_uart_obj[uart_num]->tx_task_handle = NULL; - } if(p_uart_obj[uart_num]->tx_fifo_sem) { vSemaphoreDelete(p_uart_obj[uart_num]->tx_fifo_sem); p_uart_obj[uart_num]->tx_fifo_sem = NULL; diff --git a/components/freertos/ringbuf.c b/components/freertos/ringbuf.c index ce5504596a..560eb5fdd9 100644 --- a/components/freertos/ringbuf.c +++ b/components/freertos/ringbuf.c @@ -77,9 +77,13 @@ static int ringbufferFreeMem(ringbuf_t *rb) { int free_size = rb->free_ptr-rb->write_ptr; if (free_size <= 0) free_size += rb->size; + //If we free the last dummy item in the buffer, free_ptr will point to rb->data + //In this case, after we write the last some bytes, the buffer might wrap around if we don't have room for a header anymore. +// if (free_size == 0 && rb->read_ptr == rb->write_ptr) free_size += rb->size; //Reserve one byte. If we do not do this and the entire buffer is filled, we get a situation - //where read_ptr == free_ptr, messing up the next calculation. - return free_size-1; + //where write_ptr == free_ptr, messing up the next calculation. +// return free_size == 0 ? 0 : free_size - 1; + return free_size - 1; } @@ -334,6 +338,10 @@ static uint8_t *getItemFromRingbufByteBuf(ringbuf_t *rb, size_t *length, int wan //can be increase. //This function by itself is not threadsafe, always call from within a muxed section. static void returnItemToRingbufDefault(ringbuf_t *rb, void *item) { + ets_printf("in returnItemToRingbufDefault\n"); + xRingbufferPrintInfo(rb); + + uint8_t *data=(uint8_t*)item; configASSERT(((int)rb->free_ptr&3)==0); configASSERT(data >= rb->data); @@ -350,9 +358,16 @@ static void returnItemToRingbufDefault(ringbuf_t *rb, void *item) { hdr=(buf_entry_hdr_t *)rb->free_ptr; //basically forward free_ptr until we run into either a block that is still in use or the write pointer. while (((hdr->flags & iflag_free) || (hdr->flags & iflag_dummydata)) && rb->free_ptr != rb->write_ptr) { + if (hdr->flags & iflag_dummydata) { + ets_printf("hrd len: %d; flg: 0x%02x\n",hdr->len,hdr->flags); //Rest is dummy data. Reset to start of ringbuffer. rb->free_ptr=rb->data; + //If the read_ptr is pointing to this dummy item, + //we should also move the read pointer to data, in case we overwrite the read hdr. +// if(rb->read_ptr == (uint8_t*)hdr) { +// rb->read_ptr = rb->data; +// } } else { //Skip past item size_t len=(hdr->len+3)&~3; @@ -363,8 +378,10 @@ static void returnItemToRingbufDefault(ringbuf_t *rb, void *item) { if ((rb->data+rb->size)-rb->free_ptr < sizeof(buf_entry_hdr_t)) { rb->free_ptr=rb->data; } + if(rb->free_ptr == rb->read_ptr) break; //Next header hdr=(buf_entry_hdr_t *)rb->free_ptr; + } } @@ -386,6 +403,12 @@ void xRingbufferPrintInfo(RingbufHandle_t ringbuf) configASSERT(rb); ets_printf("Rb size %d free %d rptr %d freeptr %d wptr %d\n", rb->size, ringbufferFreeMem(rb), rb->read_ptr-rb->data, rb->free_ptr-rb->data, rb->write_ptr-rb->data); + buf_entry_hdr_t *hdr=(buf_entry_hdr_t *)rb->read_ptr; + if(rb->write_ptr == rb->read_ptr) { + ets_printf("write que read\n"); + } else { + ets_printf("hdr len: %d; flg: 0x%08x\n", hdr->len, hdr->flags); + } } @@ -493,7 +516,7 @@ BaseType_t xRingbufferSend(RingbufHandle_t ringbuf, void *data, size_t dataSize, ticks_to_wait = ticks_end - xTaskGetTickCount(); } } while (ringbufferFreeMem(rb) < needed_size && ticks_to_wait>=0); - + //Lock the mux in order to make sure no one else is messing with the ringbuffer and do the copy. portENTER_CRITICAL(&rb->mux); //Another thread may have been able to sneak its write first. Check again now we locked the ringbuff, and retry From 6602d6b7f2c25ad72da581f038cc27e474ea9d0b Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Thu, 1 Sep 2016 12:32:05 +0800 Subject: [PATCH 253/343] docs: add style guide This adds initial code style guide. Only section on code formatting is written, other sections to be added later. Also adds scripts to format code using astyle. --- docs/style-guide.rst | 182 ++++++++++++++++++++++++++++++++++++++++ tools/format-minimal.sh | 9 ++ tools/format.sh | 12 +++ 3 files changed, 203 insertions(+) create mode 100644 docs/style-guide.rst create mode 100644 tools/format-minimal.sh create mode 100644 tools/format.sh diff --git a/docs/style-guide.rst b/docs/style-guide.rst new file mode 100644 index 0000000000..971d86bc91 --- /dev/null +++ b/docs/style-guide.rst @@ -0,0 +1,182 @@ +Espressif IoT Development Framework Style Guide +=============================================== + + +About this guide +~~~~~~~~~~~~~~~~ + +Purpose of this style guide is to encourage use of common coding practices within the ESP-IDF. + +Style guide is a set of rules which are aimed to help create readable, maintainable, and robust code. By writing code which looks the same way across the code base we help others read and comprehend the code. By using same conventions for spaces and newlines we reduce chances that future changes will produce huge unreadable diffs. By following common patterns for module structure and by using language features consistently we help others understand code behavior. + +We try to keep rules simple enough, which means that they can not cover all potential cases. In some cases one has to bend these simple rules to achieve readability, maintainability, or robustness. + +When doing modifications to third-party code used in ESP-IDF, follow the way that particular project is written. That will help propose useful changes for merging into upstream project. + +C code formatting +~~~~~~~~~~~~~~~~~ + +Indentation +----------- + +Use 4 spaces for each indentation level. Don't use tabs for indentation. Configure the editor to emit 4 spaces each time you press tab key. + +Vertical space +-------------- + +Place one empty line between functions. Don't begin or end a function with an empty line. +:: + + void function1() + { + do_one_thing(); + do_another_thing(); + // INCORRECT, don't place empty line here + } + // place empty line here + void function2() + { + // INCORRECT, don't use an empty line here + int var = 0; + while (var < SOME_CONSTANT) { + do_stuff(&var); + } + } + +Horizontal space +---------------- + +Always add single space after conditional and loop keywords:: + + if (condition) { // correct + // ... + } + + switch (n) { // correct + case 0: + // ... + } + + for(int i = 0; i < CONST; ++i) { // INCORRECT + // ... + } + +Add single space around binary operators. No space is necessary for unary operators. It is okay to drop space around multiply and divide operators:: + + const int y = y0 + (x - x0) * (y1 - y0) / (x1 - x0); // correct + + const int y = y0 + (x - x0)*(y1 - y0)/(x1 - x0); // also okay + + int y_cur = -y; // correct + ++y_cur; + + const int y = y0+(x-x0)*(y1-y0)/(x1-x0); // INCORRECT + + +No space is necessary around ``.`` and ``->`` operators. + + +Sometimes adding horizontal space within a line can help make code more readable. For example, you can add space to align function arguments:: + + gpio_matrix_in(PIN_CAM_D6, I2S0I_DATA_IN14_IDX, false); + gpio_matrix_in(PIN_CAM_D7, I2S0I_DATA_IN15_IDX, false); + gpio_matrix_in(PIN_CAM_HREF, I2S0I_H_ENABLE_IDX, false); + gpio_matrix_in(PIN_CAM_PCLK, I2S0I_DATA_IN15_IDX, false); + +Note however that if someone goes to add new line with a longer identifier as first argument (e.g. ``PIN_CAM_VSYNC``), it will not fit. So other lines would have to be realigned, adding meaningless changes to the commit. + +Therefore, use horizontal alignment sparingly, especially if you expect new lines to be added to the list later. + +Never use TAB characters for horizontal alignment. + +Never add trailing whitespace at the end of the line. + + +Braces +------ + +- Function definition should have a brace on a separate line:: + + // This is correct: + void function(int arg) + { + + } + + // NOT like this: + void function(int arg) { + + } + +- Within a function, place opening brace on the same line with conditional and loop statements:: + + if (condition) { + do_one(); + } + else if (other_condition) { + do_two(); + } + + +Comments +-------- + +Use ``//`` for single line comments. For multi-line comments it is okay to use either ``//`` on each line or a ``/* */`` block. + +Although not directly related to formatting, here are a few notes about using comments effectively. + +- Don't use single comments to disable some functionality:: + + void init_something() + { + setup_dma(); + // load_resources(); // WHY is this thing commented, asks the reader? + start_timer(); + } + +- If some code is no longer required, remove it completely. If you need it you can always look it up in git history of this file. If you disable some call because of temporary reasons, with an intention to restore it in the future, add explanation on the adjacent line:: + + void init_something() + { + setup_dma(); + // TODO: we should load resources here, but loader is not fully integrated yet. + // load_resources(); + start_timer(); + } + +- Same goes for ``#if 0 ... #endif`` blocks. Remove code block completely if it is not used. Otherwise, add comment explaining why the block is disabled. Don't use ``#if 0 ... #endif`` or comments to store code snippets which you may need in the future. + +- Don't add trivial comments about authorship and change date. You can always look up who modified any given line using git. E.g. this comment adds clutter to the code without adding any useful information:: + + void init_something() + { + setup_dma(); + // XXX add 2016-09-01 + init_dma_list(); + fill_dma_item(0); + // end XXX add + start_timer(); + } + + +Formatting your code +-------------------- + +You can use ``astyle`` program to format your code according to the above recommendations. + +If you are writing a file from scratch, or doing a complete rewrite, feel free to re-format the entire file. If you are changing a small portion of file, don't re-format the code you didn't change. This will help others when they review your changes. + +To re-format a file, run:: + + tools/format.sh components/my_component/file.c + +Structure and naming +~~~~~~~~~~~~~~~~~~~~ + +To be written. + +Language features +~~~~~~~~~~~~~~~~~ + +To be written. + diff --git a/tools/format-minimal.sh b/tools/format-minimal.sh new file mode 100644 index 0000000000..ff829247d3 --- /dev/null +++ b/tools/format-minimal.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# Runs astyle with parameters which should be checked in a pre-commit hook +astyle \ + --style=otbs \ + --indent=spaces=4 \ + --convert-tabs \ + --keep-one-line-statements \ + --pad-header \ + "$@" diff --git a/tools/format.sh b/tools/format.sh new file mode 100644 index 0000000000..aadb337aaa --- /dev/null +++ b/tools/format.sh @@ -0,0 +1,12 @@ +#!/bin/bash +# Runs astyle with the full set of formatting options +astyle \ + --style=otbs \ + --indent=spaces=4 \ + --convert-tabs \ + --align-pointer=name \ + --align-reference=name \ + --keep-one-line-statements \ + --pad-header \ + --pad-oper \ + "$@" From b717e44eb2bbb51b61b656d4c976c45adcdf22e3 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Wed, 7 Sep 2016 12:45:08 +0800 Subject: [PATCH 254/343] tools: add code formatter rules for Eclipse Generated with Eclipse Neon, should work in earlier versions as well. This file can be imported - into the workspace via Preferences > C++ > Code Style > Formatter > Import - or into the project via Project Preferences > C++ General > Formatter > Import Configuration options in Eclipse are not exactly the same as in astyle. There may be some discrepancy between the format astyle and Eclipse will produce. If anyone notices that, please let me know. --- tools/eclipse-code-style.xml | 167 +++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 tools/eclipse-code-style.xml diff --git a/tools/eclipse-code-style.xml b/tools/eclipse-code-style.xml new file mode 100644 index 0000000000..f589a00800 --- /dev/null +++ b/tools/eclipse-code-style.xml @@ -0,0 +1,167 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 4d3ed9efdee93dd97325a05942c4bc2a5f69d80c Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Thu, 3 Nov 2016 19:07:41 +0800 Subject: [PATCH 255/343] docs: update style guide --- docs/style-guide.rst | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/docs/style-guide.rst b/docs/style-guide.rst index 971d86bc91..4fa8321762 100644 --- a/docs/style-guide.rst +++ b/docs/style-guide.rst @@ -3,7 +3,7 @@ Espressif IoT Development Framework Style Guide About this guide -~~~~~~~~~~~~~~~~ +---------------- Purpose of this style guide is to encourage use of common coding practices within the ESP-IDF. @@ -14,15 +14,15 @@ We try to keep rules simple enough, which means that they can not cover all pote When doing modifications to third-party code used in ESP-IDF, follow the way that particular project is written. That will help propose useful changes for merging into upstream project. C code formatting -~~~~~~~~~~~~~~~~~ +----------------- Indentation ------------ +^^^^^^^^^^^ Use 4 spaces for each indentation level. Don't use tabs for indentation. Configure the editor to emit 4 spaces each time you press tab key. Vertical space --------------- +^^^^^^^^^^^^^^ Place one empty line between functions. Don't begin or end a function with an empty line. :: @@ -44,7 +44,7 @@ Place one empty line between functions. Don't begin or end a function with an em } Horizontal space ----------------- +^^^^^^^^^^^^^^^^ Always add single space after conditional and loop keywords:: @@ -93,7 +93,7 @@ Never add trailing whitespace at the end of the line. Braces ------- +^^^^^^ - Function definition should have a brace on a separate line:: @@ -112,14 +112,13 @@ Braces if (condition) { do_one(); - } - else if (other_condition) { + } else if (other_condition) { do_two(); } Comments --------- +^^^^^^^^ Use ``//`` for single line comments. For multi-line comments it is okay to use either ``//`` on each line or a ``/* */`` block. @@ -160,7 +159,7 @@ Although not directly related to formatting, here are a few notes about using co Formatting your code --------------------- +^^^^^^^^^^^^^^^^^^^^ You can use ``astyle`` program to format your code according to the above recommendations. @@ -170,13 +169,18 @@ To re-format a file, run:: tools/format.sh components/my_component/file.c -Structure and naming -~~~~~~~~~~~~~~~~~~~~ +Documenting code +---------------- + +Please see the guide here: `Documenting Code `_. + +Structure and naming +-------------------- + -To be written. Language features -~~~~~~~~~~~~~~~~~ +----------------- To be written. From e314f42b0c71fd96913e0f4f8b79d4e16e69982a Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Thu, 3 Nov 2016 20:18:30 +0800 Subject: [PATCH 256/343] nvs: fix Page::findItem and Storage::findItem regression When read caching was added, Page::findItem started modifying itemIndex reference argument even if item wasn't found. Incidentally, Storage::findItem reused itemIndex when starting search at next page. So, - if the first page had a cached index (findItem was called for that page), and it pointed to a non-zero index, - first page has a few empty items at the end (but is marked full), - next search looked up the item on the second page, - index of the item on the second page was less than the cached index on the first page, then the search would fail because cached starting index was reused. This change fixes both sides of the problem: - Page::findItem shouldn't modify itemIndex argument if item is not found - Storage::findItem should not reuse itemIndex between pages Two tests have been added. --- components/nvs_flash/src/nvs_page.cpp | 11 ++--- components/nvs_flash/src/nvs_storage.cpp | 2 +- components/nvs_flash/test/test_nvs.cpp | 54 ++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 6 deletions(-) diff --git a/components/nvs_flash/src/nvs_page.cpp b/components/nvs_flash/src/nvs_page.cpp index 23cefd1aad..d2ca225352 100644 --- a/components/nvs_flash/src/nvs_page.cpp +++ b/components/nvs_flash/src/nvs_page.cpp @@ -656,19 +656,20 @@ esp_err_t Page::findItem(uint8_t nsIndex, ItemType datatype, const char* key, si if (mState == PageState::CORRUPT || mState == PageState::INVALID || mState == PageState::UNINITIALIZED) { return ESP_ERR_NVS_NOT_FOUND; } - - if (itemIndex >= ENTRY_COUNT) { + + size_t findBeginIndex = itemIndex; + if (findBeginIndex >= ENTRY_COUNT) { return ESP_ERR_NVS_NOT_FOUND; } CachedFindInfo findInfo(nsIndex, datatype, key); if (mFindInfo == findInfo) { - itemIndex = mFindInfo.itemIndex(); + findBeginIndex = mFindInfo.itemIndex(); } size_t start = mFirstUsedEntry; - if (itemIndex > mFirstUsedEntry && itemIndex < ENTRY_COUNT) { - start = itemIndex; + if (findBeginIndex > mFirstUsedEntry && findBeginIndex < ENTRY_COUNT) { + start = findBeginIndex; } size_t end = mNextFreeEntry; diff --git a/components/nvs_flash/src/nvs_storage.cpp b/components/nvs_flash/src/nvs_storage.cpp index eb90cac5bc..cacfbd4022 100644 --- a/components/nvs_flash/src/nvs_storage.cpp +++ b/components/nvs_flash/src/nvs_storage.cpp @@ -71,8 +71,8 @@ esp_err_t Storage::init(uint32_t baseSector, uint32_t sectorCount) esp_err_t Storage::findItem(uint8_t nsIndex, ItemType datatype, const char* key, Page* &page, Item& item) { - size_t itemIndex = 0; for (auto it = std::begin(mPageManager); it != std::end(mPageManager); ++it) { + size_t itemIndex = 0; auto err = it->findItem(nsIndex, datatype, key, itemIndex, item); if (err == ESP_OK) { page = it; diff --git a/components/nvs_flash/test/test_nvs.cpp b/components/nvs_flash/test/test_nvs.cpp index 528c9df686..81bf7fd216 100644 --- a/components/nvs_flash/test/test_nvs.cpp +++ b/components/nvs_flash/test/test_nvs.cpp @@ -300,6 +300,27 @@ TEST_CASE("storage doesn't add duplicates within multiple pages", "[nvs]") CHECK(page.findItem(1, itemTypeOf(), "bar") == ESP_OK); } +TEST_CASE("storage can find items on second page if first is not fully written and has cached search data", "[nvs]") +{ + SpiFlashEmulator emu(3); + Storage storage; + CHECK(storage.init(0, 3) == ESP_OK); + int bar = 0; + uint8_t bigdata[100 * 32] = {0}; + // write one big chunk of data + ESP_ERROR_CHECK(storage.writeItem(0, ItemType::BLOB, "first", bigdata, sizeof(bigdata))); + + // write second one; it will not fit into the first page + ESP_ERROR_CHECK(storage.writeItem(0, ItemType::BLOB, "second", bigdata, sizeof(bigdata))); + + size_t size; + ESP_ERROR_CHECK(storage.getItemDataSize(0, ItemType::BLOB, "first", size)); + CHECK(size == sizeof(bigdata)); + ESP_ERROR_CHECK(storage.getItemDataSize(0, ItemType::BLOB, "second", size)); + CHECK(size == sizeof(bigdata)); +} + + TEST_CASE("can write and read variable length data lots of times", "[nvs]") { SpiFlashEmulator emu(8); @@ -1055,6 +1076,39 @@ TEST_CASE("crc error in variable length item is handled", "[nvs]") } +TEST_CASE("read/write failure (TW8406)", "[nvs]") +{ + SpiFlashEmulator emu(3); + nvs_flash_init_custom(0, 3); + for (int attempts = 0; attempts < 3; ++attempts) { + int i = 0; + nvs_handle light_handle = 0; + char key[15] = {0}; + char data[76] = {12, 13, 14, 15, 16}; + uint8_t number = 20; + size_t data_len = sizeof(data); + + ESP_ERROR_CHECK(nvs_open("LIGHT", NVS_READWRITE, &light_handle)); + ESP_ERROR_CHECK(nvs_set_u8(light_handle, "RecordNum", number)); + for (i = 0; i < number; ++i) { + sprintf(key, "light%d", i); + ESP_ERROR_CHECK(nvs_set_blob(light_handle, key, data, sizeof(data))); + } + nvs_commit(light_handle); + + uint8_t get_number = 0; + ESP_ERROR_CHECK(nvs_get_u8(light_handle, "RecordNum", &get_number)); + REQUIRE(number == get_number); + for (i = 0; i < number; ++i) { + char data[76] = {0}; + sprintf(key, "light%d", i); + ESP_ERROR_CHECK(nvs_get_blob(light_handle, key, data, &data_len)); + } + nvs_close(light_handle); + } +} + + TEST_CASE("dump all performance data", "[nvs]") { std::cout << "====================" << std::endl << "Dumping benchmarks" << std::endl; From e96d4a0a3289ec2c57f5f446026f6ba74176ae73 Mon Sep 17 00:00:00 2001 From: Sandeep Mistry Date: Tue, 4 Oct 2016 16:07:06 -0400 Subject: [PATCH 257/343] Allow OS X to build without libintl --- tools/kconfig/lxdialog/check-lxdialog.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tools/kconfig/lxdialog/check-lxdialog.sh b/tools/kconfig/lxdialog/check-lxdialog.sh index 6964d2b0c5..48c19278a9 100755 --- a/tools/kconfig/lxdialog/check-lxdialog.sh +++ b/tools/kconfig/lxdialog/check-lxdialog.sh @@ -5,8 +5,8 @@ ldflags() { if [ $(uname -s) == "Darwin" ]; then - #OSX seems to need intl too - echo -n "-lintl " + #OSX seems to need ncurses too + echo -n "-lncurses" fi pkg-config --libs ncursesw 2>/dev/null && exit pkg-config --libs ncurses 2>/dev/null && exit @@ -41,6 +41,10 @@ ccflags() else echo '-DCURSES_LOC=""' fi + if [ $(uname -s) == "Darwin" ]; then + #OSX doesn't have libintl + echo -n "-DKBUILD_NO_NLS" + fi } # Temp file, try to clean up after us From 9ed7c4f8bc7f0c8d1f26bf68877b95099b6703ef Mon Sep 17 00:00:00 2001 From: Wangjialin Date: Thu, 3 Nov 2016 23:30:54 +0800 Subject: [PATCH 258/343] fix ringbuffer bug. --- components/driver/include/driver/uart.h | 3 +- components/driver/uart.c | 427 ++++++++++++------------ components/freertos/ringbuf.c | 30 +- 3 files changed, 214 insertions(+), 246 deletions(-) diff --git a/components/driver/include/driver/uart.h b/components/driver/include/driver/uart.h index 445d71b685..0d9ab3c563 100644 --- a/components/driver/include/driver/uart.h +++ b/components/driver/include/driver/uart.h @@ -437,13 +437,12 @@ esp_err_t uart_intr_config(uart_port_t uart_num, uart_intr_config_t *p_intr_conf * @param queue_size UART event queue size/depth. * @param uart_intr_num UART interrupt number,check the info in soc.h, and please refer to core-isa.h for more details * @param uart_queue UART event queue handle, if set NULL, driver will not use an event queue. - * @param buf_type UART RX ring_buffer type * * @return * - ESP_OK Success * - ESP_FAIL Parameter error */ -esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_buffer_size, int queue_size, int uart_intr_num, void* uart_queue, ringbuf_type_t rx_buf_type); +esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_buffer_size, int queue_size, int uart_intr_num, void* uart_queue); /** * @brief Uninstall UART driver. diff --git a/components/driver/uart.c b/components/driver/uart.c index d6585405f2..9eaf783438 100644 --- a/components/driver/uart.c +++ b/components/driver/uart.c @@ -43,28 +43,35 @@ const char* UART_TAG = "UART"; #define UART_EXIT_CRITICAL(mux) portEXIT_CRITICAL(mux) typedef struct { - uart_port_t uart_num; - SemaphoreHandle_t tx_fifo_sem; - SemaphoreHandle_t tx_mutex; - SemaphoreHandle_t tx_buffer_mutex; - SemaphoreHandle_t tx_done_sem; - SemaphoreHandle_t tx_brk_sem; - SemaphoreHandle_t rx_mux; - QueueHandle_t xQueueUart; - int queue_size; - int intr_num; - int rx_buf_size; - ringbuf_type_t rx_buf_type; - RingbufHandle_t rx_ring_buf; - int tx_buf_size; - RingbufHandle_t tx_ring_buf; - bool buffer_full_flg; - bool tx_waiting; - int cur_remain; - uint8_t* rd_ptr; - uint8_t* head_ptr; - uint8_t data_buf[UART_FIFO_LEN]; - uint8_t data_len; + uart_port_t uart_num; /*!< UART port number*/ + int queue_size; /*!< UART event queue size*/ + QueueHandle_t xQueueUart; /*!< UART queue handler*/ + int intr_num; /*!< UART interrupt number*/ + //rx parameters + SemaphoreHandle_t rx_mux; /*!< UART RX data mutex*/ + int rx_buf_size; /*!< RX ring buffer size */ + RingbufHandle_t rx_ring_buf; /*!< RX ring buffer handler*/ + bool rx_buffer_full_flg; /*!< RX ring buffer full flag. */ + int rx_cur_remain; /*!< Data number that waiting to be read out in ring buffer item*/ + uint8_t* rx_ptr; /*!< pointer to the current data in ring buffer*/ + uint8_t* rx_head_ptr; /*!< pointer to the head of RX item*/ + uint8_t rx_data_buf[UART_FIFO_LEN]; /*!< Data buffer to stash FIFO data*/ + uint8_t rx_stash_len; /*!< stashed data length.(When using flow control, after reading out FIFO data, if we fail to push to buffer, we can just stash them.) */ + //tx parameters + SemaphoreHandle_t tx_fifo_sem; /*!< UART TX FIFO semaphore*/ + SemaphoreHandle_t tx_mux; /*!< UART TX mutex*/ + SemaphoreHandle_t tx_buffer_mux; /*!< UART TX buffer semaphore*/ + SemaphoreHandle_t tx_done_sem; /*!< UART TX done semaphore*/ + SemaphoreHandle_t tx_brk_sem; /*!< UART TX send break done semaphore*/ + int tx_buf_size; /*!< TX ring buffer size */ + RingbufHandle_t tx_ring_buf; /*!< TX ring buffer handler*/ + bool tx_waiting_fifo; /*!< this flag indicates that some task is waiting for FIFO empty interrupt, used to send all data without any data buffer*/ + uint8_t* tx_ptr; /*!< TX data pointer to push to FIFO in TX buffer mode*/ + uart_event_t* tx_head; /*!< TX data pointer to head of the current buffer in TX ring buffer*/ + uint32_t tx_len_tot; /*!< Total length of current item in ring buffer*/ + uint8_t tx_brk_flg; /*!< Flag to indicate to send a break signal in the end of the item sending procedure */ + uint8_t tx_brk_len; /*!< TX break signal cycle length/number */ + uint8_t tx_waiting_brk; /*!< Flag to indicate that TX FIFO is ready to send break signal after FIFO is empty, do not push data into TX FIFO right now.*/ } uart_obj_t; static uart_obj_t *p_uart_obj[UART_NUM_MAX] = {0}; @@ -438,16 +445,8 @@ static void IRAM_ATTR uart_rx_intr_handler_default(void *param) uint32_t uart_intr_status = UART[uart_num]->int_st.val; int rx_fifo_len = 0; uart_event_t uart_event; - - static uint8_t * tx_ptr; - static uart_event_t* tx_head; - static int tx_len_tot = 0; - static int brk_flg = 0; - static int tx_brk_len = 0; - static int wait_brk = 0; - - portBASE_TYPE HPTaskAwoken = 0; + while(uart_intr_status != 0x0) { buf_idx = 0; uart_event.type = UART_EVENT_MAX; @@ -456,85 +455,92 @@ static void IRAM_ATTR uart_rx_intr_handler_default(void *param) uart_reg->int_ena.txfifo_empty = 0; uart_reg->int_clr.txfifo_empty = 1; UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); - if(wait_brk) { + if(p_uart->tx_waiting_brk) { return; } - if(p_uart->tx_waiting == true) { - p_uart->tx_waiting = false; + if(p_uart->tx_waiting_fifo == true) { + p_uart->tx_waiting_fifo = false; xSemaphoreGiveFromISR(p_uart->tx_fifo_sem, NULL); } else { + //We don't use TX ring buffer, because the size if zero. + if(p_uart->tx_buf_size == 0) { + return; + } int tx_fifo_rem = UART_FIFO_LEN - UART[uart_num]->status.txfifo_cnt; bool en_tx_flg = false; - if(tx_len_tot == 0) { - size_t size; -// ets_printf("dbg1,tot=0,get 1st head\n"); -// xRingbufferPrintInfo(p_uart->tx_ring_buf); - tx_head = (uart_event_t*) xRingbufferReceiveFromISR(p_uart->tx_ring_buf, &size); -// xRingbufferPrintInfo(p_uart->tx_ring_buf); - if(tx_head) { //enable empty intr -// tx_ptr = (uint8_t*)tx_head + sizeof(uart_event_t); - tx_ptr = NULL; -// en_tx_flg = true; - tx_len_tot = tx_head->data.size; - if(tx_head->type == UART_DATA_BREAK) { - tx_len_tot = tx_head->data.size; - brk_flg = 1; - tx_brk_len = tx_head->data.brk_len; + //We need to put a loop here, in case all the buffer items are very short. + //That would cause a watch_dog reset because empty interrupt happens so often. + //Although this is a loop in ISR, this loop will execute at most 128 turns. + while(tx_fifo_rem) { + if(p_uart->tx_len_tot == 0) { + size_t size; + //The first item is the data description + //Get the first item to get the data information + p_uart->tx_head = (uart_event_t*) xRingbufferReceiveFromISR(p_uart->tx_ring_buf, &size); + if(p_uart->tx_head) { + p_uart->tx_ptr = NULL; + p_uart->tx_len_tot = p_uart->tx_head->data.size; + if(p_uart->tx_head->type == UART_DATA_BREAK) { + p_uart->tx_len_tot = p_uart->tx_head->data.size; + p_uart->tx_brk_flg = 1; + p_uart->tx_brk_len = p_uart->tx_head->data.brk_len; + } + //We have saved the data description from the 1st item, return buffer. + vRingbufferReturnItemFromISR(p_uart->tx_ring_buf, p_uart->tx_head, &HPTaskAwoken); + } + else { + //Can not get data from ring buffer, return; + return; } -// ets_printf("ret1,tot: %d\n", tx_len_tot); - vRingbufferReturnItemFromISR(p_uart->tx_ring_buf, tx_head, &HPTaskAwoken); -// xRingbufferPrintInfo(p_uart->tx_ring_buf); -// xRingbufferPrintInfo(p_uart->tx_ring_buf); } - else { - return; - } - } - if(tx_ptr == NULL) { - size_t size; -// ets_printf("dbg2, tx ptr null, get 2nd tx ptr\n"); -// xRingbufferPrintInfo(p_uart->tx_ring_buf); - tx_ptr = (uint8_t*) xRingbufferReceiveFromISR(p_uart->tx_ring_buf, &size); - -// xRingbufferPrintInfo(p_uart->tx_ring_buf); - if(tx_ptr) { - tx_head = (void*) tx_ptr; -// ets_printf("get size: %d ; h size: %d\n", size, tx_len_tot); - en_tx_flg = true; - } else { - return; - } - } -// else - if(tx_len_tot > 0 && tx_ptr) { //tx - int send_len = tx_len_tot > tx_fifo_rem ? tx_fifo_rem : tx_len_tot; - for(buf_idx = 0; buf_idx < send_len; buf_idx++) { - WRITE_PERI_REG(UART_FIFO_AHB_REG(uart_num), *(tx_ptr++) & 0xff); - } - tx_len_tot -= send_len; -// ets_printf("tot: %d\n", tx_len_tot); - if(tx_len_tot == 0) { - if(brk_flg == 1) { - UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); - uart_reg->int_ena.tx_brk_done = 0; - uart_reg->idle_conf.tx_brk_num = tx_brk_len; - uart_reg->conf0.txd_brk = 1; - uart_reg->int_clr.tx_brk_done = 1; - uart_reg->int_ena.tx_brk_done = 1; - UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); - wait_brk = 1; + if(p_uart->tx_ptr == NULL) { + size_t size; + //2nd item is the data we need to send through UART + //Get 2nd item from ring buffer + p_uart->tx_ptr = (uint8_t*) xRingbufferReceiveFromISR(p_uart->tx_ring_buf, &size); + if(p_uart->tx_ptr) { + //Update the TX item head, we will need this to return item to buffer. + p_uart->tx_head = (void*) p_uart->tx_ptr; + en_tx_flg = true; } else { + //Can not get data from ring buffer, return; + return; + } + } + if(p_uart->tx_len_tot > 0 && p_uart->tx_ptr) { + //To fill the TX FIFO. + int send_len = p_uart->tx_len_tot > tx_fifo_rem ? tx_fifo_rem : p_uart->tx_len_tot; + for(buf_idx = 0; buf_idx < send_len; buf_idx++) { + WRITE_PERI_REG(UART_FIFO_AHB_REG(uart_num), *(p_uart->tx_ptr++) & 0xff); + } + p_uart->tx_len_tot -= send_len; + tx_fifo_rem -= send_len; + if(p_uart->tx_len_tot == 0) { + //Sending item done, now we need to send break if there is a record. + //Return item to ring buffer. + vRingbufferReturnItemFromISR(p_uart->tx_ring_buf, p_uart->tx_head, &HPTaskAwoken); + p_uart->tx_head = NULL; + p_uart->tx_ptr = NULL; + //Set TX break signal after FIFO is empty + if(p_uart->tx_brk_flg == 1) { + UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); + uart_reg->int_ena.tx_brk_done = 0; + uart_reg->idle_conf.tx_brk_num = p_uart->tx_brk_len; + uart_reg->conf0.txd_brk = 1; + uart_reg->int_clr.tx_brk_done = 1; + uart_reg->int_ena.tx_brk_done = 1; + UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); + p_uart->tx_waiting_brk = 1; + return; + } else { + //enable TX empty interrupt + en_tx_flg = true; + } + } else { + //enable TX empty interrupt en_tx_flg = true; } -// ets_printf("ret2\n"); - vRingbufferReturnItemFromISR(p_uart->tx_ring_buf, tx_head, &HPTaskAwoken); -// xRingbufferPrintInfo(p_uart->tx_ring_buf); -// xRingbufferPrintInfo(p_uart->tx_ring_buf); - tx_head = NULL; - tx_ptr = NULL; - } else { - en_tx_flg = true; } } if(en_tx_flg) { @@ -546,14 +552,13 @@ static void IRAM_ATTR uart_rx_intr_handler_default(void *param) } } else if((uart_intr_status & UART_RXFIFO_TOUT_INT_ST_M) || (uart_intr_status & UART_RXFIFO_FULL_INT_ST_M)) { - if(p_uart->buffer_full_flg == false) { + if(p_uart->rx_buffer_full_flg == false) { //Get the buffer from the FIFO -// ESP_LOGE(UART_TAG, "FULL\n"); rx_fifo_len = uart_reg->status.rxfifo_cnt; - p_uart->data_len = rx_fifo_len; - memset(p_uart->data_buf, 0, sizeof(p_uart->data_buf)); + p_uart->rx_stash_len = rx_fifo_len; + //We have to read out all data in RX FIFO to clear the interrupt signal while(buf_idx < rx_fifo_len) { - p_uart->data_buf[buf_idx++] = uart_reg->fifo.rw_byte; + p_uart->rx_data_buf[buf_idx++] = uart_reg->fifo.rw_byte; } //After Copying the Data From FIFO ,Clear intr_status UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); @@ -562,12 +567,14 @@ static void IRAM_ATTR uart_rx_intr_handler_default(void *param) UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); uart_event.type = UART_DATA; uart_event.data.size = rx_fifo_len; - if(pdFALSE == xRingbufferSendFromISR(p_uart->rx_ring_buf, p_uart->data_buf, p_uart->data_len, &HPTaskAwoken)) { + //If we fail to push data to ring buffer, we will have to stash the data, and send next time. + //Mainly for applications that uses flow control or small ring buffer. + if(pdFALSE == xRingbufferSendFromISR(p_uart->rx_ring_buf, p_uart->rx_data_buf, p_uart->rx_stash_len, &HPTaskAwoken)) { UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); uart_reg->int_ena.rxfifo_full = 0; uart_reg->int_ena.rxfifo_tout = 0; UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); - p_uart->buffer_full_flg = true; + p_uart->rx_buffer_full_flg = true; uart_event.type = UART_BUFFER_FULL; } else { uart_event.type = UART_DATA; @@ -597,19 +604,17 @@ static void IRAM_ATTR uart_rx_intr_handler_default(void *param) uart_reg->int_clr.frm_err = 1; uart_event.type = UART_PARITY_ERR; } else if(uart_intr_status & UART_TX_BRK_DONE_INT_ST_M) { -// ESP_LOGE(UART_TAG, "UART TX BRK DONE\n"); - ets_printf("tx brk done\n"); UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); uart_reg->conf0.txd_brk = 0; uart_reg->int_ena.tx_brk_done = 0; uart_reg->int_clr.tx_brk_done = 1; - if(brk_flg == 1) { + if(p_uart->tx_brk_flg == 1) { uart_reg->int_ena.txfifo_empty = 1; } UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); - if(brk_flg == 1) { - brk_flg = 0; - wait_brk = 0; + if(p_uart->tx_brk_flg == 1) { + p_uart->tx_brk_flg = 0; + p_uart->tx_waiting_brk = 0; } else { xSemaphoreGiveFromISR(p_uart->tx_brk_sem, &HPTaskAwoken); } @@ -644,8 +649,8 @@ esp_err_t uart_wait_tx_done(uart_port_t uart_num, TickType_t ticks_to_wait) UART_CHECK((p_uart_obj[uart_num]), "uart driver error"); BaseType_t res; portTickType ticks_end = xTaskGetTickCount() + ticks_to_wait; - //Take tx_mutex - res = xSemaphoreTake(p_uart_obj[uart_num]->tx_mutex, (portTickType)ticks_to_wait); + //Take tx_mux + res = xSemaphoreTake(p_uart_obj[uart_num]->tx_mux, (portTickType)ticks_to_wait); if(res == pdFALSE) { return ESP_ERR_TIMEOUT; } @@ -653,7 +658,7 @@ esp_err_t uart_wait_tx_done(uart_port_t uart_num, TickType_t ticks_to_wait) xSemaphoreTake(p_uart_obj[uart_num]->tx_done_sem, 0); ticks_to_wait = ticks_end - xTaskGetTickCount(); if(UART[uart_num]->status.txfifo_cnt == 0) { - xSemaphoreGive(p_uart_obj[uart_num]->tx_mutex); + xSemaphoreGive(p_uart_obj[uart_num]->tx_mux); return ESP_OK; } uart_enable_intr_mask(uart_num, UART_TX_DONE_INT_ENA_M); @@ -661,10 +666,10 @@ esp_err_t uart_wait_tx_done(uart_port_t uart_num, TickType_t ticks_to_wait) res = xSemaphoreTake(p_uart_obj[uart_num]->tx_done_sem, (portTickType)ticks_to_wait); if(res == pdFALSE) { uart_disable_intr_mask(uart_num, UART_TX_DONE_INT_ENA_M); - xSemaphoreGive(p_uart_obj[uart_num]->tx_mutex); + xSemaphoreGive(p_uart_obj[uart_num]->tx_mux); return ESP_ERR_TIMEOUT; } - xSemaphoreGive(p_uart_obj[uart_num]->tx_mutex); + xSemaphoreGive(p_uart_obj[uart_num]->tx_mux); return ESP_OK; } @@ -701,9 +706,9 @@ int uart_tx_chars(uart_port_t uart_num, char* buffer, uint32_t len) if(len == 0) { return 0; } - xSemaphoreTake(p_uart_obj[uart_num]->tx_mutex, (portTickType)portMAX_DELAY); + xSemaphoreTake(p_uart_obj[uart_num]->tx_mux, (portTickType)portMAX_DELAY); int tx_len = uart_fill_fifo(uart_num, buffer, len); - xSemaphoreGive(p_uart_obj[uart_num]->tx_mutex); + xSemaphoreGive(p_uart_obj[uart_num]->tx_mux); return tx_len; } @@ -716,14 +721,14 @@ static int uart_tx_all(uart_port_t uart_num, const char* src, size_t size, bool return 0; } //lock for uart_tx - xSemaphoreTake(p_uart_obj[uart_num]->tx_mutex, (portTickType)portMAX_DELAY); + xSemaphoreTake(p_uart_obj[uart_num]->tx_mux, (portTickType)portMAX_DELAY); size_t original_size = size; while(size) { //semaphore for tx_fifo available if(pdTRUE == xSemaphoreTake(p_uart_obj[uart_num]->tx_fifo_sem, (portTickType)portMAX_DELAY)) { size_t sent = uart_fill_fifo(uart_num, (char*) src, size); if(sent < size) { - p_uart_obj[uart_num]->tx_waiting = true; + p_uart_obj[uart_num]->tx_waiting_fifo = true; uart_enable_tx_intr(uart_num, 1, UART_EMPTY_THRESH_DEFAULT); } size -= sent; @@ -735,49 +740,25 @@ static int uart_tx_all(uart_port_t uart_num, const char* src, size_t size, bool xSemaphoreTake(p_uart_obj[uart_num]->tx_brk_sem, (portTickType)portMAX_DELAY); } xSemaphoreGive(p_uart_obj[uart_num]->tx_fifo_sem); - xSemaphoreGive(p_uart_obj[uart_num]->tx_mutex); + xSemaphoreGive(p_uart_obj[uart_num]->tx_mux); return original_size; } -//static void uart_tx_task(void* arg) -//{ -// uart_obj_t* p_uart = (uart_obj_t*) arg; -// size_t size; -// uart_event_t evt; -// for(;;) { -// char* data = (char*) xRingbufferReceive(p_uart->tx_ring_buf, &size, portMAX_DELAY); -// if(data == NULL) { -// continue; -// } -// memcpy(&evt, data, sizeof(evt)); -// if(evt.type == UART_DATA) { -// uart_tx_all(p_uart->uart_num, (const char*) data + sizeof(uart_event_t), evt.data.size, 0, 0); -// } else if(evt.type == UART_DATA_BREAK) { -// uart_tx_all(p_uart->uart_num, (const char*) data + sizeof(uart_event_t), evt.data.size, 1, evt.data.brk_len); -// } -// vRingbufferReturnItem(p_uart->tx_ring_buf, data); -// } -// vTaskDelete(NULL); -//} - int uart_tx_all_chars(uart_port_t uart_num, const char* src, size_t size) { UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); UART_CHECK((p_uart_obj[uart_num] != NULL), "uart driver error"); UART_CHECK(src, "buffer null"); + //Push data to TX ring buffer and return, ISR will send the data. if(p_uart_obj[uart_num]->tx_buf_size > 0) { if(xRingbufferGetMaxItemSize(p_uart_obj[uart_num]->tx_ring_buf) > (size + sizeof(uart_event_t))) { uart_event_t evt; - xSemaphoreTake(p_uart_obj[uart_num]->tx_buffer_mutex, (portTickType)portMAX_DELAY); + xSemaphoreTake(p_uart_obj[uart_num]->tx_buffer_mux, (portTickType)portMAX_DELAY); evt.type = UART_DATA; evt.data.size = size; - ets_printf("-----1st send-----\n"); xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void*) &evt, sizeof(uart_event_t), portMAX_DELAY); - xRingbufferPrintInfo(p_uart_obj[uart_num]->tx_ring_buf); - ets_printf("====2nd send====\n"); xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void*) src, size, portMAX_DELAY); - xRingbufferPrintInfo(p_uart_obj[uart_num]->tx_ring_buf); - xSemaphoreGive(p_uart_obj[uart_num]->tx_buffer_mutex); + xSemaphoreGive(p_uart_obj[uart_num]->tx_buffer_mux); uart_enable_tx_intr(uart_num, 1, UART_EMPTY_THRESH_DEFAULT); return size; } else { @@ -785,6 +766,7 @@ int uart_tx_all_chars(uart_port_t uart_num, const char* src, size_t size) return uart_tx_all(uart_num, src, size, 0, 0); } } else { + //Send data without TX ring buffer, the task will block until all data have been sent out return uart_tx_all(uart_num, src, size, 0, 0); } } @@ -796,16 +778,17 @@ int uart_tx_all_chars_with_break(uart_port_t uart_num, const char* src, size_t s UART_CHECK((size > 0), "uart size error"); UART_CHECK((src), "uart data null"); UART_CHECK((brk_len > 0 && brk_len < 256), "break_num error"); + //Push data to TX ring buffer and return, ISR will send the data. if(p_uart_obj[uart_num]->tx_buf_size > 0) { if(xRingbufferGetMaxItemSize(p_uart_obj[uart_num]->tx_ring_buf) > (size)) { uart_event_t evt; - xSemaphoreTake(p_uart_obj[uart_num]->tx_buffer_mutex, (portTickType)portMAX_DELAY); + xSemaphoreTake(p_uart_obj[uart_num]->tx_buffer_mux, (portTickType)portMAX_DELAY); evt.type = UART_DATA_BREAK; evt.data.size = size; evt.data.brk_len = brk_len; xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void*) &evt, sizeof(uart_event_t), portMAX_DELAY); xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void*) src, size, portMAX_DELAY); - xSemaphoreGive(p_uart_obj[uart_num]->tx_buffer_mutex); + xSemaphoreGive(p_uart_obj[uart_num]->tx_buffer_mux); uart_enable_tx_intr(uart_num, 1, UART_EMPTY_THRESH_DEFAULT); return size; } else { @@ -813,6 +796,7 @@ int uart_tx_all_chars_with_break(uart_port_t uart_num, const char* src, size_t s return uart_tx_all(uart_num, src, size, 1, brk_len); } } else { + //Send data without TX ring buffer, the task will block until all data have been sent out return uart_tx_all(uart_num, src, size, 1, brk_len); } } @@ -828,29 +812,29 @@ int uart_read_char(uart_port_t uart_num, TickType_t ticks_to_wait) if(xSemaphoreTake(p_uart_obj[uart_num]->rx_mux,(portTickType)ticks_to_wait) != pdTRUE) { return -1; } - if(p_uart_obj[uart_num]->cur_remain == 0) { + if(p_uart_obj[uart_num]->rx_cur_remain == 0) { ticks_to_wait = ticks_end - xTaskGetTickCount(); data = (uint8_t*) xRingbufferReceive(p_uart_obj[uart_num]->rx_ring_buf, &size, (portTickType) ticks_to_wait); if(data) { - p_uart_obj[uart_num]->head_ptr = data; - p_uart_obj[uart_num]->rd_ptr = data; - p_uart_obj[uart_num]->cur_remain = size; + p_uart_obj[uart_num]->rx_head_ptr = data; + p_uart_obj[uart_num]->rx_ptr = data; + p_uart_obj[uart_num]->rx_cur_remain = size; } else { xSemaphoreGive(p_uart_obj[uart_num]->rx_mux); return -1; } } - val = *(p_uart_obj[uart_num]->rd_ptr); - p_uart_obj[uart_num]->rd_ptr++; - p_uart_obj[uart_num]->cur_remain--; - if(p_uart_obj[uart_num]->cur_remain == 0) { - vRingbufferReturnItem(p_uart_obj[uart_num]->rx_ring_buf, p_uart_obj[uart_num]->head_ptr); - p_uart_obj[uart_num]->head_ptr = NULL; - p_uart_obj[uart_num]->rd_ptr = NULL; - if(p_uart_obj[uart_num]->buffer_full_flg) { - BaseType_t res = xRingbufferSend(p_uart_obj[uart_num]->rx_ring_buf, p_uart_obj[uart_num]->data_buf, p_uart_obj[uart_num]->data_len, 1); + val = *(p_uart_obj[uart_num]->rx_ptr); + p_uart_obj[uart_num]->rx_ptr++; + p_uart_obj[uart_num]->rx_cur_remain--; + if(p_uart_obj[uart_num]->rx_cur_remain == 0) { + vRingbufferReturnItem(p_uart_obj[uart_num]->rx_ring_buf, p_uart_obj[uart_num]->rx_head_ptr); + p_uart_obj[uart_num]->rx_head_ptr = NULL; + p_uart_obj[uart_num]->rx_ptr = NULL; + if(p_uart_obj[uart_num]->rx_buffer_full_flg) { + BaseType_t res = xRingbufferSend(p_uart_obj[uart_num]->rx_ring_buf, p_uart_obj[uart_num]->rx_data_buf, p_uart_obj[uart_num]->rx_stash_len, 1); if(res == pdTRUE) { - p_uart_obj[uart_num]->buffer_full_flg = false; + p_uart_obj[uart_num]->rx_buffer_full_flg = false; uart_enable_rx_intr(p_uart_obj[uart_num]->uart_num); } } @@ -872,46 +856,40 @@ int uart_read_bytes(uart_port_t uart_num, uint8_t* buf, uint32_t length, TickTyp return -1; } while(length) { - if(p_uart_obj[uart_num]->cur_remain == 0) { + if(p_uart_obj[uart_num]->rx_cur_remain == 0) { data = (uint8_t*) xRingbufferReceive(p_uart_obj[uart_num]->rx_ring_buf, &size, (portTickType) ticks_to_wait); if(data) { - p_uart_obj[uart_num]->head_ptr = data; - p_uart_obj[uart_num]->rd_ptr = data; - p_uart_obj[uart_num]->cur_remain = size; -// ets_printf("dbg0\n"); + p_uart_obj[uart_num]->rx_head_ptr = data; + p_uart_obj[uart_num]->rx_ptr = data; + p_uart_obj[uart_num]->rx_cur_remain = size; } else { xSemaphoreGive(p_uart_obj[uart_num]->rx_mux); -// ets_printf("dbg1\n"); return copy_len; } } - if(p_uart_obj[uart_num]->cur_remain > length) { + if(p_uart_obj[uart_num]->rx_cur_remain > length) { len_tmp = length; } else { - len_tmp = p_uart_obj[uart_num]->cur_remain; + len_tmp = p_uart_obj[uart_num]->rx_cur_remain; } -// ets_printf("dbga\n"); - memcpy(buf + copy_len, p_uart_obj[uart_num]->rd_ptr, len_tmp); - p_uart_obj[uart_num]->rd_ptr += len_tmp; - p_uart_obj[uart_num]->cur_remain -= len_tmp; + memcpy(buf + copy_len, p_uart_obj[uart_num]->rx_ptr, len_tmp); + p_uart_obj[uart_num]->rx_ptr += len_tmp; + p_uart_obj[uart_num]->rx_cur_remain -= len_tmp; copy_len += len_tmp; length -= len_tmp; -// ets_printf("dbgb\n"); - if(p_uart_obj[uart_num]->cur_remain == 0) { - vRingbufferReturnItem(p_uart_obj[uart_num]->rx_ring_buf, p_uart_obj[uart_num]->head_ptr); - p_uart_obj[uart_num]->head_ptr = NULL; - p_uart_obj[uart_num]->rd_ptr = NULL; - if(p_uart_obj[uart_num]->buffer_full_flg) { - BaseType_t res = xRingbufferSend(p_uart_obj[uart_num]->rx_ring_buf, p_uart_obj[uart_num]->data_buf, p_uart_obj[uart_num]->data_len, 1); -// ets_printf("dbg2\n"); + if(p_uart_obj[uart_num]->rx_cur_remain == 0) { + vRingbufferReturnItem(p_uart_obj[uart_num]->rx_ring_buf, p_uart_obj[uart_num]->rx_head_ptr); + p_uart_obj[uart_num]->rx_head_ptr = NULL; + p_uart_obj[uart_num]->rx_ptr = NULL; + if(p_uart_obj[uart_num]->rx_buffer_full_flg) { + BaseType_t res = xRingbufferSend(p_uart_obj[uart_num]->rx_ring_buf, p_uart_obj[uart_num]->rx_data_buf, p_uart_obj[uart_num]->rx_stash_len, 1); if(res == pdTRUE) { - p_uart_obj[uart_num]->buffer_full_flg = false; + p_uart_obj[uart_num]->rx_buffer_full_flg = false; uart_enable_rx_intr(p_uart_obj[uart_num]->uart_num); } } } } -// ets_printf("dbg3\n"); xSemaphoreGive(p_uart_obj[uart_num]->rx_mux); return copy_len; } @@ -926,11 +904,11 @@ esp_err_t uart_flush(uart_port_t uart_num) //rx sem protect the ring buffer read related functions xSemaphoreTake(p_uart->rx_mux, (portTickType)portMAX_DELAY); while(true) { - if(p_uart->head_ptr) { - vRingbufferReturnItem(p_uart->rx_ring_buf, p_uart->head_ptr); - p_uart->rd_ptr = NULL; - p_uart->cur_remain = 0; - p_uart->head_ptr = NULL; + if(p_uart->rx_head_ptr) { + vRingbufferReturnItem(p_uart->rx_ring_buf, p_uart->rx_head_ptr); + p_uart->rx_ptr = NULL; + p_uart->rx_cur_remain = 0; + p_uart->rx_head_ptr = NULL; } data = (uint8_t*) xRingbufferReceive(p_uart->rx_ring_buf, &size, (portTickType) 0); if(data == NULL) { @@ -938,19 +916,24 @@ esp_err_t uart_flush(uart_port_t uart_num) } vRingbufferReturnItem(p_uart->rx_ring_buf, data); } - p_uart->rd_ptr = NULL; - p_uart->cur_remain = 0; - p_uart->head_ptr = NULL; + p_uart->rx_ptr = NULL; + p_uart->rx_cur_remain = 0; + p_uart->rx_head_ptr = NULL; xSemaphoreGive(p_uart->rx_mux); - xSemaphoreTake(p_uart->tx_mutex, (portTickType)portMAX_DELAY); - do { - data = (uint8_t*) xRingbufferReceive(p_uart->tx_ring_buf, &size, (portTickType) 0); - if(data == NULL) { - break; - } - vRingbufferReturnItem(p_uart->rx_ring_buf, data); - } while(1); - xSemaphoreGive(p_uart->tx_mutex); + + xSemaphoreTake(p_uart->tx_mux, (portTickType)portMAX_DELAY); + if(p_uart->tx_buf_size > 0) { + xSemaphoreTake(p_uart->tx_buffer_mux, (portTickType)portMAX_DELAY); + do { + data = (uint8_t*) xRingbufferReceive(p_uart->tx_ring_buf, &size, (portTickType) 0); + if(data == NULL) { + break; + } + vRingbufferReturnItem(p_uart->rx_ring_buf, data); + } while(1); + xSemaphoreGive(p_uart->tx_buffer_mux); + } + xSemaphoreGive(p_uart->tx_mux); uart_wait_tx_done(uart_num, portMAX_DELAY); uart_reset_fifo(uart_num); return ESP_OK; @@ -1009,7 +992,7 @@ int uart_get_print_port() return s_uart_print_nport; } -esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_buffer_size, int queue_size, int uart_intr_num, void* uart_queue, ringbuf_type_t rx_buf_type) +esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_buffer_size, int queue_size, int uart_intr_num, void* uart_queue) { UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); UART_CHECK((rx_buffer_size > 0), "uart rx buffer length error\n"); @@ -1025,11 +1008,16 @@ esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_b xSemaphoreGive(p_uart_obj[uart_num]->tx_fifo_sem); p_uart_obj[uart_num]->tx_done_sem = xSemaphoreCreateBinary(); p_uart_obj[uart_num]->tx_brk_sem = xSemaphoreCreateBinary(); - p_uart_obj[uart_num]->tx_mutex = xSemaphoreCreateMutex(); - p_uart_obj[uart_num]->tx_buffer_mutex = xSemaphoreCreateMutex(); + p_uart_obj[uart_num]->tx_mux = xSemaphoreCreateMutex(); p_uart_obj[uart_num]->rx_mux = xSemaphoreCreateMutex(); p_uart_obj[uart_num]->intr_num = uart_intr_num; p_uart_obj[uart_num]->queue_size = queue_size; + p_uart_obj[uart_num]->tx_ptr = NULL; + p_uart_obj[uart_num]->tx_head = NULL; + p_uart_obj[uart_num]->tx_len_tot = 0; + p_uart_obj[uart_num]->tx_brk_flg = 0; + p_uart_obj[uart_num]->tx_brk_len = 0; + p_uart_obj[uart_num]->tx_waiting_brk = 0; if(uart_queue) { p_uart_obj[uart_num]->xQueueUart = xQueueCreate(queue_size, sizeof(uart_event_t)); @@ -1038,19 +1026,20 @@ esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_b } else { p_uart_obj[uart_num]->xQueueUart = NULL; } - p_uart_obj[uart_num]->buffer_full_flg = false; - p_uart_obj[uart_num]->tx_waiting = false; - p_uart_obj[uart_num]->rd_ptr = NULL; - p_uart_obj[uart_num]->cur_remain = 0; - p_uart_obj[uart_num]->head_ptr = NULL; - p_uart_obj[uart_num]->rx_buf_type = rx_buf_type; - p_uart_obj[uart_num]->rx_ring_buf = xRingbufferCreate(rx_buffer_size, rx_buf_type); + p_uart_obj[uart_num]->rx_buffer_full_flg = false; + p_uart_obj[uart_num]->tx_waiting_fifo = false; + p_uart_obj[uart_num]->rx_ptr = NULL; + p_uart_obj[uart_num]->rx_cur_remain = 0; + p_uart_obj[uart_num]->rx_head_ptr = NULL; + p_uart_obj[uart_num]->rx_ring_buf = xRingbufferCreate(rx_buffer_size, RINGBUF_TYPE_BYTEBUF); if(tx_buffer_size > 0) { p_uart_obj[uart_num]->tx_ring_buf = xRingbufferCreate(tx_buffer_size, RINGBUF_TYPE_NOSPLIT);//RINGBUF_TYPE_BYTEBUF);//RINGBUF_TYPE_NOSPLIT); p_uart_obj[uart_num]->tx_buf_size = tx_buffer_size; + p_uart_obj[uart_num]->tx_buffer_mux = xSemaphoreCreateMutex(); } else { p_uart_obj[uart_num]->tx_ring_buf = NULL; p_uart_obj[uart_num]->tx_buf_size = 0; + p_uart_obj[uart_num]->tx_buffer_mux = NULL; } } else { ESP_LOGE(UART_TAG, "UART driver already installed\n"); @@ -1097,13 +1086,13 @@ esp_err_t uart_driver_delete(uart_port_t uart_num) vSemaphoreDelete(p_uart_obj[uart_num]->tx_brk_sem); p_uart_obj[uart_num]->tx_brk_sem = NULL; } - if(p_uart_obj[uart_num]->tx_mutex) { - vSemaphoreDelete(p_uart_obj[uart_num]->tx_mutex); - p_uart_obj[uart_num]->tx_mutex = NULL; + if(p_uart_obj[uart_num]->tx_mux) { + vSemaphoreDelete(p_uart_obj[uart_num]->tx_mux); + p_uart_obj[uart_num]->tx_mux = NULL; } - if(p_uart_obj[uart_num]->tx_buffer_mutex) { - vSemaphoreDelete(p_uart_obj[uart_num]->tx_buffer_mutex); - p_uart_obj[uart_num]->tx_buffer_mutex = NULL; + if(p_uart_obj[uart_num]->tx_buffer_mux) { + vSemaphoreDelete(p_uart_obj[uart_num]->tx_buffer_mux); + p_uart_obj[uart_num]->tx_buffer_mux = NULL; } if(p_uart_obj[uart_num]->rx_mux) { vSemaphoreDelete(p_uart_obj[uart_num]->rx_mux); diff --git a/components/freertos/ringbuf.c b/components/freertos/ringbuf.c index 560eb5fdd9..a4205d88dc 100644 --- a/components/freertos/ringbuf.c +++ b/components/freertos/ringbuf.c @@ -77,13 +77,9 @@ static int ringbufferFreeMem(ringbuf_t *rb) { int free_size = rb->free_ptr-rb->write_ptr; if (free_size <= 0) free_size += rb->size; - //If we free the last dummy item in the buffer, free_ptr will point to rb->data - //In this case, after we write the last some bytes, the buffer might wrap around if we don't have room for a header anymore. -// if (free_size == 0 && rb->read_ptr == rb->write_ptr) free_size += rb->size; //Reserve one byte. If we do not do this and the entire buffer is filled, we get a situation - //where write_ptr == free_ptr, messing up the next calculation. -// return free_size == 0 ? 0 : free_size - 1; - return free_size - 1; + //where read_ptr == free_ptr, messing up the next calculation. + return free_size-1; } @@ -338,10 +334,6 @@ static uint8_t *getItemFromRingbufByteBuf(ringbuf_t *rb, size_t *length, int wan //can be increase. //This function by itself is not threadsafe, always call from within a muxed section. static void returnItemToRingbufDefault(ringbuf_t *rb, void *item) { - ets_printf("in returnItemToRingbufDefault\n"); - xRingbufferPrintInfo(rb); - - uint8_t *data=(uint8_t*)item; configASSERT(((int)rb->free_ptr&3)==0); configASSERT(data >= rb->data); @@ -358,16 +350,9 @@ static void returnItemToRingbufDefault(ringbuf_t *rb, void *item) { hdr=(buf_entry_hdr_t *)rb->free_ptr; //basically forward free_ptr until we run into either a block that is still in use or the write pointer. while (((hdr->flags & iflag_free) || (hdr->flags & iflag_dummydata)) && rb->free_ptr != rb->write_ptr) { - if (hdr->flags & iflag_dummydata) { - ets_printf("hrd len: %d; flg: 0x%02x\n",hdr->len,hdr->flags); //Rest is dummy data. Reset to start of ringbuffer. rb->free_ptr=rb->data; - //If the read_ptr is pointing to this dummy item, - //we should also move the read pointer to data, in case we overwrite the read hdr. -// if(rb->read_ptr == (uint8_t*)hdr) { -// rb->read_ptr = rb->data; -// } } else { //Skip past item size_t len=(hdr->len+3)&~3; @@ -378,10 +363,11 @@ static void returnItemToRingbufDefault(ringbuf_t *rb, void *item) { if ((rb->data+rb->size)-rb->free_ptr < sizeof(buf_entry_hdr_t)) { rb->free_ptr=rb->data; } + //The free_ptr can not exceed read_ptr, otherwise write_ptr might overwrite read_ptr. + //Read_ptr can not set to rb->data with free_ptr, otherwise write_ptr might wrap around to rb->data. if(rb->free_ptr == rb->read_ptr) break; //Next header hdr=(buf_entry_hdr_t *)rb->free_ptr; - } } @@ -403,12 +389,6 @@ void xRingbufferPrintInfo(RingbufHandle_t ringbuf) configASSERT(rb); ets_printf("Rb size %d free %d rptr %d freeptr %d wptr %d\n", rb->size, ringbufferFreeMem(rb), rb->read_ptr-rb->data, rb->free_ptr-rb->data, rb->write_ptr-rb->data); - buf_entry_hdr_t *hdr=(buf_entry_hdr_t *)rb->read_ptr; - if(rb->write_ptr == rb->read_ptr) { - ets_printf("write que read\n"); - } else { - ets_printf("hdr len: %d; flg: 0x%08x\n", hdr->len, hdr->flags); - } } @@ -516,7 +496,7 @@ BaseType_t xRingbufferSend(RingbufHandle_t ringbuf, void *data, size_t dataSize, ticks_to_wait = ticks_end - xTaskGetTickCount(); } } while (ringbufferFreeMem(rb) < needed_size && ticks_to_wait>=0); - + //Lock the mux in order to make sure no one else is messing with the ringbuffer and do the copy. portENTER_CRITICAL(&rb->mux); //Another thread may have been able to sneak its write first. Check again now we locked the ringbuff, and retry From a6b3be6734b8f8acd13a8f401d046f3531b7a893 Mon Sep 17 00:00:00 2001 From: Wangjialin Date: Fri, 4 Nov 2016 02:48:25 +0800 Subject: [PATCH 259/343] Update UART driver 1. fix bug in ringbuffer.c: When return an dummy item, free_ptr might exceed rd_ptr, so the write_ptr would overwrite rd_ptr in this case. 2. Delete UART tx task in buffer mode. UART ISR will copy the data from tx buffer to fifo. --- components/driver/include/driver/uart.h | 110 +++++++-- components/driver/uart.c | 285 ++++++++++++------------ 2 files changed, 237 insertions(+), 158 deletions(-) diff --git a/components/driver/include/driver/uart.h b/components/driver/include/driver/uart.h index 0d9ab3c563..200d1148cb 100644 --- a/components/driver/include/driver/uart.h +++ b/components/driver/include/driver/uart.h @@ -87,8 +87,8 @@ typedef struct { uart_word_length_t data_bits; /*!< UART byte size*/ uart_parity_t parity; /*!< UART parity mode*/ uart_stop_bits_t stop_bits; /*!< UART stop bits*/ - uart_hw_flowcontrol_t flow_ctrl; /*!< UART hw flow control mode(cts/rts)*/ - uint8_t rx_flow_ctrl_thresh ; /*!< UART hw RTS threshold*/ + uart_hw_flowcontrol_t flow_ctrl; /*!< UART HW flow control mode(cts/rts)*/ + uint8_t rx_flow_ctrl_thresh ; /*!< UART HW RTS threshold*/ } uart_config_t; typedef struct { @@ -124,6 +124,7 @@ typedef struct { * @brief Set UART data bits. * * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * * @param data_bit UART data bits * * @return @@ -147,6 +148,7 @@ esp_err_t uart_get_word_length(uart_port_t uart_num, uart_word_length_t* data_bi * @brief Set UART stop bits. * * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * * @param bit_num UART stop bits * * @return @@ -170,6 +172,7 @@ esp_err_t uart_get_stop_bits(uart_port_t uart_num, uart_stop_bits_t* stop_bit); * @brief Set UART parity. * * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * * @param parity_mode the enum of uart parity configuration * * @return @@ -194,6 +197,7 @@ esp_err_t uart_get_parity(uart_port_t uart_num, uart_parity_t* parity_mode); * @brief Set UART baud rate. * * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * * @param baud_rate UART baud-rate. * * @return @@ -216,7 +220,9 @@ esp_err_t uart_get_baudrate(uart_port_t uart_num, uint32_t* baudrate); /** * @brief Set UART line inverse mode + * * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * * @param inverse_mask Choose the wires that need to be inversed. * * (inverse_mask should be chosen from uart_inverse_t, combine with OR-OPERATION) @@ -232,7 +238,9 @@ esp_err_t uart_set_line_inverse(uart_port_t uart_no, uint32_t inverse_mask) ; * @brief Set hardware flow control. * * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * * @param flow_ctrl Hardware flow control mode + * * @param rx_thresh Threshold of Hardware RX flow control(0 ~ UART_FIFO_LEN) * * @return @@ -243,6 +251,7 @@ esp_err_t uart_set_hw_flow_ctrl(uart_port_t uart_no, uart_hw_flowcontrol_t flow_ /** * @brief Get hardware flow control mode + * * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 * * @return @@ -255,6 +264,7 @@ esp_err_t uart_get_hw_flow_ctrl(uart_port_t uart_num, uart_hw_flowcontrol_t* flo * @brief Clear UART interrupt status * * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * * @param clr_mask Bit mask of the status that to be cleared. * * (enable_mask should be chosen from the fields of register UART_INT_CLR_REG) @@ -269,6 +279,7 @@ esp_err_t uart_clear_intr_status(uart_port_t uart_num, uint32_t clr_mask); * @brief Set UART interrupt enable * * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * * @param enable_mask Bit mask of the enable bits. * * (enable_mask should be chosen from the fields of register UART_INT_ENA_REG) @@ -283,6 +294,7 @@ esp_err_t uart_enable_intr_mask(uart_port_t uart_num, uint32_t enable_mask); * @brief Clear UART interrupt enable bits * * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * * @param disable_mask Bit mask of the disable bits. * * (disable_mask should be chosen from the fields of register UART_INT_ENA_REG) @@ -331,7 +343,9 @@ esp_err_t uart_disable_tx_intr(uart_port_t uart_num); * @brief Enable UART TX interrupt(RX_FULL & RX_TIMEOUT INTERRUPT) * * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * * @param enable 1: enable; 0: disable + * * @param thresh Threshold of TX interrupt, 0 ~ UART_FIFO_LEN * * @return @@ -342,13 +356,16 @@ esp_err_t uart_enable_tx_intr(uart_port_t uart_num, int enable, int thresh); /** * @brief register UART interrupt handler(ISR). +* @note * UART ISR handler will be attached to the same CPU core that this function is running on. * Users should know that which CPU is running and then pick a INUM that is not used by system. * We can find the information of INUM and interrupt level in soc.h. * * * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * * @param uart_intr_num UART interrupt number,check the info in soc.h, and please refer to core-isa.h for more details + * * @param fn Interrupt handler function. * @attention * The ISR handler function MUST be defined with attribution of "IRAM_ATTR" for now. @@ -364,9 +381,13 @@ esp_err_t uart_isr_register(uart_port_t uart_num, uint8_t uart_intr_num, void (* * @brief Set UART pin number * * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * * @param tx_io_num UART TX pin GPIO number + * * @param rx_io_num UART RX pin GPIO number + * * @param rts_io_num UART RTS pin GPIO number + * * @param cts_io_num UART CTS pin GPIO number * * @return @@ -380,6 +401,7 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r * UART rx hardware flow control should not be set. * * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * * @param level 1: RTS output low(active); 0: RTS output high(block) * * @return @@ -392,6 +414,7 @@ esp_err_t uart_set_rts(uart_port_t uart_num, int level); * @brief UART set DTR level (before inverse) * * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * * @param level 1: DTR output low; 0: DTR output high * * @return @@ -404,6 +427,7 @@ esp_err_t uart_set_dtr(uart_port_t uart_num, int level); * @brief UART parameter configure * * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * * @param uart_config UART parameter settings * * @return @@ -416,6 +440,7 @@ esp_err_t uart_param_config(uart_port_t uart_num, uart_config_t *uart_config); * @brief UART interrupt configure * * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * * @param p_intr_conf UART interrupt settings * * @return @@ -431,12 +456,19 @@ esp_err_t uart_intr_config(uart_port_t uart_num, uart_intr_config_t *p_intr_conf * Users should know that which CPU is running and then pick a INUM that is not used by system. * We can find the information of INUM and interrupt level in soc.h. * - * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param rx_buffer_size UART RX ring buffer size - * @param tx_buffer_size UART TX ring buffer size, if set to zero, driver will not use TX buffer and TX task. - * @param queue_size UART event queue size/depth. + * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * + * @param rx_buffer_size UART RX ring buffer size + * + * @param tx_buffer_size UART TX ring buffer size. + * + * If set to zero, driver will not use TX buffer, TX function will block task until all data have been sent out.. + * + * @param queue_size UART event queue size/depth. + * * @param uart_intr_num UART interrupt number,check the info in soc.h, and please refer to core-isa.h for more details - * @param uart_queue UART event queue handle, if set NULL, driver will not use an event queue. + * + * @param uart_queue UART event queue handle, if set NULL, driver will not use an event queue. * * @return * - ESP_OK Success @@ -459,6 +491,7 @@ esp_err_t uart_driver_delete(uart_port_t uart_num); * @brief Wait UART TX FIFO empty * * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * * @param ticks_to_wait Timeout, count in RTOS ticks * * @return @@ -473,7 +506,9 @@ esp_err_t uart_wait_tx_done(uart_port_t uart_num, TickType_t ticks_to_wait); * This function will not wait for the space in TX FIFO, just fill the TX FIFO and return when the FIFO is full. * * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * * @param buffer data buffer address + * * @param len data length to send * * @return @@ -484,10 +519,17 @@ int uart_tx_chars(uart_port_t uart_no, char* buffer, uint32_t len); /** * @brief Send data to the UART port from a given buffer and length, + * + * If parameter tx_buffer_size is set to zero: * This function will not return until all the data have been sent out, or at least pushed into TX FIFO. * + * Otherwise, if tx_buffer_size > 0, this function will return after copying all the data to tx ringbuffer, + * then, UART ISR will move data from ring buffer to TX FIFO gradually. + * * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * * @param src data buffer address + * * @param size data length to send * * @return @@ -498,23 +540,37 @@ int uart_tx_all_chars(uart_port_t uart_num, const char* src, size_t size); /** * @brief Send data to the UART port from a given buffer and length, + * + * If parameter tx_buffer_size is set to zero: * This function will not return until all the data and the break signal have been sent out. + * After all data send out, send a break signal. + * + * Otherwise, if tx_buffer_size > 0, this function will return after copying all the data to tx ringbuffer, + * then, UART ISR will move data from ring buffer to TX FIFO gradually. + * After all data send out, send a break signal. + * + * * * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * * @param src data buffer address + * * @param size data length to send + * * @param brk_len break signal length (unit: one bit's time@current_baudrate) * * @return * - (-1) Parameter error * - OTHERS(>=0) The number of data that pushed to the TX FIFO */ + int uart_tx_all_chars_with_break(uart_port_t uart_num, const char* src, size_t size, int brk_len); /** * @brief UART read one char * * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * * @param ticks_to_wait Timeout, count in RTOS ticks * * @return @@ -527,10 +583,14 @@ int uart_read_char(uart_port_t uart_num, TickType_t ticks_to_wait); * @brief UART read bytes from UART buffer * * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * * @param buf pointer to the buffer. + * * @param length data length + * * @param ticks_to_wait sTimeout, count in RTOS ticks * + * * @return * - (-1) Error * - Others return a char data from uart fifo. @@ -588,14 +648,17 @@ int uart_get_print_port(void); * uart_param_config(uart_num, &uart_config); * //b1. Setup UART driver(with UART queue) * QueueHandle_t uart_queue; - * uart_driver_install(uart_num, 1024 * 2, 10, UART_INTR_NUM, &uart_queue);//parameters here are just an example + * //parameters here are just an example, tx buffer size is 2048 + * uart_driver_install(uart_num, 1024 * 2, 1024 * 2, 10, UART_INTR_NUM, &uart_queue); * //b2. Setup UART driver(without UART queue) - * uart_driver_install(uart_num, 1024 * 2, 10, UART_INTR_NUM, NULL); //parameters here are just an example + * //parameters here are just an example, tx buffer size is 0 + * uart_driver_install(uart_num, 1024 * 2, 0, 10, UART_INTR_NUM, NULL); *@endcode *-----------------------------------------------------------------------------* * @code{c} * //2. Set UART pin - * uart_set_pin(uart_num, -1, -1, 15, 13); //set UART pin, not needed if use default pins. + * //set UART pin, not needed if use default pins. + * uart_set_pin(uart_num, -1, -1, 15, 13); * @endcode *-----------------------------------------------------------------------------* * @code{c} @@ -629,15 +692,20 @@ int uart_get_print_port(void); * .flow_ctrl = UART_HW_FLOWCTRL_CTS_RTS, * .rx_flow_ctrl_thresh = 122, * }; - * uart_param_config(uart_num, &uart_config); //Config UART1 parameters - * uart_set_pin(uart_num, 16, 17, 18, 19); //Set UART1 pins(TX: IO16, RX: IO17, RTS: IO18, CTS: IO19) - * esp_log_level_set(UART_TAG, ESP_LOG_ERROR); //Set UART log level + * //Configure UART1 parameters + * uart_param_config(uart_num, &uart_config); + * //Set UART1 pins(TX: IO16, RX: IO17, RTS: IO18, CTS: IO19) + * uart_set_pin(uart_num, 16, 17, 18, 19); + * //Set UART log level + * esp_log_level_set(UART_TAG, ESP_LOG_ERROR); * //Install UART driver( We don't need an event queue here) * uart_driver_install(uart_num, 1024 * 2, 1024*4, 10, 17, NULL, RINGBUF_TYPE_BYTEBUF); * uint8_t data[1000]; * while(1) { - * int len = uart_read_bytes(uart_num, data, sizeof(data), 10); //Read data from UART - * uart_tx_all_chars(uart_num, (const char*)data, len); //Write data back to UART + * //Read data from UART + * int len = uart_read_bytes(uart_num, data, sizeof(data), 10); + * //Write data back to UART + * uart_tx_all_chars(uart_num, (const char*)data, len); * } * } * @endcode @@ -704,12 +772,16 @@ int uart_get_print_port(void); * .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, * .rx_flow_ctrl_thresh = 122, * }; - * uart_param_config(uart_num, &uart_config); //Set UART parameters - * uart_set_pin(uart_num, -1, -1, 15, 13); //Set UART pins,(-1: default pin, no change.) - * esp_log_level_set(UART_TAG, ESP_LOG_INFO); //Set UART log level + * //Set UART parameters + * uart_param_config(uart_num, &uart_config); + * //Set UART pins,(-1: default pin, no change.) + * uart_set_pin(uart_num, -1, -1, 15, 13); + * //Set UART log level + * esp_log_level_set(UART_TAG, ESP_LOG_INFO); * //Install UART driver, and get the queue. * uart_driver_install(uart_num, 1024 * 2, 1024*4, 10, 17, &uart0_queue, RINGBUF_TYPE_BYTEBUF); - * xTaskCreate(uart_task, "uTask", 2048*8, (void*)uart_num, 10, NULL); //Create a task to handler UART event from ISR + * //Create a task to handler UART event from ISR + * xTaskCreate(uart_task, "uTask", 2048*8, (void*)uart_num, 10, NULL); * } * @endcode * diff --git a/components/driver/uart.c b/components/driver/uart.c index 9eaf783438..cab05dd0be 100644 --- a/components/driver/uart.c +++ b/components/driver/uart.c @@ -30,9 +30,9 @@ #include "soc/uart_struct.h" const char* UART_TAG = "UART"; -#define UART_CHECK(a, str) if (!(a)) { \ +#define UART_CHECK(a, str, ret) if (!(a)) { \ ESP_LOGE(UART_TAG,"%s:%d (%s):%s\n", __FILE__, __LINE__, __FUNCTION__, str); \ - return ESP_FAIL; \ + return (ret); \ } #define UART_EMPTY_THRESH_DEFAULT (10) #define UART_FULL_THRESH_DEFAULT (120) @@ -42,6 +42,7 @@ const char* UART_TAG = "UART"; #define UART_ENTER_CRITICAL(mux) portENTER_CRITICAL(mux) #define UART_EXIT_CRITICAL(mux) portEXIT_CRITICAL(mux) + typedef struct { uart_port_t uart_num; /*!< UART port number*/ int queue_size; /*!< UART event queue size*/ @@ -60,7 +61,6 @@ typedef struct { //tx parameters SemaphoreHandle_t tx_fifo_sem; /*!< UART TX FIFO semaphore*/ SemaphoreHandle_t tx_mux; /*!< UART TX mutex*/ - SemaphoreHandle_t tx_buffer_mux; /*!< UART TX buffer semaphore*/ SemaphoreHandle_t tx_done_sem; /*!< UART TX done semaphore*/ SemaphoreHandle_t tx_brk_sem; /*!< UART TX send break done semaphore*/ int tx_buf_size; /*!< TX ring buffer size */ @@ -69,6 +69,7 @@ typedef struct { uint8_t* tx_ptr; /*!< TX data pointer to push to FIFO in TX buffer mode*/ uart_event_t* tx_head; /*!< TX data pointer to head of the current buffer in TX ring buffer*/ uint32_t tx_len_tot; /*!< Total length of current item in ring buffer*/ + uint32_t tx_len_cur; uint8_t tx_brk_flg; /*!< Flag to indicate to send a break signal in the end of the item sending procedure */ uint8_t tx_brk_len; /*!< TX break signal cycle length/number */ uint8_t tx_waiting_brk; /*!< Flag to indicate that TX FIFO is ready to send break signal after FIFO is empty, do not push data into TX FIFO right now.*/ @@ -80,8 +81,8 @@ static portMUX_TYPE uart_spinlock[UART_NUM_MAX] = {portMUX_INITIALIZER_UNLOCKED, esp_err_t uart_set_word_length(uart_port_t uart_num, uart_word_length_t data_bit) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); - UART_CHECK((data_bit < UART_DATA_MAX_BITS), "data bit error"); + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + UART_CHECK((data_bit < UART_DATA_MAX_BITS), "data bit error", ESP_FAIL); UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); UART[uart_num]->conf0.bit_num = data_bit; UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); @@ -90,15 +91,15 @@ esp_err_t uart_set_word_length(uart_port_t uart_num, uart_word_length_t data_bit esp_err_t uart_get_word_length(uart_port_t uart_num, uart_word_length_t* data_bit) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); *(data_bit) = UART[uart_num]->conf0.bit_num; return ESP_OK; } esp_err_t uart_set_stop_bits(uart_port_t uart_num, uart_stop_bits_t stop_bit) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); - UART_CHECK((stop_bit < UART_STOP_BITS_MAX), "stop bit error"); + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + UART_CHECK((stop_bit < UART_STOP_BITS_MAX), "stop bit error", ESP_FAIL); UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); UART[uart_num]->conf0.stop_bit_num = stop_bit; UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); @@ -107,14 +108,14 @@ esp_err_t uart_set_stop_bits(uart_port_t uart_num, uart_stop_bits_t stop_bit) esp_err_t uart_get_stop_bits(uart_port_t uart_num, uart_stop_bits_t* stop_bit) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); (*stop_bit) = UART[uart_num]->conf0.stop_bit_num; return ESP_OK; } esp_err_t uart_set_parity(uart_port_t uart_num, uart_parity_t parity_mode) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); UART[uart_num]->conf0.parity = parity_mode & 0x1; UART[uart_num]->conf0.parity_en = (parity_mode >> 1) & 0x1; @@ -124,7 +125,7 @@ esp_err_t uart_set_parity(uart_port_t uart_num, uart_parity_t parity_mode) esp_err_t uart_get_parity(uart_port_t uart_num, uart_parity_t* parity_mode) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); int val = UART[uart_num]->conf0.val; if(val & UART_PARITY_EN_M) { if(val & UART_PARITY_M) { @@ -140,8 +141,8 @@ esp_err_t uart_get_parity(uart_port_t uart_num, uart_parity_t* parity_mode) esp_err_t uart_set_baudrate(uart_port_t uart_num, uint32_t baud_rate) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); - UART_CHECK((baud_rate < UART_BITRATE_MAX), "baud_rate error"); + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + UART_CHECK((baud_rate < UART_BITRATE_MAX), "baud_rate error", ESP_FAIL); uint32_t clk_div = (((UART_CLK_FREQ) << 4) / baud_rate); UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); UART[uart_num]->clk_div.div_int = clk_div >> 4; @@ -152,7 +153,7 @@ esp_err_t uart_set_baudrate(uart_port_t uart_num, uint32_t baud_rate) esp_err_t uart_get_baudrate(uart_port_t uart_num, uint32_t* baudrate) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); uint32_t clk_div = (UART[uart_num]->clk_div.div_int << 4) | UART[uart_num]->clk_div.div_frag; UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); @@ -162,8 +163,8 @@ esp_err_t uart_get_baudrate(uart_port_t uart_num, uint32_t* baudrate) esp_err_t uart_set_line_inverse(uart_port_t uart_num, uint32_t inverse_mask) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); - UART_CHECK((((inverse_mask & UART_LINE_INV_MASK) == 0) && (inverse_mask != 0)), "inverse_mask error"); + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + UART_CHECK((((inverse_mask & UART_LINE_INV_MASK) == 0) && (inverse_mask != 0)), "inverse_mask error", ESP_FAIL); UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); CLEAR_PERI_REG_MASK(UART_CONF0_REG(uart_num), UART_LINE_INV_MASK); SET_PERI_REG_MASK(UART_CONF0_REG(uart_num), inverse_mask); @@ -174,9 +175,9 @@ esp_err_t uart_set_line_inverse(uart_port_t uart_num, uint32_t inverse_mask) //only when UART_HW_FLOWCTRL_RTS is set , will the rx_thresh value be set. esp_err_t uart_set_hw_flow_ctrl(uart_port_t uart_num, uart_hw_flowcontrol_t flow_ctrl, uint8_t rx_thresh) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); - UART_CHECK((rx_thresh < UART_FIFO_LEN), "rx flow thresh error"); - UART_CHECK((flow_ctrl < UART_HW_FLOWCTRL_MAX), "hw_flowctrl mode error"); + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + UART_CHECK((rx_thresh < UART_FIFO_LEN), "rx flow thresh error", ESP_FAIL); + UART_CHECK((flow_ctrl < UART_HW_FLOWCTRL_MAX), "hw_flowctrl mode error", ESP_FAIL); UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); if(flow_ctrl & UART_HW_FLOWCTRL_RTS) { UART[uart_num]->conf1.rx_flow_thrhd = rx_thresh; @@ -195,7 +196,7 @@ esp_err_t uart_set_hw_flow_ctrl(uart_port_t uart_num, uart_hw_flowcontrol_t flow esp_err_t uart_get_hw_flow_ctrl(uart_port_t uart_num, uart_hw_flowcontrol_t* flow_ctrl) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); uart_hw_flowcontrol_t val = UART_HW_FLOWCTRL_DISABLE; if(UART[uart_num]->conf1.rx_flow_en) { val |= UART_HW_FLOWCTRL_RTS; @@ -209,7 +210,7 @@ esp_err_t uart_get_hw_flow_ctrl(uart_port_t uart_num, uart_hw_flowcontrol_t* flo static esp_err_t uart_reset_fifo(uart_port_t uart_num) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); UART[uart_num]->conf0.rxfifo_rst = 1; UART[uart_num]->conf0.rxfifo_rst = 0; @@ -221,7 +222,7 @@ static esp_err_t uart_reset_fifo(uart_port_t uart_num) esp_err_t uart_clear_intr_status(uart_port_t uart_num, uint32_t clr_mask) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); //intr_clr register is write-only UART[uart_num]->int_clr.val = clr_mask; return ESP_OK; @@ -229,7 +230,7 @@ esp_err_t uart_clear_intr_status(uart_port_t uart_num, uint32_t clr_mask) esp_err_t uart_enable_intr_mask(uart_port_t uart_num, uint32_t enable_mask) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); SET_PERI_REG_MASK(UART_INT_CLR_REG(uart_num), enable_mask); SET_PERI_REG_MASK(UART_INT_ENA_REG(uart_num), enable_mask); @@ -239,7 +240,7 @@ esp_err_t uart_enable_intr_mask(uart_port_t uart_num, uint32_t enable_mask) esp_err_t uart_disable_intr_mask(uart_port_t uart_num, uint32_t disable_mask) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); CLEAR_PERI_REG_MASK(UART_INT_ENA_REG(uart_num), disable_mask); UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); @@ -248,7 +249,7 @@ esp_err_t uart_disable_intr_mask(uart_port_t uart_num, uint32_t disable_mask) esp_err_t uart_enable_rx_intr(uart_port_t uart_num) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); SET_PERI_REG_MASK(UART_INT_ENA_REG(uart_num), UART_RXFIFO_FULL_INT_ENA|UART_RXFIFO_TOUT_INT_ENA); UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); @@ -257,7 +258,7 @@ esp_err_t uart_enable_rx_intr(uart_port_t uart_num) esp_err_t uart_disable_rx_intr(uart_port_t uart_num) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); CLEAR_PERI_REG_MASK(UART_INT_ENA_REG(uart_num), UART_RXFIFO_FULL_INT_ENA|UART_RXFIFO_TOUT_INT_ENA); UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); @@ -266,7 +267,7 @@ esp_err_t uart_disable_rx_intr(uart_port_t uart_num) esp_err_t uart_disable_tx_intr(uart_port_t uart_num) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); UART[uart_num]->int_ena.txfifo_empty = 0; UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); @@ -275,8 +276,8 @@ esp_err_t uart_disable_tx_intr(uart_port_t uart_num) esp_err_t uart_enable_tx_intr(uart_port_t uart_num, int enable, int thresh) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); - UART_CHECK((thresh < UART_FIFO_LEN), "empty intr threshold error"); + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + UART_CHECK((thresh < UART_FIFO_LEN), "empty intr threshold error", ESP_FAIL); UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); UART[uart_num]->int_clr.txfifo_empty = 1; UART[uart_num]->conf1.txfifo_empty_thrhd = thresh & UART_TXFIFO_EMPTY_THRHD_V; @@ -288,7 +289,7 @@ esp_err_t uart_enable_tx_intr(uart_port_t uart_num, int enable, int thresh) esp_err_t uart_isr_register(uart_port_t uart_num, uint8_t uart_intr_num, void (*fn)(void*), void * arg) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); ESP_INTR_DISABLE(uart_intr_num); switch(uart_num) { @@ -313,11 +314,11 @@ esp_err_t uart_isr_register(uart_port_t uart_num, uint8_t uart_intr_num, void (* //only one GPIO pad can connect with input signal esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int rts_io_num, int cts_io_num) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); - UART_CHECK((tx_io_num < 0 || (GPIO_IS_VALID_OUTPUT_GPIO(tx_io_num))), "tx_io_num error"); - UART_CHECK((rx_io_num < 0 || (GPIO_IS_VALID_GPIO(rx_io_num))), "rx_io_num error"); - UART_CHECK((rts_io_num < 0 || (GPIO_IS_VALID_OUTPUT_GPIO(rts_io_num))), "rts_io_num error"); - UART_CHECK((cts_io_num < 0 || (GPIO_IS_VALID_GPIO(cts_io_num))), "cts_io_num error"); + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + UART_CHECK((tx_io_num < 0 || (GPIO_IS_VALID_OUTPUT_GPIO(tx_io_num))), "tx_io_num error", ESP_FAIL); + UART_CHECK((rx_io_num < 0 || (GPIO_IS_VALID_GPIO(rx_io_num))), "rx_io_num error", ESP_FAIL); + UART_CHECK((rts_io_num < 0 || (GPIO_IS_VALID_OUTPUT_GPIO(rts_io_num))), "rts_io_num error", ESP_FAIL); + UART_CHECK((cts_io_num < 0 || (GPIO_IS_VALID_GPIO(cts_io_num))), "cts_io_num error", ESP_FAIL); int tx_sig, rx_sig, rts_sig, cts_sig; switch(uart_num) { @@ -373,8 +374,8 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r esp_err_t uart_set_rts(uart_port_t uart_num, int level) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); - UART_CHECK((UART[uart_num]->conf1.rx_flow_en != 1), "disable hw flowctrl before using sw control\n"); + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + UART_CHECK((UART[uart_num]->conf1.rx_flow_en != 1), "disable hw flowctrl before using sw control\n", ESP_FAIL); UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); UART[uart_num]->conf0.sw_rts = level & 0x1; UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); @@ -383,7 +384,7 @@ esp_err_t uart_set_rts(uart_port_t uart_num, int level) esp_err_t uart_set_dtr(uart_port_t uart_num, int level) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); UART[uart_num]->conf0.sw_dtr = level & 0x1; UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); @@ -392,8 +393,8 @@ esp_err_t uart_set_dtr(uart_port_t uart_num, int level) esp_err_t uart_param_config(uart_port_t uart_num, uart_config_t *uart_config) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); - UART_CHECK((uart_config), "param null\n"); + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + UART_CHECK((uart_config), "param null\n", ESP_FAIL); if(uart_num == UART_NUM_0) { periph_module_enable(PERIPH_UART0_MODULE); } else if(uart_num == UART_NUM_1) { @@ -414,8 +415,8 @@ esp_err_t uart_param_config(uart_port_t uart_num, uart_config_t *uart_config) esp_err_t uart_intr_config(uart_port_t uart_num, uart_intr_config_t *p_intr_conf) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); - UART_CHECK((p_intr_conf), "param null\n"); + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + UART_CHECK((p_intr_conf), "param null\n", ESP_FAIL); UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); UART[uart_num]->int_clr.val = UART_INTR_MASK; if(p_intr_conf->intr_enable_mask & UART_RXFIFO_TOUT_INT_ENA_M) { @@ -458,7 +459,8 @@ static void IRAM_ATTR uart_rx_intr_handler_default(void *param) if(p_uart->tx_waiting_brk) { return; } - if(p_uart->tx_waiting_fifo == true) { + //TX semaphore used in none tx ringbuffer mode. + if(p_uart->tx_waiting_fifo == true && p_uart->tx_buf_size > 0) { p_uart->tx_waiting_fifo = false; xSemaphoreGiveFromISR(p_uart->tx_fifo_sem, NULL); } @@ -473,57 +475,51 @@ static void IRAM_ATTR uart_rx_intr_handler_default(void *param) //That would cause a watch_dog reset because empty interrupt happens so often. //Although this is a loop in ISR, this loop will execute at most 128 turns. while(tx_fifo_rem) { - if(p_uart->tx_len_tot == 0) { + if(p_uart->tx_len_tot == 0 || p_uart->tx_ptr == NULL || p_uart->tx_len_cur == 0) { size_t size; - //The first item is the data description - //Get the first item to get the data information p_uart->tx_head = (uart_event_t*) xRingbufferReceiveFromISR(p_uart->tx_ring_buf, &size); if(p_uart->tx_head) { - p_uart->tx_ptr = NULL; - p_uart->tx_len_tot = p_uart->tx_head->data.size; - if(p_uart->tx_head->type == UART_DATA_BREAK) { + //The first item is the data description + //Get the first item to get the data information + if(p_uart->tx_len_tot == 0) { + p_uart->tx_ptr = NULL; p_uart->tx_len_tot = p_uart->tx_head->data.size; - p_uart->tx_brk_flg = 1; - p_uart->tx_brk_len = p_uart->tx_head->data.brk_len; + if(p_uart->tx_head->type == UART_DATA_BREAK) { + p_uart->tx_len_tot = p_uart->tx_head->data.size; + p_uart->tx_brk_flg = 1; + p_uart->tx_brk_len = p_uart->tx_head->data.brk_len; + } + //We have saved the data description from the 1st item, return buffer. + vRingbufferReturnItemFromISR(p_uart->tx_ring_buf, p_uart->tx_head, &HPTaskAwoken); + }else if(p_uart->tx_ptr == NULL) { + //Update the TX item pointer, we will need this to return item to buffer. + p_uart->tx_ptr = (uint8_t*) p_uart->tx_head; + en_tx_flg = true; + p_uart->tx_len_cur = size; } - //We have saved the data description from the 1st item, return buffer. - vRingbufferReturnItemFromISR(p_uart->tx_ring_buf, p_uart->tx_head, &HPTaskAwoken); } else { //Can not get data from ring buffer, return; return; } } - if(p_uart->tx_ptr == NULL) { - size_t size; - //2nd item is the data we need to send through UART - //Get 2nd item from ring buffer - p_uart->tx_ptr = (uint8_t*) xRingbufferReceiveFromISR(p_uart->tx_ring_buf, &size); - if(p_uart->tx_ptr) { - //Update the TX item head, we will need this to return item to buffer. - p_uart->tx_head = (void*) p_uart->tx_ptr; - en_tx_flg = true; - } else { - //Can not get data from ring buffer, return; - return; - } - } - if(p_uart->tx_len_tot > 0 && p_uart->tx_ptr) { + if(p_uart->tx_len_tot > 0 && p_uart->tx_ptr && p_uart->tx_len_cur > 0) { //To fill the TX FIFO. - int send_len = p_uart->tx_len_tot > tx_fifo_rem ? tx_fifo_rem : p_uart->tx_len_tot; + int send_len = p_uart->tx_len_cur > tx_fifo_rem ? tx_fifo_rem : p_uart->tx_len_cur; for(buf_idx = 0; buf_idx < send_len; buf_idx++) { WRITE_PERI_REG(UART_FIFO_AHB_REG(uart_num), *(p_uart->tx_ptr++) & 0xff); } p_uart->tx_len_tot -= send_len; + p_uart->tx_len_cur -= send_len; tx_fifo_rem -= send_len; - if(p_uart->tx_len_tot == 0) { - //Sending item done, now we need to send break if there is a record. + if(p_uart->tx_len_cur == 0) { //Return item to ring buffer. vRingbufferReturnItemFromISR(p_uart->tx_ring_buf, p_uart->tx_head, &HPTaskAwoken); p_uart->tx_head = NULL; p_uart->tx_ptr = NULL; + //Sending item done, now we need to send break if there is a record. //Set TX break signal after FIFO is empty - if(p_uart->tx_brk_flg == 1) { + if(p_uart->tx_brk_flg == 1 && p_uart->tx_len_tot == 0) { UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); uart_reg->int_ena.tx_brk_done = 0; uart_reg->idle_conf.tx_brk_num = p_uart->tx_brk_len; @@ -645,8 +641,8 @@ static void IRAM_ATTR uart_rx_intr_handler_default(void *param) /**************************************************************/ esp_err_t uart_wait_tx_done(uart_port_t uart_num, TickType_t ticks_to_wait) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); - UART_CHECK((p_uart_obj[uart_num]), "uart driver error"); + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + UART_CHECK((p_uart_obj[uart_num]), "uart driver error", ESP_FAIL); BaseType_t res; portTickType ticks_end = xTaskGetTickCount() + ticks_to_wait; //Take tx_mux @@ -700,9 +696,9 @@ static int uart_fill_fifo(uart_port_t uart_num, char* buffer, uint32_t len) int uart_tx_chars(uart_port_t uart_num, char* buffer, uint32_t len) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); - UART_CHECK((p_uart_obj[uart_num]), "uart driver error"); - UART_CHECK(buffer, "buffer null"); + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", (-1)); + UART_CHECK((p_uart_obj[uart_num]), "uart driver error", (-1)); + UART_CHECK(buffer, "buffer null", (-1)); if(len == 0) { return 0; } @@ -714,9 +710,6 @@ int uart_tx_chars(uart_port_t uart_num, char* buffer, uint32_t len) static int uart_tx_all(uart_port_t uart_num, const char* src, size_t size, bool brk_en, int brk_len) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); - UART_CHECK((p_uart_obj[uart_num]), "uart driver error"); - UART_CHECK(src, "buffer null"); if(size == 0) { return 0; } @@ -746,25 +739,28 @@ static int uart_tx_all(uart_port_t uart_num, const char* src, size_t size, bool int uart_tx_all_chars(uart_port_t uart_num, const char* src, size_t size) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); - UART_CHECK((p_uart_obj[uart_num] != NULL), "uart driver error"); - UART_CHECK(src, "buffer null"); + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", (-1)); + UART_CHECK((p_uart_obj[uart_num] != NULL), "uart driver error", (-1)); + UART_CHECK(src, "buffer null", (-1)); //Push data to TX ring buffer and return, ISR will send the data. if(p_uart_obj[uart_num]->tx_buf_size > 0) { - if(xRingbufferGetMaxItemSize(p_uart_obj[uart_num]->tx_ring_buf) > (size + sizeof(uart_event_t))) { - uart_event_t evt; - xSemaphoreTake(p_uart_obj[uart_num]->tx_buffer_mux, (portTickType)portMAX_DELAY); - evt.type = UART_DATA; - evt.data.size = size; - xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void*) &evt, sizeof(uart_event_t), portMAX_DELAY); - xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void*) src, size, portMAX_DELAY); - xSemaphoreGive(p_uart_obj[uart_num]->tx_buffer_mux); - uart_enable_tx_intr(uart_num, 1, UART_EMPTY_THRESH_DEFAULT); - return size; - } else { - ESP_LOGW(UART_TAG, "UART TX BUFFER TOO SMALL[0], SEND DIRECTLY\n"); - return uart_tx_all(uart_num, src, size, 0, 0); + xSemaphoreTake(p_uart_obj[uart_num]->tx_mux, (portTickType)portMAX_DELAY); + int max_size = xRingbufferGetMaxItemSize(p_uart_obj[uart_num]->tx_ring_buf); + int ori_size = size; + int offset = 0; + uart_event_t evt; + evt.type = UART_DATA; + evt.data.size = size; + xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void*) &evt, sizeof(uart_event_t), portMAX_DELAY); + while(size > 0) { + int send_size = size > max_size / 2 ? max_size / 2 : size; + xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void*) (src + offset), send_size, portMAX_DELAY); + size -= send_size; + offset += send_size; } + xSemaphoreGive(p_uart_obj[uart_num]->tx_mux); + uart_enable_tx_intr(uart_num, 1, UART_EMPTY_THRESH_DEFAULT); + return ori_size; } else { //Send data without TX ring buffer, the task will block until all data have been sent out return uart_tx_all(uart_num, src, size, 0, 0); @@ -773,28 +769,31 @@ int uart_tx_all_chars(uart_port_t uart_num, const char* src, size_t size) int uart_tx_all_chars_with_break(uart_port_t uart_num, const char* src, size_t size, int brk_len) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); - UART_CHECK((p_uart_obj[uart_num]), "uart driver error"); - UART_CHECK((size > 0), "uart size error"); - UART_CHECK((src), "uart data null"); - UART_CHECK((brk_len > 0 && brk_len < 256), "break_num error"); + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", (-1)); + UART_CHECK((p_uart_obj[uart_num]), "uart driver error", (-1)); + UART_CHECK((size > 0), "uart size error", (-1)); + UART_CHECK((src), "uart data null", (-1)); + UART_CHECK((brk_len > 0 && brk_len < 256), "break_num error", (-1)); //Push data to TX ring buffer and return, ISR will send the data. if(p_uart_obj[uart_num]->tx_buf_size > 0) { - if(xRingbufferGetMaxItemSize(p_uart_obj[uart_num]->tx_ring_buf) > (size)) { - uart_event_t evt; - xSemaphoreTake(p_uart_obj[uart_num]->tx_buffer_mux, (portTickType)portMAX_DELAY); - evt.type = UART_DATA_BREAK; - evt.data.size = size; - evt.data.brk_len = brk_len; - xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void*) &evt, sizeof(uart_event_t), portMAX_DELAY); - xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void*) src, size, portMAX_DELAY); - xSemaphoreGive(p_uart_obj[uart_num]->tx_buffer_mux); - uart_enable_tx_intr(uart_num, 1, UART_EMPTY_THRESH_DEFAULT); - return size; - } else { - ESP_LOGW(UART_TAG, "UART TX BUFFER TOO SMALL[1], SEND DIRECTLY\n"); - return uart_tx_all(uart_num, src, size, 1, brk_len); + xSemaphoreTake(p_uart_obj[uart_num]->tx_mux, (portTickType)portMAX_DELAY); + int max_size = xRingbufferGetMaxItemSize(p_uart_obj[uart_num]->tx_ring_buf); + int ori_size = size; + int offset = 0; + uart_event_t evt; + evt.type = UART_DATA_BREAK; + evt.data.size = size; + evt.data.brk_len = brk_len; + xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void*) &evt, sizeof(uart_event_t), portMAX_DELAY); + while(size > 0) { + int send_size = size > max_size / 2 ? max_size / 2 : size; + xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void*) (src + offset), send_size, portMAX_DELAY); + size -= send_size; + offset += send_size; } + xSemaphoreGive(p_uart_obj[uart_num]->tx_mux); + uart_enable_tx_intr(uart_num, 1, UART_EMPTY_THRESH_DEFAULT); + return ori_size; } else { //Send data without TX ring buffer, the task will block until all data have been sent out return uart_tx_all(uart_num, src, size, 1, brk_len); @@ -803,8 +802,8 @@ int uart_tx_all_chars_with_break(uart_port_t uart_num, const char* src, size_t s int uart_read_char(uart_port_t uart_num, TickType_t ticks_to_wait) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); - UART_CHECK((p_uart_obj[uart_num]), "uart driver error"); + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", (-1)); + UART_CHECK((p_uart_obj[uart_num]), "uart driver error", (-1)); uint8_t* data; size_t size; int val; @@ -845,9 +844,9 @@ int uart_read_char(uart_port_t uart_num, TickType_t ticks_to_wait) int uart_read_bytes(uart_port_t uart_num, uint8_t* buf, uint32_t length, TickType_t ticks_to_wait) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); - UART_CHECK((buf), "uart_num error"); - UART_CHECK((p_uart_obj[uart_num]), "uart driver error"); + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", (-1)); + UART_CHECK((buf), "uart_num error", (-1)); + UART_CHECK((p_uart_obj[uart_num]), "uart driver error", (-1)); uint8_t* data = NULL; size_t size; size_t copy_len = 0; @@ -896,13 +895,15 @@ int uart_read_bytes(uart_port_t uart_num, uint8_t* buf, uint32_t length, TickTyp esp_err_t uart_flush(uart_port_t uart_num) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); - UART_CHECK((p_uart_obj[uart_num]), "uart driver error"); + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + UART_CHECK((p_uart_obj[uart_num]), "uart driver error", ESP_FAIL); uart_obj_t* p_uart = p_uart_obj[uart_num]; uint8_t* data; size_t size; + //rx sem protect the ring buffer read related functions xSemaphoreTake(p_uart->rx_mux, (portTickType)portMAX_DELAY); + ESP_INTR_DISABLE(p_uart->intr_num); while(true) { if(p_uart->rx_head_ptr) { vRingbufferReturnItem(p_uart->rx_ring_buf, p_uart->rx_head_ptr); @@ -919,11 +920,16 @@ esp_err_t uart_flush(uart_port_t uart_num) p_uart->rx_ptr = NULL; p_uart->rx_cur_remain = 0; p_uart->rx_head_ptr = NULL; + ESP_INTR_ENABLE(p_uart->intr_num); xSemaphoreGive(p_uart->rx_mux); - xSemaphoreTake(p_uart->tx_mux, (portTickType)portMAX_DELAY); if(p_uart->tx_buf_size > 0) { - xSemaphoreTake(p_uart->tx_buffer_mux, (portTickType)portMAX_DELAY); + xSemaphoreTake(p_uart->tx_mux, (portTickType)portMAX_DELAY); + ESP_INTR_DISABLE(p_uart->intr_num); + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + UART[uart_num]->int_ena.txfifo_empty = 0; + UART[uart_num]->int_clr.txfifo_empty = 1; + UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); do { data = (uint8_t*) xRingbufferReceive(p_uart->tx_ring_buf, &size, (portTickType) 0); if(data == NULL) { @@ -931,10 +937,17 @@ esp_err_t uart_flush(uart_port_t uart_num) } vRingbufferReturnItem(p_uart->rx_ring_buf, data); } while(1); - xSemaphoreGive(p_uart->tx_buffer_mux); + p_uart->tx_brk_flg = 0; + p_uart->tx_brk_len = 0; + p_uart->tx_head = NULL; + p_uart->tx_len_cur = 0; + p_uart->tx_len_tot = 0; + p_uart->tx_ptr = NULL; + p_uart->tx_waiting_brk = 0; + p_uart->tx_waiting_fifo = false; + ESP_INTR_ENABLE(p_uart->intr_num); + xSemaphoreGive(p_uart->tx_mux); } - xSemaphoreGive(p_uart->tx_mux); - uart_wait_tx_done(uart_num, portMAX_DELAY); uart_reset_fifo(uart_num); return ESP_OK; } @@ -966,8 +979,8 @@ static void uart_ignore_char(char chr) //Only effective to ets_printf function, not ESP_LOGX macro. esp_err_t uart_set_print_port(uart_port_t uart_num) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); - UART_CHECK((p_uart_obj[uart_num]), "UART driver error"); + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + UART_CHECK((p_uart_obj[uart_num]), "UART driver error", ESP_FAIL); s_uart_print_nport = uart_num; switch(s_uart_print_nport) { case UART_NUM_0: @@ -994,8 +1007,8 @@ int uart_get_print_port() esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_buffer_size, int queue_size, int uart_intr_num, void* uart_queue) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); - UART_CHECK((rx_buffer_size > 0), "uart rx buffer length error\n"); + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + UART_CHECK((rx_buffer_size > 0), "uart rx buffer length error\n", ESP_FAIL); if(p_uart_obj[uart_num] == NULL) { ESP_INTR_DISABLE(uart_intr_num); p_uart_obj[uart_num] = (uart_obj_t*) malloc(sizeof(uart_obj_t)); @@ -1033,13 +1046,11 @@ esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_b p_uart_obj[uart_num]->rx_head_ptr = NULL; p_uart_obj[uart_num]->rx_ring_buf = xRingbufferCreate(rx_buffer_size, RINGBUF_TYPE_BYTEBUF); if(tx_buffer_size > 0) { - p_uart_obj[uart_num]->tx_ring_buf = xRingbufferCreate(tx_buffer_size, RINGBUF_TYPE_NOSPLIT);//RINGBUF_TYPE_BYTEBUF);//RINGBUF_TYPE_NOSPLIT); + p_uart_obj[uart_num]->tx_ring_buf = xRingbufferCreate(tx_buffer_size, RINGBUF_TYPE_NOSPLIT); p_uart_obj[uart_num]->tx_buf_size = tx_buffer_size; - p_uart_obj[uart_num]->tx_buffer_mux = xSemaphoreCreateMutex(); } else { p_uart_obj[uart_num]->tx_ring_buf = NULL; p_uart_obj[uart_num]->tx_buf_size = 0; - p_uart_obj[uart_num]->tx_buffer_mux = NULL; } } else { ESP_LOGE(UART_TAG, "UART driver already installed\n"); @@ -1064,7 +1075,7 @@ esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_b //Make sure no other tasks are still using UART before you call this function esp_err_t uart_driver_delete(uart_port_t uart_num) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error"); + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); if(p_uart_obj[uart_num] == NULL) { ESP_LOGI(UART_TAG, "ALREADY NULL\n"); return ESP_OK; @@ -1090,10 +1101,6 @@ esp_err_t uart_driver_delete(uart_port_t uart_num) vSemaphoreDelete(p_uart_obj[uart_num]->tx_mux); p_uart_obj[uart_num]->tx_mux = NULL; } - if(p_uart_obj[uart_num]->tx_buffer_mux) { - vSemaphoreDelete(p_uart_obj[uart_num]->tx_buffer_mux); - p_uart_obj[uart_num]->tx_buffer_mux = NULL; - } if(p_uart_obj[uart_num]->rx_mux) { vSemaphoreDelete(p_uart_obj[uart_num]->rx_mux); p_uart_obj[uart_num]->rx_mux = NULL; From 8bdcf0c5f7872953220283ff4ac04145155fda86 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 4 Nov 2016 10:55:25 +0800 Subject: [PATCH 260/343] newlib: fix compilation error when no timers are enabled in menuconfig --- components/newlib/time.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/components/newlib/time.c b/components/newlib/time.c index 5f60e1d7b2..a474f1ca33 100644 --- a/components/newlib/time.c +++ b/components/newlib/time.c @@ -55,14 +55,16 @@ static uint64_t get_rtc_time_us() #endif // WITH_RTC -// time from Epoch to the first boot time +// s_boot_time: time from Epoch to the first boot time #ifdef WITH_RTC static RTC_DATA_ATTR struct timeval s_boot_time; -#else +#elif defined(WITH_FRC1) static struct timeval s_boot_time; #endif -static _lock_t s_boot_time_lock; +#if defined(WITH_RTC) || defined(WITH_FRC1) +static _lock_t s_boot_time_lock; +#endif #ifdef WITH_FRC1 #define FRC1_PRESCALER 16 @@ -121,6 +123,7 @@ clock_t IRAM_ATTR _times_r(struct _reent *r, struct tms *ptms) return (clock_t) tv.tv_sec; } +#if defined( WITH_FRC1 ) || defined( WITH_RTC ) static uint64_t get_time_since_boot() { uint64_t microseconds = 0; @@ -140,6 +143,7 @@ static uint64_t get_time_since_boot() #endif return microseconds; } +#endif // defined( WITH_FRC1 ) || defined( WITH_RTC ) int IRAM_ATTR _gettimeofday_r(struct _reent *r, struct timeval *tv, void *tz) { @@ -176,7 +180,7 @@ int settimeofday(const struct timeval *tv, const struct timezone *tz) } return 0; #else - __errno_r(r) = ENOSYS; + errno = ENOSYS; return -1; #endif } From 2fa00ebd909bef152518194d4f891c2670a75e90 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 4 Nov 2016 12:18:57 +0800 Subject: [PATCH 261/343] ld scripts: fix overlap between bootloader and application IRAM ranges --- components/bootloader/src/main/bootloader_start.c | 9 ++++----- components/bootloader/src/main/esp32.bootloader.ld | 2 +- components/esp32/cpu_start.c | 5 ++++- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/components/bootloader/src/main/bootloader_start.c b/components/bootloader/src/main/bootloader_start.c index 5b1e152070..e1bcc18fd5 100644 --- a/components/bootloader/src/main/bootloader_start.c +++ b/components/bootloader/src/main/bootloader_start.c @@ -51,7 +51,7 @@ extern void Cache_Flush(int); void bootloader_main(); void unpack_load_app(const esp_partition_pos_t *app_node); void print_flash_info(const esp_image_header_t* pfhdr); -void IRAM_ATTR set_cache_and_start_app(uint32_t drom_addr, +void set_cache_and_start_app(uint32_t drom_addr, uint32_t drom_load_addr, uint32_t drom_size, uint32_t irom_addr, @@ -445,7 +445,7 @@ void unpack_load_app(const esp_partition_pos_t* partition) image_header.entry_addr); } -void IRAM_ATTR set_cache_and_start_app( +void set_cache_and_start_app( uint32_t drom_addr, uint32_t drom_load_addr, uint32_t drom_size, @@ -456,9 +456,7 @@ void IRAM_ATTR set_cache_and_start_app( { ESP_LOGD(TAG, "configure drom and irom and start"); Cache_Read_Disable( 0 ); - Cache_Read_Disable( 1 ); Cache_Flush( 0 ); - Cache_Flush( 1 ); uint32_t drom_page_count = (drom_size + 64*1024 - 1) / (64*1024); // round up to 64k ESP_LOGV(TAG, "d mmu set paddr=%08x vaddr=%08x size=%d n=%d", drom_addr & 0xffff0000, drom_load_addr & 0xffff0000, drom_size, drom_page_count ); int rc = cache_flash_mmu_set( 0, 0, drom_load_addr & 0xffff0000, drom_addr & 0xffff0000, 64, drom_page_count ); @@ -474,7 +472,8 @@ void IRAM_ATTR set_cache_and_start_app( REG_CLR_BIT( DPORT_PRO_CACHE_CTRL1_REG, (DPORT_PRO_CACHE_MASK_IRAM0) | (DPORT_PRO_CACHE_MASK_IRAM1 & 0) | (DPORT_PRO_CACHE_MASK_IROM0 & 0) | DPORT_PRO_CACHE_MASK_DROM0 | DPORT_PRO_CACHE_MASK_DRAM1 ); REG_CLR_BIT( DPORT_APP_CACHE_CTRL1_REG, (DPORT_APP_CACHE_MASK_IRAM0) | (DPORT_APP_CACHE_MASK_IRAM1 & 0) | (DPORT_APP_CACHE_MASK_IROM0 & 0) | DPORT_APP_CACHE_MASK_DROM0 | DPORT_APP_CACHE_MASK_DRAM1 ); Cache_Read_Enable( 0 ); - Cache_Read_Enable( 1 ); + + // Application will need to do Cache_Flush(1) and Cache_Read_Enable(1) ESP_LOGD(TAG, "start: 0x%08x", entry_addr); typedef void (*entry_t)(void); diff --git a/components/bootloader/src/main/esp32.bootloader.ld b/components/bootloader/src/main/esp32.bootloader.ld index af97bda3ad..6a77eb6ade 100644 --- a/components/bootloader/src/main/esp32.bootloader.ld +++ b/components/bootloader/src/main/esp32.bootloader.ld @@ -15,7 +15,7 @@ MEMORY of the various regions. The 'data access port' dram/drom regions map to the same iram/irom regions but are connected to the data port of the CPU and eg allow bytewise access. */ dport0_seg (RW) : org = 0x3FF00000, len = 0x10 /* IO */ - iram_seg (RWX) : org = 0x40098000, len = 0x1000 + iram_seg (RWX) : org = 0x40080000, len = 0x400 /* 1k of IRAM used by bootloader functions which need to flush/enable APP CPU cache */ iram_pool_1_seg (RWX) : org = 0x40078000, len = 0x8000 /* IRAM POOL1, used for APP CPU cache. We can abuse it in bootloader because APP CPU is still held in reset, until we enable APP CPU cache */ dram_seg (RW) : org = 0x3FFC0000, len = 0x20000 /* Shared RAM, minus rom bss/data/stack.*/ } diff --git a/components/esp32/cpu_start.c b/components/esp32/cpu_start.c index c82c528597..2688cd7f81 100644 --- a/components/esp32/cpu_start.c +++ b/components/esp32/cpu_start.c @@ -20,6 +20,7 @@ #include "rom/ets_sys.h" #include "rom/uart.h" #include "rom/rtc.h" +#include "rom/cache.h" #include "soc/cpu.h" #include "soc/dport_reg.h" @@ -110,7 +111,9 @@ void IRAM_ATTR call_start_cpu0() #if !CONFIG_FREERTOS_UNICORE ESP_EARLY_LOGI(TAG, "Starting app cpu, entry point is %p", call_start_cpu1); - + //Flush and enable icache for APP CPU + Cache_Flush(1); + Cache_Read_Enable(1); //Un-stall the app cpu; the panic handler may have stalled it. CLEAR_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, RTC_CNTL_SW_STALL_APPCPU_C1_M); CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_STALL_APPCPU_C0_M); From 3ec23f1b837959548da8e7ddec4dfd7db7929a6c Mon Sep 17 00:00:00 2001 From: Wangjialin Date: Fri, 4 Nov 2016 12:52:34 +0800 Subject: [PATCH 262/343] Modify as Angus's suggestion: 1. Set XXX_TAG static, remove extern XXX_TAG in uart.h/ledc.h/gpio.h 2. I removed uart_set/get_print_port() functions, these functions are not well tested, I removed them for now. 3. Modify some function names for uart_read/write_bytes 4. Modify uart_write_bytes and uart_write_bytes_with_break. --- components/driver/gpio.c | 2 +- components/driver/include/driver/gpio.h | 2 +- components/driver/include/driver/ledc.h | 1 - components/driver/include/driver/uart.h | 98 ++++------ components/driver/ledc.c | 2 +- components/driver/uart.c | 238 ++++++------------------ 6 files changed, 96 insertions(+), 247 deletions(-) diff --git a/components/driver/gpio.c b/components/driver/gpio.c index da0fedb895..62a0e7faa7 100644 --- a/components/driver/gpio.c +++ b/components/driver/gpio.c @@ -20,7 +20,7 @@ #include "soc/soc.h" #include "esp_log.h" -const char* GPIO_TAG = "GPIO"; +static const char* GPIO_TAG = "GPIO"; #define GPIO_CHECK(a, str, ret_val) if (!(a)) { \ ESP_LOGE(GPIO_TAG,"%s:%d (%s):%s\n", __FILE__, __LINE__, __FUNCTION__, str); \ return (ret_val); \ diff --git a/components/driver/include/driver/gpio.h b/components/driver/include/driver/gpio.h index a31c2f64b7..903621f619 100644 --- a/components/driver/include/driver/gpio.h +++ b/components/driver/include/driver/gpio.h @@ -27,7 +27,7 @@ #ifdef __cplusplus extern "C" { #endif -extern const char* GPIO_TAG; + #define GPIO_SEL_0 (BIT(0)) /*!< Pin 0 selected */ #define GPIO_SEL_1 (BIT(1)) /*!< Pin 1 selected */ #define GPIO_SEL_2 (BIT(2)) /*!< Pin 2 selected */ diff --git a/components/driver/include/driver/ledc.h b/components/driver/include/driver/ledc.h index ac29eaf56a..3ab0ebff1e 100644 --- a/components/driver/include/driver/ledc.h +++ b/components/driver/include/driver/ledc.h @@ -26,7 +26,6 @@ extern "C" { #endif -extern const char* LEDC_TAG; #define LEDC_APB_CLK_HZ (APB_CLK_FREQ) #define LEDC_REF_CLK_HZ (1*1000000) diff --git a/components/driver/include/driver/uart.h b/components/driver/include/driver/uart.h index 200d1148cb..ba487d57d5 100644 --- a/components/driver/include/driver/uart.h +++ b/components/driver/include/driver/uart.h @@ -32,11 +32,11 @@ extern "C" { #include "freertos/ringbuf.h" #include -extern const char* UART_TAG; -#define UART_FIFO_LEN (128) //Do not change this, this value describes the length of the gardware FIFO in the ESP32 +#define UART_FIFO_LEN (128) /*< Length of the hardware FIFO buffers */ #define UART_INTR_MASK 0x1ff #define UART_LINE_INV_MASK (0x3f << 19) #define UART_BITRATE_MAX 5000000 +#define UART_PIN_NO_CHANGE (-1) typedef enum { UART_DATA_5_BITS = 0x0, /*!< word length: 5bits*/ @@ -243,6 +243,8 @@ esp_err_t uart_set_line_inverse(uart_port_t uart_no, uint32_t inverse_mask) ; * * @param rx_thresh Threshold of Hardware RX flow control(0 ~ UART_FIFO_LEN) * + * Only when UART_HW_FLOWCTRL_RTS is set , will the rx_thresh value be set. + * * @return * - ESP_OK Success * - ESP_FAIL Parameter error @@ -380,15 +382,19 @@ esp_err_t uart_isr_register(uart_port_t uart_num, uint8_t uart_intr_num, void (* /** * @brief Set UART pin number * + * @note + * Internal signal can be output to multiple GPIO pads + * Only one GPIO pad can connect with input signal + * * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 * - * @param tx_io_num UART TX pin GPIO number + * @param tx_io_num UART TX pin GPIO number, if set to UART_PIN_NO_CHANGE, use the current pin. * - * @param rx_io_num UART RX pin GPIO number + * @param rx_io_num UART RX pin GPIO number, if set to UART_PIN_NO_CHANGE, use the current pin. * - * @param rts_io_num UART RTS pin GPIO number + * @param rts_io_num UART RTS pin GPIO number, if set to UART_PIN_NO_CHANGE, use the current pin. * - * @param cts_io_num UART CTS pin GPIO number + * @param cts_io_num UART CTS pin GPIO number, if set to UART_PIN_NO_CHANGE, use the current pin. * * @return * - ESP_OK Success @@ -434,20 +440,20 @@ esp_err_t uart_set_dtr(uart_port_t uart_num, int level); * - ESP_OK Success * - ESP_FAIL Parameter error */ -esp_err_t uart_param_config(uart_port_t uart_num, uart_config_t *uart_config); +esp_err_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_config); /** * @brief UART interrupt configure * * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 * - * @param p_intr_conf UART interrupt settings + * @param intr_conf UART interrupt settings * * @return * - ESP_OK Success * - ESP_FAIL Parameter error */ -esp_err_t uart_intr_config(uart_port_t uart_num, uart_intr_config_t *p_intr_conf); +esp_err_t uart_intr_config(uart_port_t uart_num, const uart_intr_config_t *intr_conf); /** * @brief Install UART driver. @@ -504,6 +510,9 @@ esp_err_t uart_wait_tx_done(uart_port_t uart_num, TickType_t ticks_to_wait); /** * @brief Send data to the UART port from a given buffer and length, * This function will not wait for the space in TX FIFO, just fill the TX FIFO and return when the FIFO is full. + * @note + * This function should only be used when UART TX buffer is not enabled. + * * * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 * @@ -515,7 +524,7 @@ esp_err_t uart_wait_tx_done(uart_port_t uart_num, TickType_t ticks_to_wait); * - (-1) Parameter error * - OTHERS(>=0) The number of data that pushed to the TX FIFO */ -int uart_tx_chars(uart_port_t uart_no, char* buffer, uint32_t len); +int uart_tx_chars(uart_port_t uart_no, const char* buffer, uint32_t len); /** * @brief Send data to the UART port from a given buffer and length, @@ -536,7 +545,7 @@ int uart_tx_chars(uart_port_t uart_no, char* buffer, uint32_t len); * - (-1) Parameter error * - OTHERS(>=0) The number of data that pushed to the TX FIFO */ -int uart_tx_all_chars(uart_port_t uart_num, const char* src, size_t size); +int uart_write_bytes(uart_port_t uart_num, const char* src, size_t size); /** * @brief Send data to the UART port from a given buffer and length, @@ -564,20 +573,7 @@ int uart_tx_all_chars(uart_port_t uart_num, const char* src, size_t size); * - OTHERS(>=0) The number of data that pushed to the TX FIFO */ -int uart_tx_all_chars_with_break(uart_port_t uart_num, const char* src, size_t size, int brk_len); - -/** -* @brief UART read one char - * - * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * - * @param ticks_to_wait Timeout, count in RTOS ticks - * - * @return - * - (-1) Error - * - Others return a char data from UART. - */ -int uart_read_char(uart_port_t uart_num, TickType_t ticks_to_wait); +int uart_write_bytes_with_break(uart_port_t uart_num, const char* src, size_t size, int brk_len); /** * @brief UART read bytes from UART buffer @@ -608,25 +604,6 @@ int uart_read_bytes(uart_port_t uart_num, uint8_t* buf, uint32_t length, TickTyp */ esp_err_t uart_flush(uart_port_t uart_num); -/** - * @brief Set the serial output port for ets_printf function, not effective for ESP_LOGX macro. - * - * @param uart_no UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * - * @return - * - ESP_OK Success - * - ESP_FAIL Parameter error, or UART driver not installed. - */ -esp_err_t uart_set_print_port(uart_port_t uart_no); - -/** - * @brief Get the current serial port for ets_printf function - * - * - * @return current print port(0: UART0; 1: UART1; 2: UART2) - */ -int uart_get_print_port(void); - /***************************EXAMPLE********************************** * * @@ -658,7 +635,7 @@ int uart_get_print_port(void); * @code{c} * //2. Set UART pin * //set UART pin, not needed if use default pins. - * uart_set_pin(uart_num, -1, -1, 15, 13); + * uart_set_pin(uart_num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, 15, 13); * @endcode *-----------------------------------------------------------------------------* * @code{c} @@ -671,12 +648,12 @@ int uart_get_print_port(void); * @code{c} * //4. Write data to UART. * char* test_str = "This is a test string.\n" - * uart_tx_all_chars(uart_num, (const char*)test_str, strlen(test_str)); + * uart_write_bytes(uart_num, (const char*)test_str, strlen(test_str)); * @endcode *-----------------------------------------------------------------------------* * @code{c} * //5. Write data to UART, end with a break signal. - * uart_tx_all_chars_with_break(0, "test break\n",strlen("test break\n"), 100); + * uart_write_bytes_with_break(0, "test break\n",strlen("test break\n"), 100); * @endcode *-----------------------------------------------------------------------------* * @code{c} @@ -696,8 +673,6 @@ int uart_get_print_port(void); * uart_param_config(uart_num, &uart_config); * //Set UART1 pins(TX: IO16, RX: IO17, RTS: IO18, CTS: IO19) * uart_set_pin(uart_num, 16, 17, 18, 19); - * //Set UART log level - * esp_log_level_set(UART_TAG, ESP_LOG_ERROR); * //Install UART driver( We don't need an event queue here) * uart_driver_install(uart_num, 1024 * 2, 1024*4, 10, 17, NULL, RINGBUF_TYPE_BYTEBUF); * uint8_t data[1000]; @@ -705,7 +680,7 @@ int uart_get_print_port(void); * //Read data from UART * int len = uart_read_bytes(uart_num, data, sizeof(data), 10); * //Write data back to UART - * uart_tx_all_chars(uart_num, (const char*)data, len); + * uart_write_bytes(uart_num, (const char*)data, len); * } * } * @endcode @@ -715,6 +690,7 @@ int uart_get_print_port(void); * #include "freertos/queue.h" * //A queue to handle UART event. * QueueHandle_t uart0_queue; + * static const char *TAG = "uart_example"; * void uart_task(void *pvParameters) * { * int uart_num = (int)pvParameters; @@ -723,37 +699,37 @@ int uart_get_print_port(void); * for(;;) { * //Waiting for UART event. * if(xQueueReceive(uart0_queue, (void * )&event, (portTickType)portMAX_DELAY)) { - * ESP_LOGI(UART_TAG, "uart[%d] event:", uart_num); + * ESP_LOGI(TAG, "uart[%d] event:", uart_num); * switch(event.type) { * //Event of UART receving data * case UART_DATA: - * ESP_LOGI(UART_TAG,"data, len: %d\n", event.data.size); + * ESP_LOGI(TAG,"data, len: %d\n", event.data.size); * int len = uart_read_bytes(uart_num, dtmp, event.data.size, 10); - * ESP_LOGI(UART_TAG, "uart read: %d\n", len); + * ESP_LOGI(TAG, "uart read: %d\n", len); * break; * //Event of HW FIFO overflow detected * case UART_FIFO_OVF: - * ESP_LOGI(UART_TAG, "hw fifo overflow\n"); + * ESP_LOGI(TAG, "hw fifo overflow\n"); * break; * //Event of UART ring buffer full * case UART_BUFFER_FULL: - * ESP_LOGI(UART_TAG, "ring buffer full\n"); + * ESP_LOGI(TAG, "ring buffer full\n"); * break; * //Event of UART RX break detected * case UART_BREAK: - * ESP_LOGI(UART_TAG, "uart rx break\n"); + * ESP_LOGI(TAG, "uart rx break\n"); * break; * //Event of UART parity check error * case UART_PARITY_ERR: - * ESP_LOGI(UART_TAG, "uart parity error\n"); + * ESP_LOGI(TAG, "uart parity error\n"); * break; * //Event of UART frame error * case UART_FRAME_ERR: - * ESP_LOGI(UART_TAG, "uart frame error\n"); + * ESP_LOGI(TAG, "uart frame error\n"); * break; * //Others * default: - * ESP_LOGI(UART_TAG, "uart event type: %d\n", event.type); + * ESP_LOGI(TAG, "uart event type: %d\n", event.type); * break; * } * } @@ -775,9 +751,9 @@ int uart_get_print_port(void); * //Set UART parameters * uart_param_config(uart_num, &uart_config); * //Set UART pins,(-1: default pin, no change.) - * uart_set_pin(uart_num, -1, -1, 15, 13); + * uart_set_pin(uart_num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, 15, 13); * //Set UART log level - * esp_log_level_set(UART_TAG, ESP_LOG_INFO); + * esp_log_level_set(TAG, ESP_LOG_INFO); * //Install UART driver, and get the queue. * uart_driver_install(uart_num, 1024 * 2, 1024*4, 10, 17, &uart0_queue, RINGBUF_TYPE_BYTEBUF); * //Create a task to handler UART event from ISR diff --git a/components/driver/ledc.c b/components/driver/ledc.c index 771c4a17df..b9039cf626 100644 --- a/components/driver/ledc.c +++ b/components/driver/ledc.c @@ -20,7 +20,7 @@ #include "driver/ledc.h" #include "esp_log.h" -const char* LEDC_TAG = "LEDC"; +static const char* LEDC_TAG = "LEDC"; static portMUX_TYPE ledc_spinlock = portMUX_INITIALIZER_UNLOCKED; #define LEDC_CHECK(a, str, ret_val) if (!(a)) { \ ESP_LOGE(LEDC_TAG,"%s:%d (%s):%s\n", __FILE__, __LINE__, __FUNCTION__, str); \ diff --git a/components/driver/uart.c b/components/driver/uart.c index cab05dd0be..a3e0b92b2b 100644 --- a/components/driver/uart.c +++ b/components/driver/uart.c @@ -29,7 +29,7 @@ #include "driver/gpio.h" #include "soc/uart_struct.h" -const char* UART_TAG = "UART"; +static const char* UART_TAG = "UART"; #define UART_CHECK(a, str, ret) if (!(a)) { \ ESP_LOGE(UART_TAG,"%s:%d (%s):%s\n", __FILE__, __LINE__, __FUNCTION__, str); \ return (ret); \ @@ -249,28 +249,19 @@ esp_err_t uart_disable_intr_mask(uart_port_t uart_num, uint32_t disable_mask) esp_err_t uart_enable_rx_intr(uart_port_t uart_num) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); - UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); - SET_PERI_REG_MASK(UART_INT_ENA_REG(uart_num), UART_RXFIFO_FULL_INT_ENA|UART_RXFIFO_TOUT_INT_ENA); - UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + uart_enable_intr_mask(uart_num, UART_RXFIFO_FULL_INT_ENA|UART_RXFIFO_TOUT_INT_ENA); return ESP_OK; } esp_err_t uart_disable_rx_intr(uart_port_t uart_num) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); - UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); - CLEAR_PERI_REG_MASK(UART_INT_ENA_REG(uart_num), UART_RXFIFO_FULL_INT_ENA|UART_RXFIFO_TOUT_INT_ENA); - UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + uart_disable_intr_mask(uart_num, UART_RXFIFO_FULL_INT_ENA|UART_RXFIFO_TOUT_INT_ENA); return ESP_OK; } esp_err_t uart_disable_tx_intr(uart_port_t uart_num) { - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); - UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); - UART[uart_num]->int_ena.txfifo_empty = 0; - UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + uart_disable_intr_mask(uart_num, UART_TXFIFO_EMPTY_INT_ENA); return ESP_OK; } @@ -391,7 +382,7 @@ esp_err_t uart_set_dtr(uart_port_t uart_num, int level) return ESP_OK; } -esp_err_t uart_param_config(uart_port_t uart_num, uart_config_t *uart_config) +esp_err_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_config) { UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); UART_CHECK((uart_config), "param null\n", ESP_FAIL); @@ -413,25 +404,25 @@ esp_err_t uart_param_config(uart_port_t uart_num, uart_config_t *uart_config) return ESP_OK; } -esp_err_t uart_intr_config(uart_port_t uart_num, uart_intr_config_t *p_intr_conf) +esp_err_t uart_intr_config(uart_port_t uart_num, const uart_intr_config_t *intr_conf) { UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); - UART_CHECK((p_intr_conf), "param null\n", ESP_FAIL); + UART_CHECK((intr_conf), "param null\n", ESP_FAIL); UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); UART[uart_num]->int_clr.val = UART_INTR_MASK; - if(p_intr_conf->intr_enable_mask & UART_RXFIFO_TOUT_INT_ENA_M) { - UART[uart_num]->conf1.rx_tout_thrhd = ((p_intr_conf->rx_timeout_thresh) & UART_RX_TOUT_THRHD_V); + if(intr_conf->intr_enable_mask & UART_RXFIFO_TOUT_INT_ENA_M) { + UART[uart_num]->conf1.rx_tout_thrhd = ((intr_conf->rx_timeout_thresh) & UART_RX_TOUT_THRHD_V); UART[uart_num]->conf1.rx_tout_en = 1; } else { UART[uart_num]->conf1.rx_tout_en = 0; } - if(p_intr_conf->intr_enable_mask & UART_RXFIFO_FULL_INT_ENA_M) { - UART[uart_num]->conf1.rxfifo_full_thrhd = p_intr_conf->rxfifo_full_thresh; + if(intr_conf->intr_enable_mask & UART_RXFIFO_FULL_INT_ENA_M) { + UART[uart_num]->conf1.rxfifo_full_thrhd = intr_conf->rxfifo_full_thresh; } - if(p_intr_conf->intr_enable_mask & UART_TXFIFO_EMPTY_INT_ENA_M) { - UART[uart_num]->conf1.txfifo_empty_thrhd = p_intr_conf->txfifo_empty_intr_thresh; + if(intr_conf->intr_enable_mask & UART_TXFIFO_EMPTY_INT_ENA_M) { + UART[uart_num]->conf1.txfifo_empty_thrhd = intr_conf->txfifo_empty_intr_thresh; } - UART[uart_num]->int_ena.val = p_intr_conf->intr_enable_mask; + UART[uart_num]->int_ena.val = intr_conf->intr_enable_mask; UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); return ESP_FAIL; } @@ -459,8 +450,8 @@ static void IRAM_ATTR uart_rx_intr_handler_default(void *param) if(p_uart->tx_waiting_brk) { return; } - //TX semaphore used in none tx ringbuffer mode. - if(p_uart->tx_waiting_fifo == true && p_uart->tx_buf_size > 0) { + //TX semaphore will only be used when tx_buf_size is zero. + if(p_uart->tx_waiting_fifo == true && p_uart->tx_buf_size == 0) { p_uart->tx_waiting_fifo = false; xSemaphoreGiveFromISR(p_uart->tx_fifo_sem, NULL); } @@ -682,7 +673,7 @@ static esp_err_t uart_set_break(uart_port_t uart_num, int break_num) //Fill UART tx_fifo and return a number, //This function by itself is not thread-safe, always call from within a muxed section. -static int uart_fill_fifo(uart_port_t uart_num, char* buffer, uint32_t len) +static int uart_fill_fifo(uart_port_t uart_num, const char* buffer, uint32_t len) { uint8_t i = 0; uint8_t tx_fifo_cnt = UART[uart_num]->status.txfifo_cnt; @@ -694,7 +685,7 @@ static int uart_fill_fifo(uart_port_t uart_num, char* buffer, uint32_t len) return copy_cnt; } -int uart_tx_chars(uart_port_t uart_num, char* buffer, uint32_t len) +int uart_tx_chars(uart_port_t uart_num, const char* buffer, uint32_t len) { UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", (-1)); UART_CHECK((p_uart_obj[uart_num]), "uart driver error", (-1)); @@ -703,7 +694,7 @@ int uart_tx_chars(uart_port_t uart_num, char* buffer, uint32_t len) return 0; } xSemaphoreTake(p_uart_obj[uart_num]->tx_mux, (portTickType)portMAX_DELAY); - int tx_len = uart_fill_fifo(uart_num, buffer, len); + int tx_len = uart_fill_fifo(uart_num, (const char*) buffer, len); xSemaphoreGive(p_uart_obj[uart_num]->tx_mux); return tx_len; } @@ -713,44 +704,21 @@ static int uart_tx_all(uart_port_t uart_num, const char* src, size_t size, bool if(size == 0) { return 0; } + size_t original_size = size; + //lock for uart_tx xSemaphoreTake(p_uart_obj[uart_num]->tx_mux, (portTickType)portMAX_DELAY); - size_t original_size = size; - while(size) { - //semaphore for tx_fifo available - if(pdTRUE == xSemaphoreTake(p_uart_obj[uart_num]->tx_fifo_sem, (portTickType)portMAX_DELAY)) { - size_t sent = uart_fill_fifo(uart_num, (char*) src, size); - if(sent < size) { - p_uart_obj[uart_num]->tx_waiting_fifo = true; - uart_enable_tx_intr(uart_num, 1, UART_EMPTY_THRESH_DEFAULT); - } - size -= sent; - src += sent; - } - } - if(brk_en) { - uart_set_break(uart_num, brk_len); - xSemaphoreTake(p_uart_obj[uart_num]->tx_brk_sem, (portTickType)portMAX_DELAY); - } - xSemaphoreGive(p_uart_obj[uart_num]->tx_fifo_sem); - xSemaphoreGive(p_uart_obj[uart_num]->tx_mux); - return original_size; -} - -int uart_tx_all_chars(uart_port_t uart_num, const char* src, size_t size) -{ - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", (-1)); - UART_CHECK((p_uart_obj[uart_num] != NULL), "uart driver error", (-1)); - UART_CHECK(src, "buffer null", (-1)); - //Push data to TX ring buffer and return, ISR will send the data. if(p_uart_obj[uart_num]->tx_buf_size > 0) { - xSemaphoreTake(p_uart_obj[uart_num]->tx_mux, (portTickType)portMAX_DELAY); int max_size = xRingbufferGetMaxItemSize(p_uart_obj[uart_num]->tx_ring_buf); - int ori_size = size; int offset = 0; uart_event_t evt; - evt.type = UART_DATA; evt.data.size = size; + evt.data.brk_len = brk_len; + if(brk_en) { + evt.type = UART_DATA_BREAK; + } else { + evt.type = UART_DATA; + } xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void*) &evt, sizeof(uart_event_t), portMAX_DELAY); while(size > 0) { int send_size = size > max_size / 2 ? max_size / 2 : size; @@ -760,86 +728,45 @@ int uart_tx_all_chars(uart_port_t uart_num, const char* src, size_t size) } xSemaphoreGive(p_uart_obj[uart_num]->tx_mux); uart_enable_tx_intr(uart_num, 1, UART_EMPTY_THRESH_DEFAULT); - return ori_size; } else { - //Send data without TX ring buffer, the task will block until all data have been sent out - return uart_tx_all(uart_num, src, size, 0, 0); + while(size) { + //semaphore for tx_fifo available + if(pdTRUE == xSemaphoreTake(p_uart_obj[uart_num]->tx_fifo_sem, (portTickType)portMAX_DELAY)) { + size_t sent = uart_fill_fifo(uart_num, (char*) src, size); + if(sent < size) { + p_uart_obj[uart_num]->tx_waiting_fifo = true; + uart_enable_tx_intr(uart_num, 1, UART_EMPTY_THRESH_DEFAULT); + } + size -= sent; + src += sent; + } + } + if(brk_en) { + uart_set_break(uart_num, brk_len); + xSemaphoreTake(p_uart_obj[uart_num]->tx_brk_sem, (portTickType)portMAX_DELAY); + } + xSemaphoreGive(p_uart_obj[uart_num]->tx_fifo_sem); } + xSemaphoreGive(p_uart_obj[uart_num]->tx_mux); + return original_size; } -int uart_tx_all_chars_with_break(uart_port_t uart_num, const char* src, size_t size, int brk_len) +int uart_write_bytes(uart_port_t uart_num, const char* src, size_t size) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", (-1)); + UART_CHECK((p_uart_obj[uart_num] != NULL), "uart driver error", (-1)); + UART_CHECK(src, "buffer null", (-1)); + return uart_tx_all(uart_num, src, size, 0, 0); +} + +int uart_write_bytes_with_break(uart_port_t uart_num, const char* src, size_t size, int brk_len) { UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", (-1)); UART_CHECK((p_uart_obj[uart_num]), "uart driver error", (-1)); UART_CHECK((size > 0), "uart size error", (-1)); UART_CHECK((src), "uart data null", (-1)); UART_CHECK((brk_len > 0 && brk_len < 256), "break_num error", (-1)); - //Push data to TX ring buffer and return, ISR will send the data. - if(p_uart_obj[uart_num]->tx_buf_size > 0) { - xSemaphoreTake(p_uart_obj[uart_num]->tx_mux, (portTickType)portMAX_DELAY); - int max_size = xRingbufferGetMaxItemSize(p_uart_obj[uart_num]->tx_ring_buf); - int ori_size = size; - int offset = 0; - uart_event_t evt; - evt.type = UART_DATA_BREAK; - evt.data.size = size; - evt.data.brk_len = brk_len; - xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void*) &evt, sizeof(uart_event_t), portMAX_DELAY); - while(size > 0) { - int send_size = size > max_size / 2 ? max_size / 2 : size; - xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void*) (src + offset), send_size, portMAX_DELAY); - size -= send_size; - offset += send_size; - } - xSemaphoreGive(p_uart_obj[uart_num]->tx_mux); - uart_enable_tx_intr(uart_num, 1, UART_EMPTY_THRESH_DEFAULT); - return ori_size; - } else { - //Send data without TX ring buffer, the task will block until all data have been sent out - return uart_tx_all(uart_num, src, size, 1, brk_len); - } -} - -int uart_read_char(uart_port_t uart_num, TickType_t ticks_to_wait) -{ - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", (-1)); - UART_CHECK((p_uart_obj[uart_num]), "uart driver error", (-1)); - uint8_t* data; - size_t size; - int val; - portTickType ticks_end = xTaskGetTickCount() + ticks_to_wait; - if(xSemaphoreTake(p_uart_obj[uart_num]->rx_mux,(portTickType)ticks_to_wait) != pdTRUE) { - return -1; - } - if(p_uart_obj[uart_num]->rx_cur_remain == 0) { - ticks_to_wait = ticks_end - xTaskGetTickCount(); - data = (uint8_t*) xRingbufferReceive(p_uart_obj[uart_num]->rx_ring_buf, &size, (portTickType) ticks_to_wait); - if(data) { - p_uart_obj[uart_num]->rx_head_ptr = data; - p_uart_obj[uart_num]->rx_ptr = data; - p_uart_obj[uart_num]->rx_cur_remain = size; - } else { - xSemaphoreGive(p_uart_obj[uart_num]->rx_mux); - return -1; - } - } - val = *(p_uart_obj[uart_num]->rx_ptr); - p_uart_obj[uart_num]->rx_ptr++; - p_uart_obj[uart_num]->rx_cur_remain--; - if(p_uart_obj[uart_num]->rx_cur_remain == 0) { - vRingbufferReturnItem(p_uart_obj[uart_num]->rx_ring_buf, p_uart_obj[uart_num]->rx_head_ptr); - p_uart_obj[uart_num]->rx_head_ptr = NULL; - p_uart_obj[uart_num]->rx_ptr = NULL; - if(p_uart_obj[uart_num]->rx_buffer_full_flg) { - BaseType_t res = xRingbufferSend(p_uart_obj[uart_num]->rx_ring_buf, p_uart_obj[uart_num]->rx_data_buf, p_uart_obj[uart_num]->rx_stash_len, 1); - if(res == pdTRUE) { - p_uart_obj[uart_num]->rx_buffer_full_flg = false; - uart_enable_rx_intr(p_uart_obj[uart_num]->uart_num); - } - } - } - xSemaphoreGive(p_uart_obj[uart_num]->rx_mux); - return val; + return uart_tx_all(uart_num, src, size, 1, brk_len); } int uart_read_bytes(uart_port_t uart_num, uint8_t* buf, uint32_t length, TickType_t ticks_to_wait) @@ -952,59 +879,6 @@ esp_err_t uart_flush(uart_port_t uart_num) return ESP_OK; } -//----------------------------------- -//Should not enable hw flow control the debug print port. -//Use uart_tx_all_chars() as a thread-safe function to send data. -static int s_uart_print_nport = UART_NUM_0; -static void uart2_write_char(char chr) -{ - uart_tx_all_chars(UART_NUM_2, (const char*)&chr, 1); -} - -static void uart1_write_char(char chr) -{ - uart_tx_all_chars(UART_NUM_1, (const char*)&chr, 1); -} - -static void uart0_write_char(char chr) -{ - uart_tx_all_chars(UART_NUM_0, (const char*)&chr, 1); -} - -static void uart_ignore_char(char chr) -{ - -} - -//Only effective to ets_printf function, not ESP_LOGX macro. -esp_err_t uart_set_print_port(uart_port_t uart_num) -{ - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); - UART_CHECK((p_uart_obj[uart_num]), "UART driver error", ESP_FAIL); - s_uart_print_nport = uart_num; - switch(s_uart_print_nport) { - case UART_NUM_0: - ets_install_putc1(uart0_write_char); - break; - case UART_NUM_1: - ets_install_putc1(uart1_write_char); - break; - case UART_NUM_2: - ets_install_putc1(uart2_write_char); - break; - case UART_NUM_MAX: - default: - ets_install_putc1(uart_ignore_char); - break; - } - return ESP_OK; -} - -int uart_get_print_port() -{ - return s_uart_print_nport; -} - esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_buffer_size, int queue_size, int uart_intr_num, void* uart_queue) { UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); From 2d88fc0329d5679d0ff8f6280443e5c4cb83dac0 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 4 Nov 2016 14:12:21 +0800 Subject: [PATCH 263/343] wpa_supplicant: replace pre-built crypto library with source code --- components/esp32/component.mk | 2 +- components/wpa_supplicant/COPYING | 22 + components/wpa_supplicant/component.mk | 6 + .../wpa_supplicant/include/crypto/aes.h | 27 + .../wpa_supplicant/include/crypto/aes_i.h | 131 + .../wpa_supplicant/include/crypto/aes_wrap.h | 48 + .../wpa_supplicant/include/crypto/base64.h | 23 + .../wpa_supplicant/include/crypto/common.h | 481 +++ .../wpa_supplicant/include/crypto/crypto.h | 471 +++ .../wpa_supplicant/include/crypto/dh_group5.h | 23 + .../wpa_supplicant/include/crypto/dh_groups.h | 32 + .../wpa_supplicant/include/crypto/includes.h | 65 + .../wpa_supplicant/include/crypto/md5.h | 35 + .../wpa_supplicant/include/crypto/md5_i.h | 29 + .../wpa_supplicant/include/crypto/random.h | 34 + .../wpa_supplicant/include/crypto/sha1.h | 33 + .../wpa_supplicant/include/crypto/sha1_i.h | 29 + .../wpa_supplicant/include/crypto/sha256.h | 27 + .../wpa_supplicant/include/wpa/ap_config.h | 544 +++ .../wpa_supplicant/include/wpa/common.h | 324 ++ components/wpa_supplicant/include/wpa/defs.h | 307 ++ .../wpa_supplicant/include/wpa/eapol_common.h | 71 + .../wpa_supplicant/include/wpa/hostapd.h | 312 ++ .../include/wpa/ieee80211_crypto.h | 226 ++ .../include/wpa/ieee802_11_defs.h | 607 +++ .../wpa_supplicant/include/wpa/ieee802_1x.h | 64 + .../wpa_supplicant/include/wpa/includes.h | 31 + components/wpa_supplicant/include/wpa/list.h | 101 + .../wpa_supplicant/include/wpa/sta_info.h | 194 + .../include/wpa/state_machine.h | 138 + components/wpa_supplicant/include/wpa/wpa.h | 193 + .../wpa_supplicant/include/wpa/wpa_auth.h | 292 ++ .../wpa_supplicant/include/wpa/wpa_auth_i.h | 234 ++ .../wpa_supplicant/include/wpa/wpa_auth_ie.h | 50 + .../wpa_supplicant/include/wpa/wpa_common.h | 332 ++ .../wpa_supplicant/include/wpa/wpa_debug.h | 193 + components/wpa_supplicant/include/wpa/wpa_i.h | 89 + .../wpa_supplicant/include/wpa/wpa_ie.h | 56 + .../wpa_supplicant/include/wpa/wpabuf.h | 168 + .../wpa_supplicant/include/wpa/wpas_glue.h | 31 + .../include/wpa2/eap_peer/eap.h | 24 + .../include/wpa2/eap_peer/eap_common.h | 23 + .../include/wpa2/eap_peer/eap_config.h | 220 ++ .../include/wpa2/eap_peer/eap_defs.h | 92 + .../include/wpa2/eap_peer/eap_i.h | 88 + .../include/wpa2/eap_peer/eap_tls.h | 25 + .../include/wpa2/eap_peer/eap_tls_common.h | 131 + .../wpa_supplicant/include/wpa2/tls/asn1.h | 66 + .../wpa_supplicant/include/wpa2/tls/bignum.h | 38 + .../include/wpa2/tls/libtommath.h | 3443 +++++++++++++++++ .../wpa_supplicant/include/wpa2/tls/pkcs1.h | 22 + .../wpa_supplicant/include/wpa2/tls/pkcs5.h | 16 + .../wpa_supplicant/include/wpa2/tls/pkcs8.h | 16 + .../wpa_supplicant/include/wpa2/tls/rsa.h | 23 + .../wpa_supplicant/include/wpa2/tls/tls.h | 537 +++ .../include/wpa2/tls/tlsv1_client.h | 54 + .../include/wpa2/tls/tlsv1_client_i.h | 84 + .../include/wpa2/tls/tlsv1_common.h | 261 ++ .../include/wpa2/tls/tlsv1_cred.h | 40 + .../include/wpa2/tls/tlsv1_record.h | 71 + .../include/wpa2/tls/tlsv1_server.h | 48 + .../include/wpa2/tls/tlsv1_server_i.h | 71 + .../wpa_supplicant/include/wpa2/tls/x509v3.h | 123 + .../include/wpa2/utils/base64.h | 17 + .../include/wpa2/utils/ext_password.h | 33 + .../include/wpa2/utils/ext_password_i.h | 23 + .../wpa_supplicant/port/include/byteswap.h | 65 + .../wpa_supplicant/port/include/endian.h | 229 ++ components/wpa_supplicant/port/include/os.h | 286 ++ .../wpa_supplicant/src/crypto/aes-cbc.c | 88 + .../src/crypto/aes-internal-dec.c | 172 + .../src/crypto/aes-internal-enc.c | 134 + .../wpa_supplicant/src/crypto/aes-internal.c | 854 ++++ .../wpa_supplicant/src/crypto/aes-unwrap.c | 80 + .../wpa_supplicant/src/crypto/aes-wrap.c | 70 + components/wpa_supplicant/src/crypto/bignum.c | 244 ++ components/wpa_supplicant/src/crypto/bignum.h | 38 + .../src/crypto/crypto_internal-cipher.c | 268 ++ .../src/crypto/crypto_internal-modexp.c | 56 + .../src/crypto/crypto_internal-rsa.c | 111 + .../src/crypto/crypto_internal.c | 280 ++ .../wpa_supplicant/src/crypto/dh_group5.c | 43 + .../wpa_supplicant/src/crypto/dh_groups.c | 641 +++ .../wpa_supplicant/src/crypto/libtommath.h | 3440 ++++++++++++++++ .../wpa_supplicant/src/crypto/md5-internal.c | 298 ++ components/wpa_supplicant/src/crypto/md5.c | 113 + components/wpa_supplicant/src/crypto/rc4.c | 61 + .../wpa_supplicant/src/crypto/sha1-internal.c | 313 ++ .../wpa_supplicant/src/crypto/sha1-pbkdf2.c | 101 + components/wpa_supplicant/src/crypto/sha1.c | 166 + .../src/crypto/sha256-internal.c | 249 ++ components/wpa_supplicant/src/crypto/sha256.c | 160 + 92 files changed, 20223 insertions(+), 1 deletion(-) create mode 100644 components/wpa_supplicant/COPYING create mode 100644 components/wpa_supplicant/component.mk create mode 100644 components/wpa_supplicant/include/crypto/aes.h create mode 100644 components/wpa_supplicant/include/crypto/aes_i.h create mode 100644 components/wpa_supplicant/include/crypto/aes_wrap.h create mode 100644 components/wpa_supplicant/include/crypto/base64.h create mode 100644 components/wpa_supplicant/include/crypto/common.h create mode 100644 components/wpa_supplicant/include/crypto/crypto.h create mode 100644 components/wpa_supplicant/include/crypto/dh_group5.h create mode 100644 components/wpa_supplicant/include/crypto/dh_groups.h create mode 100644 components/wpa_supplicant/include/crypto/includes.h create mode 100644 components/wpa_supplicant/include/crypto/md5.h create mode 100644 components/wpa_supplicant/include/crypto/md5_i.h create mode 100644 components/wpa_supplicant/include/crypto/random.h create mode 100644 components/wpa_supplicant/include/crypto/sha1.h create mode 100644 components/wpa_supplicant/include/crypto/sha1_i.h create mode 100644 components/wpa_supplicant/include/crypto/sha256.h create mode 100644 components/wpa_supplicant/include/wpa/ap_config.h create mode 100644 components/wpa_supplicant/include/wpa/common.h create mode 100644 components/wpa_supplicant/include/wpa/defs.h create mode 100644 components/wpa_supplicant/include/wpa/eapol_common.h create mode 100644 components/wpa_supplicant/include/wpa/hostapd.h create mode 100644 components/wpa_supplicant/include/wpa/ieee80211_crypto.h create mode 100644 components/wpa_supplicant/include/wpa/ieee802_11_defs.h create mode 100644 components/wpa_supplicant/include/wpa/ieee802_1x.h create mode 100644 components/wpa_supplicant/include/wpa/includes.h create mode 100644 components/wpa_supplicant/include/wpa/list.h create mode 100644 components/wpa_supplicant/include/wpa/sta_info.h create mode 100644 components/wpa_supplicant/include/wpa/state_machine.h create mode 100644 components/wpa_supplicant/include/wpa/wpa.h create mode 100644 components/wpa_supplicant/include/wpa/wpa_auth.h create mode 100644 components/wpa_supplicant/include/wpa/wpa_auth_i.h create mode 100644 components/wpa_supplicant/include/wpa/wpa_auth_ie.h create mode 100644 components/wpa_supplicant/include/wpa/wpa_common.h create mode 100644 components/wpa_supplicant/include/wpa/wpa_debug.h create mode 100644 components/wpa_supplicant/include/wpa/wpa_i.h create mode 100644 components/wpa_supplicant/include/wpa/wpa_ie.h create mode 100644 components/wpa_supplicant/include/wpa/wpabuf.h create mode 100644 components/wpa_supplicant/include/wpa/wpas_glue.h create mode 100644 components/wpa_supplicant/include/wpa2/eap_peer/eap.h create mode 100644 components/wpa_supplicant/include/wpa2/eap_peer/eap_common.h create mode 100644 components/wpa_supplicant/include/wpa2/eap_peer/eap_config.h create mode 100644 components/wpa_supplicant/include/wpa2/eap_peer/eap_defs.h create mode 100644 components/wpa_supplicant/include/wpa2/eap_peer/eap_i.h create mode 100644 components/wpa_supplicant/include/wpa2/eap_peer/eap_tls.h create mode 100644 components/wpa_supplicant/include/wpa2/eap_peer/eap_tls_common.h create mode 100644 components/wpa_supplicant/include/wpa2/tls/asn1.h create mode 100644 components/wpa_supplicant/include/wpa2/tls/bignum.h create mode 100644 components/wpa_supplicant/include/wpa2/tls/libtommath.h create mode 100644 components/wpa_supplicant/include/wpa2/tls/pkcs1.h create mode 100644 components/wpa_supplicant/include/wpa2/tls/pkcs5.h create mode 100644 components/wpa_supplicant/include/wpa2/tls/pkcs8.h create mode 100644 components/wpa_supplicant/include/wpa2/tls/rsa.h create mode 100644 components/wpa_supplicant/include/wpa2/tls/tls.h create mode 100644 components/wpa_supplicant/include/wpa2/tls/tlsv1_client.h create mode 100644 components/wpa_supplicant/include/wpa2/tls/tlsv1_client_i.h create mode 100644 components/wpa_supplicant/include/wpa2/tls/tlsv1_common.h create mode 100644 components/wpa_supplicant/include/wpa2/tls/tlsv1_cred.h create mode 100644 components/wpa_supplicant/include/wpa2/tls/tlsv1_record.h create mode 100644 components/wpa_supplicant/include/wpa2/tls/tlsv1_server.h create mode 100644 components/wpa_supplicant/include/wpa2/tls/tlsv1_server_i.h create mode 100644 components/wpa_supplicant/include/wpa2/tls/x509v3.h create mode 100644 components/wpa_supplicant/include/wpa2/utils/base64.h create mode 100644 components/wpa_supplicant/include/wpa2/utils/ext_password.h create mode 100644 components/wpa_supplicant/include/wpa2/utils/ext_password_i.h create mode 100644 components/wpa_supplicant/port/include/byteswap.h create mode 100644 components/wpa_supplicant/port/include/endian.h create mode 100644 components/wpa_supplicant/port/include/os.h create mode 100644 components/wpa_supplicant/src/crypto/aes-cbc.c create mode 100644 components/wpa_supplicant/src/crypto/aes-internal-dec.c create mode 100644 components/wpa_supplicant/src/crypto/aes-internal-enc.c create mode 100644 components/wpa_supplicant/src/crypto/aes-internal.c create mode 100644 components/wpa_supplicant/src/crypto/aes-unwrap.c create mode 100644 components/wpa_supplicant/src/crypto/aes-wrap.c create mode 100644 components/wpa_supplicant/src/crypto/bignum.c create mode 100644 components/wpa_supplicant/src/crypto/bignum.h create mode 100644 components/wpa_supplicant/src/crypto/crypto_internal-cipher.c create mode 100644 components/wpa_supplicant/src/crypto/crypto_internal-modexp.c create mode 100644 components/wpa_supplicant/src/crypto/crypto_internal-rsa.c create mode 100644 components/wpa_supplicant/src/crypto/crypto_internal.c create mode 100644 components/wpa_supplicant/src/crypto/dh_group5.c create mode 100644 components/wpa_supplicant/src/crypto/dh_groups.c create mode 100644 components/wpa_supplicant/src/crypto/libtommath.h create mode 100644 components/wpa_supplicant/src/crypto/md5-internal.c create mode 100644 components/wpa_supplicant/src/crypto/md5.c create mode 100644 components/wpa_supplicant/src/crypto/rc4.c create mode 100644 components/wpa_supplicant/src/crypto/sha1-internal.c create mode 100644 components/wpa_supplicant/src/crypto/sha1-pbkdf2.c create mode 100644 components/wpa_supplicant/src/crypto/sha1.c create mode 100644 components/wpa_supplicant/src/crypto/sha256-internal.c create mode 100644 components/wpa_supplicant/src/crypto/sha256.c diff --git a/components/esp32/component.mk b/components/esp32/component.mk index 788f880127..e91020c3e6 100644 --- a/components/esp32/component.mk +++ b/components/esp32/component.mk @@ -10,7 +10,7 @@ COMPONENT_SRCDIRS := . hwcrypto -LIBS := crypto core net80211 phy rtc pp wpa smartconfig +LIBS := core net80211 phy rtc pp wpa smartconfig LINKER_SCRIPTS += -T esp32_out.ld -T esp32.common.ld -T esp32.rom.ld -T esp32.peripherals.ld diff --git a/components/wpa_supplicant/COPYING b/components/wpa_supplicant/COPYING new file mode 100644 index 0000000000..7efce0dee1 --- /dev/null +++ b/components/wpa_supplicant/COPYING @@ -0,0 +1,22 @@ +wpa_supplicant and hostapd +-------------------------- + +Copyright (c) 2002-2016, Jouni Malinen and contributors +All Rights Reserved. + + +See the README file for the current license terms. + +This software was previously distributed under BSD/GPL v2 dual license +terms that allowed either of those license alternatives to be +selected. As of February 11, 2012, the project has chosen to use only +the BSD license option for future distribution. As such, the GPL v2 +license option is no longer used. It should be noted that the BSD +license option (the one with advertisement clause removed) is compatible +with GPL and as such, does not prevent use of this software in projects +that use GPL. + +Some of the files may still include pointers to GPL version 2 license +terms. However, such copyright and license notifications are maintained +only for attribution purposes and any distribution of this software +after February 11, 2012 is no longer under the GPL v2 option. diff --git a/components/wpa_supplicant/component.mk b/components/wpa_supplicant/component.mk new file mode 100644 index 0000000000..6e5d7e0600 --- /dev/null +++ b/components/wpa_supplicant/component.mk @@ -0,0 +1,6 @@ +COMPONENT_ADD_INCLUDEDIRS := include port/include +COMPONENT_SRCDIRS := src/crypto + +CFLAGS += -DEMBEDDED_SUPP -D__ets__ + +include $(IDF_PATH)/make/component_common.mk diff --git a/components/wpa_supplicant/include/crypto/aes.h b/components/wpa_supplicant/include/crypto/aes.h new file mode 100644 index 0000000000..ba384a9dae --- /dev/null +++ b/components/wpa_supplicant/include/crypto/aes.h @@ -0,0 +1,27 @@ +/* + * AES functions + * Copyright (c) 2003-2006, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef AES_H +#define AES_H + +#define AES_BLOCK_SIZE 16 + +void * aes_encrypt_init(const u8 *key, size_t len); +void aes_encrypt(void *ctx, const u8 *plain, u8 *crypt); +void aes_encrypt_deinit(void *ctx); +void * aes_decrypt_init(const u8 *key, size_t len); +void aes_decrypt(void *ctx, const u8 *crypt, u8 *plain); +void aes_decrypt_deinit(void *ctx); + +#endif /* AES_H */ diff --git a/components/wpa_supplicant/include/crypto/aes_i.h b/components/wpa_supplicant/include/crypto/aes_i.h new file mode 100644 index 0000000000..1063422a81 --- /dev/null +++ b/components/wpa_supplicant/include/crypto/aes_i.h @@ -0,0 +1,131 @@ +/* + * AES (Rijndael) cipher + * Copyright (c) 2003-2005, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef AES_I_H +#define AES_I_H + +#include "aes.h" + +/* #define FULL_UNROLL */ +#define AES_SMALL_TABLES + +extern const u32 Te0[256]; +extern const u32 Te1[256]; +extern const u32 Te2[256]; +extern const u32 Te3[256]; +extern const u32 Te4[256]; +extern const u32 Td0[256]; +extern const u32 Td1[256]; +extern const u32 Td2[256]; +extern const u32 Td3[256]; +extern const u32 Td4[256]; +extern const u32 rcon[10]; +extern const u8 Td4s[256]; +extern const u8 rcons[10]; + +#ifndef AES_SMALL_TABLES + +#define RCON(i) rcon[(i)] + +#define TE0(i) Te0[((i) >> 24) & 0xff] +#define TE1(i) Te1[((i) >> 16) & 0xff] +#define TE2(i) Te2[((i) >> 8) & 0xff] +#define TE3(i) Te3[(i) & 0xff] +#define TE41(i) (Te4[((i) >> 24) & 0xff] & 0xff000000) +#define TE42(i) (Te4[((i) >> 16) & 0xff] & 0x00ff0000) +#define TE43(i) (Te4[((i) >> 8) & 0xff] & 0x0000ff00) +#define TE44(i) (Te4[(i) & 0xff] & 0x000000ff) +#define TE421(i) (Te4[((i) >> 16) & 0xff] & 0xff000000) +#define TE432(i) (Te4[((i) >> 8) & 0xff] & 0x00ff0000) +#define TE443(i) (Te4[(i) & 0xff] & 0x0000ff00) +#define TE414(i) (Te4[((i) >> 24) & 0xff] & 0x000000ff) +#define TE411(i) (Te4[((i) >> 24) & 0xff] & 0xff000000) +#define TE422(i) (Te4[((i) >> 16) & 0xff] & 0x00ff0000) +#define TE433(i) (Te4[((i) >> 8) & 0xff] & 0x0000ff00) +#define TE444(i) (Te4[(i) & 0xff] & 0x000000ff) +#define TE4(i) (Te4[(i)] & 0x000000ff) + +#define TD0(i) Td0[((i) >> 24) & 0xff] +#define TD1(i) Td1[((i) >> 16) & 0xff] +#define TD2(i) Td2[((i) >> 8) & 0xff] +#define TD3(i) Td3[(i) & 0xff] +#define TD41(i) (Td4[((i) >> 24) & 0xff] & 0xff000000) +#define TD42(i) (Td4[((i) >> 16) & 0xff] & 0x00ff0000) +#define TD43(i) (Td4[((i) >> 8) & 0xff] & 0x0000ff00) +#define TD44(i) (Td4[(i) & 0xff] & 0x000000ff) +#define TD0_(i) Td0[(i) & 0xff] +#define TD1_(i) Td1[(i) & 0xff] +#define TD2_(i) Td2[(i) & 0xff] +#define TD3_(i) Td3[(i) & 0xff] + +#else /* AES_SMALL_TABLES */ + +#define RCON(i) (rcons[(i)] << 24) + +static inline u32 rotr(u32 val, int bits) +{ + return (val >> bits) | (val << (32 - bits)); +} + +#define TE0(i) Te0[((i) >> 24) & 0xff] +#define TE1(i) rotr(Te0[((i) >> 16) & 0xff], 8) +#define TE2(i) rotr(Te0[((i) >> 8) & 0xff], 16) +#define TE3(i) rotr(Te0[(i) & 0xff], 24) +#define TE41(i) ((Te0[((i) >> 24) & 0xff] << 8) & 0xff000000) +#define TE42(i) (Te0[((i) >> 16) & 0xff] & 0x00ff0000) +#define TE43(i) (Te0[((i) >> 8) & 0xff] & 0x0000ff00) +#define TE44(i) ((Te0[(i) & 0xff] >> 8) & 0x000000ff) +#define TE421(i) ((Te0[((i) >> 16) & 0xff] << 8) & 0xff000000) +#define TE432(i) (Te0[((i) >> 8) & 0xff] & 0x00ff0000) +#define TE443(i) (Te0[(i) & 0xff] & 0x0000ff00) +#define TE414(i) ((Te0[((i) >> 24) & 0xff] >> 8) & 0x000000ff) +#define TE411(i) ((Te0[((i) >> 24) & 0xff] << 8) & 0xff000000) +#define TE422(i) (Te0[((i) >> 16) & 0xff] & 0x00ff0000) +#define TE433(i) (Te0[((i) >> 8) & 0xff] & 0x0000ff00) +#define TE444(i) ((Te0[(i) & 0xff] >> 8) & 0x000000ff) +#define TE4(i) ((Te0[(i)] >> 8) & 0x000000ff) + +#define TD0(i) Td0[((i) >> 24) & 0xff] +#define TD1(i) rotr(Td0[((i) >> 16) & 0xff], 8) +#define TD2(i) rotr(Td0[((i) >> 8) & 0xff], 16) +#define TD3(i) rotr(Td0[(i) & 0xff], 24) +#define TD41(i) (Td4s[((i) >> 24) & 0xff] << 24) +#define TD42(i) (Td4s[((i) >> 16) & 0xff] << 16) +#define TD43(i) (Td4s[((i) >> 8) & 0xff] << 8) +#define TD44(i) (Td4s[(i) & 0xff]) +#define TD0_(i) Td0[(i) & 0xff] +#define TD1_(i) rotr(Td0[(i) & 0xff], 8) +#define TD2_(i) rotr(Td0[(i) & 0xff], 16) +#define TD3_(i) rotr(Td0[(i) & 0xff], 24) + +#endif /* AES_SMALL_TABLES */ + +#ifdef _MSC_VER +#define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00) +#define GETU32(p) SWAP(*((u32 *)(p))) +#define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); } +#else +#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ \ +((u32)(pt)[2] << 8) ^ ((u32)(pt)[3])) +#define PUTU32(ct, st) { \ +(ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); \ +(ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); } +#endif + +#define AES_PRIV_SIZE (4 * 4 * 15 + 4) +#define AES_PRIV_NR_POS (4 * 15) + +int rijndaelKeySetupEnc(u32 rk[], const u8 cipherKey[], int keyBits); + +#endif /* AES_I_H */ diff --git a/components/wpa_supplicant/include/crypto/aes_wrap.h b/components/wpa_supplicant/include/crypto/aes_wrap.h new file mode 100644 index 0000000000..4b1c7b083b --- /dev/null +++ b/components/wpa_supplicant/include/crypto/aes_wrap.h @@ -0,0 +1,48 @@ +/* + * AES-based functions + * + * - AES Key Wrap Algorithm (128-bit KEK) (RFC3394) + * - One-Key CBC MAC (OMAC1) hash with AES-128 + * - AES-128 CTR mode encryption + * - AES-128 EAX mode encryption/decryption + * - AES-128 CBC + * + * Copyright (c) 2003-2007, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef AES_WRAP_H +#define AES_WRAP_H + +int __must_check aes_wrap(const u8 *kek, int n, const u8 *plain, u8 *cipher); +int __must_check aes_unwrap(const u8 *kek, int n, const u8 *cipher, u8 *plain); +int __must_check omac1_aes_128_vector(const u8 *key, size_t num_elem, + const u8 *addr[], const size_t *len, + u8 *mac); +int __must_check omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, + u8 *mac); +int __must_check aes_128_encrypt_block(const u8 *key, const u8 *in, u8 *out); +int __must_check aes_128_ctr_encrypt(const u8 *key, const u8 *nonce, + u8 *data, size_t data_len); +int __must_check aes_128_eax_encrypt(const u8 *key, + const u8 *nonce, size_t nonce_len, + const u8 *hdr, size_t hdr_len, + u8 *data, size_t data_len, u8 *tag); +int __must_check aes_128_eax_decrypt(const u8 *key, + const u8 *nonce, size_t nonce_len, + const u8 *hdr, size_t hdr_len, + u8 *data, size_t data_len, const u8 *tag); +int __must_check aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, + size_t data_len); +int __must_check aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, + size_t data_len); + +#endif /* AES_WRAP_H */ diff --git a/components/wpa_supplicant/include/crypto/base64.h b/components/wpa_supplicant/include/crypto/base64.h new file mode 100644 index 0000000000..b87a1682f8 --- /dev/null +++ b/components/wpa_supplicant/include/crypto/base64.h @@ -0,0 +1,23 @@ +/* + * Base64 encoding/decoding (RFC1341) + * Copyright (c) 2005, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef BASE64_H +#define BASE64_H + +unsigned char * base64_encode(const unsigned char *src, size_t len, + size_t *out_len); +unsigned char * base64_decode(const unsigned char *src, size_t len, + size_t *out_len); + +#endif /* BASE64_H */ diff --git a/components/wpa_supplicant/include/crypto/common.h b/components/wpa_supplicant/include/crypto/common.h new file mode 100644 index 0000000000..319b861e45 --- /dev/null +++ b/components/wpa_supplicant/include/crypto/common.h @@ -0,0 +1,481 @@ +/* + * wpa_supplicant/hostapd / common helper functions, etc. + * Copyright (c) 2002-2007, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef COMMON_H +#define COMMON_H + +#include "os.h" + +#if defined(__XTENSA__) +#include +#define __BYTE_ORDER BYTE_ORDER +#define __LITTLE_ENDIAN LITTLE_ENDIAN +#define __BIG_ENDIAN BIG_ENDIAN +#endif /*__XTENSA__*/ + +#if defined(__linux__) || defined(__GLIBC__) +#include +#include +#endif /* __linux__ */ + +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || \ + defined(__OpenBSD__) +#include +#include +#define __BYTE_ORDER _BYTE_ORDER +#define __LITTLE_ENDIAN _LITTLE_ENDIAN +#define __BIG_ENDIAN _BIG_ENDIAN +#ifdef __OpenBSD__ +#define bswap_16 swap16 +#define bswap_32 swap32 +#define bswap_64 swap64 +#else /* __OpenBSD__ */ +#define bswap_16 bswap16 +#define bswap_32 bswap32 +#define bswap_64 bswap64 +#endif /* __OpenBSD__ */ +#endif /* defined(__FreeBSD__) || defined(__NetBSD__) || + * defined(__DragonFly__) || defined(__OpenBSD__) */ + +#ifdef __APPLE__ +#include +#include +#define __BYTE_ORDER _BYTE_ORDER +#define __LITTLE_ENDIAN _LITTLE_ENDIAN +#define __BIG_ENDIAN _BIG_ENDIAN +static inline unsigned short bswap_16(unsigned short v) +{ + return ((v & 0xff) << 8) | (v >> 8); +} + +static inline unsigned int bswap_32(unsigned int v) +{ + return ((v & 0xff) << 24) | ((v & 0xff00) << 8) | + ((v & 0xff0000) >> 8) | (v >> 24); +} +#endif /* __APPLE__ */ + +#ifdef CONFIG_TI_COMPILER +#define __BIG_ENDIAN 4321 +#define __LITTLE_ENDIAN 1234 +#ifdef __big_endian__ +#define __BYTE_ORDER __BIG_ENDIAN +#else +#define __BYTE_ORDER __LITTLE_ENDIAN +#endif +#endif /* CONFIG_TI_COMPILER */ + +#ifdef __SYMBIAN32__ +#define __BIG_ENDIAN 4321 +#define __LITTLE_ENDIAN 1234 +#define __BYTE_ORDER __LITTLE_ENDIAN +#endif /* __SYMBIAN32__ */ + +#ifdef CONFIG_NATIVE_WINDOWS +#include + +typedef int socklen_t; + +#ifndef MSG_DONTWAIT +#define MSG_DONTWAIT 0 /* not supported */ +#endif + +#endif /* CONFIG_NATIVE_WINDOWS */ + +#ifdef _MSC_VER +#define inline __inline + +#undef vsnprintf +#define vsnprintf _vsnprintf +#undef close +#define close closesocket +#endif /* _MSC_VER */ + + +/* Define platform specific integer types */ + +#ifdef _MSC_VER +typedef UINT64 u64; +typedef UINT32 u32; +typedef UINT16 u16; +typedef UINT8 u8; +typedef INT64 s64; +typedef INT32 s32; +typedef INT16 s16; +typedef INT8 s8; +#define WPA_TYPES_DEFINED +#endif /* _MSC_VER */ + +#ifdef __vxworks +typedef unsigned long long u64; +typedef UINT32 u32; +typedef UINT16 u16; +typedef UINT8 u8; +typedef long long s64; +typedef INT32 s32; +typedef INT16 s16; +typedef INT8 s8; +#define WPA_TYPES_DEFINED +#endif /* __vxworks */ + +#ifdef CONFIG_TI_COMPILER +#ifdef _LLONG_AVAILABLE +typedef unsigned long long u64; +#else +/* + * TODO: 64-bit variable not available. Using long as a workaround to test the + * build, but this will likely not work for all operations. + */ +typedef unsigned long u64; +#endif +typedef unsigned int u32; +typedef unsigned short u16; +typedef unsigned char u8; +#define WPA_TYPES_DEFINED +#endif /* CONFIG_TI_COMPILER */ + +#ifdef __SYMBIAN32__ +#define __REMOVE_PLATSEC_DIAGNOSTICS__ +#include +typedef TUint64 u64; +typedef TUint32 u32; +typedef TUint16 u16; +typedef TUint8 u8; +#define WPA_TYPES_DEFINED +#endif /* __SYMBIAN32__ */ + +#ifndef WPA_TYPES_DEFINED +#ifdef CONFIG_USE_INTTYPES_H +#include +#else +#include +#endif + +typedef uint64_t u64; +typedef uint32_t u32; +typedef uint16_t u16; +typedef uint8_t u8; +typedef int64_t s64; +typedef int32_t s32; +typedef int16_t s16; +typedef int8_t s8; +#define WPA_TYPES_DEFINED +#endif /* !WPA_TYPES_DEFINED */ + + +/* Define platform specific byte swapping macros */ + +#if defined(__CYGWIN__) || defined(CONFIG_NATIVE_WINDOWS) + +static inline unsigned short wpa_swap_16(unsigned short v) +{ + return ((v & 0xff) << 8) | (v >> 8); +} + +static inline unsigned int wpa_swap_32(unsigned int v) +{ + return ((v & 0xff) << 24) | ((v & 0xff00) << 8) | + ((v & 0xff0000) >> 8) | (v >> 24); +} + +#define le_to_host16(n) (n) +#define host_to_le16(n) (n) +#define be_to_host16(n) wpa_swap_16(n) +#define host_to_be16(n) wpa_swap_16(n) +#define le_to_host32(n) (n) +#define be_to_host32(n) wpa_swap_32(n) +#define host_to_be32(n) wpa_swap_32(n) + +#define WPA_BYTE_SWAP_DEFINED + +#endif /* __CYGWIN__ || CONFIG_NATIVE_WINDOWS */ + + +#ifndef WPA_BYTE_SWAP_DEFINED + +#ifndef __BYTE_ORDER +#ifndef __LITTLE_ENDIAN +#ifndef __BIG_ENDIAN +#define __LITTLE_ENDIAN 1234 +#define __BIG_ENDIAN 4321 +#if defined(sparc) +#define __BYTE_ORDER __BIG_ENDIAN +#endif +#endif /* __BIG_ENDIAN */ +#endif /* __LITTLE_ENDIAN */ +#endif /* __BYTE_ORDER */ + +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define le_to_host16(n) ((__force u16) (le16) (n)) +#define host_to_le16(n) ((__force le16) (u16) (n)) +#define be_to_host16(n) bswap_16((__force u16) (be16) (n)) +#define host_to_be16(n) ((__force be16) bswap_16((n))) +#define le_to_host32(n) ((__force u32) (le32) (n)) +#define host_to_le32(n) ((__force le32) (u32) (n)) +#define be_to_host32(n) bswap_32((__force u32) (be32) (n)) +#define host_to_be32(n) ((__force be32) bswap_32((n))) +#define le_to_host64(n) ((__force u64) (le64) (n)) +#define host_to_le64(n) ((__force le64) (u64) (n)) +#define be_to_host64(n) bswap_64((__force u64) (be64) (n)) +#define host_to_be64(n) ((__force be64) bswap_64((n))) +#elif __BYTE_ORDER == __BIG_ENDIAN +#define le_to_host16(n) bswap_16(n) +#define host_to_le16(n) bswap_16(n) +#define be_to_host16(n) (n) +#define host_to_be16(n) (n) +#define le_to_host32(n) bswap_32(n) +#define be_to_host32(n) (n) +#define host_to_be32(n) (n) +#define le_to_host64(n) bswap_64(n) +#define host_to_le64(n) bswap_64(n) +#define be_to_host64(n) (n) +#define host_to_be64(n) (n) +#ifndef WORDS_BIGENDIAN +#define WORDS_BIGENDIAN +#endif +#else +#error Could not determine CPU byte order +#endif + +#define WPA_BYTE_SWAP_DEFINED +#endif /* !WPA_BYTE_SWAP_DEFINED */ + + +/* Macros for handling unaligned memory accesses */ + +#define WPA_GET_BE16(a) ((u16) (((a)[0] << 8) | (a)[1])) +#define WPA_PUT_BE16(a, val) \ + do { \ + (a)[0] = ((u16) (val)) >> 8; \ + (a)[1] = ((u16) (val)) & 0xff; \ + } while (0) + +#define WPA_GET_LE16(a) ((u16) (((a)[1] << 8) | (a)[0])) +#define WPA_PUT_LE16(a, val) \ + do { \ + (a)[1] = ((u16) (val)) >> 8; \ + (a)[0] = ((u16) (val)) & 0xff; \ + } while (0) + +#define WPA_GET_BE24(a) ((((u32) (a)[0]) << 16) | (((u32) (a)[1]) << 8) | \ + ((u32) (a)[2])) +#define WPA_PUT_BE24(a, val) \ + do { \ + (a)[0] = (u8) ((((u32) (val)) >> 16) & 0xff); \ + (a)[1] = (u8) ((((u32) (val)) >> 8) & 0xff); \ + (a)[2] = (u8) (((u32) (val)) & 0xff); \ + } while (0) + +#define WPA_GET_BE32(a) ((((u32) (a)[0]) << 24) | (((u32) (a)[1]) << 16) | \ + (((u32) (a)[2]) << 8) | ((u32) (a)[3])) +#define WPA_PUT_BE32(a, val) \ + do { \ + (a)[0] = (u8) ((((u32) (val)) >> 24) & 0xff); \ + (a)[1] = (u8) ((((u32) (val)) >> 16) & 0xff); \ + (a)[2] = (u8) ((((u32) (val)) >> 8) & 0xff); \ + (a)[3] = (u8) (((u32) (val)) & 0xff); \ + } while (0) + +#define WPA_GET_LE32(a) ((((u32) (a)[3]) << 24) | (((u32) (a)[2]) << 16) | \ + (((u32) (a)[1]) << 8) | ((u32) (a)[0])) +#define WPA_PUT_LE32(a, val) \ + do { \ + (a)[3] = (u8) ((((u32) (val)) >> 24) & 0xff); \ + (a)[2] = (u8) ((((u32) (val)) >> 16) & 0xff); \ + (a)[1] = (u8) ((((u32) (val)) >> 8) & 0xff); \ + (a)[0] = (u8) (((u32) (val)) & 0xff); \ + } while (0) + +#define WPA_GET_BE64(a) ((((u64) (a)[0]) << 56) | (((u64) (a)[1]) << 48) | \ + (((u64) (a)[2]) << 40) | (((u64) (a)[3]) << 32) | \ + (((u64) (a)[4]) << 24) | (((u64) (a)[5]) << 16) | \ + (((u64) (a)[6]) << 8) | ((u64) (a)[7])) +#define WPA_PUT_BE64(a, val) \ + do { \ + (a)[0] = (u8) (((u64) (val)) >> 56); \ + (a)[1] = (u8) (((u64) (val)) >> 48); \ + (a)[2] = (u8) (((u64) (val)) >> 40); \ + (a)[3] = (u8) (((u64) (val)) >> 32); \ + (a)[4] = (u8) (((u64) (val)) >> 24); \ + (a)[5] = (u8) (((u64) (val)) >> 16); \ + (a)[6] = (u8) (((u64) (val)) >> 8); \ + (a)[7] = (u8) (((u64) (val)) & 0xff); \ + } while (0) + +#define WPA_GET_LE64(a) ((((u64) (a)[7]) << 56) | (((u64) (a)[6]) << 48) | \ + (((u64) (a)[5]) << 40) | (((u64) (a)[4]) << 32) | \ + (((u64) (a)[3]) << 24) | (((u64) (a)[2]) << 16) | \ + (((u64) (a)[1]) << 8) | ((u64) (a)[0])) + + +#ifndef ETH_ALEN +#define ETH_ALEN 6 +#endif +#ifndef IFNAMSIZ +#define IFNAMSIZ 16 +#endif +#ifndef ETH_P_ALL +#define ETH_P_ALL 0x0003 +#endif +#ifndef ETH_P_PAE +#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */ +#endif /* ETH_P_PAE */ +#ifndef ETH_P_EAPOL +#define ETH_P_EAPOL ETH_P_PAE +#endif /* ETH_P_EAPOL */ +#ifndef ETH_P_RSN_PREAUTH +#define ETH_P_RSN_PREAUTH 0x88c7 +#endif /* ETH_P_RSN_PREAUTH */ +#ifndef ETH_P_RRB +#define ETH_P_RRB 0x890D +#endif /* ETH_P_RRB */ + + +#ifdef __GNUC__ +#define PRINTF_FORMAT(a,b) __attribute__ ((format (printf, (a), (b)))) +#define STRUCT_PACKED __attribute__ ((packed)) +#else +#define PRINTF_FORMAT(a,b) +#define STRUCT_PACKED +#endif + +#ifdef CONFIG_ANSI_C_EXTRA + +#if !defined(_MSC_VER) || _MSC_VER < 1400 +/* snprintf - used in number of places; sprintf() is _not_ a good replacement + * due to possible buffer overflow; see, e.g., + * http://www.ijs.si/software/snprintf/ for portable implementation of + * snprintf. */ +int snprintf(char *str, size_t size, const char *format, ...); + +/* vsnprintf - only used for wpa_msg() in wpa_supplicant.c */ +int vsnprintf(char *str, size_t size, const char *format, va_list ap); +#endif /* !defined(_MSC_VER) || _MSC_VER < 1400 */ + +/* getopt - only used in main.c */ +int getopt(int argc, char *const argv[], const char *optstring); +extern char *optarg; +extern int optind; + +#ifndef CONFIG_NO_SOCKLEN_T_TYPEDEF +#ifndef __socklen_t_defined +typedef int socklen_t; +#endif +#endif + +/* inline - define as __inline or just define it to be empty, if needed */ +#ifdef CONFIG_NO_INLINE +#define inline +#else +#define inline __inline +#endif + +#ifndef __func__ +#define __func__ "__func__ not defined" +#endif + +#ifndef bswap_16 +#define bswap_16(a) ((((u16) (a) << 8) & 0xff00) | (((u16) (a) >> 8) & 0xff)) +#endif + +#ifndef bswap_32 +#define bswap_32(a) ((((u32) (a) << 24) & 0xff000000) | \ + (((u32) (a) << 8) & 0xff0000) | \ + (((u32) (a) >> 8) & 0xff00) | \ + (((u32) (a) >> 24) & 0xff)) +#endif + +#ifndef MSG_DONTWAIT +#define MSG_DONTWAIT 0 +#endif + +#ifdef _WIN32_WCE +void perror(const char *s); +#endif /* _WIN32_WCE */ + +#endif /* CONFIG_ANSI_C_EXTRA */ + +#ifndef MAC2STR +#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] +#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" +#endif + +#ifndef BIT +#define BIT(x) (1 << (x)) +#endif + +/* + * Definitions for sparse validation + * (http://kernel.org/pub/linux/kernel/people/josh/sparse/) + */ +#ifdef __CHECKER__ +#define __force __attribute__((force)) +#define __bitwise __attribute__((bitwise)) +#else +#define __force +#define __bitwise +#endif + +typedef u16 __bitwise be16; +typedef u16 __bitwise le16; +typedef u32 __bitwise be32; +typedef u32 __bitwise le32; +typedef u64 __bitwise be64; +typedef u64 __bitwise le64; + +#ifndef __must_check +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +#define __must_check __attribute__((__warn_unused_result__)) +#else +#define __must_check +#endif /* __GNUC__ */ +#endif /* __must_check */ + +int hwaddr_aton(const char *txt, u8 *addr); +int hwaddr_aton2(const char *txt, u8 *addr); +int hexstr2bin(const char *hex, u8 *buf, size_t len); +void inc_byte_array(u8 *counter, size_t len); +void wpa_get_ntp_timestamp(u8 *buf); +int wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len); +int wpa_snprintf_hex_uppercase(char *buf, size_t buf_size, const u8 *data, + size_t len); + +#ifdef CONFIG_NATIVE_WINDOWS +void wpa_unicode2ascii_inplace(TCHAR *str); +TCHAR * wpa_strdup_tchar(const char *str); +#else /* CONFIG_NATIVE_WINDOWS */ +#define wpa_unicode2ascii_inplace(s) do { } while (0) +#define wpa_strdup_tchar(s) strdup((s)) +#endif /* CONFIG_NATIVE_WINDOWS */ + +const char * wpa_ssid_txt(const u8 *ssid, size_t ssid_len); + +static inline int is_zero_ether_addr(const u8 *a) +{ + return !(a[0] | a[1] | a[2] | a[3] | a[4] | a[5]); +} + +/* + * gcc 4.4 ends up generating strict-aliasing warnings about some very common + * networking socket uses that do not really result in a real problem and + * cannot be easily avoided with union-based type-punning due to struct + * definitions including another struct in system header files. To avoid having + * to fully disable strict-aliasing warnings, provide a mechanism to hide the + * typecast from aliasing for now. A cleaner solution will hopefully be found + * in the future to handle these cases. + */ +void * __hide_aliasing_typecast(void *foo); +#define aliasing_hide_typecast(a,t) (t *) __hide_aliasing_typecast((a)) + +#endif /* COMMON_H */ diff --git a/components/wpa_supplicant/include/crypto/crypto.h b/components/wpa_supplicant/include/crypto/crypto.h new file mode 100644 index 0000000000..f0b9f22430 --- /dev/null +++ b/components/wpa_supplicant/include/crypto/crypto.h @@ -0,0 +1,471 @@ +/* + * WPA Supplicant / wrapper functions for crypto libraries + * Copyright (c) 2004-2009, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + * + * This file defines the cryptographic functions that need to be implemented + * for wpa_supplicant and hostapd. When TLS is not used, internal + * implementation of MD5, SHA1, and AES is used and no external libraries are + * required. When TLS is enabled (e.g., by enabling EAP-TLS or EAP-PEAP), the + * crypto library used by the TLS implementation is expected to be used for + * non-TLS needs, too, in order to save space by not implementing these + * functions twice. + * + * Wrapper code for using each crypto library is in its own file (crypto*.c) + * and one of these files is build and linked in to provide the functions + * defined here. + */ + +#ifndef CRYPTO_H +#define CRYPTO_H + +/** + * md4_vector - MD4 hash for data vector + * @num_elem: Number of elements in the data vector + * @addr: Pointers to the data areas + * @len: Lengths of the data blocks + * @mac: Buffer for the hash + * Returns: 0 on success, -1 on failure + */ +int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac); + +/** + * md5_vector - MD5 hash for data vector + * @num_elem: Number of elements in the data vector + * @addr: Pointers to the data areas + * @len: Lengths of the data blocks + * @mac: Buffer for the hash + * Returns: 0 on success, -1 on failure + */ +int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac); + +#ifdef CONFIG_FIPS +/** + * md5_vector_non_fips_allow - MD5 hash for data vector (non-FIPS use allowed) + * @num_elem: Number of elements in the data vector + * @addr: Pointers to the data areas + * @len: Lengths of the data blocks + * @mac: Buffer for the hash + * Returns: 0 on success, -1 on failure + */ +int md5_vector_non_fips_allow(size_t num_elem, const u8 *addr[], + const size_t *len, u8 *mac); +#else /* CONFIG_FIPS */ +#define md5_vector_non_fips_allow md5_vector +#endif /* CONFIG_FIPS */ + + +/** + * sha1_vector - SHA-1 hash for data vector + * @num_elem: Number of elements in the data vector + * @addr: Pointers to the data areas + * @len: Lengths of the data blocks + * @mac: Buffer for the hash + * Returns: 0 on success, -1 on failure + */ +int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, + u8 *mac); + +/** + * fips186_2-prf - NIST FIPS Publication 186-2 change notice 1 PRF + * @seed: Seed/key for the PRF + * @seed_len: Seed length in bytes + * @x: Buffer for PRF output + * @xlen: Output length in bytes + * Returns: 0 on success, -1 on failure + * + * This function implements random number generation specified in NIST FIPS + * Publication 186-2 for EAP-SIM. This PRF uses a function that is similar to + * SHA-1, but has different message padding. + */ +int __must_check fips186_2_prf(const u8 *seed, size_t seed_len, u8 *x, + size_t xlen); + +/** + * sha256_vector - SHA256 hash for data vector + * @num_elem: Number of elements in the data vector + * @addr: Pointers to the data areas + * @len: Lengths of the data blocks + * @mac: Buffer for the hash + * Returns: 0 on success, -1 on failure + */ +int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, + u8 *mac); + +/** + * des_encrypt - Encrypt one block with DES + * @clear: 8 octets (in) + * @key: 7 octets (in) (no parity bits included) + * @cypher: 8 octets (out) + */ +void des_encrypt(const u8 *clear, const u8 *key, u8 *cypher); + +/** + * aes_encrypt_init - Initialize AES for encryption + * @key: Encryption key + * @len: Key length in bytes (usually 16, i.e., 128 bits) + * Returns: Pointer to context data or %NULL on failure + */ +void * aes_encrypt_init(const u8 *key, size_t len); + +/** + * aes_encrypt - Encrypt one AES block + * @ctx: Context pointer from aes_encrypt_init() + * @plain: Plaintext data to be encrypted (16 bytes) + * @crypt: Buffer for the encrypted data (16 bytes) + */ +void aes_encrypt(void *ctx, const u8 *plain, u8 *crypt); + +/** + * aes_encrypt_deinit - Deinitialize AES encryption + * @ctx: Context pointer from aes_encrypt_init() + */ +void aes_encrypt_deinit(void *ctx); + +/** + * aes_decrypt_init - Initialize AES for decryption + * @key: Decryption key + * @len: Key length in bytes (usually 16, i.e., 128 bits) + * Returns: Pointer to context data or %NULL on failure + */ +void * aes_decrypt_init(const u8 *key, size_t len); + +/** + * aes_decrypt - Decrypt one AES block + * @ctx: Context pointer from aes_encrypt_init() + * @crypt: Encrypted data (16 bytes) + * @plain: Buffer for the decrypted data (16 bytes) + */ +void aes_decrypt(void *ctx, const u8 *crypt, u8 *plain); + +/** + * aes_decrypt_deinit - Deinitialize AES decryption + * @ctx: Context pointer from aes_encrypt_init() + */ +void aes_decrypt_deinit(void *ctx); + + +enum crypto_hash_alg { + CRYPTO_HASH_ALG_MD5, CRYPTO_HASH_ALG_SHA1, + CRYPTO_HASH_ALG_HMAC_MD5, CRYPTO_HASH_ALG_HMAC_SHA1, + CRYPTO_HASH_ALG_SHA256, CRYPTO_HASH_ALG_HMAC_SHA256 +}; + + +struct crypto_hash; + +/** + * crypto_hash_init - Initialize hash/HMAC function + * @alg: Hash algorithm + * @key: Key for keyed hash (e.g., HMAC) or %NULL if not needed + * @key_len: Length of the key in bytes + * Returns: Pointer to hash context to use with other hash functions or %NULL + * on failure + * + * This function is only used with internal TLSv1 implementation + * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need + * to implement this. + */ +struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key, + size_t key_len); + +/** + * crypto_hash_update - Add data to hash calculation + * @ctx: Context pointer from crypto_hash_init() + * @data: Data buffer to add + * @len: Length of the buffer + * + * This function is only used with internal TLSv1 implementation + * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need + * to implement this. + */ +void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len); + +/** + * crypto_hash_finish - Complete hash calculation + * @ctx: Context pointer from crypto_hash_init() + * @hash: Buffer for hash value or %NULL if caller is just freeing the hash + * context + * @len: Pointer to length of the buffer or %NULL if caller is just freeing the + * hash context; on return, this is set to the actual length of the hash value + * Returns: 0 on success, -1 if buffer is too small (len set to needed length), + * or -2 on other failures (including failed crypto_hash_update() operations) + * + * This function calculates the hash value and frees the context buffer that + * was used for hash calculation. + * + * This function is only used with internal TLSv1 implementation + * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need + * to implement this. + */ +int crypto_hash_finish(struct crypto_hash *ctx, u8 *hash, size_t *len); + + +enum crypto_cipher_alg { + CRYPTO_CIPHER_NULL = 0, CRYPTO_CIPHER_ALG_AES, CRYPTO_CIPHER_ALG_3DES, + CRYPTO_CIPHER_ALG_DES, CRYPTO_CIPHER_ALG_RC2, CRYPTO_CIPHER_ALG_RC4 +}; + +struct crypto_cipher; + +/** + * crypto_cipher_init - Initialize block/stream cipher function + * @alg: Cipher algorithm + * @iv: Initialization vector for block ciphers or %NULL for stream ciphers + * @key: Cipher key + * @key_len: Length of key in bytes + * Returns: Pointer to cipher context to use with other cipher functions or + * %NULL on failure + * + * This function is only used with internal TLSv1 implementation + * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need + * to implement this. + */ +struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg, + const u8 *iv, const u8 *key, + size_t key_len); + +/** + * crypto_cipher_encrypt - Cipher encrypt + * @ctx: Context pointer from crypto_cipher_init() + * @plain: Plaintext to cipher + * @crypt: Resulting ciphertext + * @len: Length of the plaintext + * Returns: 0 on success, -1 on failure + * + * This function is only used with internal TLSv1 implementation + * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need + * to implement this. + */ +int __must_check crypto_cipher_encrypt(struct crypto_cipher *ctx, + const u8 *plain, u8 *crypt, size_t len); + +/** + * crypto_cipher_decrypt - Cipher decrypt + * @ctx: Context pointer from crypto_cipher_init() + * @crypt: Ciphertext to decrypt + * @plain: Resulting plaintext + * @len: Length of the cipher text + * Returns: 0 on success, -1 on failure + * + * This function is only used with internal TLSv1 implementation + * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need + * to implement this. + */ +int __must_check crypto_cipher_decrypt(struct crypto_cipher *ctx, + const u8 *crypt, u8 *plain, size_t len); + +/** + * crypto_cipher_decrypt - Free cipher context + * @ctx: Context pointer from crypto_cipher_init() + * + * This function is only used with internal TLSv1 implementation + * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need + * to implement this. + */ +void crypto_cipher_deinit(struct crypto_cipher *ctx); + + +struct crypto_public_key; +struct crypto_private_key; + +/** + * crypto_public_key_import - Import an RSA public key + * @key: Key buffer (DER encoded RSA public key) + * @len: Key buffer length in bytes + * Returns: Pointer to the public key or %NULL on failure + * + * This function can just return %NULL if the crypto library supports X.509 + * parsing. In that case, crypto_public_key_from_cert() is used to import the + * public key from a certificate. + * + * This function is only used with internal TLSv1 implementation + * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need + * to implement this. + */ +struct crypto_public_key * crypto_public_key_import(const u8 *key, size_t len); + +/** + * crypto_private_key_import - Import an RSA private key + * @key: Key buffer (DER encoded RSA private key) + * @len: Key buffer length in bytes + * @passwd: Key encryption password or %NULL if key is not encrypted + * Returns: Pointer to the private key or %NULL on failure + * + * This function is only used with internal TLSv1 implementation + * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need + * to implement this. + */ +struct crypto_private_key * crypto_private_key_import(const u8 *key, + size_t len, + const char *passwd); + +/** + * crypto_public_key_from_cert - Import an RSA public key from a certificate + * @buf: DER encoded X.509 certificate + * @len: Certificate buffer length in bytes + * Returns: Pointer to public key or %NULL on failure + * + * This function can just return %NULL if the crypto library does not support + * X.509 parsing. In that case, internal code will be used to parse the + * certificate and public key is imported using crypto_public_key_import(). + * + * This function is only used with internal TLSv1 implementation + * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need + * to implement this. + */ +struct crypto_public_key * crypto_public_key_from_cert(const u8 *buf, + size_t len); + +/** + * crypto_public_key_encrypt_pkcs1_v15 - Public key encryption (PKCS #1 v1.5) + * @key: Public key + * @in: Plaintext buffer + * @inlen: Length of plaintext buffer in bytes + * @out: Output buffer for encrypted data + * @outlen: Length of output buffer in bytes; set to used length on success + * Returns: 0 on success, -1 on failure + * + * This function is only used with internal TLSv1 implementation + * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need + * to implement this. + */ +int __must_check crypto_public_key_encrypt_pkcs1_v15( + struct crypto_public_key *key, const u8 *in, size_t inlen, + u8 *out, size_t *outlen); + +/** + * crypto_private_key_decrypt_pkcs1_v15 - Private key decryption (PKCS #1 v1.5) + * @key: Private key + * @in: Encrypted buffer + * @inlen: Length of encrypted buffer in bytes + * @out: Output buffer for encrypted data + * @outlen: Length of output buffer in bytes; set to used length on success + * Returns: 0 on success, -1 on failure + * + * This function is only used with internal TLSv1 implementation + * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need + * to implement this. + */ +int __must_check crypto_private_key_decrypt_pkcs1_v15( + struct crypto_private_key *key, const u8 *in, size_t inlen, + u8 *out, size_t *outlen); + +/** + * crypto_private_key_sign_pkcs1 - Sign with private key (PKCS #1) + * @key: Private key from crypto_private_key_import() + * @in: Plaintext buffer + * @inlen: Length of plaintext buffer in bytes + * @out: Output buffer for encrypted (signed) data + * @outlen: Length of output buffer in bytes; set to used length on success + * Returns: 0 on success, -1 on failure + * + * This function is only used with internal TLSv1 implementation + * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need + * to implement this. + */ +int __must_check crypto_private_key_sign_pkcs1(struct crypto_private_key *key, + const u8 *in, size_t inlen, + u8 *out, size_t *outlen); + +/** + * crypto_public_key_free - Free public key + * @key: Public key + * + * This function is only used with internal TLSv1 implementation + * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need + * to implement this. + */ +void crypto_public_key_free(struct crypto_public_key *key); + +/** + * crypto_private_key_free - Free private key + * @key: Private key from crypto_private_key_import() + * + * This function is only used with internal TLSv1 implementation + * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need + * to implement this. + */ +void crypto_private_key_free(struct crypto_private_key *key); + +/** + * crypto_public_key_decrypt_pkcs1 - Decrypt PKCS #1 signature + * @key: Public key + * @crypt: Encrypted signature data (using the private key) + * @crypt_len: Encrypted signature data length + * @plain: Buffer for plaintext (at least crypt_len bytes) + * @plain_len: Plaintext length (max buffer size on input, real len on output); + * Returns: 0 on success, -1 on failure + */ +int __must_check crypto_public_key_decrypt_pkcs1( + struct crypto_public_key *key, const u8 *crypt, size_t crypt_len, + u8 *plain, size_t *plain_len); + +/** + * crypto_global_init - Initialize crypto wrapper + * + * This function is only used with internal TLSv1 implementation + * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need + * to implement this. + */ +int __must_check crypto_global_init(void); + +/** + * crypto_global_deinit - Deinitialize crypto wrapper + * + * This function is only used with internal TLSv1 implementation + * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need + * to implement this. + */ +void crypto_global_deinit(void); + +/** + * crypto_mod_exp - Modular exponentiation of large integers + * @base: Base integer (big endian byte array) + * @base_len: Length of base integer in bytes + * @power: Power integer (big endian byte array) + * @power_len: Length of power integer in bytes + * @modulus: Modulus integer (big endian byte array) + * @modulus_len: Length of modulus integer in bytes + * @result: Buffer for the result + * @result_len: Result length (max buffer size on input, real len on output) + * Returns: 0 on success, -1 on failure + * + * This function calculates result = base ^ power mod modulus. modules_len is + * used as the maximum size of modulus buffer. It is set to the used size on + * success. + * + * This function is only used with internal TLSv1 implementation + * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need + * to implement this. + */ +int __must_check crypto_mod_exp(const u8 *base, size_t base_len, + const u8 *power, size_t power_len, + const u8 *modulus, size_t modulus_len, + u8 *result, size_t *result_len); + +/** + * rc4_skip - XOR RC4 stream to given data with skip-stream-start + * @key: RC4 key + * @keylen: RC4 key length + * @skip: number of bytes to skip from the beginning of the RC4 stream + * @data: data to be XOR'ed with RC4 stream + * @data_len: buf length + * Returns: 0 on success, -1 on failure + * + * Generate RC4 pseudo random stream for the given key, skip beginning of the + * stream, and XOR the end result with the data buffer to perform RC4 + * encryption/decryption. + */ +int rc4_skip(const u8 *key, size_t keylen, size_t skip, + u8 *data, size_t data_len); + +#endif /* CRYPTO_H */ diff --git a/components/wpa_supplicant/include/crypto/dh_group5.h b/components/wpa_supplicant/include/crypto/dh_group5.h new file mode 100644 index 0000000000..595f1114fe --- /dev/null +++ b/components/wpa_supplicant/include/crypto/dh_group5.h @@ -0,0 +1,23 @@ +/* + * Diffie-Hellman group 5 operations + * Copyright (c) 2009, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef DH_GROUP5_H +#define DH_GROUP5_H + +void * dh5_init(struct wpabuf **priv, struct wpabuf **publ); +struct wpabuf * dh5_derive_shared(void *ctx, const struct wpabuf *peer_public, + const struct wpabuf *own_private); +void dh5_free(void *ctx); + +#endif /* DH_GROUP5_H */ diff --git a/components/wpa_supplicant/include/crypto/dh_groups.h b/components/wpa_supplicant/include/crypto/dh_groups.h new file mode 100644 index 0000000000..5c61539b70 --- /dev/null +++ b/components/wpa_supplicant/include/crypto/dh_groups.h @@ -0,0 +1,32 @@ +/* + * Diffie-Hellman groups + * Copyright (c) 2007, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef DH_GROUPS_H +#define DH_GROUPS_H + +struct dh_group { + int id; + const u8 *generator; + size_t generator_len; + const u8 *prime; + size_t prime_len; +}; + +const struct dh_group * dh_groups_get(int id); +struct wpabuf * dh_init(const struct dh_group *dh, struct wpabuf **priv); +struct wpabuf * dh_derive_shared(const struct wpabuf *peer_public, + const struct wpabuf *own_private, + const struct dh_group *dh); + +#endif /* DH_GROUPS_H */ diff --git a/components/wpa_supplicant/include/crypto/includes.h b/components/wpa_supplicant/include/crypto/includes.h new file mode 100644 index 0000000000..dbc65759b0 --- /dev/null +++ b/components/wpa_supplicant/include/crypto/includes.h @@ -0,0 +1,65 @@ +/* + * wpa_supplicant/hostapd - Default include files + * Copyright (c) 2005-2006, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + * + * This header file is included into all C files so that commonly used header + * files can be selected with OS specific ifdef blocks in one place instead of + * having to have OS/C library specific selection in many files. + */ + +#ifndef INCLUDES_H +#define INCLUDES_H + +/* Include possible build time configuration before including anything else */ +//#include "build_config.h" //don't need anymore +#ifndef __ets__ +#include +#include +#include +#include +#ifndef _WIN32_WCE +#ifndef CONFIG_TI_COMPILER +#include +#include +#endif /* CONFIG_TI_COMPILER */ +#include +#endif /* _WIN32_WCE */ +#include +#include + +#ifndef CONFIG_TI_COMPILER +#ifndef _MSC_VER +#include +#endif /* _MSC_VER */ +#endif /* CONFIG_TI_COMPILER */ + +#ifndef CONFIG_NATIVE_WINDOWS +#ifndef CONFIG_TI_COMPILER +//#include +//#include +//#include +#ifndef __vxworks +#ifndef __SYMBIAN32__ +//#include +#endif /* __SYMBIAN32__ */ +#include +#endif /* __vxworks */ +#endif /* CONFIG_TI_COMPILER */ +#endif /* CONFIG_NATIVE_WINDOWS */ + +#else + +#include "rom/ets_sys.h" + +#endif /* !__ets__ */ + +#endif /* INCLUDES_H */ diff --git a/components/wpa_supplicant/include/crypto/md5.h b/components/wpa_supplicant/include/crypto/md5.h new file mode 100644 index 0000000000..8952590782 --- /dev/null +++ b/components/wpa_supplicant/include/crypto/md5.h @@ -0,0 +1,35 @@ +/* + * MD5 hash implementation and interface functions + * Copyright (c) 2003-2009, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef MD5_H +#define MD5_H + +#define MD5_MAC_LEN 16 + +int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem, + const u8 *addr[], const size_t *len, u8 *mac); +int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len, + u8 *mac); +#ifdef CONFIG_FIPS +int hmac_md5_vector_non_fips_allow(const u8 *key, size_t key_len, + size_t num_elem, const u8 *addr[], + const size_t *len, u8 *mac); +int hmac_md5_non_fips_allow(const u8 *key, size_t key_len, const u8 *data, + size_t data_len, u8 *mac); +#else /* CONFIG_FIPS */ +#define hmac_md5_vector_non_fips_allow hmac_md5_vector +#define hmac_md5_non_fips_allow hmac_md5 +#endif /* CONFIG_FIPS */ + +#endif /* MD5_H */ diff --git a/components/wpa_supplicant/include/crypto/md5_i.h b/components/wpa_supplicant/include/crypto/md5_i.h new file mode 100644 index 0000000000..b7f6596052 --- /dev/null +++ b/components/wpa_supplicant/include/crypto/md5_i.h @@ -0,0 +1,29 @@ +/* + * MD5 internal definitions + * Copyright (c) 2003-2005, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef MD5_I_H +#define MD5_I_H + +struct MD5Context { + u32 buf[4]; + u32 bits[2]; + u8 in[64]; +}; + +void MD5Init(struct MD5Context *context); +void MD5Update(struct MD5Context *context, unsigned char const *buf, + unsigned len); +void MD5Final(unsigned char digest[16], struct MD5Context *context); + +#endif /* MD5_I_H */ diff --git a/components/wpa_supplicant/include/crypto/random.h b/components/wpa_supplicant/include/crypto/random.h new file mode 100644 index 0000000000..cbfa8773fd --- /dev/null +++ b/components/wpa_supplicant/include/crypto/random.h @@ -0,0 +1,34 @@ +/* + * Random number generator + * Copyright (c) 2010-2011, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef RANDOM_H +#define RANDOM_H + +#define CONFIG_NO_RANDOM_POOL + +#ifdef CONFIG_NO_RANDOM_POOL +#define random_init(e) do { } while (0) +#define random_deinit() do { } while (0) +#define random_add_randomness(b, l) do { } while (0) +#define random_get_bytes(b, l) os_get_random((b), (l)) +#define random_pool_ready() 1 +#define random_mark_pool_ready() do { } while (0) +#else /* CONFIG_NO_RANDOM_POOL */ +void random_init(const char *entropy_file); +void random_deinit(void); +void random_add_randomness(const void *buf, size_t len); +int random_get_bytes(void *buf, size_t len); +#endif /* CONFIG_NO_RANDOM_POOL */ + +#endif /* RANDOM_H */ diff --git a/components/wpa_supplicant/include/crypto/sha1.h b/components/wpa_supplicant/include/crypto/sha1.h new file mode 100644 index 0000000000..b3d186bdbc --- /dev/null +++ b/components/wpa_supplicant/include/crypto/sha1.h @@ -0,0 +1,33 @@ +/* + * SHA1 hash implementation and interface functions + * Copyright (c) 2003-2009, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef SHA1_H +#define SHA1_H + +#define SHA1_MAC_LEN 20 + +int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem, + const u8 *addr[], const size_t *len, u8 *mac); +int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len, + u8 *mac); +int sha1_prf(const u8 *key, size_t key_len, const char *label, + const u8 *data, size_t data_len, u8 *buf, size_t buf_len); +int sha1_t_prf(const u8 *key, size_t key_len, const char *label, + const u8 *seed, size_t seed_len, u8 *buf, size_t buf_len); +//int __must_check tls_prf(const u8 *secret, size_t secret_len, +// const char *label, const u8 *seed, size_t seed_len, +// u8 *out, size_t outlen); +int pbkdf2_sha1(const char *passphrase, const char *ssid, size_t ssid_len, + int iterations, u8 *buf, size_t buflen); +#endif /* SHA1_H */ diff --git a/components/wpa_supplicant/include/crypto/sha1_i.h b/components/wpa_supplicant/include/crypto/sha1_i.h new file mode 100644 index 0000000000..ec2f82f75b --- /dev/null +++ b/components/wpa_supplicant/include/crypto/sha1_i.h @@ -0,0 +1,29 @@ +/* + * SHA1 internal definitions + * Copyright (c) 2003-2005, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef SHA1_I_H +#define SHA1_I_H + +struct SHA1Context { + u32 state[5]; + u32 count[2]; + unsigned char buffer[64]; +}; + +void SHA1Init(struct SHA1Context *context); +void SHA1Update(struct SHA1Context *context, const void *data, u32 len); +void SHA1Final(unsigned char digest[20], struct SHA1Context *context); +void SHA1Transform(u32 state[5], const unsigned char buffer[64]); + +#endif /* SHA1_I_H */ diff --git a/components/wpa_supplicant/include/crypto/sha256.h b/components/wpa_supplicant/include/crypto/sha256.h new file mode 100644 index 0000000000..dc597f09b5 --- /dev/null +++ b/components/wpa_supplicant/include/crypto/sha256.h @@ -0,0 +1,27 @@ +/* + * SHA256 hash implementation and interface functions + * Copyright (c) 2003-2006, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef SHA256_H +#define SHA256_H + +#define SHA256_MAC_LEN 32 + +void hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem, + const u8 *addr[], const size_t *len, u8 *mac); +void hmac_sha256(const u8 *key, size_t key_len, const u8 *data, + size_t data_len, u8 *mac); +void sha256_prf(const u8 *key, size_t key_len, const char *label, + const u8 *data, size_t data_len, u8 *buf, size_t buf_len); + +#endif /* SHA256_H */ diff --git a/components/wpa_supplicant/include/wpa/ap_config.h b/components/wpa_supplicant/include/wpa/ap_config.h new file mode 100644 index 0000000000..761becb484 --- /dev/null +++ b/components/wpa_supplicant/include/wpa/ap_config.h @@ -0,0 +1,544 @@ +/* + * hostapd / Configuration definitions and helpers functions + * Copyright (c) 2003-2012, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef HOSTAPD_CONFIG_H +#define HOSTAPD_CONFIG_H + +#include "wpa/defs.h" +//#include "ip_addr.h" +#include "wpa/wpa_common.h" +//#include "common/ieee802_11_common.h" +//#include "wps/wps.h" + +#define MAX_STA_COUNT 4 +#define MAX_VLAN_ID 4094 + +typedef u8 macaddr[ETH_ALEN]; + +struct mac_acl_entry { + macaddr addr; + int vlan_id; +}; + +struct hostapd_radius_servers; +struct ft_remote_r0kh; +struct ft_remote_r1kh; + +#define HOSTAPD_MAX_SSID_LEN 32 + +#define NUM_WEP_KEYS 4 +struct hostapd_wep_keys { + u8 idx; + u8 *key[NUM_WEP_KEYS]; + size_t len[NUM_WEP_KEYS]; + int keys_set; + size_t default_len; /* key length used for dynamic key generation */ +}; + +typedef enum hostap_security_policy { + SECURITY_PLAINTEXT = 0, + SECURITY_STATIC_WEP = 1, + SECURITY_IEEE_802_1X = 2, + SECURITY_WPA_PSK = 3, + SECURITY_WPA = 4 +} secpolicy; + +struct hostapd_ssid { + u8 ssid[HOSTAPD_MAX_SSID_LEN]; + size_t ssid_len; + unsigned int ssid_set:1; + unsigned int utf8_ssid:1; + +// char vlan[IFNAMSIZ + 1]; +// secpolicy security_policy; + + struct hostapd_wpa_psk *wpa_psk; + char *wpa_passphrase; +// char *wpa_psk_file; + + struct hostapd_wep_keys wep; + +#if 0 +#define DYNAMIC_VLAN_DISABLED 0 +#define DYNAMIC_VLAN_OPTIONAL 1 +#define DYNAMIC_VLAN_REQUIRED 2 + int dynamic_vlan; +#define DYNAMIC_VLAN_NAMING_WITHOUT_DEVICE 0 +#define DYNAMIC_VLAN_NAMING_WITH_DEVICE 1 +#define DYNAMIC_VLAN_NAMING_END 2 + int vlan_naming; +#ifdef CONFIG_FULL_DYNAMIC_VLAN + char *vlan_tagged_interface; +#endif /* CONFIG_FULL_DYNAMIC_VLAN */ + struct hostapd_wep_keys **dyn_vlan_keys; + size_t max_dyn_vlan_keys; +#endif +}; + +#if 0 +#define VLAN_ID_WILDCARD -1 + +struct hostapd_vlan { + struct hostapd_vlan *next; + int vlan_id; /* VLAN ID or -1 (VLAN_ID_WILDCARD) for wildcard entry */ + char ifname[IFNAMSIZ + 1]; + int dynamic_vlan; +#ifdef CONFIG_FULL_DYNAMIC_VLAN + +#define DVLAN_CLEAN_BR 0x1 +#define DVLAN_CLEAN_VLAN 0x2 +#define DVLAN_CLEAN_VLAN_PORT 0x4 +#define DVLAN_CLEAN_WLAN_PORT 0x8 + int clean; +#endif /* CONFIG_FULL_DYNAMIC_VLAN */ +}; +#endif + +#define PMK_LEN 32 +struct hostapd_sta_wpa_psk_short { + struct hostapd_sta_wpa_psk_short *next; + u8 psk[PMK_LEN]; +}; + +struct hostapd_wpa_psk { + struct hostapd_wpa_psk *next; + int group; + u8 psk[PMK_LEN]; + u8 addr[ETH_ALEN]; +}; + +#if 0 +struct hostapd_eap_user { + struct hostapd_eap_user *next; + u8 *identity; + size_t identity_len; + struct { + int vendor; + u32 method; + } methods[EAP_MAX_METHODS]; + u8 *password; + size_t password_len; + int phase2; + int force_version; + unsigned int wildcard_prefix:1; + unsigned int password_hash:1; /* whether password is hashed with + * nt_password_hash() */ + int ttls_auth; /* EAP_TTLS_AUTH_* bitfield */ +}; + +struct hostapd_radius_attr { + u8 type; + struct wpabuf *val; + struct hostapd_radius_attr *next; +}; + + +#define NUM_TX_QUEUES 4 + +struct hostapd_tx_queue_params { + int aifs; + int cwmin; + int cwmax; + int burst; /* maximum burst time in 0.1 ms, i.e., 10 = 1 ms */ +}; + + +#define MAX_ROAMING_CONSORTIUM_LEN 15 + +struct hostapd_roaming_consortium { + u8 len; + u8 oi[MAX_ROAMING_CONSORTIUM_LEN]; +}; + +struct hostapd_lang_string { + u8 lang[3]; + u8 name_len; + u8 name[252]; +}; + +#define MAX_NAI_REALMS 10 +#define MAX_NAI_REALMLEN 255 +#define MAX_NAI_EAP_METHODS 5 +#define MAX_NAI_AUTH_TYPES 4 +struct hostapd_nai_realm_data { + u8 encoding; + char realm_buf[MAX_NAI_REALMLEN + 1]; + char *realm[MAX_NAI_REALMS]; + u8 eap_method_count; + struct hostapd_nai_realm_eap { + u8 eap_method; + u8 num_auths; + u8 auth_id[MAX_NAI_AUTH_TYPES]; + u8 auth_val[MAX_NAI_AUTH_TYPES]; + } eap_method[MAX_NAI_EAP_METHODS]; +}; +#endif + +/** + * struct hostapd_bss_config - Per-BSS configuration + */ +struct hostapd_bss_config { +// char iface[IFNAMSIZ + 1]; +// char bridge[IFNAMSIZ + 1]; +// char wds_bridge[IFNAMSIZ + 1]; + +// enum hostapd_logger_level logger_syslog_level, logger_stdout_level; + +// unsigned int logger_syslog; /* module bitfield */ +// unsigned int logger_stdout; /* module bitfield */ + +// char *dump_log_name; /* file name for state dump (SIGUSR1) */ + + int max_num_sta; /* maximum number of STAs in station table */ + + int dtim_period; + + int ieee802_1x; /* use IEEE 802.1X */ + int eapol_version; +// int eap_server; /* Use internal EAP server instead of external +// * RADIUS server */ +// struct hostapd_eap_user *eap_user; +// char *eap_user_sqlite; +// char *eap_sim_db; +// struct hostapd_ip_addr own_ip_addr; +// char *nas_identifier; +// struct hostapd_radius_servers *radius; +// int acct_interim_interval; +// int radius_request_cui; +// struct hostapd_radius_attr *radius_auth_req_attr; +// struct hostapd_radius_attr *radius_acct_req_attr; +// int radius_das_port; +// unsigned int radius_das_time_window; +// int radius_das_require_event_timestamp; +// struct hostapd_ip_addr radius_das_client_addr; +// u8 *radius_das_shared_secret; +// size_t radius_das_shared_secret_len; + + struct hostapd_ssid ssid; + +// char *eap_req_id_text; /* optional displayable message sent with +// * EAP Request-Identity */ +// size_t eap_req_id_text_len; +// int eapol_key_index_workaround; + +// size_t default_wep_key_len; +// int individual_wep_key_len; + int wep_rekeying_period; + int broadcast_key_idx_min, broadcast_key_idx_max; +// int eap_reauth_period; + +// int ieee802_11f; /* use IEEE 802.11f (IAPP) */ +// char iapp_iface[IFNAMSIZ + 1]; /* interface used with IAPP broadcast +// * frames */ + + enum { + ACCEPT_UNLESS_DENIED = 0, + DENY_UNLESS_ACCEPTED = 1, + USE_EXTERNAL_RADIUS_AUTH = 2 + } macaddr_acl; +// struct mac_acl_entry *accept_mac; +// int num_accept_mac; +// struct mac_acl_entry *deny_mac; +// int num_deny_mac; +// int wds_sta; +// int isolate; + + int auth_algs; /* bitfield of allowed IEEE 802.11 authentication + * algorithms, WPA_AUTH_ALG_{OPEN,SHARED,LEAP} */ + + int wpa; /* bitfield of WPA_PROTO_WPA, WPA_PROTO_RSN */ + int wpa_key_mgmt; +#ifdef CONFIG_IEEE80211W + enum mfp_options ieee80211w; + /* dot11AssociationSAQueryMaximumTimeout (in TUs) */ + unsigned int assoc_sa_query_max_timeout; + /* dot11AssociationSAQueryRetryTimeout (in TUs) */ + int assoc_sa_query_retry_timeout; +#endif /* CONFIG_IEEE80211W */ + enum { + PSK_RADIUS_IGNORED = 0, + PSK_RADIUS_ACCEPTED = 1, + PSK_RADIUS_REQUIRED = 2 + } wpa_psk_radius; + int wpa_pairwise; + int wpa_group; + int wpa_group_rekey; + int wpa_strict_rekey; + int wpa_gmk_rekey; + int wpa_ptk_rekey; + int rsn_pairwise; + int rsn_preauth; + char *rsn_preauth_interfaces; + int peerkey; + +#ifdef CONFIG_IEEE80211R + /* IEEE 802.11r - Fast BSS Transition */ + u8 mobility_domain[MOBILITY_DOMAIN_ID_LEN]; + u8 r1_key_holder[FT_R1KH_ID_LEN]; + u32 r0_key_lifetime; + u32 reassociation_deadline; + struct ft_remote_r0kh *r0kh_list; + struct ft_remote_r1kh *r1kh_list; + int pmk_r1_push; + int ft_over_ds; +#endif /* CONFIG_IEEE80211R */ + +// char *ctrl_interface; /* directory for UNIX domain sockets */ +#ifndef CONFIG_NATIVE_WINDOWS +// gid_t ctrl_interface_gid; +#endif /* CONFIG_NATIVE_WINDOWS */ +// int ctrl_interface_gid_set; + +// char *ca_cert; +// char *server_cert; +// char *private_key; +// char *private_key_passwd; +// int check_crl; +// char *dh_file; +// u8 *pac_opaque_encr_key; +// u8 *eap_fast_a_id; +// size_t eap_fast_a_id_len; +// char *eap_fast_a_id_info; +// int eap_fast_prov; +// int pac_key_lifetime; +// int pac_key_refresh_time; +// int eap_sim_aka_result_ind; +// int tnc; +// int fragment_size; +// u16 pwd_group; + +// char *radius_server_clients; +// int radius_server_auth_port; +// int radius_server_ipv6; + +// char *test_socket; /* UNIX domain socket path for driver_test */ + +// int use_pae_group_addr; /* Whether to send EAPOL frames to PAE group +// * address instead of individual address +// * (for driver_wired.c). +// */ + + int ap_max_inactivity; + int ignore_broadcast_ssid; + + int wmm_enabled; + int wmm_uapsd; + +// struct hostapd_vlan *vlan, *vlan_tail; + + macaddr bssid; + + /* + * Maximum listen interval that STAs can use when associating with this + * BSS. If a STA tries to use larger value, the association will be + * denied with status code 51. + */ + u16 max_listen_interval; + +// int disable_pmksa_caching; +// int okc; /* Opportunistic Key Caching */ + +// int wps_state; +#ifdef CONFIG_WPS + int ap_setup_locked; + u8 uuid[16]; + char *wps_pin_requests; + char *device_name; + char *manufacturer; + char *model_name; + char *model_number; + char *serial_number; + u8 device_type[WPS_DEV_TYPE_LEN]; + char *config_methods; + u8 os_version[4]; + char *ap_pin; + int skip_cred_build; + u8 *extra_cred; + size_t extra_cred_len; + int wps_cred_processing; + u8 *ap_settings; + size_t ap_settings_len; + char *upnp_iface; + char *friendly_name; + char *manufacturer_url; + char *model_description; + char *model_url; + char *upc; + struct wpabuf *wps_vendor_ext[MAX_WPS_VENDOR_EXTENSIONS]; + int wps_nfc_dev_pw_id; + struct wpabuf *wps_nfc_dh_pubkey; + struct wpabuf *wps_nfc_dh_privkey; + struct wpabuf *wps_nfc_dev_pw; +#endif /* CONFIG_WPS */ +// int pbc_in_m1; + +#define P2P_ENABLED BIT(0) +#define P2P_GROUP_OWNER BIT(1) +#define P2P_GROUP_FORMATION BIT(2) +#define P2P_MANAGE BIT(3) +#define P2P_ALLOW_CROSS_CONNECTION BIT(4) +// int p2p; + +// int disassoc_low_ack; +// int skip_inactivity_poll; + +#define TDLS_PROHIBIT BIT(0) +#define TDLS_PROHIBIT_CHAN_SWITCH BIT(1) +// int tdls; +// int disable_11n; +// int disable_11ac; + + /* IEEE 802.11v */ +// int time_advertisement; +// char *time_zone; +// int wnm_sleep_mode; +// int bss_transition; + + /* IEEE 802.11u - Interworking */ +// int interworking; +// int access_network_type; +// int internet; +// int asra; +// int esr; +// int uesa; +// int venue_info_set; +// u8 venue_group; +// u8 venue_type; +// u8 hessid[ETH_ALEN]; + + /* IEEE 802.11u - Roaming Consortium list */ +// unsigned int roaming_consortium_count; +// struct hostapd_roaming_consortium *roaming_consortium; + + /* IEEE 802.11u - Venue Name duples */ +// unsigned int venue_name_count; +// struct hostapd_lang_string *venue_name; + + /* IEEE 802.11u - Network Authentication Type */ +// u8 *network_auth_type; +// size_t network_auth_type_len; + + /* IEEE 802.11u - IP Address Type Availability */ +// u8 ipaddr_type_availability; +// u8 ipaddr_type_configured; + + /* IEEE 802.11u - 3GPP Cellular Network */ +// u8 *anqp_3gpp_cell_net; +// size_t anqp_3gpp_cell_net_len; + + /* IEEE 802.11u - Domain Name */ +// u8 *domain_name; +// size_t domain_name_len; + +// unsigned int nai_realm_count; +// struct hostapd_nai_realm_data *nai_realm_data; + +// u16 gas_comeback_delay; +// int gas_frag_limit; + +#ifdef CONFIG_HS20 + int hs20; + int disable_dgaf; + unsigned int hs20_oper_friendly_name_count; + struct hostapd_lang_string *hs20_oper_friendly_name; + u8 *hs20_wan_metrics; + u8 *hs20_connection_capability; + size_t hs20_connection_capability_len; + u8 *hs20_operating_class; + u8 hs20_operating_class_len; +#endif /* CONFIG_HS20 */ + +// u8 wps_rf_bands; /* RF bands for WPS (WPS_RF_*) */ + +#ifdef CONFIG_RADIUS_TEST + char *dump_msk_file; +#endif /* CONFIG_RADIUS_TEST */ + +// struct wpabuf *vendor_elements; +}; + + +/** + * struct hostapd_config - Per-radio interface configuration + */ +struct hostapd_config { + struct hostapd_bss_config *bss, *last_bss; + size_t num_bss; + + u16 beacon_int; + int rts_threshold; + int fragm_threshold; + u8 send_probe_response; + u8 channel; + enum hostapd_hw_mode hw_mode; /* HOSTAPD_MODE_IEEE80211A, .. */ + enum { + LONG_PREAMBLE = 0, + SHORT_PREAMBLE = 1 + } preamble; + + int *supported_rates; + int *basic_rates; + + const struct wpa_driver_ops *driver; + + int ap_table_max_size; + int ap_table_expiration_time; + + char country[3]; /* first two octets: country code as described in + * ISO/IEC 3166-1. Third octet: + * ' ' (ascii 32): all environments + * 'O': Outdoor environemnt only + * 'I': Indoor environment only + */ + + int ieee80211d; + +// struct hostapd_tx_queue_params tx_queue[NUM_TX_QUEUES]; + + /* + * WMM AC parameters, in same order as 802.1D, i.e. + * 0 = BE (best effort) + * 1 = BK (background) + * 2 = VI (video) + * 3 = VO (voice) + */ +// struct hostapd_wmm_ac_params wmm_ac_params[4]; + + int ht_op_mode_fixed; + u16 ht_capab; + int ieee80211n; + int secondary_channel; + int require_ht; + u32 vht_capab; + int ieee80211ac; + int require_vht; + u8 vht_oper_chwidth; + u8 vht_oper_centr_freq_seg0_idx; + u8 vht_oper_centr_freq_seg1_idx; +}; + + +int hostapd_mac_comp(const void *a, const void *b); +int hostapd_mac_comp_empty(const void *a); +struct hostapd_config * hostapd_config_defaults(void); +void hostapd_config_defaults_bss(struct hostapd_bss_config *bss); +void hostapd_config_free(struct hostapd_config *conf); +int hostapd_maclist_found(struct mac_acl_entry *list, int num_entries, + const u8 *addr, int *vlan_id); +int hostapd_rate_found(int *list, int rate); +int hostapd_wep_key_cmp(struct hostapd_wep_keys *a, + struct hostapd_wep_keys *b); +const u8 * hostapd_get_psk(const struct hostapd_bss_config *conf, + const u8 *addr, const u8 *prev_psk); +int hostapd_setup_wpa_psk(struct hostapd_bss_config *conf); +//const char * hostapd_get_vlan_id_ifname(struct hostapd_vlan *vlan, +// int vlan_id); +//struct hostapd_radius_attr * +//hostapd_config_get_radius_attr(struct hostapd_radius_attr *attr, u8 type); + +#endif /* HOSTAPD_CONFIG_H */ diff --git a/components/wpa_supplicant/include/wpa/common.h b/components/wpa_supplicant/include/wpa/common.h new file mode 100644 index 0000000000..ca80c2394f --- /dev/null +++ b/components/wpa_supplicant/include/wpa/common.h @@ -0,0 +1,324 @@ +/* + * wpa_supplicant/hostapd / common helper functions, etc. + * Copyright (c) 2002-2007, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef COMMON_H +#define COMMON_H + +#if defined(__ets__) +#endif /* ets */ +#include "os.h" + +#if defined(__XTENSA__) +#include +#define __BYTE_ORDER BYTE_ORDER +#define __LITTLE_ENDIAN LITTLE_ENDIAN +#define __BIG_ENDIAN BIG_ENDIAN +#endif /*__XTENSA__*/ + +#if defined(__linux__) || defined(__GLIBC__) || defined(__ets__) +#include +#include +#endif /* __linux__ */ + +/* Define platform specific byte swapping macros */ + +#if defined(__CYGWIN__) || defined(CONFIG_NATIVE_WINDOWS) + +static inline unsigned short wpa_swap_16(unsigned short v) +{ + return ((v & 0xff) << 8) | (v >> 8); +} + +static inline unsigned int wpa_swap_32(unsigned int v) +{ + return ((v & 0xff) << 24) | ((v & 0xff00) << 8) | + ((v & 0xff0000) >> 8) | (v >> 24); +} + +#define le_to_host16(n) (n) +#define host_to_le16(n) (n) +#define be_to_host16(n) wpa_swap_16(n) +#define host_to_be16(n) wpa_swap_16(n) +#define le_to_host32(n) (n) +#define be_to_host32(n) wpa_swap_32(n) +#define host_to_be32(n) wpa_swap_32(n) + +#define WPA_BYTE_SWAP_DEFINED + +#endif /* __CYGWIN__ || CONFIG_NATIVE_WINDOWS */ + + +#ifndef WPA_BYTE_SWAP_DEFINED + +#ifndef __BYTE_ORDER +#ifndef __LITTLE_ENDIAN +#ifndef __BIG_ENDIAN +#define __LITTLE_ENDIAN 1234 +#define __BIG_ENDIAN 4321 +#if defined(sparc) +#define __BYTE_ORDER __BIG_ENDIAN +#endif +#endif /* __BIG_ENDIAN */ +#endif /* __LITTLE_ENDIAN */ +#endif /* __BYTE_ORDER */ + +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define le_to_host16(n) ((__force u16) (le16) (n)) +#define host_to_le16(n) ((__force le16) (u16) (n)) +#define be_to_host16(n) __bswap_16((__force u16) (be16) (n)) +#define host_to_be16(n) ((__force be16) __bswap_16((n))) +#define le_to_host32(n) ((__force u32) (le32) (n)) +#define host_to_le32(n) ((__force le32) (u32) (n)) +#define be_to_host32(n) __bswap_32((__force u32) (be32) (n)) +#define host_to_be32(n) ((__force be32) __bswap_32((n))) +#define le_to_host64(n) ((__force u64) (le64) (n)) +#define host_to_le64(n) ((__force le64) (u64) (n)) +#define be_to_host64(n) __bswap_64((__force u64) (be64) (n)) +#define host_to_be64(n) ((__force be64) bswap_64((n))) +#elif __BYTE_ORDER == __BIG_ENDIAN +#define le_to_host16(n) __bswap_16(n) +#define host_to_le16(n) __bswap_16(n) +#define be_to_host16(n) (n) +#define host_to_be16(n) (n) +#define le_to_host32(n) __bswap_32(n) +#define be_to_host32(n) (n) +#define host_to_be32(n) (n) +#define le_to_host64(n) __bswap_64(n) +#define host_to_le64(n) __bswap_64(n) +#define be_to_host64(n) (n) +#define host_to_be64(n) (n) +#ifndef WORDS_BIGENDIAN +#define WORDS_BIGENDIAN +#endif +#else +#error Could not determine CPU byte order +#endif + +#define WPA_BYTE_SWAP_DEFINED +#endif /* !WPA_BYTE_SWAP_DEFINED */ + + +/* Macros for handling unaligned memory accesses */ + +#define WPA_GET_BE16(a) ((u16) (((a)[0] << 8) | (a)[1])) +#define WPA_PUT_BE16(a, val) \ + do { \ + (a)[0] = ((u16) (val)) >> 8; \ + (a)[1] = ((u16) (val)) & 0xff; \ + } while (0) + +#define WPA_GET_LE16(a) ((u16) (((a)[1] << 8) | (a)[0])) +#define WPA_PUT_LE16(a, val) \ + do { \ + (a)[1] = ((u16) (val)) >> 8; \ + (a)[0] = ((u16) (val)) & 0xff; \ + } while (0) + +#define WPA_GET_BE24(a) ((((u32) (a)[0]) << 16) | (((u32) (a)[1]) << 8) | \ + ((u32) (a)[2])) +#define WPA_PUT_BE24(a, val) \ + do { \ + (a)[0] = (u8) ((((u32) (val)) >> 16) & 0xff); \ + (a)[1] = (u8) ((((u32) (val)) >> 8) & 0xff); \ + (a)[2] = (u8) (((u32) (val)) & 0xff); \ + } while (0) + +#define WPA_GET_BE32(a) ((((u32) (a)[0]) << 24) | (((u32) (a)[1]) << 16) | \ + (((u32) (a)[2]) << 8) | ((u32) (a)[3])) +#define WPA_PUT_BE32(a, val) \ + do { \ + (a)[0] = (u8) ((((u32) (val)) >> 24) & 0xff); \ + (a)[1] = (u8) ((((u32) (val)) >> 16) & 0xff); \ + (a)[2] = (u8) ((((u32) (val)) >> 8) & 0xff); \ + (a)[3] = (u8) (((u32) (val)) & 0xff); \ + } while (0) + +#define WPA_GET_LE32(a) ((((u32) (a)[3]) << 24) | (((u32) (a)[2]) << 16) | \ + (((u32) (a)[1]) << 8) | ((u32) (a)[0])) +#define WPA_PUT_LE32(a, val) \ + do { \ + (a)[3] = (u8) ((((u32) (val)) >> 24) & 0xff); \ + (a)[2] = (u8) ((((u32) (val)) >> 16) & 0xff); \ + (a)[1] = (u8) ((((u32) (val)) >> 8) & 0xff); \ + (a)[0] = (u8) (((u32) (val)) & 0xff); \ + } while (0) + +#define WPA_GET_BE64(a) ((((u64) (a)[0]) << 56) | (((u64) (a)[1]) << 48) | \ + (((u64) (a)[2]) << 40) | (((u64) (a)[3]) << 32) | \ + (((u64) (a)[4]) << 24) | (((u64) (a)[5]) << 16) | \ + (((u64) (a)[6]) << 8) | ((u64) (a)[7])) +#define WPA_PUT_BE64(a, val) \ + do { \ + (a)[0] = (u8) (((u64) (val)) >> 56); \ + (a)[1] = (u8) (((u64) (val)) >> 48); \ + (a)[2] = (u8) (((u64) (val)) >> 40); \ + (a)[3] = (u8) (((u64) (val)) >> 32); \ + (a)[4] = (u8) (((u64) (val)) >> 24); \ + (a)[5] = (u8) (((u64) (val)) >> 16); \ + (a)[6] = (u8) (((u64) (val)) >> 8); \ + (a)[7] = (u8) (((u64) (val)) & 0xff); \ + } while (0) + +#define WPA_GET_LE64(a) ((((u64) (a)[7]) << 56) | (((u64) (a)[6]) << 48) | \ + (((u64) (a)[5]) << 40) | (((u64) (a)[4]) << 32) | \ + (((u64) (a)[3]) << 24) | (((u64) (a)[2]) << 16) | \ + (((u64) (a)[1]) << 8) | ((u64) (a)[0])) + + +#ifndef ETH_ALEN +#define ETH_ALEN 6 +#endif +//#ifndef IFNAMSIZ +//#define IFNAMSIZ 16 +//#endif +#ifndef ETH_P_ALL +#define ETH_P_ALL 0x0003 +#endif +#ifndef ETH_P_PAE +#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */ +#endif /* ETH_P_PAE */ +#ifndef ETH_P_EAPOL +#define ETH_P_EAPOL ETH_P_PAE +#endif /* ETH_P_EAPOL */ +#ifndef ETH_P_RSN_PREAUTH +#define ETH_P_RSN_PREAUTH 0x88c7 +#endif /* ETH_P_RSN_PREAUTH */ +#ifndef ETH_P_RRB +#define ETH_P_RRB 0x890D +#endif /* ETH_P_RRB */ + + +#ifdef __GNUC__ +#define PRINTF_FORMAT(a,b) __attribute__ ((format (printf, (a), (b)))) +#define STRUCT_PACKED __attribute__ ((packed)) +#else +#define PRINTF_FORMAT(a,b) +#define STRUCT_PACKED +#endif + +#ifdef CONFIG_ANSI_C_EXTRA + +/* inline - define as __inline or just define it to be empty, if needed */ +#ifdef CONFIG_NO_INLINE +#define inline +#else +#define inline __inline +#endif + +#ifndef __func__ +#define __func__ "__func__ not defined" +#endif + +#ifndef bswap_16 +#define bswap_16(a) ((((u16) (a) << 8) & 0xff00) | (((u16) (a) >> 8) & 0xff)) +#endif + +#ifndef bswap_32 +#define bswap_32(a) ((((u32) (a) << 24) & 0xff000000) | \ + (((u32) (a) << 8) & 0xff0000) | \ + (((u32) (a) >> 8) & 0xff00) | \ + (((u32) (a) >> 24) & 0xff)) +#endif + +#ifndef MSG_DONTWAIT +#define MSG_DONTWAIT 0 +#endif + +#ifdef _WIN32_WCE +void perror(const char *s); +#endif /* _WIN32_WCE */ + +#endif /* CONFIG_ANSI_C_EXTRA */ + +#ifndef MAC2STR +#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] +#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" +#endif + +#ifndef BIT +#define BIT(x) (1 << (x)) +#endif + +/* + * Definitions for sparse validation + * (http://kernel.org/pub/linux/kernel/people/josh/sparse/) + */ +#ifdef __CHECKER__ +#define __force __attribute__((force)) +#define __bitwise __attribute__((bitwise)) +#else +#define __force +#define __bitwise +#endif + +typedef u16 __bitwise be16; +typedef u16 __bitwise le16; +typedef u32 __bitwise be32; +typedef u32 __bitwise le32; +typedef u64 __bitwise be64; +typedef u64 __bitwise le64; + +#ifndef __must_check +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +#define __must_check __attribute__((__warn_unused_result__)) +#else +#define __must_check +#endif /* __GNUC__ */ +#endif /* __must_check */ + +int hwaddr_aton(const char *txt, u8 *addr); +int hwaddr_aton2(const char *txt, u8 *addr); +int hexstr2bin(const char *hex, u8 *buf, size_t len); +void inc_byte_array(u8 *counter, size_t len); +void wpa_get_ntp_timestamp(u8 *buf); +int wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len); +int wpa_snprintf_hex_uppercase(char *buf, size_t buf_size, const u8 *data, + size_t len); + +#ifdef CONFIG_NATIVE_WINDOWS +void wpa_unicode2ascii_inplace(TCHAR *str); +TCHAR * wpa_strdup_tchar(const char *str); +#else /* CONFIG_NATIVE_WINDOWS */ +#define wpa_unicode2ascii_inplace(s) do { } while (0) +#define wpa_strdup_tchar(s) strdup((s)) +#endif /* CONFIG_NATIVE_WINDOWS */ + +const char * wpa_ssid_txt(const u8 *ssid, size_t ssid_len); +char * wpa_config_parse_string(const char *value, size_t *len); + +static inline int is_zero_ether_addr(const u8 *a) +{ + return !(a[0] | a[1] | a[2] | a[3] | a[4] | a[5]); +} + +extern const struct eth_addr ethbroadcast; +#define broadcast_ether_addr ðbroadcast + +#include "wpabuf.h" +#include "wpa_debug.h" + + +/* + * gcc 4.4 ends up generating strict-aliasing warnings about some very common + * networking socket uses that do not really result in a real problem and + * cannot be easily avoided with union-based type-punning due to struct + * definitions including another struct in system header files. To avoid having + * to fully disable strict-aliasing warnings, provide a mechanism to hide the + * typecast from aliasing for now. A cleaner solution will hopefully be found + * in the future to handle these cases. + */ +void * __hide_aliasing_typecast(void *foo); +#define aliasing_hide_typecast(a,t) (t *) __hide_aliasing_typecast((a)) + +#endif /* COMMON_H */ diff --git a/components/wpa_supplicant/include/wpa/defs.h b/components/wpa_supplicant/include/wpa/defs.h new file mode 100644 index 0000000000..f019cee992 --- /dev/null +++ b/components/wpa_supplicant/include/wpa/defs.h @@ -0,0 +1,307 @@ +/* + * WPA Supplicant - Common definitions + * Copyright (c) 2004-2008, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef DEFS_H +#define DEFS_H + +#ifdef FALSE +#undef FALSE +#endif +#ifdef TRUE +#undef TRUE +#endif +typedef enum { FALSE = 0, TRUE = 1 } Boolean; + +/* +#define WPA_CIPHER_NONE BIT(0) +#define WPA_CIPHER_WEP40 BIT(1) +#define WPA_CIPHER_WEP104 BIT(2) +#define WPA_CIPHER_TKIP BIT(3) +#define WPA_CIPHER_CCMP BIT(4) +#ifdef CONFIG_IEEE80211W +#define WPA_CIPHER_AES_128_CMAC BIT(5) +#endif +*/ + +/* + * NB: these values are ordered carefully; there are lots of + * of implications in any reordering. Beware that 4 is used + * only to indicate h/w TKIP MIC support in driver capabilities; + * there is no separate cipher support (it's rolled into the + * TKIP cipher support). + */ +#define IEEE80211_CIPHER_NONE 0 /* pseudo value */ +#define IEEE80211_CIPHER_TKIP 1 +#define IEEE80211_CIPHER_AES_OCB 2 +#define IEEE80211_CIPHER_AES_CCM 3 +#define IEEE80211_CIPHER_TKIPMIC 4 /* TKIP MIC capability */ +#define IEEE80211_CIPHER_CKIP 5 +#define IEEE80211_CIPHER_WEP 6 +#define IEEE80211_CIPHER_WEP40 7 +#define IEEE80211_CIPHER_WEP104 8 + + +#define IEEE80211_CIPHER_MAX (IEEE80211_CIPHER_NONE+2) + +/* capability bits in ic_cryptocaps/iv_cryptocaps */ +#define IEEE80211_CRYPTO_NONE (1<wpa_state). The current state can be retrieved with + * wpa_supplicant_get_state() function and the state can be changed by calling + * wpa_supplicant_set_state(). In WPA state machine (wpa.c and preauth.c), the + * wrapper functions wpa_sm_get_state() and wpa_sm_set_state() should be used + * to access the state variable. + */ +enum wpa_states { + /** + * WPA_DISCONNECTED - Disconnected state + * + * This state indicates that client is not associated, but is likely to + * start looking for an access point. This state is entered when a + * connection is lost. + */ + WPA_DISCONNECTED, + + /** + * WPA_INACTIVE - Inactive state (wpa_supplicant disabled) + * + * This state is entered if there are no enabled networks in the + * configuration. wpa_supplicant is not trying to associate with a new + * network and external interaction (e.g., ctrl_iface call to add or + * enable a network) is needed to start association. + */ + WPA_INACTIVE, + + /** + * WPA_SCANNING - Scanning for a network + * + * This state is entered when wpa_supplicant starts scanning for a + * network. + */ + WPA_SCANNING, + + /** + * WPA_AUTHENTICATING - Trying to authenticate with a BSS/SSID + * + * This state is entered when wpa_supplicant has found a suitable BSS + * to authenticate with and the driver is configured to try to + * authenticate with this BSS. This state is used only with drivers + * that use wpa_supplicant as the SME. + */ + WPA_AUTHENTICATING, + + /** + * WPA_ASSOCIATING - Trying to associate with a BSS/SSID + * + * This state is entered when wpa_supplicant has found a suitable BSS + * to associate with and the driver is configured to try to associate + * with this BSS in ap_scan=1 mode. When using ap_scan=2 mode, this + * state is entered when the driver is configured to try to associate + * with a network using the configured SSID and security policy. + */ + WPA_ASSOCIATING, + + /** + * WPA_ASSOCIATED - Association completed + * + * This state is entered when the driver reports that association has + * been successfully completed with an AP. If IEEE 802.1X is used + * (with or without WPA/WPA2), wpa_supplicant remains in this state + * until the IEEE 802.1X/EAPOL authentication has been completed. + */ + WPA_ASSOCIATED, + + /** + * WPA_4WAY_HANDSHAKE - WPA 4-Way Key Handshake in progress + * + * This state is entered when WPA/WPA2 4-Way Handshake is started. In + * case of WPA-PSK, this happens when receiving the first EAPOL-Key + * frame after association. In case of WPA-EAP, this state is entered + * when the IEEE 802.1X/EAPOL authentication has been completed. + */ + WPA_FIRST_HALF_4WAY_HANDSHAKE, + + WPA_LAST_HALF_4WAY_HANDSHAKE, + + /** + * WPA_GROUP_HANDSHAKE - WPA Group Key Handshake in progress + * + * This state is entered when 4-Way Key Handshake has been completed + * (i.e., when the supplicant sends out message 4/4) and when Group + * Key rekeying is started by the AP (i.e., when supplicant receives + * message 1/2). + */ + WPA_GROUP_HANDSHAKE, + + /** + * WPA_COMPLETED - All authentication completed + * + * This state is entered when the full authentication process is + * completed. In case of WPA2, this happens when the 4-Way Handshake is + * successfully completed. With WPA, this state is entered after the + * Group Key Handshake; with IEEE 802.1X (non-WPA) connection is + * completed after dynamic keys are received (or if not used, after + * the EAP authentication has been completed). With static WEP keys and + * plaintext connections, this state is entered when an association + * has been completed. + * + * This state indicates that the supplicant has completed its + * processing for the association phase and that data connection is + * fully configured. + */ + WPA_COMPLETED, + + WPA_MIC_FAILURE, // first mic_error event occur + + WPA_TKIP_COUNTERMEASURES //in countermeasure period that stop connect with ap in 60 sec +}; + +#define MLME_SETPROTECTION_PROTECT_TYPE_NONE 0 +#define MLME_SETPROTECTION_PROTECT_TYPE_RX 1 +#define MLME_SETPROTECTION_PROTECT_TYPE_TX 2 +#define MLME_SETPROTECTION_PROTECT_TYPE_RX_TX 3 + +#define MLME_SETPROTECTION_KEY_TYPE_GROUP 0 +#define MLME_SETPROTECTION_KEY_TYPE_PAIRWISE 1 + +/** + * enum hostapd_hw_mode - Hardware mode + */ +enum hostapd_hw_mode { + HOSTAPD_MODE_IEEE80211B, + HOSTAPD_MODE_IEEE80211G, + HOSTAPD_MODE_IEEE80211A, + HOSTAPD_MODE_IEEE80211AD, + NUM_HOSTAPD_MODES +}; + +#endif /* DEFS_H */ diff --git a/components/wpa_supplicant/include/wpa/eapol_common.h b/components/wpa_supplicant/include/wpa/eapol_common.h new file mode 100644 index 0000000000..6a40ac33b3 --- /dev/null +++ b/components/wpa_supplicant/include/wpa/eapol_common.h @@ -0,0 +1,71 @@ +/* + * EAPOL definitions shared between hostapd and wpa_supplicant + * Copyright (c) 2002-2007, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef EAPOL_COMMON_H +#define EAPOL_COMMON_H + +/* IEEE Std 802.1X-2004 */ + +struct ieee802_1x_hdr { + u8 version; + u8 type; + be16 length; + /* followed by length octets of data */ +} STRUCT_PACKED; + + +#define EAPOL_VERSION 2 + +enum { IEEE802_1X_TYPE_EAP_PACKET = 0, + IEEE802_1X_TYPE_EAPOL_START = 1, + IEEE802_1X_TYPE_EAPOL_LOGOFF = 2, + IEEE802_1X_TYPE_EAPOL_KEY = 3, + IEEE802_1X_TYPE_EAPOL_ENCAPSULATED_ASF_ALERT = 4 +}; + +enum { EAPOL_KEY_TYPE_RC4 = 1, EAPOL_KEY_TYPE_RSN = 2, + EAPOL_KEY_TYPE_WPA = 254 }; + +#define IEEE8021X_REPLAY_COUNTER_LEN 8 +#define IEEE8021X_KEY_SIGN_LEN 16 +#define IEEE8021X_KEY_IV_LEN 16 + +#define IEEE8021X_KEY_INDEX_FLAG 0x80 +#define IEEE8021X_KEY_INDEX_MASK 0x03 + +struct ieee802_1x_eapol_key { + u8 type; + /* Note: key_length is unaligned */ + u8 key_length[2]; + /* does not repeat within the life of the keying material used to + * encrypt the Key field; 64-bit NTP timestamp MAY be used here */ + u8 replay_counter[IEEE8021X_REPLAY_COUNTER_LEN]; + u8 key_iv[IEEE8021X_KEY_IV_LEN]; /* cryptographically random number */ + u8 key_index; /* key flag in the most significant bit: + * 0 = broadcast (default key), + * 1 = unicast (key mapping key); key index is in the + * 7 least significant bits */ + /* HMAC-MD5 message integrity check computed with MS-MPPE-Send-Key as + * the key */ + u8 key_signature[IEEE8021X_KEY_SIGN_LEN]; + + /* followed by key: if packet body length = 44 + key length, then the + * key field (of key_length bytes) contains the key in encrypted form; + * if packet body length = 44, key field is absent and key_length + * represents the number of least significant octets from + * MS-MPPE-Send-Key attribute to be used as the keying material; + * RC4 key used in encryption = Key-IV + MS-MPPE-Recv-Key */ +} STRUCT_PACKED; + +#endif /* EAPOL_COMMON_H */ diff --git a/components/wpa_supplicant/include/wpa/hostapd.h b/components/wpa_supplicant/include/wpa/hostapd.h new file mode 100644 index 0000000000..1d52659a22 --- /dev/null +++ b/components/wpa_supplicant/include/wpa/hostapd.h @@ -0,0 +1,312 @@ +/* + * hostapd / Initialization and configuration + * Copyright (c) 2002-2009, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef HOSTAPD_H +#define HOSTAPD_H + +#include "wpa/defs.h" +#include "wpa/ap_config.h" + +struct wpa_driver_ops; +struct wpa_ctrl_dst; +struct radius_server_data; +struct upnp_wps_device_sm; +struct hostapd_data; +struct sta_info; +struct hostap_sta_driver_data; +struct ieee80211_ht_capabilities; +struct full_dynamic_vlan; +enum wps_event; +union wps_event_data; + +struct hostapd_iface; + +struct hapd_interfaces { + int (*reload_config)(struct hostapd_iface *iface); + struct hostapd_config * (*config_read_cb)(const char *config_fname); + int (*ctrl_iface_init)(struct hostapd_data *hapd); + void (*ctrl_iface_deinit)(struct hostapd_data *hapd); + int (*for_each_interface)(struct hapd_interfaces *interfaces, + int (*cb)(struct hostapd_iface *iface, + void *ctx), void *ctx); + int (*driver_init)(struct hostapd_iface *iface); + + size_t count; + int global_ctrl_sock; + char *global_iface_path; + char *global_iface_name; + struct hostapd_iface **iface; +}; + + +struct hostapd_probereq_cb { + int (*cb)(void *ctx, const u8 *sa, const u8 *da, const u8 *bssid, + const u8 *ie, size_t ie_len, int ssi_signal); + void *ctx; +}; + +#define HOSTAPD_RATE_BASIC 0x00000001 + +struct hostapd_rate_data { + int rate; /* rate in 100 kbps */ + int flags; /* HOSTAPD_RATE_ flags */ +}; + +struct hostapd_frame_info { + u32 channel; + u32 datarate; + int ssi_signal; /* dBm */ +}; + + +/** + * struct hostapd_data - hostapd per-BSS data structure + */ +struct hostapd_data { +// struct hostapd_iface *iface; + struct hostapd_config *iconf; + struct hostapd_bss_config *conf; + int interface_added; /* virtual interface added for this BSS */ + + u8 own_addr[ETH_ALEN]; + + int num_sta; /* number of entries in sta_list */ +// struct sta_info *sta_list; /* STA info list head */ +//#define STA_HASH_SIZE 256 +//#define STA_HASH(sta) (sta[5]) +// struct sta_info *sta_hash[STA_HASH_SIZE]; + +// /* +// * Bitfield for indicating which AIDs are allocated. Only AID values +// * 1-2007 are used and as such, the bit at index 0 corresponds to AID +// * 1. +// */ +//#define AID_WORDS ((2008 + 31) / 32) +// u32 sta_aid[AID_WORDS]; + +// const struct wpa_driver_ops *driver; +// void *drv_priv; + +// void (*new_assoc_sta_cb)(struct hostapd_data *hapd, +// struct sta_info *sta, int reassoc); + +// void *msg_ctx; /* ctx for wpa_msg() calls */ +// void *msg_ctx_parent; /* parent interface ctx for wpa_msg() calls */ + +// struct radius_client_data *radius; +// u32 acct_session_id_hi, acct_session_id_lo; +// struct radius_das_data *radius_das; + +// struct iapp_data *iapp; + +// struct hostapd_cached_radius_acl *acl_cache; +// struct hostapd_acl_query_data *acl_queries; + + struct wpa_authenticator *wpa_auth; +// struct eapol_authenticator *eapol_auth; + +// struct rsn_preauth_interface *preauth_iface; +// time_t michael_mic_failure; +// int michael_mic_failures; +// int tkip_countermeasures; + +// int ctrl_sock; +// struct wpa_ctrl_dst *ctrl_dst; + +// void *ssl_ctx; +// void *eap_sim_db_priv; +// struct radius_server_data *radius_srv; + +// int parameter_set_count; + + /* Time Advertisement */ +// u8 time_update_counter; +// struct wpabuf *time_adv; + +#ifdef CONFIG_FULL_DYNAMIC_VLAN + struct full_dynamic_vlan *full_dynamic_vlan; +#endif /* CONFIG_FULL_DYNAMIC_VLAN */ + +// struct l2_packet_data *l2; +// struct wps_context *wps; + +// int beacon_set_done; +// struct wpabuf *wps_beacon_ie; +// struct wpabuf *wps_probe_resp_ie; +#ifdef CONFIG_WPS + unsigned int ap_pin_failures; + unsigned int ap_pin_failures_consecutive; + struct upnp_wps_device_sm *wps_upnp; + unsigned int ap_pin_lockout_time; +#endif /* CONFIG_WPS */ + +// struct hostapd_probereq_cb *probereq_cb; +// size_t num_probereq_cb; + +// void (*public_action_cb)(void *ctx, const u8 *buf, size_t len, +// int freq); +// void *public_action_cb_ctx; + +// int (*vendor_action_cb)(void *ctx, const u8 *buf, size_t len, +// int freq); +// void *vendor_action_cb_ctx; + +// void (*wps_reg_success_cb)(void *ctx, const u8 *mac_addr, +// const u8 *uuid_e); +// void *wps_reg_success_cb_ctx; + +// void (*wps_event_cb)(void *ctx, enum wps_event event, +// union wps_event_data *data); +// void *wps_event_cb_ctx; + +// void (*sta_authorized_cb)(void *ctx, const u8 *mac_addr, +// int authorized, const u8 *p2p_dev_addr); +// void *sta_authorized_cb_ctx; + +// void (*setup_complete_cb)(void *ctx); +// void *setup_complete_cb_ctx; + +#ifdef CONFIG_P2P + struct p2p_data *p2p; + struct p2p_group *p2p_group; + struct wpabuf *p2p_beacon_ie; + struct wpabuf *p2p_probe_resp_ie; + + /* Number of non-P2P association stations */ + int num_sta_no_p2p; + + /* Periodic NoA (used only when no non-P2P clients in the group) */ + int noa_enabled; + int noa_start; + int noa_duration; +#endif /* CONFIG_P2P */ +#ifdef CONFIG_INTERWORKING + size_t gas_frag_limit; +#endif /* CONFIG_INTERWORKING */ + +#ifdef CONFIG_SQLITE + struct hostapd_eap_user tmp_eap_user; +#endif /* CONFIG_SQLITE */ +}; + +#if 0 +/** + * struct hostapd_iface - hostapd per-interface data structure + */ +struct hostapd_iface { + struct hapd_interfaces *interfaces; + void *owner; + char *config_fname; + struct hostapd_config *conf; + + size_t num_bss; + struct hostapd_data **bss; + + int num_ap; /* number of entries in ap_list */ + struct ap_info *ap_list; /* AP info list head */ + struct ap_info *ap_hash[STA_HASH_SIZE]; + struct ap_info *ap_iter_list; + + unsigned int drv_flags; + + /* + * A bitmap of supported protocols for probe response offload. See + * struct wpa_driver_capa in driver.h + */ + unsigned int probe_resp_offloads; + + struct hostapd_hw_modes *hw_features; + int num_hw_features; + struct hostapd_hw_modes *current_mode; + /* Rates that are currently used (i.e., filtered copy of + * current_mode->channels */ + int num_rates; + struct hostapd_rate_data *current_rates; + int *basic_rates; + int freq; + + u16 hw_flags; + + /* Number of associated Non-ERP stations (i.e., stations using 802.11b + * in 802.11g BSS) */ + int num_sta_non_erp; + + /* Number of associated stations that do not support Short Slot Time */ + int num_sta_no_short_slot_time; + + /* Number of associated stations that do not support Short Preamble */ + int num_sta_no_short_preamble; + + int olbc; /* Overlapping Legacy BSS Condition */ + + /* Number of HT associated stations that do not support greenfield */ + int num_sta_ht_no_gf; + + /* Number of associated non-HT stations */ + int num_sta_no_ht; + + /* Number of HT associated stations 20 MHz */ + int num_sta_ht_20mhz; + + /* Overlapping BSS information */ + int olbc_ht; + + u16 ht_op_mode; + void (*scan_cb)(struct hostapd_iface *iface); +}; +#endif + +#if 0 +/* hostapd.c */ +int hostapd_for_each_interface(struct hapd_interfaces *interfaces, + int (*cb)(struct hostapd_iface *iface, + void *ctx), void *ctx); +int hostapd_reload_config(struct hostapd_iface *iface); +struct hostapd_data * +hostapd_alloc_bss_data(struct hostapd_iface *hapd_iface, + struct hostapd_config *conf, + struct hostapd_bss_config *bss); +int hostapd_setup_interface(struct hostapd_iface *iface); +int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err); +void hostapd_interface_deinit(struct hostapd_iface *iface); +void hostapd_interface_free(struct hostapd_iface *iface); +void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta, + int reassoc); +void hostapd_interface_deinit_free(struct hostapd_iface *iface); +int hostapd_enable_iface(struct hostapd_iface *hapd_iface); +int hostapd_reload_iface(struct hostapd_iface *hapd_iface); +int hostapd_disable_iface(struct hostapd_iface *hapd_iface); +int hostapd_add_iface(struct hapd_interfaces *ifaces, char *buf); +int hostapd_remove_iface(struct hapd_interfaces *ifaces, char *buf); + +/* utils.c */ +int hostapd_register_probereq_cb(struct hostapd_data *hapd, + int (*cb)(void *ctx, const u8 *sa, + const u8 *da, const u8 *bssid, + const u8 *ie, size_t ie_len, + int ssi_signal), + void *ctx); +void hostapd_prune_associations(struct hostapd_data *hapd, const u8 *addr); + +/* drv_callbacks.c (TODO: move to somewhere else?) */ +int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr, + const u8 *ie, size_t ielen, int reassoc); +void hostapd_notif_disassoc(struct hostapd_data *hapd, const u8 *addr); +void hostapd_event_sta_low_ack(struct hostapd_data *hapd, const u8 *addr); +int hostapd_probe_req_rx(struct hostapd_data *hapd, const u8 *sa, const u8 *da, + const u8 *bssid, const u8 *ie, size_t ie_len, + int ssi_signal); +void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht, + int offset); + +const struct hostapd_eap_user * +hostapd_get_eap_user(struct hostapd_data *hapd, const u8 *identity, + size_t identity_len, int phase2); +#endif + +#endif /* HOSTAPD_H */ diff --git a/components/wpa_supplicant/include/wpa/ieee80211_crypto.h b/components/wpa_supplicant/include/wpa/ieee80211_crypto.h new file mode 100644 index 0000000000..be0fb9aa12 --- /dev/null +++ b/components/wpa_supplicant/include/wpa/ieee80211_crypto.h @@ -0,0 +1,226 @@ +/*- + * Copyright (c) 2001 Atsushi Onoe + * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +/* + * copyright (c) 2010-2011 Espressif System + */ +#ifndef _NET80211_IEEE80211_CRYPTO_H_ +#define _NET80211_IEEE80211_CRYPTO_H_ + +//#include "pp/esf_buf.h" + +/* + * 802.11 protocol crypto-related definitions. + */ +#define IEEE80211_KEYBUF_SIZE 16 +#define IEEE80211_MICBUF_SIZE (8+8) /* space for both tx+rx keys */ + +/* + * Old WEP-style key. Deprecated. + */ + +#if 0 +struct ieee80211_rsnparms { + uint8_t rsn_mcastcipher; /* mcast/group cipher */ + uint8_t rsn_mcastkeylen; /* mcast key length */ + uint8_t rsn_ucastcipher; /* selected unicast cipher */ + uint8_t rsn_ucastkeylen; /* unicast key length */ + uint8_t rsn_keymgmt; /* selected key mgmt algo */ + uint16_t rsn_caps; /* capabilities */ +}; +#endif //0000 + +/* + * Template for a supported cipher. Ciphers register with the + * crypto code and are typically loaded as separate modules + * (the null cipher is always present). + * XXX may need refcnts + */ + +/* + * Crypto key state. There is sufficient room for all supported + * ciphers (see below). The underlying ciphers are handled + * separately through loadable cipher modules that register with + * the generic crypto support. A key has a reference to an instance + * of the cipher; any per-key state is hung off wk_private by the + * cipher when it is attached. Ciphers are automatically called + * to detach and cleanup any such state when the key is deleted. + * + * The generic crypto support handles encap/decap of cipher-related + * frame contents for both hardware- and software-based implementations. + * A key requiring software crypto support is automatically flagged and + * the cipher is expected to honor this and do the necessary work. + * Ciphers such as TKIP may also support mixed hardware/software + * encrypt/decrypt and MIC processing. + */ +typedef uint16_t ieee80211_keyix; /* h/w key index */ + +struct ieee80211_key { + uint8_t wk_keylen; /* key length in bytes */ + uint8_t wk_pad; + uint16_t wk_flags; +#define IEEE80211_KEY_XMIT 0x0001 /* key used for xmit */ +#define IEEE80211_KEY_RECV 0x0002 /* key used for recv */ +#define IEEE80211_KEY_GROUP 0x0004 /* key used for WPA group operation */ +#define IEEE80211_KEY_SWENCRYPT 0x0010 /* host-based encrypt */ +#define IEEE80211_KEY_SWDECRYPT 0x0020 /* host-based decrypt */ +#define IEEE80211_KEY_SWENMIC 0x0040 /* host-based enmic */ +#define IEEE80211_KEY_SWDEMIC 0x0080 /* host-based demic */ +#define IEEE80211_KEY_DEVKEY 0x0100 /* device key request completed */ +#define IEEE80211_KEY_CIPHER0 0x1000 /* cipher-specific action 0 */ +#define IEEE80211_KEY_CIPHER1 0x2000 /* cipher-specific action 1 */ +#define IEEE80211_KEY_EMPTY 0x0000 + ieee80211_keyix wk_keyix; /* h/w key index */ + ieee80211_keyix wk_rxkeyix; /* optional h/w rx key index */ + uint8_t wk_key[IEEE80211_KEYBUF_SIZE+IEEE80211_MICBUF_SIZE]; +#define wk_txmic wk_key+IEEE80211_KEYBUF_SIZE+0 /* XXX can't () right */ +#define wk_rxmic wk_key+IEEE80211_KEYBUF_SIZE+8 /* XXX can't () right */ + /* key receive sequence counter */ + uint64_t wk_keyrsc[IEEE80211_TID_SIZE]; + uint64_t wk_keytsc; /* key transmit sequence counter */ + const struct ieee80211_cipher *wk_cipher; + //void *wk_private; /* private cipher state */ + //uint8_t wk_macaddr[IEEE80211_ADDR_LEN]; //JLU: no need ... +}; +#define IEEE80211_KEY_COMMON /* common flags passed in by apps */\ + (IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV | IEEE80211_KEY_GROUP) +#define IEEE80211_KEY_DEVICE /* flags owned by device driver */\ + (IEEE80211_KEY_DEVKEY|IEEE80211_KEY_CIPHER0|IEEE80211_KEY_CIPHER1) + +#define IEEE80211_KEY_SWCRYPT \ + (IEEE80211_KEY_SWENCRYPT | IEEE80211_KEY_SWDECRYPT) +#define IEEE80211_KEY_SWMIC (IEEE80211_KEY_SWENMIC | IEEE80211_KEY_SWDEMIC) + +//#define IEEE80211_KEYIX_NONE ((ieee80211_keyix) -1) + +/* + * NB: these values are ordered carefully; there are lots of + * of implications in any reordering. Beware that 4 is used + * only to indicate h/w TKIP MIC support in driver capabilities; + * there is no separate cipher support (it's rolled into the + * TKIP cipher support). + */ +#define IEEE80211_CIPHER_NONE 0 /* pseudo value */ +#define IEEE80211_CIPHER_TKIP 1 +#define IEEE80211_CIPHER_AES_OCB 2 +#define IEEE80211_CIPHER_AES_CCM 3 +#define IEEE80211_CIPHER_TKIPMIC 4 /* TKIP MIC capability */ +#define IEEE80211_CIPHER_CKIP 5 +#define IEEE80211_CIPHER_WEP 6 +#define IEEE80211_CIPHER_WEP40 7 +#define IEEE80211_CIPHER_WEP104 8 + + +#define IEEE80211_CIPHER_MAX (IEEE80211_CIPHER_NONE+2) + +/* capability bits in ic_cryptocaps/iv_cryptocaps */ +#define IEEE80211_CRYPTO_NONE (1<wk_cipher == &ieee80211_cipher_none) + +struct ieee80211_key *ieee80211_crypto_encap(struct ieee80211_conn *, + esf_buf *); + +struct ieee80211_key *ieee80211_crypto_decap(struct ieee80211_conn *, + esf_buf *, int); + +#if 0 //H/W MIC +/* + * Check and remove any MIC. + */ +static INLINE int +ieee80211_crypto_demic(struct ieee80211vap *vap, struct ieee80211_key *k, + esf_buf *m, int force) +{ + const struct ieee80211_cipher *cip = k->wk_cipher; + return (cip->ic_miclen > 0 ? cip->ic_demic(k, m, force) : 1); +} + +/* + * Add any MIC. + */ +static INLINE int +ieee80211_crypto_enmic(struct ieee80211vap *vap, + struct ieee80211_key *k, esf_buf *m, int force) +{ + const struct ieee80211_cipher *cip = k->wk_cipher; + return (cip->ic_miclen > 0 ? cip->ic_enmic(k, m, force) : 1); +} +#endif //0000 + +/* + * Setup crypto support for a device/shared instance. + */ +void ieee80211_crypto_attach(struct ieee80211com *ic); + +/* + * Reset key state to an unused state. The crypto + * key allocation mechanism insures other state (e.g. + * key data) is properly setup before a key is used. + */ +static inline void +ieee80211_crypto_resetkey(struct ieee80211_key *k) +{ + k->wk_cipher = NULL; + k->wk_flags = IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV; +} + +/* + * Crypt-related notification methods. + */ +//void ieee80211_notify_replay_failure(const struct ieee80211_frame *, const struct ieee80211_key *, +// uint64_t rsc, int tid); +//void ieee80211_notify_michael_failure(const struct ieee80211_frame *, u_int keyix); + +#endif /* _NET80211_IEEE80211_CRYPTO_H_ */ diff --git a/components/wpa_supplicant/include/wpa/ieee802_11_defs.h b/components/wpa_supplicant/include/wpa/ieee802_11_defs.h new file mode 100644 index 0000000000..4881e39a01 --- /dev/null +++ b/components/wpa_supplicant/include/wpa/ieee802_11_defs.h @@ -0,0 +1,607 @@ +/* + * IEEE 802.11 Frame type definitions + * Copyright (c) 2002-2009, Jouni Malinen + * Copyright (c) 2007-2008 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef IEEE802_11_DEFS_H +#define IEEE802_11_DEFS_H + +/* IEEE 802.11 defines */ + +#define WLAN_FC_PVER 0x0003 +#define WLAN_FC_TODS 0x0100 +#define WLAN_FC_FROMDS 0x0200 +#define WLAN_FC_MOREFRAG 0x0400 +#define WLAN_FC_RETRY 0x0800 +#define WLAN_FC_PWRMGT 0x1000 +#define WLAN_FC_MOREDATA 0x2000 +#define WLAN_FC_ISWEP 0x4000 +#define WLAN_FC_ORDER 0x8000 + +#define WLAN_FC_GET_TYPE(fc) (((fc) & 0x000c) >> 2) +#define WLAN_FC_GET_STYPE(fc) (((fc) & 0x00f0) >> 4) + +#define WLAN_GET_SEQ_FRAG(seq) ((seq) & (BIT(3) | BIT(2) | BIT(1) | BIT(0))) +#define WLAN_GET_SEQ_SEQ(seq) \ + (((seq) & (~(BIT(3) | BIT(2) | BIT(1) | BIT(0)))) >> 4) + +#define WLAN_FC_TYPE_MGMT 0 +#define WLAN_FC_TYPE_CTRL 1 +#define WLAN_FC_TYPE_DATA 2 + +/* management */ +#define WLAN_FC_STYPE_ASSOC_REQ 0 +#define WLAN_FC_STYPE_ASSOC_RESP 1 +#define WLAN_FC_STYPE_REASSOC_REQ 2 +#define WLAN_FC_STYPE_REASSOC_RESP 3 +#define WLAN_FC_STYPE_PROBE_REQ 4 +#define WLAN_FC_STYPE_PROBE_RESP 5 +#define WLAN_FC_STYPE_BEACON 8 +#define WLAN_FC_STYPE_ATIM 9 +#define WLAN_FC_STYPE_DISASSOC 10 +#define WLAN_FC_STYPE_AUTH 11 +#define WLAN_FC_STYPE_DEAUTH 12 +#define WLAN_FC_STYPE_ACTION 13 + +/* control */ +#define WLAN_FC_STYPE_PSPOLL 10 +#define WLAN_FC_STYPE_RTS 11 +#define WLAN_FC_STYPE_CTS 12 +#define WLAN_FC_STYPE_ACK 13 +#define WLAN_FC_STYPE_CFEND 14 +#define WLAN_FC_STYPE_CFENDACK 15 + +/* data */ +#define WLAN_FC_STYPE_DATA 0 +#define WLAN_FC_STYPE_DATA_CFACK 1 +#define WLAN_FC_STYPE_DATA_CFPOLL 2 +#define WLAN_FC_STYPE_DATA_CFACKPOLL 3 +#define WLAN_FC_STYPE_NULLFUNC 4 +#define WLAN_FC_STYPE_CFACK 5 +#define WLAN_FC_STYPE_CFPOLL 6 +#define WLAN_FC_STYPE_CFACKPOLL 7 +#define WLAN_FC_STYPE_QOS_DATA 8 + +/* Authentication algorithms */ +#define WLAN_AUTH_OPEN 0 +#define WLAN_AUTH_SHARED_KEY 1 +#define WLAN_AUTH_FT 2 +#define WLAN_AUTH_LEAP 128 + +#define WLAN_AUTH_CHALLENGE_LEN 128 + +#define WLAN_CAPABILITY_ESS BIT(0) +#define WLAN_CAPABILITY_IBSS BIT(1) +#define WLAN_CAPABILITY_CF_POLLABLE BIT(2) +#define WLAN_CAPABILITY_CF_POLL_REQUEST BIT(3) +#define WLAN_CAPABILITY_PRIVACY BIT(4) +#define WLAN_CAPABILITY_SHORT_PREAMBLE BIT(5) +#define WLAN_CAPABILITY_PBCC BIT(6) +#define WLAN_CAPABILITY_CHANNEL_AGILITY BIT(7) +#define WLAN_CAPABILITY_SPECTRUM_MGMT BIT(8) +#define WLAN_CAPABILITY_SHORT_SLOT_TIME BIT(10) +#define WLAN_CAPABILITY_DSSS_OFDM BIT(13) + +/* Status codes (IEEE 802.11-2007, 7.3.1.9, Table 7-23) */ +#define WLAN_STATUS_SUCCESS 0 +#define WLAN_STATUS_UNSPECIFIED_FAILURE 1 +#define WLAN_STATUS_CAPS_UNSUPPORTED 10 +#define WLAN_STATUS_REASSOC_NO_ASSOC 11 +#define WLAN_STATUS_ASSOC_DENIED_UNSPEC 12 +#define WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG 13 +#define WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION 14 +#define WLAN_STATUS_CHALLENGE_FAIL 15 +#define WLAN_STATUS_AUTH_TIMEOUT 16 +#define WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA 17 +#define WLAN_STATUS_ASSOC_DENIED_RATES 18 +/* IEEE 802.11b */ +#define WLAN_STATUS_ASSOC_DENIED_NOSHORT 19 +#define WLAN_STATUS_ASSOC_DENIED_NOPBCC 20 +#define WLAN_STATUS_ASSOC_DENIED_NOAGILITY 21 +/* IEEE 802.11h */ +#define WLAN_STATUS_SPEC_MGMT_REQUIRED 22 +#define WLAN_STATUS_PWR_CAPABILITY_NOT_VALID 23 +#define WLAN_STATUS_SUPPORTED_CHANNEL_NOT_VALID 24 +/* IEEE 802.11g */ +#define WLAN_STATUS_ASSOC_DENIED_NO_SHORT_SLOT_TIME 25 +#define WLAN_STATUS_ASSOC_DENIED_NO_ER_PBCC 26 +#define WLAN_STATUS_ASSOC_DENIED_NO_DSSS_OFDM 27 +#define WLAN_STATUS_R0KH_UNREACHABLE 28 +/* IEEE 802.11w */ +#define WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY 30 +#define WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION 31 +#define WLAN_STATUS_UNSPECIFIED_QOS_FAILURE 32 +#define WLAN_STATUS_REQUEST_DECLINED 37 +#define WLAN_STATUS_INVALID_PARAMETERS 38 +/* IEEE 802.11i */ +#define WLAN_STATUS_INVALID_IE 40 +#define WLAN_STATUS_GROUP_CIPHER_NOT_VALID 41 +#define WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID 42 +#define WLAN_STATUS_AKMP_NOT_VALID 43 +#define WLAN_STATUS_UNSUPPORTED_RSN_IE_VERSION 44 +#define WLAN_STATUS_INVALID_RSN_IE_CAPAB 45 +#define WLAN_STATUS_CIPHER_REJECTED_PER_POLICY 46 +#define WLAN_STATUS_TS_NOT_CREATED 47 +#define WLAN_STATUS_DIRECT_LINK_NOT_ALLOWED 48 +#define WLAN_STATUS_DEST_STA_NOT_PRESENT 49 +#define WLAN_STATUS_DEST_STA_NOT_QOS_STA 50 +#define WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE 51 +/* IEEE 802.11r */ +#define WLAN_STATUS_INVALID_FT_ACTION_FRAME_COUNT 52 +#define WLAN_STATUS_INVALID_PMKID 53 +#define WLAN_STATUS_INVALID_MDIE 54 +#define WLAN_STATUS_INVALID_FTIE 55 + +/* Reason codes (IEEE 802.11-2007, 7.3.1.7, Table 7-22) */ +#define WLAN_REASON_UNSPECIFIED 1 +#define WLAN_REASON_PREV_AUTH_NOT_VALID 2 +#define WLAN_REASON_DEAUTH_LEAVING 3 +#define WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY 4 +#define WLAN_REASON_DISASSOC_AP_BUSY 5 +#define WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA 6 +#define WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA 7 +#define WLAN_REASON_DISASSOC_STA_HAS_LEFT 8 +#define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9 +/* IEEE 802.11h */ +#define WLAN_REASON_PWR_CAPABILITY_NOT_VALID 10 +#define WLAN_REASON_SUPPORTED_CHANNEL_NOT_VALID 11 +/* IEEE 802.11i */ +#define WLAN_REASON_INVALID_IE 13 +#define WLAN_REASON_MICHAEL_MIC_FAILURE 14 +#define WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT 15 +#define WLAN_REASON_GROUP_KEY_UPDATE_TIMEOUT 16 +#define WLAN_REASON_IE_IN_4WAY_DIFFERS 17 +#define WLAN_REASON_GROUP_CIPHER_NOT_VALID 18 +#define WLAN_REASON_PAIRWISE_CIPHER_NOT_VALID 19 +#define WLAN_REASON_AKMP_NOT_VALID 20 +#define WLAN_REASON_UNSUPPORTED_RSN_IE_VERSION 21 +#define WLAN_REASON_INVALID_RSN_IE_CAPAB 22 +#define WLAN_REASON_IEEE_802_1X_AUTH_FAILED 23 +#define WLAN_REASON_CIPHER_SUITE_REJECTED 24 + + +/* Information Element IDs */ +#define WLAN_EID_SSID 0 +#define WLAN_EID_SUPP_RATES 1 +#define WLAN_EID_FH_PARAMS 2 +#define WLAN_EID_DS_PARAMS 3 +#define WLAN_EID_CF_PARAMS 4 +#define WLAN_EID_TIM 5 +#define WLAN_EID_IBSS_PARAMS 6 +#define WLAN_EID_COUNTRY 7 +#define WLAN_EID_CHALLENGE 16 +/* EIDs defined by IEEE 802.11h - START */ +#define WLAN_EID_PWR_CONSTRAINT 32 +#define WLAN_EID_PWR_CAPABILITY 33 +#define WLAN_EID_TPC_REQUEST 34 +#define WLAN_EID_TPC_REPORT 35 +#define WLAN_EID_SUPPORTED_CHANNELS 36 +#define WLAN_EID_CHANNEL_SWITCH 37 +#define WLAN_EID_MEASURE_REQUEST 38 +#define WLAN_EID_MEASURE_REPORT 39 +#define WLAN_EID_QUITE 40 +#define WLAN_EID_IBSS_DFS 41 +/* EIDs defined by IEEE 802.11h - END */ +#define WLAN_EID_ERP_INFO 42 +#define WLAN_EID_HT_CAP 45 +#define WLAN_EID_RSN 48 +#define WLAN_EID_EXT_SUPP_RATES 50 +#define WLAN_EID_MOBILITY_DOMAIN 54 +#define WLAN_EID_FAST_BSS_TRANSITION 55 +#define WLAN_EID_TIMEOUT_INTERVAL 56 +#define WLAN_EID_RIC_DATA 57 +#define WLAN_EID_HT_OPERATION 61 +#define WLAN_EID_SECONDARY_CHANNEL_OFFSET 62 +#define WLAN_EID_20_40_BSS_COEXISTENCE 72 +#define WLAN_EID_20_40_BSS_INTOLERANT 73 +#define WLAN_EID_OVERLAPPING_BSS_SCAN_PARAMS 74 +#define WLAN_EID_MMIE 76 +#define WLAN_EID_VENDOR_SPECIFIC 221 + + +/* Action frame categories (IEEE 802.11-2007, 7.3.1.11, Table 7-24) */ +#define WLAN_ACTION_SPECTRUM_MGMT 0 +#define WLAN_ACTION_QOS 1 +#define WLAN_ACTION_DLS 2 +#define WLAN_ACTION_BLOCK_ACK 3 +#define WLAN_ACTION_PUBLIC 4 +#define WLAN_ACTION_RADIO_MEASUREMENT 5 +#define WLAN_ACTION_FT 6 +#define WLAN_ACTION_HT 7 +#define WLAN_ACTION_SA_QUERY 8 +#define WLAN_ACTION_WMM 17 /* WMM Specification 1.1 */ + +/* SA Query Action frame (IEEE 802.11w/D8.0, 7.4.9) */ +#define WLAN_SA_QUERY_REQUEST 0 +#define WLAN_SA_QUERY_RESPONSE 1 + +#define WLAN_SA_QUERY_TR_ID_LEN 2 + +/* Timeout Interval Type */ +#define WLAN_TIMEOUT_REASSOC_DEADLINE 1 +#define WLAN_TIMEOUT_KEY_LIFETIME 2 +#define WLAN_TIMEOUT_ASSOC_COMEBACK 3 + + +#ifdef _MSC_VER +#pragma pack(push, 1) +#endif /* _MSC_VER */ + +struct ieee80211_hdr { + le16 frame_control; + le16 duration_id; + u8 addr1[6]; + u8 addr2[6]; + u8 addr3[6]; + le16 seq_ctrl; + /* followed by 'u8 addr4[6];' if ToDS and FromDS is set in data frame + */ +} STRUCT_PACKED; + +#define IEEE80211_DA_FROMDS addr1 +#define IEEE80211_BSSID_FROMDS addr2 +#define IEEE80211_SA_FROMDS addr3 + +#define IEEE80211_HDRLEN (sizeof(struct ieee80211_hdr)) + +#define IEEE80211_FC(type, stype) host_to_le16((type << 2) | (stype << 4)) + +struct ieee80211_mgmt { + le16 frame_control; + le16 duration; + u8 da[6]; + u8 sa[6]; + u8 bssid[6]; + le16 seq_ctrl; + union { + struct { + le16 auth_alg; + le16 auth_transaction; + le16 status_code; + /* possibly followed by Challenge text */ + u8 variable[0]; + } STRUCT_PACKED auth; + struct { + le16 reason_code; + } STRUCT_PACKED deauth; + struct { + le16 capab_info; + le16 listen_interval; + /* followed by SSID and Supported rates */ + u8 variable[0]; + } STRUCT_PACKED assoc_req; + struct { + le16 capab_info; + le16 status_code; + le16 aid; + /* followed by Supported rates */ + u8 variable[0]; + } STRUCT_PACKED assoc_resp, reassoc_resp; + struct { + le16 capab_info; + le16 listen_interval; + u8 current_ap[6]; + /* followed by SSID and Supported rates */ + u8 variable[0]; + } STRUCT_PACKED reassoc_req; + struct { + le16 reason_code; + } STRUCT_PACKED disassoc; + struct { + u8 timestamp[8]; + le16 beacon_int; + le16 capab_info; + /* followed by some of SSID, Supported rates, + * FH Params, DS Params, CF Params, IBSS Params, TIM */ + u8 variable[0]; + } STRUCT_PACKED beacon; + struct { + /* only variable items: SSID, Supported rates */ + u8 variable[0]; + } STRUCT_PACKED probe_req; + struct { + u8 timestamp[8]; + le16 beacon_int; + le16 capab_info; + /* followed by some of SSID, Supported rates, + * FH Params, DS Params, CF Params, IBSS Params */ + u8 variable[0]; + } STRUCT_PACKED probe_resp; + struct { + u8 category; + union { + struct { + u8 action_code; + u8 dialog_token; + u8 status_code; + u8 variable[0]; + } STRUCT_PACKED wmm_action; + struct{ + u8 action_code; + u8 element_id; + u8 length; + u8 switch_mode; + u8 new_chan; + u8 switch_count; + } STRUCT_PACKED chan_switch; + struct { + u8 action; + u8 sta_addr[ETH_ALEN]; + u8 target_ap_addr[ETH_ALEN]; + u8 variable[0]; /* FT Request */ + } STRUCT_PACKED ft_action_req; + struct { + u8 action; + u8 sta_addr[ETH_ALEN]; + u8 target_ap_addr[ETH_ALEN]; + le16 status_code; + u8 variable[0]; /* FT Request */ + } STRUCT_PACKED ft_action_resp; + struct { + u8 action; + u8 trans_id[WLAN_SA_QUERY_TR_ID_LEN]; + } STRUCT_PACKED sa_query_req; + struct { + u8 action; /* */ + u8 trans_id[WLAN_SA_QUERY_TR_ID_LEN]; + } STRUCT_PACKED sa_query_resp; + } u; + } STRUCT_PACKED action; + } u; +} STRUCT_PACKED; + + +struct ieee80211_ht_capabilities { + le16 ht_capabilities_info; + u8 a_mpdu_params; + u8 supported_mcs_set[16]; + le16 ht_extended_capabilities; + le32 tx_bf_capability_info; + u8 asel_capabilities; +} STRUCT_PACKED; + + +struct ieee80211_ht_operation { + u8 control_chan; + u8 ht_param; + le16 operation_mode; + le16 stbc_param; + u8 basic_set[16]; +} STRUCT_PACKED; + +#ifdef _MSC_VER +#pragma pack(pop) +#endif /* _MSC_VER */ + +#define ERP_INFO_NON_ERP_PRESENT BIT(0) +#define ERP_INFO_USE_PROTECTION BIT(1) +#define ERP_INFO_BARKER_PREAMBLE_MODE BIT(2) + + +#define HT_CAP_INFO_LDPC_CODING_CAP ((u16) BIT(0)) +#define HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET ((u16) BIT(1)) +#define HT_CAP_INFO_SMPS_MASK ((u16) (BIT(2) | BIT(3))) +#define HT_CAP_INFO_SMPS_STATIC ((u16) 0) +#define HT_CAP_INFO_SMPS_DYNAMIC ((u16) BIT(2)) +#define HT_CAP_INFO_SMPS_DISABLED ((u16) (BIT(2) | BIT(3))) +#define HT_CAP_INFO_GREEN_FIELD ((u16) BIT(4)) +#define HT_CAP_INFO_SHORT_GI20MHZ ((u16) BIT(5)) +#define HT_CAP_INFO_SHORT_GI40MHZ ((u16) BIT(6)) +#define HT_CAP_INFO_TX_STBC ((u16) BIT(7)) +#define HT_CAP_INFO_RX_STBC_MASK ((u16) (BIT(8) | BIT(9))) +#define HT_CAP_INFO_RX_STBC_1 ((u16) BIT(8)) +#define HT_CAP_INFO_RX_STBC_12 ((u16) BIT(9)) +#define HT_CAP_INFO_RX_STBC_123 ((u16) (BIT(8) | BIT(9))) +#define HT_CAP_INFO_DELAYED_BA ((u16) BIT(10)) +#define HT_CAP_INFO_MAX_AMSDU_SIZE ((u16) BIT(11)) +#define HT_CAP_INFO_DSSS_CCK40MHZ ((u16) BIT(12)) +#define HT_CAP_INFO_PSMP_SUPP ((u16) BIT(13)) +#define HT_CAP_INFO_40MHZ_INTOLERANT ((u16) BIT(14)) +#define HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT ((u16) BIT(15)) + + +#define EXT_HT_CAP_INFO_PCO ((u16) BIT(0)) +#define EXT_HT_CAP_INFO_TRANS_TIME_OFFSET 1 +#define EXT_HT_CAP_INFO_MCS_FEEDBACK_OFFSET 8 +#define EXT_HT_CAP_INFO_HTC_SUPPORTED ((u16) BIT(10)) +#define EXT_HT_CAP_INFO_RD_RESPONDER ((u16) BIT(11)) + + +#define TX_BEAMFORM_CAP_TXBF_CAP ((u32) BIT(0)) +#define TX_BEAMFORM_CAP_RX_STAGGERED_SOUNDING_CAP ((u32) BIT(1)) +#define TX_BEAMFORM_CAP_TX_STAGGERED_SOUNDING_CAP ((u32) BIT(2)) +#define TX_BEAMFORM_CAP_RX_ZLF_CAP ((u32) BIT(3)) +#define TX_BEAMFORM_CAP_TX_ZLF_CAP ((u32) BIT(4)) +#define TX_BEAMFORM_CAP_IMPLICIT_ZLF_CAP ((u32) BIT(5)) +#define TX_BEAMFORM_CAP_CALIB_OFFSET 6 +#define TX_BEAMFORM_CAP_EXPLICIT_CSI_TXBF_CAP ((u32) BIT(8)) +#define TX_BEAMFORM_CAP_EXPLICIT_UNCOMPR_STEERING_MATRIX_CAP ((u32) BIT(9)) +#define TX_BEAMFORM_CAP_EXPLICIT_BF_CSI_FEEDBACK_CAP ((u32) BIT(10)) +#define TX_BEAMFORM_CAP_EXPLICIT_BF_CSI_FEEDBACK_OFFSET 11 +#define TX_BEAMFORM_CAP_EXPLICIT_UNCOMPR_STEERING_MATRIX_FEEDBACK_OFFSET 13 +#define TX_BEAMFORM_CAP_EXPLICIT_COMPRESSED_STEERING_MATRIX_FEEDBACK_OFFSET 15 +#define TX_BEAMFORM_CAP_MINIMAL_GROUPING_OFFSET 17 +#define TX_BEAMFORM_CAP_CSI_NUM_BEAMFORMER_ANT_OFFSET 19 +#define TX_BEAMFORM_CAP_UNCOMPRESSED_STEERING_MATRIX_BEAMFORMER_ANT_OFFSET 21 +#define TX_BEAMFORM_CAP_COMPRESSED_STEERING_MATRIX_BEAMFORMER_ANT_OFFSET 23 +#define TX_BEAMFORM_CAP_SCI_MAX_OF_ROWS_BEANFORMER_SUPPORTED_OFFSET 25 + + +#define ASEL_CAPABILITY_ASEL_CAPABLE ((u8) BIT(0)) +#define ASEL_CAPABILITY_EXPLICIT_CSI_FEEDBACK_BASED_TX_AS_CAP ((u8) BIT(1)) +#define ASEL_CAPABILITY_ANT_INDICES_FEEDBACK_BASED_TX_AS_CAP ((u8) BIT(2)) +#define ASEL_CAPABILITY_EXPLICIT_CSI_FEEDBACK_CAP ((u8) BIT(3)) +#define ASEL_CAPABILITY_ANT_INDICES_FEEDBACK_CAP ((u8) BIT(4)) +#define ASEL_CAPABILITY_RX_AS_CAP ((u8) BIT(5)) +#define ASEL_CAPABILITY_TX_SOUND_PPDUS_CAP ((u8) BIT(6)) + +#define HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK ((u8) BIT(0) | BIT(1)) +#define HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE ((u8) BIT(0)) +#define HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW ((u8) BIT(0) | BIT(1)) +#define HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH ((u8) BIT(2)) +#define HT_INFO_HT_PARAM_RIFS_MODE ((u8) BIT(3)) +#define HT_INFO_HT_PARAM_CTRL_ACCESS_ONLY ((u8) BIT(4)) +#define HT_INFO_HT_PARAM_SRV_INTERVAL_GRANULARITY ((u8) BIT(5)) + + +#define OP_MODE_PURE 0 +#define OP_MODE_MAY_BE_LEGACY_STAS 1 +#define OP_MODE_20MHZ_HT_STA_ASSOCED 2 +#define OP_MODE_MIXED 3 + +#define HT_INFO_OPERATION_MODE_OP_MODE_MASK \ + ((le16) (0x0001 | 0x0002)) +#define HT_INFO_OPERATION_MODE_OP_MODE_OFFSET 0 +#define HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT ((u8) BIT(2)) +#define HT_INFO_OPERATION_MODE_TRANSMIT_BURST_LIMIT ((u8) BIT(3)) +#define HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT ((u8) BIT(4)) + +#define HT_INFO_STBC_PARAM_DUAL_BEACON ((u16) BIT(6)) +#define HT_INFO_STBC_PARAM_DUAL_STBC_PROTECT ((u16) BIT(7)) +#define HT_INFO_STBC_PARAM_SECONDARY_BCN ((u16) BIT(8)) +#define HT_INFO_STBC_PARAM_LSIG_TXOP_PROTECT_ALLOWED ((u16) BIT(9)) +#define HT_INFO_STBC_PARAM_PCO_ACTIVE ((u16) BIT(10)) +#define HT_INFO_STBC_PARAM_PCO_PHASE ((u16) BIT(11)) + + +#define OUI_MICROSOFT 0x0050f2 /* Microsoft (also used in Wi-Fi specs) + * 00:50:F2 */ +#define WPA_IE_VENDOR_TYPE 0x0050f201 +#define WPS_IE_VENDOR_TYPE 0x0050f204 + +#define WMM_OUI_TYPE 2 +#define WMM_OUI_SUBTYPE_INFORMATION_ELEMENT 0 +#define WMM_OUI_SUBTYPE_PARAMETER_ELEMENT 1 +#define WMM_OUI_SUBTYPE_TSPEC_ELEMENT 2 +#define WMM_VERSION 1 + +#define WMM_ACTION_CODE_ADDTS_REQ 0 +#define WMM_ACTION_CODE_ADDTS_RESP 1 +#define WMM_ACTION_CODE_DELTS 2 + +#define WMM_ADDTS_STATUS_ADMISSION_ACCEPTED 0 +#define WMM_ADDTS_STATUS_INVALID_PARAMETERS 1 +/* 2 - Reserved */ +#define WMM_ADDTS_STATUS_REFUSED 3 +/* 4-255 - Reserved */ + +/* WMM TSPEC Direction Field Values */ +#define WMM_TSPEC_DIRECTION_UPLINK 0 +#define WMM_TSPEC_DIRECTION_DOWNLINK 1 +/* 2 - Reserved */ +#define WMM_TSPEC_DIRECTION_BI_DIRECTIONAL 3 + +/* + * WMM Information Element (used in (Re)Association Request frames; may also be + * used in Beacon frames) + */ +struct wmm_information_element { + /* Element ID: 221 (0xdd); Length: 7 */ + /* required fields for WMM version 1 */ + u8 oui[3]; /* 00:50:f2 */ + u8 oui_type; /* 2 */ + u8 oui_subtype; /* 0 */ + u8 version; /* 1 for WMM version 1.0 */ + u8 qos_info; /* AP/STA specific QoS info */ + +} STRUCT_PACKED; + +#define WMM_AC_AIFSN_MASK 0x0f +#define WMM_AC_AIFNS_SHIFT 0 +#define WMM_AC_ACM 0x10 +#define WMM_AC_ACI_MASK 0x60 +#define WMM_AC_ACI_SHIFT 5 + +#define WMM_AC_ECWMIN_MASK 0x0f +#define WMM_AC_ECWMIN_SHIFT 0 +#define WMM_AC_ECWMAX_MASK 0xf0 +#define WMM_AC_ECWMAX_SHIFT 4 + +struct wmm_ac_parameter { + u8 aci_aifsn; /* AIFSN, ACM, ACI */ + u8 cw; /* ECWmin, ECWmax (CW = 2^ECW - 1) */ + le16 txop_limit; +} STRUCT_PACKED; + +/* + * WMM Parameter Element (used in Beacon, Probe Response, and (Re)Association + * Response frmaes) + */ +struct wmm_parameter_element { + /* Element ID: 221 (0xdd); Length: 24 */ + /* required fields for WMM version 1 */ + u8 oui[3]; /* 00:50:f2 */ + u8 oui_type; /* 2 */ + u8 oui_subtype; /* 1 */ + u8 version; /* 1 for WMM version 1.0 */ + u8 qos_info; /* AP/STA specif QoS info */ + u8 reserved; /* 0 */ + struct wmm_ac_parameter ac[4]; /* AC_BE, AC_BK, AC_VI, AC_VO */ + +} STRUCT_PACKED; + +/* WMM TSPEC Element */ +struct wmm_tspec_element { + u8 eid; /* 221 = 0xdd */ + u8 length; /* 6 + 55 = 61 */ + u8 oui[3]; /* 00:50:f2 */ + u8 oui_type; /* 2 */ + u8 oui_subtype; /* 2 */ + u8 version; /* 1 */ + /* WMM TSPEC body (55 octets): */ + u8 ts_info[3]; + le16 nominal_msdu_size; + le16 maximum_msdu_size; + le32 minimum_service_interval; + le32 maximum_service_interval; + le32 inactivity_interval; + le32 suspension_interval; + le32 service_start_time; + le32 minimum_data_rate; + le32 mean_data_rate; + le32 peak_data_rate; + le32 maximum_burst_size; + le32 delay_bound; + le32 minimum_phy_rate; + le16 surplus_bandwidth_allowance; + le16 medium_time; +} STRUCT_PACKED; + + +/* Access Categories / ACI to AC coding */ +enum { + WMM_AC_BE = 0 /* Best Effort */, + WMM_AC_BK = 1 /* Background */, + WMM_AC_VI = 2 /* Video */, + WMM_AC_VO = 3 /* Voice */ +}; + + +#define OUI_BROADCOM 0x00904c /* Broadcom (Epigram) */ + +#define VENDOR_HT_CAPAB_OUI_TYPE 0x33 /* 00-90-4c:0x33 */ + +/* cipher suite selectors */ +#define WLAN_CIPHER_SUITE_USE_GROUP 0x000FAC00 +#define WLAN_CIPHER_SUITE_WEP40 0x000FAC01 +#define WLAN_CIPHER_SUITE_TKIP 0x000FAC02 +/* reserved: 0x000FAC03 */ +#define WLAN_CIPHER_SUITE_CCMP 0x000FAC04 +#define WLAN_CIPHER_SUITE_WEP104 0x000FAC05 +#define WLAN_CIPHER_SUITE_AES_CMAC 0x000FAC06 + +/* AKM suite selectors */ +#define WLAN_AKM_SUITE_8021X 0x000FAC01 +#define WLAN_AKM_SUITE_PSK 0x000FAC02 + +#endif /* IEEE802_11_DEFS_H */ diff --git a/components/wpa_supplicant/include/wpa/ieee802_1x.h b/components/wpa_supplicant/include/wpa/ieee802_1x.h new file mode 100644 index 0000000000..e10ff7b310 --- /dev/null +++ b/components/wpa_supplicant/include/wpa/ieee802_1x.h @@ -0,0 +1,64 @@ +/* + * hostapd / IEEE 802.1X-2004 Authenticator + * Copyright (c) 2002-2012, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef IEEE802_1X_H +#define IEEE802_1X_H + +struct hostapd_data; +struct sta_info; +struct eapol_state_machine; +struct hostapd_config; +struct hostapd_bss_config; +struct hostapd_radius_attr; +struct radius_msg; + + +void ieee802_1x_receive(struct hostapd_data *hapd, const u8 *sa, const u8 *buf, + size_t len); + +#if 0 +void ieee802_1x_new_station(struct hostapd_data *hapd, struct sta_info *sta); +void ieee802_1x_free_station(struct sta_info *sta); + +void ieee802_1x_tx_key(struct hostapd_data *hapd, struct sta_info *sta); +void ieee802_1x_abort_auth(struct hostapd_data *hapd, struct sta_info *sta); +void ieee802_1x_set_sta_authorized(struct hostapd_data *hapd, + struct sta_info *sta, int authorized); +void ieee802_1x_dump_state(FILE *f, const char *prefix, struct sta_info *sta); +int ieee802_1x_init(struct hostapd_data *hapd); +void ieee802_1x_deinit(struct hostapd_data *hapd); +int ieee802_1x_tx_status(struct hostapd_data *hapd, struct sta_info *sta, + const u8 *buf, size_t len, int ack); +int ieee802_1x_eapol_tx_status(struct hostapd_data *hapd, struct sta_info *sta, + const u8 *data, int len, int ack); +u8 * ieee802_1x_get_identity(struct eapol_state_machine *sm, size_t *len); +u8 * ieee802_1x_get_radius_class(struct eapol_state_machine *sm, size_t *len, + int idx); +struct wpabuf * ieee802_1x_get_radius_cui(struct eapol_state_machine *sm); +const u8 * ieee802_1x_get_key(struct eapol_state_machine *sm, size_t *len); +void ieee802_1x_notify_port_enabled(struct eapol_state_machine *sm, + int enabled); +void ieee802_1x_notify_port_valid(struct eapol_state_machine *sm, + int valid); +void ieee802_1x_notify_pre_auth(struct eapol_state_machine *sm, int pre_auth); +int ieee802_1x_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen); +int ieee802_1x_get_mib_sta(struct hostapd_data *hapd, struct sta_info *sta, + char *buf, size_t buflen); +void hostapd_get_ntp_timestamp(u8 *buf); +char *eap_type_text(u8 type); + +const char *radius_mode_txt(struct hostapd_data *hapd); +int radius_sta_rate(struct hostapd_data *hapd, struct sta_info *sta); + +int add_common_radius_attr(struct hostapd_data *hapd, + struct hostapd_radius_attr *req_attr, + struct sta_info *sta, + struct radius_msg *msg); +#endif + +#endif /* IEEE802_1X_H */ diff --git a/components/wpa_supplicant/include/wpa/includes.h b/components/wpa_supplicant/include/wpa/includes.h new file mode 100644 index 0000000000..993bc49941 --- /dev/null +++ b/components/wpa_supplicant/include/wpa/includes.h @@ -0,0 +1,31 @@ +/* + * wpa_supplicant/hostapd - Default include files + * Copyright (c) 2005-2006, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + * + * This header file is included into all C files so that commonly used header + * files can be selected with OS specific ifdef blocks in one place instead of + * having to have OS/C library specific selection in many files. + */ + +#ifndef INCLUDES_H +#define INCLUDES_H + +/* Include possible build time configuration before including anything else */ +//#include "build_config.h" //don't need anymore + +//#include +//#include +//#include +//#include +//#include + +#endif /* INCLUDES_H */ diff --git a/components/wpa_supplicant/include/wpa/list.h b/components/wpa_supplicant/include/wpa/list.h new file mode 100644 index 0000000000..c8dccee83d --- /dev/null +++ b/components/wpa_supplicant/include/wpa/list.h @@ -0,0 +1,101 @@ +/* + * Doubly-linked list + * Copyright (c) 2009, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef LIST_H +#define LIST_H + +/** + * struct dl_list - Doubly-linked list + */ +struct dl_list { + struct dl_list *next; + struct dl_list *prev; +}; + +static inline void dl_list_init(struct dl_list *list) +{ + list->next = list; + list->prev = list; +} + +static inline void dl_list_add(struct dl_list *list, struct dl_list *item) +{ + item->next = list->next; + item->prev = list; + list->next->prev = item; + list->next = item; +} + +static inline void dl_list_add_tail(struct dl_list *list, struct dl_list *item) +{ + dl_list_add(list->prev, item); +} + +static inline void dl_list_del(struct dl_list *item) +{ + item->next->prev = item->prev; + item->prev->next = item->next; + item->next = NULL; + item->prev = NULL; +} + +static inline int dl_list_empty(struct dl_list *list) +{ + return list->next == list; +} + +static inline unsigned int dl_list_len(struct dl_list *list) +{ + struct dl_list *item; + int count = 0; + for (item = list->next; item != list; item = item->next) + count++; + return count; +} + +#ifndef offsetof +#define offsetof(type, member) ((long) &((type *) 0)->member) +#endif + +#define dl_list_entry(item, type, member) \ + ((type *) ((char *) item - offsetof(type, member))) + +#define dl_list_first(list, type, member) \ + (dl_list_empty((list)) ? NULL : \ + dl_list_entry((list)->next, type, member)) + +#define dl_list_last(list, type, member) \ + (dl_list_empty((list)) ? NULL : \ + dl_list_entry((list)->prev, type, member)) + +#define dl_list_for_each(item, list, type, member) \ + for (item = dl_list_entry((list)->next, type, member); \ + &item->member != (list); \ + item = dl_list_entry(item->member.next, type, member)) + +#define dl_list_for_each_safe(item, n, list, type, member) \ + for (item = dl_list_entry((list)->next, type, member), \ + n = dl_list_entry(item->member.next, type, member); \ + &item->member != (list); \ + item = n, n = dl_list_entry(n->member.next, type, member)) + +#define dl_list_for_each_reverse(item, list, type, member) \ + for (item = dl_list_entry((list)->prev, type, member); \ + &item->member != (list); \ + item = dl_list_entry(item->member.prev, type, member)) + +#define DEFINE_DL_LIST(name) \ + struct dl_list name = { &(name), &(name) } + +#endif /* LIST_H */ diff --git a/components/wpa_supplicant/include/wpa/sta_info.h b/components/wpa_supplicant/include/wpa/sta_info.h new file mode 100644 index 0000000000..44874a2ff9 --- /dev/null +++ b/components/wpa_supplicant/include/wpa/sta_info.h @@ -0,0 +1,194 @@ +/* + * hostapd / Station table + * Copyright (c) 2002-2011, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef STA_INFO_H +#define STA_INFO_H + +/* STA flags */ +#define WLAN_STA_AUTH BIT(0) +#define WLAN_STA_ASSOC BIT(1) +#define WLAN_STA_PS BIT(2) +#define WLAN_STA_TIM BIT(3) +#define WLAN_STA_PERM BIT(4) +#define WLAN_STA_AUTHORIZED BIT(5) +#define WLAN_STA_PENDING_POLL BIT(6) /* pending activity poll not ACKed */ +#define WLAN_STA_SHORT_PREAMBLE BIT(7) +#define WLAN_STA_PREAUTH BIT(8) +#define WLAN_STA_WMM BIT(9) +#define WLAN_STA_MFP BIT(10) +#define WLAN_STA_HT BIT(11) +#define WLAN_STA_WPS BIT(12) +#define WLAN_STA_MAYBE_WPS BIT(13) +#define WLAN_STA_WDS BIT(14) +#define WLAN_STA_ASSOC_REQ_OK BIT(15) +#define WLAN_STA_WPS2 BIT(16) +#define WLAN_STA_GAS BIT(17) +#define WLAN_STA_VHT BIT(18) +#define WLAN_STA_PENDING_DISASSOC_CB BIT(29) +#define WLAN_STA_PENDING_DEAUTH_CB BIT(30) +#define WLAN_STA_NONERP BIT(31) + +/* Maximum number of supported rates (from both Supported Rates and Extended + * Supported Rates IEs). */ +#define WLAN_SUPP_RATES_MAX 32 + + +struct sta_info { + struct sta_info *next; /* next entry in sta list */ + struct sta_info *hnext; /* next entry in hash table list */ + u8 addr[6]; + u16 aid; /* STA's unique AID (1 .. 2007) or 0 if not yet assigned */ + u32 flags; /* Bitfield of WLAN_STA_* */ + u16 capability; + u16 listen_interval; /* or beacon_int for APs */ + u8 supported_rates[WLAN_SUPP_RATES_MAX]; + int supported_rates_len; +// u8 qosinfo; /* Valid when WLAN_STA_WMM is set */ + +// unsigned int nonerp_set:1; +// unsigned int no_short_slot_time_set:1; +// unsigned int no_short_preamble_set:1; +// unsigned int no_ht_gf_set:1; +// unsigned int no_ht_set:1; +// unsigned int ht_20mhz_set:1; +// unsigned int no_p2p_set:1; + + u16 auth_alg; +// u8 previous_ap[6]; + + enum { + STA_NULLFUNC = 0, STA_DISASSOC, STA_DEAUTH, STA_REMOVE + } timeout_next; + +// u16 deauth_reason; +// u16 disassoc_reason; + + /* IEEE 802.1X related data */ +// struct eapol_state_machine *eapol_sm; + + /* IEEE 802.11f (IAPP) related data */ +// struct ieee80211_mgmt *last_assoc_req; + +// u32 acct_session_id_hi; +// u32 acct_session_id_lo; +// time_t acct_session_start; +// int acct_session_started; +// int acct_terminate_cause; /* Acct-Terminate-Cause */ +// int acct_interim_interval; /* Acct-Interim-Interval */ + +// unsigned long last_rx_bytes; +// unsigned long last_tx_bytes; +// u32 acct_input_gigawords; /* Acct-Input-Gigawords */ +// u32 acct_output_gigawords; /* Acct-Output-Gigawords */ + +// u8 *challenge; /* IEEE 802.11 Shared Key Authentication Challenge */ + + struct wpa_state_machine *wpa_sm; +// struct rsn_preauth_interface *preauth_iface; + + struct hostapd_ssid *ssid; /* SSID selection based on (Re)AssocReq */ +// struct hostapd_ssid *ssid_probe; /* SSID selection based on ProbeReq */ + +// int vlan_id; + /* PSKs from RADIUS authentication server */ +// struct hostapd_sta_wpa_psk_short *psk; + +// char *identity; /* User-Name from RADIUS */ +// char *radius_cui; /* Chargeable-User-Identity from RADIUS */ + +// struct ieee80211_ht_capabilities *ht_capabilities; +// struct ieee80211_vht_capabilities *vht_capabilities; + +#ifdef CONFIG_IEEE80211W + int sa_query_count; /* number of pending SA Query requests; + * 0 = no SA Query in progress */ + int sa_query_timed_out; + u8 *sa_query_trans_id; /* buffer of WLAN_SA_QUERY_TR_ID_LEN * + * sa_query_count octets of pending SA Query + * transaction identifiers */ + struct os_time sa_query_start; +#endif /* CONFIG_IEEE80211W */ + +#ifdef CONFIG_INTERWORKING +#define GAS_DIALOG_MAX 8 /* Max concurrent dialog number */ + struct gas_dialog_info *gas_dialog; + u8 gas_dialog_next; +#endif /* CONFIG_INTERWORKING */ + +// struct wpabuf *wps_ie; /* WPS IE from (Re)Association Request */ +// struct wpabuf *p2p_ie; /* P2P IE from (Re)Association Request */ +// struct wpabuf *hs20_ie; /* HS 2.0 IE from (Re)Association Request */ + +// struct os_time connected_time; + +#ifdef CONFIG_SAE + enum { SAE_INIT, SAE_COMMIT, SAE_CONFIRM } sae_state; + u16 sae_send_confirm; +#endif /* CONFIG_SAE */ +}; + + +/* Default value for maximum station inactivity. After AP_MAX_INACTIVITY has + * passed since last received frame from the station, a nullfunc data frame is + * sent to the station. If this frame is not acknowledged and no other frames + * have been received, the station will be disassociated after + * AP_DISASSOC_DELAY seconds. Similarly, the station will be deauthenticated + * after AP_DEAUTH_DELAY seconds has passed after disassociation. */ +#define AP_MAX_INACTIVITY (5 * 60) +#define AP_DISASSOC_DELAY (1) +#define AP_DEAUTH_DELAY (1) +/* Number of seconds to keep STA entry with Authenticated flag after it has + * been disassociated. */ +#define AP_MAX_INACTIVITY_AFTER_DISASSOC (1 * 30) +/* Number of seconds to keep STA entry after it has been deauthenticated. */ +#define AP_MAX_INACTIVITY_AFTER_DEAUTH (1 * 5) + + +struct hostapd_data; + +int ap_for_each_sta(struct hostapd_data *hapd, + int (*cb)(struct hostapd_data *hapd, struct sta_info *sta, + void *ctx), + void *ctx); +struct sta_info * ap_get_sta(struct hostapd_data *hapd, const u8 *sta); +void ap_sta_hash_add(struct hostapd_data *hapd, struct sta_info *sta); +void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta); +void hostapd_free_stas(struct hostapd_data *hapd); +void ap_handle_timer(void *eloop_ctx, void *timeout_ctx); +void ap_sta_session_timeout(struct hostapd_data *hapd, struct sta_info *sta, + u32 session_timeout); +void ap_sta_no_session_timeout(struct hostapd_data *hapd, + struct sta_info *sta); +struct sta_info * ap_sta_add(struct hostapd_data *hapd, const u8 *addr); +void ap_sta_disassociate(struct hostapd_data *hapd, struct sta_info *sta, + u16 reason); +void ap_sta_deauthenticate(struct hostapd_data *hapd, struct sta_info *sta, + u16 reason); +#ifdef CONFIG_WPS +int ap_sta_wps_cancel(struct hostapd_data *hapd, + struct sta_info *sta, void *ctx); +#endif /* CONFIG_WPS */ +int ap_sta_bind_vlan(struct hostapd_data *hapd, struct sta_info *sta, + int old_vlanid); +void ap_sta_start_sa_query(struct hostapd_data *hapd, struct sta_info *sta); +void ap_sta_stop_sa_query(struct hostapd_data *hapd, struct sta_info *sta); +int ap_check_sa_query_timeout(struct hostapd_data *hapd, struct sta_info *sta); +void ap_sta_disconnect(struct hostapd_data *hapd, struct sta_info *sta, + const u8 *addr, u16 reason); + +void ap_sta_set_authorized(struct hostapd_data *hapd, + struct sta_info *sta, int authorized); +static inline int ap_sta_is_authorized(struct sta_info *sta) +{ + return sta->flags & WLAN_STA_AUTHORIZED; +} + +void ap_sta_deauth_cb(struct hostapd_data *hapd, struct sta_info *sta); +void ap_sta_disassoc_cb(struct hostapd_data *hapd, struct sta_info *sta); + +#endif /* STA_INFO_H */ diff --git a/components/wpa_supplicant/include/wpa/state_machine.h b/components/wpa_supplicant/include/wpa/state_machine.h new file mode 100644 index 0000000000..ce8c51e770 --- /dev/null +++ b/components/wpa_supplicant/include/wpa/state_machine.h @@ -0,0 +1,138 @@ +/* + * wpa_supplicant/hostapd - State machine definitions + * Copyright (c) 2002-2005, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + * + * This file includes a set of pre-processor macros that can be used to + * implement a state machine. In addition to including this header file, each + * file implementing a state machine must define STATE_MACHINE_DATA to be the + * data structure including state variables (enum machine_state, + * Boolean changed), and STATE_MACHINE_DEBUG_PREFIX to be a string that is used + * as a prefix for all debug messages. If SM_ENTRY_MA macro is used to define + * a group of state machines with shared data structure, STATE_MACHINE_ADDR + * needs to be defined to point to the MAC address used in debug output. + * SM_ENTRY_M macro can be used to define similar group of state machines + * without this additional debug info. + */ + +#ifndef STATE_MACHINE_H +#define STATE_MACHINE_H + +/** + * SM_STATE - Declaration of a state machine function + * @machine: State machine name + * @state: State machine state + * + * This macro is used to declare a state machine function. It is used in place + * of a C function definition to declare functions to be run when the state is + * entered by calling SM_ENTER or SM_ENTER_GLOBAL. + */ +#define SM_STATE(machine, state) \ +static void ICACHE_FLASH_ATTR sm_ ## machine ## _ ## state ## _Enter(STATE_MACHINE_DATA *sm, \ + int global) + +/** + * SM_ENTRY - State machine function entry point + * @machine: State machine name + * @state: State machine state + * + * This macro is used inside each state machine function declared with + * SM_STATE. SM_ENTRY should be in the beginning of the function body, but + * after declaration of possible local variables. This macro prints debug + * information about state transition and update the state machine state. + */ +#define SM_ENTRY(machine, state) \ +if (!global || sm->machine ## _state != machine ## _ ## state) { \ + sm->changed = TRUE; \ + wpa_printf(MSG_DEBUG, STATE_MACHINE_DEBUG_PREFIX ": " #machine \ + " entering state " #state); \ +} \ +sm->machine ## _state = machine ## _ ## state; + +/** + * SM_ENTRY_M - State machine function entry point for state machine group + * @machine: State machine name + * @_state: State machine state + * @data: State variable prefix (full variable: prefix_state) + * + * This macro is like SM_ENTRY, but for state machine groups that use a shared + * data structure for more than one state machine. Both machine and prefix + * parameters are set to "sub-state machine" name. prefix is used to allow more + * than one state variable to be stored in the same data structure. + */ +#define SM_ENTRY_M(machine, _state, data) \ +if (!global || sm->data ## _ ## state != machine ## _ ## _state) { \ + sm->changed = TRUE; \ + wpa_printf(MSG_DEBUG, STATE_MACHINE_DEBUG_PREFIX ": " \ + #machine " entering state " #_state); \ +} \ +sm->data ## _ ## state = machine ## _ ## _state; + +/** + * SM_ENTRY_MA - State machine function entry point for state machine group + * @machine: State machine name + * @_state: State machine state + * @data: State variable prefix (full variable: prefix_state) + * + * This macro is like SM_ENTRY_M, but a MAC address is included in debug + * output. STATE_MACHINE_ADDR has to be defined to point to the MAC address to + * be included in debug. + */ +#define SM_ENTRY_MA(machine, _state, data) \ +if (!global || sm->data ## _ ## state != machine ## _ ## _state) { \ + sm->changed = TRUE; \ + wpa_printf(MSG_DEBUG, STATE_MACHINE_DEBUG_PREFIX ": " MACSTR " " \ + #machine " entering state " #_state"\n", \ + MAC2STR(STATE_MACHINE_ADDR)); \ +} \ +sm->data ## _ ## state = machine ## _ ## _state; + +/** + * SM_ENTER - Enter a new state machine state + * @machine: State machine name + * @state: State machine state + * + * This macro expands to a function call to a state machine function defined + * with SM_STATE macro. SM_ENTER is used in a state machine step function to + * move the state machine to a new state. + */ +#define SM_ENTER(machine, state) \ +sm_ ## machine ## _ ## state ## _Enter(sm, 0) + +/** + * SM_ENTER_GLOBAL - Enter a new state machine state based on global rule + * @machine: State machine name + * @state: State machine state + * + * This macro is like SM_ENTER, but this is used when entering a new state + * based on a global (not specific to any particular state) rule. A separate + * macro is used to avoid unwanted debug message floods when the same global + * rule is forcing a state machine to remain in on state. + */ +#define SM_ENTER_GLOBAL(machine, state) \ +sm_ ## machine ## _ ## state ## _Enter(sm, 1) + +/** + * SM_STEP - Declaration of a state machine step function + * @machine: State machine name + * + * This macro is used to declare a state machine step function. It is used in + * place of a C function definition to declare a function that is used to move + * state machine to a new state based on state variables. This function uses + * SM_ENTER and SM_ENTER_GLOBAL macros to enter new state. + */ +#define SM_STEP(machine) \ +static void ICACHE_FLASH_ATTR sm_ ## machine ## _Step(STATE_MACHINE_DATA *sm) + +/** + * SM_STEP_RUN - Call the state machine step function + * @machine: State machine name + * + * This macro expands to a function call to a state machine step function + * defined with SM_STEP macro. + */ +#define SM_STEP_RUN(machine) sm_ ## machine ## _Step(sm) + +#endif /* STATE_MACHINE_H */ diff --git a/components/wpa_supplicant/include/wpa/wpa.h b/components/wpa_supplicant/include/wpa/wpa.h new file mode 100644 index 0000000000..2a1adfc567 --- /dev/null +++ b/components/wpa_supplicant/include/wpa/wpa.h @@ -0,0 +1,193 @@ +/* + * wpa_supplicant - WPA definitions + * Copyright (c) 2003-2007, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef WPA_H +#define WPA_H + +#include "c_types.h" +#include "os_type.h" +#include "common.h" +#include "ets_sys.h" +#include "wpa/defs.h" +#include "wpa/wpa_common.h" + +//#include "net80211/ieee80211_var.h" +//#include "net80211/ieee80211_node.h" + +#define WPA_SM_STATE(_sm) ((_sm)->wpa_state) + +struct wpa_sm; + +int wpa_sm_rx_eapol(u8 *src_addr, u8 *buf, u32 len); + +#define WPA_ASSERT ASSERT + +struct install_key { + int mic_errors_seen; /* Michael MIC errors with the current PTK */ + int keys_cleared; + enum wpa_alg alg; + u8 addr[ETH_ALEN]; + int key_idx; + int set_tx; + u8 seq[10]; + u8 key[32]; +}; + +/** + * struct wpa_sm - Internal WPA state machine data + */ +struct wpa_sm { + u8 pmk[PMK_LEN]; + size_t pmk_len; + +// char *passphrase; //wlan password +// u8 *ssid; //wlan network name +// size_t ssid_len; + + struct wpa_ptk ptk, tptk; + int ptk_set, tptk_set; + u8 snonce[WPA_NONCE_LEN]; + u8 anonce[WPA_NONCE_LEN]; /* ANonce from the last 1/4 msg */ + int renew_snonce; + u8 rx_replay_counter[WPA_REPLAY_COUNTER_LEN]; + int rx_replay_counter_set; + u8 request_counter[WPA_REPLAY_COUNTER_LEN]; + +// void *network_ctx; + + unsigned int pairwise_cipher; + unsigned int group_cipher; + unsigned int key_mgmt; + unsigned int mgmt_group_cipher; + + int rsn_enabled; /* Whether RSN is enabled in configuration */ + + int countermeasures; /*TKIP countermeasures state flag, 1:in countermeasures state*/ + os_timer_t cm_timer; + + u8 *assoc_wpa_ie; /* Own WPA/RSN IE from (Re)AssocReq */ + size_t assoc_wpa_ie_len; + + u8 eapol_version; + + int wpa_ptk_rekey; + u8 own_addr[ETH_ALEN]; + + u8 bssid[ETH_ALEN]; + + unsigned int proto; + enum wpa_states wpa_state; + + u8 *ap_wpa_ie, *ap_rsn_ie; + size_t ap_wpa_ie_len, ap_rsn_ie_len; + + struct install_key install_ptk; + struct install_key install_gtk; + int key_entry_valid; //present current avaliable entry for bssid, for pairkey:0,5,10,15,20, gtk: pairkey_no+i (i:1~4) + +// char *msg; //send eapol msg buff +// size_t msg_len; //msg length:6 + sizeof(eth) + data_len + +// struct netif *ifp; + struct pbuf *pb; + + void (* sendto) (struct pbuf *pb); + void (*config_assoc_ie) (uint8 proto, u8 *assoc_buf, u32 assoc_wpa_ie_len); + void (*install_ppkey) (enum wpa_alg alg, uint8 *addr, int key_idx, int set_tx, + uint8 *seq, size_t seq_len, uint8 *key, size_t key_len, int key_entry_valid); + void (*wpa_deauthenticate)(uint8 reason_code); + void (*wpa_neg_complete)(); + struct wpa_gtk_data gd; //used for calllback save param + uint16 key_info; //used for txcallback param +}; + +struct l2_ethhdr { + u8 h_dest[ETH_ALEN]; + u8 h_source[ETH_ALEN]; + be16 h_proto; +} STRUCT_PACKED; + +/** + * set_key - Configure encryption key + * @ifname: Interface name (for multi-SSID/VLAN support) + * @priv: private driver interface data + * @alg: encryption algorithm (%WPA_ALG_NONE, %WPA_ALG_WEP, + * %WPA_ALG_TKIP, %WPA_ALG_CCMP, %WPA_ALG_IGTK, %WPA_ALG_PMK); + * %WPA_ALG_NONE clears the key. + * @addr: address of the peer STA or ff:ff:ff:ff:ff:ff for + * broadcast/default keys + * @key_idx: key index (0..3), usually 0 for unicast keys; 0..4095 for + * IGTK + * @set_tx: configure this key as the default Tx key (only used when + * driver does not support separate unicast/individual key + * @seq: sequence number/packet number, seq_len octets, the next + * packet number to be used for in replay protection; configured + * for Rx keys (in most cases, this is only used with broadcast + * keys and set to zero for unicast keys) + * @seq_len: length of the seq, depends on the algorithm: + * TKIP: 6 octets, CCMP: 6 octets, IGTK: 6 octets + * @key: key buffer; TKIP: 16-byte temporal key, 8-byte Tx Mic key, + * 8-byte Rx Mic Key + * @key_len: length of the key buffer in octets (WEP: 5 or 13, + * TKIP: 32, CCMP: 16, IGTK: 16) + * + * Returns: 0 on success, -1 on failure + * + * Configure the given key for the kernel driver. If the driver + * supports separate individual keys (4 default keys + 1 individual), + * addr can be used to determine whether the key is default or + * individual. If only 4 keys are supported, the default key with key + * index 0 is used as the individual key. STA must be configured to use + * it as the default Tx key (set_tx is set) and accept Rx for all the + * key indexes. In most cases, WPA uses only key indexes 1 and 2 for + * broadcast keys, so key index 0 is available for this kind of + * configuration. + * + * Please note that TKIP keys include separate TX and RX MIC keys and + * some drivers may expect them in different order than wpa_supplicant + * is using. If the TX/RX keys are swapped, all TKIP encrypted packets + * will tricker Michael MIC errors. This can be fixed by changing the + * order of MIC keys by swapping te bytes 16..23 and 24..31 of the key + * in driver_*.c set_key() implementation, see driver_ndis.c for an + * example on how this can be done. + */ + + +/** + * send_eapol - Optional function for sending EAPOL packets + * @priv: private driver interface data + * @dest: Destination MAC address + * @proto: Ethertype + * @data: EAPOL packet starting with IEEE 802.1X header + * @data_len: Size of the EAPOL packet + * + * Returns: 0 on success, -1 on failure + * + * This optional function can be used to override l2_packet operations + * with driver specific functionality. If this function pointer is set, + * l2_packet module is not used at all and the driver interface code is + * responsible for receiving and sending all EAPOL packets. The + * received EAPOL packets are sent to core code with EVENT_EAPOL_RX + * event. The driver interface is required to implement get_mac_addr() + * handler if send_eapol() is used. + */ + +#define KEYENTRY_TABLE_MAP(key_entry_valid) ((key_entry_valid)%5) + +void pp_michael_mic_failure(uint16 isunicast); + +void wpa_sm_set_state(enum wpa_states state); + +#endif /* WPA_H */ + diff --git a/components/wpa_supplicant/include/wpa/wpa_auth.h b/components/wpa_supplicant/include/wpa/wpa_auth.h new file mode 100644 index 0000000000..c729923494 --- /dev/null +++ b/components/wpa_supplicant/include/wpa/wpa_auth.h @@ -0,0 +1,292 @@ +/* + * hostapd - IEEE 802.11i-2004 / WPA Authenticator + * Copyright (c) 2004-2007, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef WPA_AUTH_H +#define WPA_AUTH_H + +#include "wpa/defs.h" +#include "wpa/eapol_common.h" +#include "wpa/wpa_common.h" + +#ifdef _MSC_VER +#pragma pack(push, 1) +#endif /* _MSC_VER */ + +/* IEEE Std 802.11r-2008, 11A.10.3 - Remote request/response frame definition + */ +struct ft_rrb_frame { + u8 frame_type; /* RSN_REMOTE_FRAME_TYPE_FT_RRB */ + u8 packet_type; /* FT_PACKET_REQUEST/FT_PACKET_RESPONSE */ + le16 action_length; /* little endian length of action_frame */ + u8 ap_address[ETH_ALEN]; + /* + * Followed by action_length bytes of FT Action frame (from Category + * field to the end of Action Frame body. + */ +} STRUCT_PACKED; + +#define RSN_REMOTE_FRAME_TYPE_FT_RRB 1 + +#define FT_PACKET_REQUEST 0 +#define FT_PACKET_RESPONSE 1 +/* Vendor-specific types for R0KH-R1KH protocol; not defined in 802.11r */ +#define FT_PACKET_R0KH_R1KH_PULL 200 +#define FT_PACKET_R0KH_R1KH_RESP 201 +#define FT_PACKET_R0KH_R1KH_PUSH 202 + +#define FT_R0KH_R1KH_PULL_DATA_LEN 44 +#define FT_R0KH_R1KH_RESP_DATA_LEN 76 +#define FT_R0KH_R1KH_PUSH_DATA_LEN 88 + +struct ft_r0kh_r1kh_pull_frame { + u8 frame_type; /* RSN_REMOTE_FRAME_TYPE_FT_RRB */ + u8 packet_type; /* FT_PACKET_R0KH_R1KH_PULL */ + le16 data_length; /* little endian length of data (44) */ + u8 ap_address[ETH_ALEN]; + + u8 nonce[16]; + u8 pmk_r0_name[WPA_PMK_NAME_LEN]; + u8 r1kh_id[FT_R1KH_ID_LEN]; + u8 s1kh_id[ETH_ALEN]; + u8 pad[4]; /* 8-octet boundary for AES key wrap */ + u8 key_wrap_extra[8]; +} STRUCT_PACKED; + +struct ft_r0kh_r1kh_resp_frame { + u8 frame_type; /* RSN_REMOTE_FRAME_TYPE_FT_RRB */ + u8 packet_type; /* FT_PACKET_R0KH_R1KH_RESP */ + le16 data_length; /* little endian length of data (76) */ + u8 ap_address[ETH_ALEN]; + + u8 nonce[16]; /* copied from pull */ + u8 r1kh_id[FT_R1KH_ID_LEN]; /* copied from pull */ + u8 s1kh_id[ETH_ALEN]; /* copied from pull */ + u8 pmk_r1[PMK_LEN]; + u8 pmk_r1_name[WPA_PMK_NAME_LEN]; + le16 pairwise; + u8 pad[2]; /* 8-octet boundary for AES key wrap */ + u8 key_wrap_extra[8]; +} STRUCT_PACKED; + +struct ft_r0kh_r1kh_push_frame { + u8 frame_type; /* RSN_REMOTE_FRAME_TYPE_FT_RRB */ + u8 packet_type; /* FT_PACKET_R0KH_R1KH_PUSH */ + le16 data_length; /* little endian length of data (88) */ + u8 ap_address[ETH_ALEN]; + + /* Encrypted with AES key-wrap */ + u8 timestamp[4]; /* current time in seconds since unix epoch, little + * endian */ + u8 r1kh_id[FT_R1KH_ID_LEN]; + u8 s1kh_id[ETH_ALEN]; + u8 pmk_r0_name[WPA_PMK_NAME_LEN]; + u8 pmk_r1[PMK_LEN]; + u8 pmk_r1_name[WPA_PMK_NAME_LEN]; + le16 pairwise; + u8 pad[6]; /* 8-octet boundary for AES key wrap */ + u8 key_wrap_extra[8]; +} STRUCT_PACKED; + +#ifdef _MSC_VER +#pragma pack(pop) +#endif /* _MSC_VER */ + + +/* per STA state machine data */ + +struct wpa_authenticator; +struct wpa_state_machine; +struct rsn_pmksa_cache_entry; +struct eapol_state_machine; + + +struct ft_remote_r0kh { + struct ft_remote_r0kh *next; + u8 addr[ETH_ALEN]; + u8 id[FT_R0KH_ID_MAX_LEN]; + size_t id_len; + u8 key[16]; +}; + + +struct ft_remote_r1kh { + struct ft_remote_r1kh *next; + u8 addr[ETH_ALEN]; + u8 id[FT_R1KH_ID_LEN]; + u8 key[16]; +}; + + +struct wpa_auth_config { + int wpa; + int wpa_key_mgmt; + int wpa_pairwise; + int wpa_group; + int wpa_group_rekey; + int wpa_strict_rekey; + int wpa_gmk_rekey; + int wpa_ptk_rekey; + int rsn_pairwise; + int rsn_preauth; + int eapol_version; + int peerkey; + int wmm_enabled; + int wmm_uapsd; + int disable_pmksa_caching; + int okc; + int tx_status; +#ifdef CONFIG_IEEE80211W + enum mfp_options ieee80211w; +#endif /* CONFIG_IEEE80211W */ +#ifdef CONFIG_IEEE80211R +#define SSID_LEN 32 + u8 ssid[SSID_LEN]; + size_t ssid_len; + u8 mobility_domain[MOBILITY_DOMAIN_ID_LEN]; + u8 r0_key_holder[FT_R0KH_ID_MAX_LEN]; + size_t r0_key_holder_len; + u8 r1_key_holder[FT_R1KH_ID_LEN]; + u32 r0_key_lifetime; + u32 reassociation_deadline; + struct ft_remote_r0kh *r0kh_list; + struct ft_remote_r1kh *r1kh_list; + int pmk_r1_push; + int ft_over_ds; +#endif /* CONFIG_IEEE80211R */ + int disable_gtk; + int ap_mlme; +}; + +typedef enum { + LOGGER_DEBUG, LOGGER_INFO, LOGGER_WARNING +} logger_level; + +typedef enum { + WPA_EAPOL_portEnabled, WPA_EAPOL_portValid, WPA_EAPOL_authorized, + WPA_EAPOL_portControl_Auto, WPA_EAPOL_keyRun, WPA_EAPOL_keyAvailable, + WPA_EAPOL_keyDone, WPA_EAPOL_inc_EapolFramesTx +} wpa_eapol_variable; + +struct wpa_auth_callbacks { + void *ctx; + void (*logger)(void *ctx, const u8 *addr, logger_level level, + const char *txt); + void (*disconnect)(void *ctx, const u8 *addr, u16 reason); + int (*mic_failure_report)(void *ctx, const u8 *addr); + void (*set_eapol)(void *ctx, const u8 *addr, wpa_eapol_variable var, + int value); + int (*get_eapol)(void *ctx, const u8 *addr, wpa_eapol_variable var); + const u8 * (*get_psk)(void *ctx, const u8 *addr, const u8 *prev_psk); + int (*get_msk)(void *ctx, const u8 *addr, u8 *msk, size_t *len); + int (*set_key)(void *ctx, int vlan_id, enum wpa_alg alg, + const u8 *addr, int idx, u8 *key, size_t key_len); + int (*get_seqnum)(void *ctx, const u8 *addr, int idx, u8 *seq); + int (*send_eapol)(void *ctx, const u8 *addr, const u8 *data, + size_t data_len, int encrypt); + int (*for_each_sta)(void *ctx, int (*cb)(struct wpa_state_machine *sm, + void *ctx), void *cb_ctx); + int (*for_each_auth)(void *ctx, int (*cb)(struct wpa_authenticator *a, + void *ctx), void *cb_ctx); + int (*send_ether)(void *ctx, const u8 *dst, u16 proto, const u8 *data, + size_t data_len); +#ifdef CONFIG_IEEE80211R + struct wpa_state_machine * (*add_sta)(void *ctx, const u8 *sta_addr); + int (*send_ft_action)(void *ctx, const u8 *dst, + const u8 *data, size_t data_len); + int (*add_tspec)(void *ctx, const u8 *sta_addr, u8 *tspec_ie, + size_t tspec_ielen); +#endif /* CONFIG_IEEE80211R */ +}; + +struct wpa_authenticator * wpa_init(const u8 *addr, + struct wpa_auth_config *conf, + struct wpa_auth_callbacks *cb); +int wpa_init_keys(struct wpa_authenticator *wpa_auth); +void wpa_deinit(struct wpa_authenticator *wpa_auth); +int wpa_reconfig(struct wpa_authenticator *wpa_auth, + struct wpa_auth_config *conf); + +enum { + WPA_IE_OK, WPA_INVALID_IE, WPA_INVALID_GROUP, WPA_INVALID_PAIRWISE, + WPA_INVALID_AKMP, WPA_NOT_ENABLED, WPA_ALLOC_FAIL, + WPA_MGMT_FRAME_PROTECTION_VIOLATION, WPA_INVALID_MGMT_GROUP_CIPHER, + WPA_INVALID_MDIE, WPA_INVALID_PROTO +}; + +int wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth, + struct wpa_state_machine *sm, + const u8 *wpa_ie, size_t wpa_ie_len/*, + const u8 *mdie, size_t mdie_len*/); +int wpa_auth_uses_mfp(struct wpa_state_machine *sm); +struct wpa_state_machine * +wpa_auth_sta_init(struct wpa_authenticator *wpa_auth, const u8 *addr); +int wpa_auth_sta_associated(struct wpa_authenticator *wpa_auth, + struct wpa_state_machine *sm); +void wpa_auth_sta_no_wpa(struct wpa_state_machine *sm); +void wpa_auth_sta_deinit(struct wpa_state_machine *sm); +void wpa_receive(struct wpa_authenticator *wpa_auth, + struct wpa_state_machine *sm, + u8 *data, size_t data_len); +typedef enum { + WPA_AUTH, WPA_ASSOC, WPA_DISASSOC, WPA_DEAUTH, WPA_REAUTH, + WPA_REAUTH_EAPOL, WPA_ASSOC_FT +} wpa_event; +void wpa_remove_ptk(struct wpa_state_machine *sm); +int wpa_auth_sm_event(struct wpa_state_machine *sm, wpa_event event); +void wpa_auth_sm_notify(struct wpa_state_machine *sm); +void wpa_gtk_rekey(struct wpa_authenticator *wpa_auth); +int wpa_get_mib(struct wpa_authenticator *wpa_auth, char *buf, size_t buflen); +int wpa_get_mib_sta(struct wpa_state_machine *sm, char *buf, size_t buflen); +void wpa_auth_countermeasures_start(struct wpa_authenticator *wpa_auth); +int wpa_auth_pairwise_set(struct wpa_state_machine *sm); +int wpa_auth_get_pairwise(struct wpa_state_machine *sm); +int wpa_auth_sta_key_mgmt(struct wpa_state_machine *sm); +int wpa_auth_sta_wpa_version(struct wpa_state_machine *sm); +int wpa_auth_sta_clear_pmksa(struct wpa_state_machine *sm, + struct rsn_pmksa_cache_entry *entry); +struct rsn_pmksa_cache_entry * +wpa_auth_sta_get_pmksa(struct wpa_state_machine *sm); +void wpa_auth_sta_local_mic_failure_report(struct wpa_state_machine *sm); +const u8 * wpa_auth_get_wpa_ie(struct wpa_authenticator *wpa_auth, + size_t *len); +int wpa_auth_pmksa_add(struct wpa_state_machine *sm, const u8 *pmk, + int session_timeout, struct eapol_state_machine *eapol); +int wpa_auth_pmksa_add_preauth(struct wpa_authenticator *wpa_auth, + const u8 *pmk, size_t len, const u8 *sta_addr, + int session_timeout, + struct eapol_state_machine *eapol); +int wpa_auth_sta_set_vlan(struct wpa_state_machine *sm, int vlan_id); +void wpa_auth_eapol_key_tx_status(struct wpa_authenticator *wpa_auth, + struct wpa_state_machine *sm, int ack); + +#ifdef CONFIG_IEEE80211R +u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos, + size_t max_len, int auth_alg, + const u8 *req_ies, size_t req_ies_len); +void wpa_ft_process_auth(struct wpa_state_machine *sm, const u8 *bssid, + u16 auth_transaction, const u8 *ies, size_t ies_len, + void (*cb)(void *ctx, const u8 *dst, const u8 *bssid, + u16 auth_transaction, u16 resp, + const u8 *ies, size_t ies_len), + void *ctx); +u16 wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies, + size_t ies_len); +int wpa_ft_action_rx(struct wpa_state_machine *sm, const u8 *data, size_t len); +int wpa_ft_rrb_rx(struct wpa_authenticator *wpa_auth, const u8 *src_addr, + const u8 *data, size_t data_len); +void wpa_ft_push_pmk_r1(struct wpa_authenticator *wpa_auth, const u8 *addr); +#endif /* CONFIG_IEEE80211R */ + +void wpa_wnmsleep_rekey_gtk(struct wpa_state_machine *sm); +void wpa_set_wnmsleep(struct wpa_state_machine *sm, int flag); +int wpa_wnmsleep_gtk_subelem(struct wpa_state_machine *sm, u8 *pos); +int wpa_wnmsleep_igtk_subelem(struct wpa_state_machine *sm, u8 *pos); + +int wpa_auth_uses_sae(struct wpa_state_machine *sm); + +#endif /* WPA_AUTH_H */ diff --git a/components/wpa_supplicant/include/wpa/wpa_auth_i.h b/components/wpa_supplicant/include/wpa/wpa_auth_i.h new file mode 100644 index 0000000000..53ad8ea941 --- /dev/null +++ b/components/wpa_supplicant/include/wpa/wpa_auth_i.h @@ -0,0 +1,234 @@ +/* + * hostapd - IEEE 802.11i-2004 / WPA Authenticator: Internal definitions + * Copyright (c) 2004-2007, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef WPA_AUTH_I_H +#define WPA_AUTH_I_H + +/* max(dot11RSNAConfigGroupUpdateCount,dot11RSNAConfigPairwiseUpdateCount) */ +#define RSNA_MAX_EAPOL_RETRIES 4 + +struct wpa_group; + +struct wpa_stsl_negotiation { + struct wpa_stsl_negotiation *next; + u8 initiator[ETH_ALEN]; + u8 peer[ETH_ALEN]; +}; + + +struct wpa_state_machine { + struct wpa_authenticator *wpa_auth; + struct wpa_group *group; + + u8 addr[ETH_ALEN]; + + enum { + WPA_PTK_INITIALIZE, WPA_PTK_DISCONNECT, WPA_PTK_DISCONNECTED, + WPA_PTK_AUTHENTICATION, WPA_PTK_AUTHENTICATION2, + WPA_PTK_INITPMK, WPA_PTK_INITPSK, WPA_PTK_PTKSTART, + WPA_PTK_PTKCALCNEGOTIATING, WPA_PTK_PTKCALCNEGOTIATING2, + WPA_PTK_PTKINITNEGOTIATING, WPA_PTK_PTKINITDONE + } wpa_ptk_state; + + enum { + WPA_PTK_GROUP_IDLE = 0, + WPA_PTK_GROUP_REKEYNEGOTIATING, + WPA_PTK_GROUP_REKEYESTABLISHED, + WPA_PTK_GROUP_KEYERROR + } wpa_ptk_group_state; + + Boolean Init; + Boolean DeauthenticationRequest; + Boolean AuthenticationRequest; + Boolean ReAuthenticationRequest; + Boolean Disconnect; + int TimeoutCtr; + int GTimeoutCtr; + Boolean TimeoutEvt; + Boolean EAPOLKeyReceived; + Boolean EAPOLKeyPairwise; + Boolean EAPOLKeyRequest; + Boolean MICVerified; + Boolean GUpdateStationKeys; + u8 ANonce[WPA_NONCE_LEN]; + u8 SNonce[WPA_NONCE_LEN]; + u8 PMK[PMK_LEN]; + struct wpa_ptk PTK; + Boolean PTK_valid; + Boolean pairwise_set; + int keycount; + Boolean Pair; + struct wpa_key_replay_counter { + u8 counter[WPA_REPLAY_COUNTER_LEN]; + Boolean valid; + } key_replay[RSNA_MAX_EAPOL_RETRIES], + prev_key_replay[RSNA_MAX_EAPOL_RETRIES]; + Boolean PInitAKeys; /* WPA only, not in IEEE 802.11i */ + Boolean PTKRequest; /* not in IEEE 802.11i state machine */ + Boolean has_GTK; + Boolean PtkGroupInit; /* init request for PTK Group state machine */ + + u8 *last_rx_eapol_key; /* starting from IEEE 802.1X header */ + size_t last_rx_eapol_key_len; + + unsigned int changed:1; + unsigned int in_step_loop:1; + unsigned int pending_deinit:1; + unsigned int started:1; + unsigned int mgmt_frame_prot:1; + unsigned int rx_eapol_key_secure:1; + unsigned int update_snonce:1; +#ifdef CONFIG_IEEE80211R + unsigned int ft_completed:1; + unsigned int pmk_r1_name_valid:1; +#endif /* CONFIG_IEEE80211R */ + unsigned int is_wnmsleep:1; + + u8 req_replay_counter[WPA_REPLAY_COUNTER_LEN]; + int req_replay_counter_used; + + u8 *wpa_ie; + size_t wpa_ie_len; + + enum { + WPA_VERSION_NO_WPA = 0 /* WPA not used */, + WPA_VERSION_WPA = 1 /* WPA / IEEE 802.11i/D3.0 */, + WPA_VERSION_WPA2 = 2 /* WPA2 / IEEE 802.11i */ + } wpa; + int pairwise; /* Pairwise cipher suite, WPA_CIPHER_* */ + int wpa_key_mgmt; /* the selected WPA_KEY_MGMT_* */ +// struct rsn_pmksa_cache_entry *pmksa; + +// u32 dot11RSNAStatsTKIPLocalMICFailures; +// u32 dot11RSNAStatsTKIPRemoteMICFailures; + +#ifdef CONFIG_IEEE80211R + u8 xxkey[PMK_LEN]; /* PSK or the second 256 bits of MSK */ + size_t xxkey_len; + u8 pmk_r1_name[WPA_PMK_NAME_LEN]; /* PMKR1Name derived from FT Auth + * Request */ + u8 r0kh_id[FT_R0KH_ID_MAX_LEN]; /* R0KH-ID from FT Auth Request */ + size_t r0kh_id_len; + u8 sup_pmk_r1_name[WPA_PMK_NAME_LEN]; /* PMKR1Name from EAPOL-Key + * message 2/4 */ + u8 *assoc_resp_ftie; +#endif /* CONFIG_IEEE80211R */ + + int pending_1_of_4_timeout; +}; + + +/* per group key state machine data */ +struct wpa_group { + struct wpa_group *next; + int vlan_id; + + Boolean GInit; + int GKeyDoneStations; + Boolean GTKReKey; + int GTK_len; + int GN, GM; + Boolean GTKAuthenticator; + u8 Counter[WPA_NONCE_LEN]; + + enum { + WPA_GROUP_GTK_INIT = 0, + WPA_GROUP_SETKEYS, WPA_GROUP_SETKEYSDONE + } wpa_group_state; + + u8 GMK[WPA_GMK_LEN]; + u8 GTK[2][WPA_GTK_MAX_LEN]; + u8 GNonce[WPA_NONCE_LEN]; + Boolean changed; + Boolean first_sta_seen; + Boolean reject_4way_hs_for_entropy; +#ifdef CONFIG_IEEE80211W + u8 IGTK[2][WPA_IGTK_LEN]; + int GN_igtk, GM_igtk; +#endif /* CONFIG_IEEE80211W */ +}; + + +struct wpa_ft_pmk_cache; + +/* per authenticator data */ +struct wpa_authenticator { + struct wpa_group *group; + +// unsigned int dot11RSNAStatsTKIPRemoteMICFailures; +// u32 dot11RSNAAuthenticationSuiteSelected; +// u32 dot11RSNAPairwiseCipherSelected; +// u32 dot11RSNAGroupCipherSelected; +// u8 dot11RSNAPMKIDUsed[PMKID_LEN]; +// u32 dot11RSNAAuthenticationSuiteRequested; /* FIX: update */ +// u32 dot11RSNAPairwiseCipherRequested; /* FIX: update */ +// u32 dot11RSNAGroupCipherRequested; /* FIX: update */ +// unsigned int dot11RSNATKIPCounterMeasuresInvoked; +// unsigned int dot11RSNA4WayHandshakeFailures; + +// struct wpa_stsl_negotiation *stsl_negotiations; + + struct wpa_auth_config conf; +// struct wpa_auth_callbacks cb; + + u8 *wpa_ie; + size_t wpa_ie_len; + + u8 addr[ETH_ALEN]; + +// struct rsn_pmksa_cache *pmksa; +// struct wpa_ft_pmk_cache *ft_pmk_cache; +}; + + +int wpa_write_rsn_ie(struct wpa_auth_config *conf, u8 *buf, size_t len, + const u8 *pmkid); +#if 0 +void wpa_auth_logger(struct wpa_authenticator *wpa_auth, const u8 *addr, + logger_level level, const char *txt); +void wpa_auth_vlogger(struct wpa_authenticator *wpa_auth, const u8 *addr, + logger_level level, const char *fmt, ...); +#endif +void __wpa_send_eapol(struct wpa_authenticator *wpa_auth, + struct wpa_state_machine *sm, int key_info, + const u8 *key_rsc, const u8 *nonce, + const u8 *kde, size_t kde_len, + int keyidx, int encr, int force_version); +int wpa_auth_for_each_sta(struct wpa_authenticator *wpa_auth, + int (*cb)(struct wpa_state_machine *sm, void *ctx), + void *cb_ctx); +int wpa_auth_for_each_auth(struct wpa_authenticator *wpa_auth, + int (*cb)(struct wpa_authenticator *a, void *ctx), + void *cb_ctx); + +#ifdef CONFIG_PEERKEY +int wpa_stsl_remove(struct wpa_authenticator *wpa_auth, + struct wpa_stsl_negotiation *neg); +void wpa_smk_error(struct wpa_authenticator *wpa_auth, + struct wpa_state_machine *sm, struct wpa_eapol_key *key); +void wpa_smk_m1(struct wpa_authenticator *wpa_auth, + struct wpa_state_machine *sm, struct wpa_eapol_key *key); +void wpa_smk_m3(struct wpa_authenticator *wpa_auth, + struct wpa_state_machine *sm, struct wpa_eapol_key *key); +#endif /* CONFIG_PEERKEY */ + +#ifdef CONFIG_IEEE80211R +int wpa_write_mdie(struct wpa_auth_config *conf, u8 *buf, size_t len); +int wpa_write_ftie(struct wpa_auth_config *conf, const u8 *r0kh_id, + size_t r0kh_id_len, + const u8 *anonce, const u8 *snonce, + u8 *buf, size_t len, const u8 *subelem, + size_t subelem_len); +int wpa_auth_derive_ptk_ft(struct wpa_state_machine *sm, const u8 *pmk, + struct wpa_ptk *ptk, size_t ptk_len); +struct wpa_ft_pmk_cache * wpa_ft_pmk_cache_init(void); +void wpa_ft_pmk_cache_deinit(struct wpa_ft_pmk_cache *cache); +void wpa_ft_install_ptk(struct wpa_state_machine *sm); +#endif /* CONFIG_IEEE80211R */ + +#endif /* WPA_AUTH_I_H */ diff --git a/components/wpa_supplicant/include/wpa/wpa_auth_ie.h b/components/wpa_supplicant/include/wpa/wpa_auth_ie.h new file mode 100644 index 0000000000..4999139510 --- /dev/null +++ b/components/wpa_supplicant/include/wpa/wpa_auth_ie.h @@ -0,0 +1,50 @@ +/* + * hostapd - WPA/RSN IE and KDE definitions + * Copyright (c) 2004-2007, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef WPA_AUTH_IE_H +#define WPA_AUTH_IE_H + +struct wpa_eapol_ie_parse { + const u8 *wpa_ie; + size_t wpa_ie_len; + const u8 *rsn_ie; + size_t rsn_ie_len; + const u8 *pmkid; + const u8 *gtk; + size_t gtk_len; + const u8 *mac_addr; + size_t mac_addr_len; +#ifdef CONFIG_PEERKEY + const u8 *smk; + size_t smk_len; + const u8 *nonce; + size_t nonce_len; + const u8 *lifetime; + size_t lifetime_len; + const u8 *error; + size_t error_len; +#endif /* CONFIG_PEERKEY */ +#ifdef CONFIG_IEEE80211W + const u8 *igtk; + size_t igtk_len; +#endif /* CONFIG_IEEE80211W */ +#ifdef CONFIG_IEEE80211R + const u8 *mdie; + size_t mdie_len; + const u8 *ftie; + size_t ftie_len; +#endif /* CONFIG_IEEE80211R */ +}; + +int wpa_parse_kde_ies(const u8 *buf, size_t len, + struct wpa_eapol_ie_parse *ie); +u8 * wpa_add_kde(u8 *pos, u32 kde, const u8 *data, size_t data_len, + const u8 *data2, size_t data2_len); +int wpa_auth_gen_wpa_ie(struct wpa_authenticator *wpa_auth); + +#endif /* WPA_AUTH_IE_H */ diff --git a/components/wpa_supplicant/include/wpa/wpa_common.h b/components/wpa_supplicant/include/wpa/wpa_common.h new file mode 100644 index 0000000000..480cf0e27e --- /dev/null +++ b/components/wpa_supplicant/include/wpa/wpa_common.h @@ -0,0 +1,332 @@ +/* + * WPA definitions shared between hostapd and wpa_supplicant + * Copyright (c) 2002-2008, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "os.h" +#ifndef WPA_COMMON_H +#define WPA_COMMON_H + +#define WPA_MAX_SSID_LEN 32 + +/* IEEE 802.11i */ +#define PMKID_LEN 16 +#define PMK_LEN 32 +#define WPA_REPLAY_COUNTER_LEN 8 +#define WPA_NONCE_LEN 32 +#define WPA_KEY_RSC_LEN 8 +#define WPA_GMK_LEN 32 +#define WPA_GTK_MAX_LEN 32 + +#define WPA_SELECTOR_LEN 4 +#define WPA_VERSION 1 +#define RSN_SELECTOR_LEN 4 +#define RSN_VERSION 1 + +#define RSN_SELECTOR(a, b, c, d) \ + ((((u32) (a)) << 24) | (((u32) (b)) << 16) | (((u32) (c)) << 8) | \ + (u32) (d)) + +#define WPA_AUTH_KEY_MGMT_NONE RSN_SELECTOR(0x00, 0x50, 0xf2, 0) +#define WPA_AUTH_KEY_MGMT_UNSPEC_802_1X RSN_SELECTOR(0x00, 0x50, 0xf2, 1) +#define WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X RSN_SELECTOR(0x00, 0x50, 0xf2, 2) +#define WPA_CIPHER_SUITE_NONE RSN_SELECTOR(0x00, 0x50, 0xf2, 0) +#define WPA_CIPHER_SUITE_WEP40 RSN_SELECTOR(0x00, 0x50, 0xf2, 1) +#define WPA_CIPHER_SUITE_TKIP RSN_SELECTOR(0x00, 0x50, 0xf2, 2) +#if 0 +#define WPA_CIPHER_SUITE_WRAP RSN_SELECTOR(0x00, 0x50, 0xf2, 3) +#endif +#define WPA_CIPHER_SUITE_CCMP RSN_SELECTOR(0x00, 0x50, 0xf2, 4) +#define WPA_CIPHER_SUITE_WEP104 RSN_SELECTOR(0x00, 0x50, 0xf2, 5) + + +#define RSN_AUTH_KEY_MGMT_UNSPEC_802_1X RSN_SELECTOR(0x00, 0x0f, 0xac, 1) +#define RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X RSN_SELECTOR(0x00, 0x0f, 0xac, 2) +#ifdef CONFIG_IEEE80211R +#define RSN_AUTH_KEY_MGMT_FT_802_1X RSN_SELECTOR(0x00, 0x0f, 0xac, 3) +#define RSN_AUTH_KEY_MGMT_FT_PSK RSN_SELECTOR(0x00, 0x0f, 0xac, 4) +#endif /* CONFIG_IEEE80211R */ +#define RSN_AUTH_KEY_MGMT_802_1X_SHA256 RSN_SELECTOR(0x00, 0x0f, 0xac, 5) +#define RSN_AUTH_KEY_MGMT_PSK_SHA256 RSN_SELECTOR(0x00, 0x0f, 0xac, 6) + +#define RSN_CIPHER_SUITE_NONE RSN_SELECTOR(0x00, 0x0f, 0xac, 0) +#define RSN_CIPHER_SUITE_WEP40 RSN_SELECTOR(0x00, 0x0f, 0xac, 1) +#define RSN_CIPHER_SUITE_TKIP RSN_SELECTOR(0x00, 0x0f, 0xac, 2) +#if 0 +#define RSN_CIPHER_SUITE_WRAP RSN_SELECTOR(0x00, 0x0f, 0xac, 3) +#endif +#define RSN_CIPHER_SUITE_CCMP RSN_SELECTOR(0x00, 0x0f, 0xac, 4) +#define RSN_CIPHER_SUITE_WEP104 RSN_SELECTOR(0x00, 0x0f, 0xac, 5) +#ifdef CONFIG_IEEE80211W +#define RSN_CIPHER_SUITE_AES_128_CMAC RSN_SELECTOR(0x00, 0x0f, 0xac, 6) +#endif /* CONFIG_IEEE80211W */ +#define RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED RSN_SELECTOR(0x00, 0x0f, 0xac, 7) +#define RSN_CIPHER_SUITE_GCMP RSN_SELECTOR(0x00, 0x0f, 0xac, 8) + +/* EAPOL-Key Key Data Encapsulation + * GroupKey and PeerKey require encryption, otherwise, encryption is optional. + */ +#define RSN_KEY_DATA_GROUPKEY RSN_SELECTOR(0x00, 0x0f, 0xac, 1) +#if 0 +#define RSN_KEY_DATA_STAKEY RSN_SELECTOR(0x00, 0x0f, 0xac, 2) +#endif +#define RSN_KEY_DATA_MAC_ADDR RSN_SELECTOR(0x00, 0x0f, 0xac, 3) +#define RSN_KEY_DATA_PMKID RSN_SELECTOR(0x00, 0x0f, 0xac, 4) +#ifdef CONFIG_PEERKEY +#define RSN_KEY_DATA_SMK RSN_SELECTOR(0x00, 0x0f, 0xac, 5) +#define RSN_KEY_DATA_NONCE RSN_SELECTOR(0x00, 0x0f, 0xac, 6) +#define RSN_KEY_DATA_LIFETIME RSN_SELECTOR(0x00, 0x0f, 0xac, 7) +#define RSN_KEY_DATA_ERROR RSN_SELECTOR(0x00, 0x0f, 0xac, 8) +#endif /* CONFIG_PEERKEY */ +#ifdef CONFIG_IEEE80211W +#define RSN_KEY_DATA_IGTK RSN_SELECTOR(0x00, 0x0f, 0xac, 9) +#endif /* CONFIG_IEEE80211W */ + +#define WPA_OUI_TYPE RSN_SELECTOR(0x00, 0x50, 0xf2, 1) + +#define RSN_SELECTOR_PUT(a, val) WPA_PUT_BE32((u8 *) (a), (val)) +#define RSN_SELECTOR_GET(a) WPA_GET_BE32((const u8 *) (a)) + +#define RSN_NUM_REPLAY_COUNTERS_1 0 +#define RSN_NUM_REPLAY_COUNTERS_2 1 +#define RSN_NUM_REPLAY_COUNTERS_4 2 +#define RSN_NUM_REPLAY_COUNTERS_16 3 + +#ifdef _MSC_VER +#pragma pack(push, 1) +#endif /* _MSC_VER */ + +#ifdef CONFIG_IEEE80211W +#define WPA_IGTK_LEN 16 +#endif /* CONFIG_IEEE80211W */ + + +/* IEEE 802.11, 7.3.2.25.3 RSN Capabilities */ +#define WPA_CAPABILITY_PREAUTH BIT(0) +#define WPA_CAPABILITY_NO_PAIRWISE BIT(1) +/* B2-B3: PTKSA Replay Counter */ +/* B4-B5: GTKSA Replay Counter */ +#define WPA_CAPABILITY_MFPR BIT(6) +#define WPA_CAPABILITY_MFPC BIT(7) +#define WPA_CAPABILITY_PEERKEY_ENABLED BIT(9) + + +/* IEEE 802.11r */ +#define MOBILITY_DOMAIN_ID_LEN 2 +#define FT_R0KH_ID_MAX_LEN 48 +#define FT_R1KH_ID_LEN 6 +#define WPA_PMK_NAME_LEN 16 + + +/* IEEE 802.11, 8.5.2 EAPOL-Key frames */ +#define WPA_KEY_INFO_TYPE_MASK ((u16) (BIT(0) | BIT(1) | BIT(2))) +#define WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 BIT(0) +#define WPA_KEY_INFO_TYPE_HMAC_SHA1_AES BIT(1) +#define WPA_KEY_INFO_TYPE_AES_128_CMAC 3 +#define WPA_KEY_INFO_KEY_TYPE BIT(3) /* 1 = Pairwise, 0 = Group key */ +/* bit4..5 is used in WPA, but is reserved in IEEE 802.11i/RSN */ +#define WPA_KEY_INFO_KEY_INDEX_MASK (BIT(4) | BIT(5)) +#define WPA_KEY_INFO_KEY_INDEX_SHIFT 4 +#define WPA_KEY_INFO_INSTALL BIT(6) /* pairwise */ +#define WPA_KEY_INFO_TXRX BIT(6) /* group */ +#define WPA_KEY_INFO_ACK BIT(7) +#define WPA_KEY_INFO_MIC BIT(8) +#define WPA_KEY_INFO_SECURE BIT(9) +#define WPA_KEY_INFO_ERROR BIT(10) +#define WPA_KEY_INFO_REQUEST BIT(11) +#define WPA_KEY_INFO_ENCR_KEY_DATA BIT(12) /* IEEE 802.11i/RSN only */ +#define WPA_KEY_INFO_SMK_MESSAGE BIT(13) + + +struct wpa_eapol_key { + u8 type; + /* Note: key_info, key_length, and key_data_length are unaligned */ + u8 key_info[2]; /* big endian */ + u8 key_length[2]; /* big endian */ + u8 replay_counter[WPA_REPLAY_COUNTER_LEN]; + u8 key_nonce[WPA_NONCE_LEN]; + u8 key_iv[16]; + u8 key_rsc[WPA_KEY_RSC_LEN]; + u8 key_id[8]; /* Reserved in IEEE 802.11i/RSN */ + u8 key_mic[16]; + u8 key_data_length[2]; /* big endian */ + /* followed by key_data_length bytes of key_data */ +} STRUCT_PACKED; + +/** + * struct wpa_ptk - WPA Pairwise Transient Key + * IEEE Std 802.11i-2004 - 8.5.1.2 Pairwise key hierarchy + */ +struct wpa_ptk { + u8 kck[16]; /* EAPOL-Key Key Confirmation Key (KCK) */ + u8 kek[16]; /* EAPOL-Key Key Encryption Key (KEK) */ + u8 tk1[16]; /* Temporal Key 1 (TK1) */ + union { + u8 tk2[16]; /* Temporal Key 2 (TK2) */ + struct { + u8 tx_mic_key[8]; + u8 rx_mic_key[8]; + } auth; + } u; +} STRUCT_PACKED; + +struct wpa_gtk_data { + enum wpa_alg alg; + int tx, key_rsc_len, keyidx; + u8 gtk[32]; + int gtk_len; +}; + + +/* WPA IE version 1 + * 00-50-f2:1 (OUI:OUI type) + * 0x01 0x00 (version; little endian) + * (all following fields are optional:) + * Group Suite Selector (4 octets) (default: TKIP) + * Pairwise Suite Count (2 octets, little endian) (default: 1) + * Pairwise Suite List (4 * n octets) (default: TKIP) + * Authenticated Key Management Suite Count (2 octets, little endian) + * (default: 1) + * Authenticated Key Management Suite List (4 * n octets) + * (default: unspec 802.1X) + * WPA Capabilities (2 octets, little endian) (default: 0) + */ + +struct wpa_ie_hdr { + u8 elem_id; + u8 len; + u8 oui[4]; /* 24-bit OUI followed by 8-bit OUI type */ + u8 version[2]; /* little endian */ +} STRUCT_PACKED; + + +/* 1/4: PMKID + * 2/4: RSN IE + * 3/4: one or two RSN IEs + GTK IE (encrypted) + * 4/4: empty + * 1/2: GTK IE (encrypted) + * 2/2: empty + */ + +/* RSN IE version 1 + * 0x01 0x00 (version; little endian) + * (all following fields are optional:) + * Group Suite Selector (4 octets) (default: CCMP) + * Pairwise Suite Count (2 octets, little endian) (default: 1) + * Pairwise Suite List (4 * n octets) (default: CCMP) + * Authenticated Key Management Suite Count (2 octets, little endian) + * (default: 1) + * Authenticated Key Management Suite List (4 * n octets) + * (default: unspec 802.1X) + * RSN Capabilities (2 octets, little endian) (default: 0) + * PMKID Count (2 octets) (default: 0) + * PMKID List (16 * n octets) + * Management Group Cipher Suite (4 octets) (default: AES-128-CMAC) + */ + +struct rsn_ie_hdr { + u8 elem_id; /* WLAN_EID_RSN */ + u8 len; + u8 version[2]; /* little endian */ +} STRUCT_PACKED; + + +#ifdef CONFIG_PEERKEY +enum { + STK_MUI_4WAY_STA_AP = 1, + STK_MUI_4WAY_STAT_STA = 2, + STK_MUI_GTK = 3, + STK_MUI_SMK = 4 +}; + +enum { + STK_ERR_STA_NR = 1, + STK_ERR_STA_NRSN = 2, + STK_ERR_CPHR_NS = 3, + STK_ERR_NO_STSL = 4 +}; +#endif /* CONFIG_PEERKEY */ + +struct rsn_error_kde { + be16 mui; + be16 error_type; +} STRUCT_PACKED; + +#ifdef CONFIG_IEEE80211W +struct wpa_igtk_kde { + u8 keyid[2]; + u8 pn[6]; + u8 igtk[WPA_IGTK_LEN]; +} STRUCT_PACKED; +#endif /* CONFIG_IEEE80211W */ + +#ifdef CONFIG_IEEE80211R +struct rsn_mdie { + u8 mobility_domain[MOBILITY_DOMAIN_ID_LEN]; + u8 ft_capab; +} STRUCT_PACKED; + +#define RSN_FT_CAPAB_FT_OVER_DS BIT(0) +#define RSN_FT_CAPAB_FT_RESOURCE_REQ_SUPP BIT(1) + +struct rsn_ftie { + u8 mic_control[2]; + u8 mic[16]; + u8 anonce[WPA_NONCE_LEN]; + u8 snonce[WPA_NONCE_LEN]; + /* followed by optional parameters */ +} STRUCT_PACKED; + +#define FTIE_SUBELEM_R1KH_ID 1 +#define FTIE_SUBELEM_GTK 2 +#define FTIE_SUBELEM_R0KH_ID 3 +#define FTIE_SUBELEM_IGTK 4 + +struct rsn_rdie { + u8 id; + u8 descr_count; + le16 status_code; +} STRUCT_PACKED; + +#endif /* CONFIG_IEEE80211R */ + +struct wpa_ie_data { + int proto; + int pairwise_cipher; + int group_cipher; + int key_mgmt; + int capabilities; + size_t num_pmkid; + const u8 *pmkid; + int mgmt_group_cipher; +}; + +const char * wpa_cipher_txt(int cipher); + +int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len, + struct wpa_ie_data *data); + +int wpa_eapol_key_mic(const u8 *key, int ver, const u8 *buf, size_t len, + u8 *mic); +int wpa_compare_rsn_ie(int ft_initial_assoc, + const u8 *ie1, size_t ie1len, + const u8 *ie2, size_t ie2len); + +void wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label, + const u8 *addr1, const u8 *addr2, + const u8 *nonce1, const u8 *nonce2, + u8 *ptk, size_t ptk_len, int use_sha256); + +void rsn_pmkid(const u8 *pmk, size_t pmk_len, const u8 *aa, const u8 *spa, + u8 *pmkid, int use_sha256); + +#endif /* WPA_COMMON_H */ diff --git a/components/wpa_supplicant/include/wpa/wpa_debug.h b/components/wpa_supplicant/include/wpa/wpa_debug.h new file mode 100644 index 0000000000..b78a657e05 --- /dev/null +++ b/components/wpa_supplicant/include/wpa/wpa_debug.h @@ -0,0 +1,193 @@ +/* + * wpa_supplicant/hostapd / Debug prints + * Copyright (c) 2002-2007, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef WPA_DEBUG_H +#define WPA_DEBUG_H + + +enum { MSG_MSGDUMP, MSG_DEBUG, MSG_INFO, MSG_WARNING, MSG_ERROR }; + +/** EAP authentication completed successfully */ +#define WPA_EVENT_EAP_SUCCESS "CTRL-EVENT-EAP-SUCCESS " + +int wpa_debug_open_file(const char *path); +void wpa_debug_close_file(void); + +/** + * wpa_debug_printf_timestamp - Print timestamp for debug output + * + * This function prints a timestamp in seconds_from_1970.microsoconds + * format if debug output has been configured to include timestamps in debug + * messages. + */ +void wpa_debug_print_timestamp(void); + +/** + * wpa_printf - conditional printf + * @level: priority level (MSG_*) of the message + * @fmt: printf format string, followed by optional arguments + * + * This function is used to print conditional debugging and error messages. The + * output may be directed to stdout, stderr, and/or syslog based on + * configuration. + * + * Note: New line '\n' is added to the end of the text when printing to stdout. + */ +//#define DEBUG_PRINT +//#define MSG_PRINT + +/** + * wpa_hexdump - conditional hex dump + * @level: priority level (MSG_*) of the message + * @title: title of for the message + * @buf: data buffer to be dumped + * @len: length of the buf + * + * This function is used to print conditional debugging and error messages. The + * output may be directed to stdout, stderr, and/or syslog based on + * configuration. The contents of buf is printed out has hex dump. + */ +#ifdef DEBUG_PRINT +#define wpa_printf(level,fmt, args...) ets_printf(fmt,## args) + +static inline void wpa_hexdump_ascii(int level, const char *title, const u8 *buf, size_t len) +{ + +} + +static inline void wpa_hexdump_ascii_key(int level, const char *title, const u8 *buf, size_t len) +{ +} + + +void wpa_hexdump(int level, const char *title, const u8 *buf, size_t len); + +static inline void wpa_hexdump_buf(int level, const char *title, + const struct wpabuf *buf) +{ + wpa_hexdump(level, title, wpabuf_head(buf), wpabuf_len(buf)); +} + +/** + * wpa_hexdump_key - conditional hex dump, hide keys + * @level: priority level (MSG_*) of the message + * @title: title of for the message + * @buf: data buffer to be dumped + * @len: length of the buf + * + * This function is used to print conditional debugging and error messages. The + * output may be directed to stdout, stderr, and/or syslog based on + * configuration. The contents of buf is printed out has hex dump. This works + * like wpa_hexdump(), but by default, does not include secret keys (passwords, + * etc.) in debug output. + */ +void wpa_hexdump_key(int level, const char *title, const u8 *buf, size_t len); + + +static inline void wpa_hexdump_buf_key(int level, const char *title, + const struct wpabuf *buf) +{ + wpa_hexdump_key(level, title, wpabuf_head(buf), wpabuf_len(buf)); +} + +/** + * wpa_hexdump_ascii - conditional hex dump + * @level: priority level (MSG_*) of the message + * @title: title of for the message + * @buf: data buffer to be dumped + * @len: length of the buf + * + * This function is used to print conditional debugging and error messages. The + * output may be directed to stdout, stderr, and/or syslog based on + * configuration. The contents of buf is printed out has hex dump with both + * the hex numbers and ASCII characters (for printable range) are shown. 16 + * bytes per line will be shown. + */ +void wpa_hexdump_ascii(int level, const char *title, const u8 *buf, + size_t len); + +/** + * wpa_hexdump_ascii_key - conditional hex dump, hide keys + * @level: priority level (MSG_*) of the message + * @title: title of for the message + * @buf: data buffer to be dumped + * @len: length of the buf + * + * This function is used to print conditional debugging and error messages. The + * output may be directed to stdout, stderr, and/or syslog based on + * configuration. The contents of buf is printed out has hex dump with both + * the hex numbers and ASCII characters (for printable range) are shown. 16 + * bytes per line will be shown. This works like wpa_hexdump_ascii(), but by + * default, does not include secret keys (passwords, etc.) in debug output. + */ +void wpa_hexdump_ascii_key(int level, const char *title, const u8 *buf, + size_t len); +#else +#define wpa_printf(level,fmt, args...) +#define wpa_hexdump(...) +#define wpa_hexdump_buf(...) +#define wpa_hexdump_key(...) +#define wpa_hexdump_buf_key(...) +#define wpa_hexdump_ascii(...) +#define wpa_hexdump_ascii_key(...) +#endif + +#define wpa_auth_logger +#define wpa_auth_vlogger + +/** + * wpa_msg - Conditional printf for default target and ctrl_iface monitors + * @ctx: Pointer to context data; this is the ctx variable registered + * with struct wpa_driver_ops::init() + * @level: priority level (MSG_*) of the message + * @fmt: printf format string, followed by optional arguments + * + * This function is used to print conditional debugging and error messages. The + * output may be directed to stdout, stderr, and/or syslog based on + * configuration. This function is like wpa_printf(), but it also sends the + * same message to all attached ctrl_iface monitors. + * + * Note: New line '\n' is added to the end of the text when printing to stdout. + */ +void wpa_msg(void *ctx, int level, const char *fmt, ...) PRINTF_FORMAT(3, 4); + +/** + * wpa_msg_ctrl - Conditional printf for ctrl_iface monitors + * @ctx: Pointer to context data; this is the ctx variable registered + * with struct wpa_driver_ops::init() + * @level: priority level (MSG_*) of the message + * @fmt: printf format string, followed by optional arguments + * + * This function is used to print conditional debugging and error messages. + * This function is like wpa_msg(), but it sends the output only to the + * attached ctrl_iface monitors. In other words, it can be used for frequent + * events that do not need to be sent to syslog. + */ +void wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...) +PRINTF_FORMAT(3, 4); + +typedef void (*wpa_msg_cb_func)(void *ctx, int level, const char *txt, + size_t len); + +typedef void (*eloop_timeout_handler)(void *eloop_data, void *user_ctx); + +int eloop_cancel_timeout(eloop_timeout_handler handler, + void *eloop_data, void *user_data); + +int eloop_register_timeout(unsigned int secs, unsigned int usecs, + eloop_timeout_handler handler, + void *eloop_data, void *user_data); + + +#endif /* WPA_DEBUG_H */ diff --git a/components/wpa_supplicant/include/wpa/wpa_i.h b/components/wpa_supplicant/include/wpa/wpa_i.h new file mode 100644 index 0000000000..a43c33d332 --- /dev/null +++ b/components/wpa_supplicant/include/wpa/wpa_i.h @@ -0,0 +1,89 @@ +/* + * Internal WPA/RSN supplicant state machine definitions + * Copyright (c) 2004-2010, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef WPA_I_H +#define WPA_I_H + +/** + * set_key - Configure encryption key + * @ifname: Interface name (for multi-SSID/VLAN support) + * @priv: private driver interface data + * @alg: encryption algorithm (%WPA_ALG_NONE, %WPA_ALG_WEP, + * %WPA_ALG_TKIP, %WPA_ALG_CCMP, %WPA_ALG_IGTK, %WPA_ALG_PMK); + * %WPA_ALG_NONE clears the key. + * @addr: address of the peer STA or ff:ff:ff:ff:ff:ff for + * broadcast/default keys + * @key_idx: key index (0..3), usually 0 for unicast keys; 0..4095 for + * IGTK + * @set_tx: configure this key as the default Tx key (only used when + * driver does not support separate unicast/individual key + * @seq: sequence number/packet number, seq_len octets, the next + * packet number to be used for in replay protection; configured + * for Rx keys (in most cases, this is only used with broadcast + * keys and set to zero for unicast keys) + * @seq_len: length of the seq, depends on the algorithm: + * TKIP: 6 octets, CCMP: 6 octets, IGTK: 6 octets + * @key: key buffer; TKIP: 16-byte temporal key, 8-byte Tx Mic key, + * 8-byte Rx Mic Key + * @key_len: length of the key buffer in octets (WEP: 5 or 13, + * TKIP: 32, CCMP: 16, IGTK: 16) + * + * Returns: 0 on success, -1 on failure + * + * Configure the given key for the kernel driver. If the driver + * supports separate individual keys (4 default keys + 1 individual), + * addr can be used to determine whether the key is default or + * individual. If only 4 keys are supported, the default key with key + * index 0 is used as the individual key. STA must be configured to use + * it as the default Tx key (set_tx is set) and accept Rx for all the + * key indexes. In most cases, WPA uses only key indexes 1 and 2 for + * broadcast keys, so key index 0 is available for this kind of + * configuration. + * + * Please note that TKIP keys include separate TX and RX MIC keys and + * some drivers may expect them in different order than wpa_supplicant + * is using. If the TX/RX keys are swapped, all TKIP encrypted packets + * will tricker Michael MIC errors. This can be fixed by changing the + * order of MIC keys by swapping te bytes 16..23 and 24..31 of the key + * in driver_*.c set_key() implementation, see driver_ndis.c for an + * example on how this can be done. + */ + +typedef void (* WPA_SEND_FUNC)(struct pbuf *pb); + +typedef void (* WPA_SET_ASSOC_IE)(uint8 proto, u8 *assoc_buf, u32 assoc_wpa_ie_len); + +typedef void (*WPA_INSTALL_KEY) (enum wpa_alg alg, uint8 *addr, int key_idx, int set_tx, + uint8 *seq, size_t seq_len, uint8 *key, size_t key_len, int key_entry_valid); + +typedef void (*WPA_DEAUTH)(uint8 reason_code); + +typedef void (*WPA_NEG_COMPLETE)(); + +void wpa_register(char * payload, WPA_SEND_FUNC snd_func, \ + WPA_SET_ASSOC_IE set_assoc_ie_func, \ + WPA_INSTALL_KEY ppinstallkey, \ + WPA_DEAUTH wpa_deauth, \ + WPA_NEG_COMPLETE wpa_neg_complete); + +#include "pp/esf_buf.h" +void eapol_txcb(esf_buf_t *eb); + +void wpa_set_profile(uint32 wpa_proto); + +void wpa_set_bss(char *macddr, char * bssid, uint8 pairwise_cipher, uint8 group_cipher, char *passphrase, u8 *ssid, size_t ssid_len); + +int wpa_sm_rx_eapol(u8 *src_addr, u8 *buf, u32 len); +#endif /* WPA_I_H */ + diff --git a/components/wpa_supplicant/include/wpa/wpa_ie.h b/components/wpa_supplicant/include/wpa/wpa_ie.h new file mode 100644 index 0000000000..94518d8457 --- /dev/null +++ b/components/wpa_supplicant/include/wpa/wpa_ie.h @@ -0,0 +1,56 @@ +/* + * wpa_supplicant - WPA/RSN IE and KDE definitions + * Copyright (c) 2004-2007, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef WPA_IE_H +#define WPA_IE_H + +struct wpa_eapol_ie_parse { + const u8 *wpa_ie; + size_t wpa_ie_len; + const u8 *rsn_ie; + size_t rsn_ie_len; + const u8 *pmkid; + const u8 *gtk; + size_t gtk_len; + const u8 *mac_addr; + size_t mac_addr_len; +#ifdef CONFIG_PEERKEY + const u8 *smk; + size_t smk_len; + const u8 *nonce; + size_t nonce_len; + const u8 *lifetime; + size_t lifetime_len; + const u8 *error; + size_t error_len; +#endif /* CONFIG_PEERKEY */ +#ifdef CONFIG_IEEE80211W + const u8 *igtk; + size_t igtk_len; +#endif /* CONFIG_IEEE80211W */ +#ifdef CONFIG_IEEE80211R + const u8 *mdie; + size_t mdie_len; + const u8 *ftie; + size_t ftie_len; + const u8 *reassoc_deadline; + const u8 *key_lifetime; +#endif /* CONFIG_IEEE80211R */ +}; + +int wpa_supplicant_parse_ies(const u8 *buf, size_t len, + struct wpa_eapol_ie_parse *ie); +int wpa_gen_wpa_ie(struct wpa_sm *sm, u8 *wpa_ie, size_t wpa_ie_len); + +#endif /* WPA_IE_H */ diff --git a/components/wpa_supplicant/include/wpa/wpabuf.h b/components/wpa_supplicant/include/wpa/wpabuf.h new file mode 100644 index 0000000000..cccfcc80ef --- /dev/null +++ b/components/wpa_supplicant/include/wpa/wpabuf.h @@ -0,0 +1,168 @@ +/* + * Dynamic data buffer + * Copyright (c) 2007-2009, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef WPABUF_H +#define WPABUF_H + +/* + * Internal data structure for wpabuf. Please do not touch this directly from + * elsewhere. This is only defined in header file to allow inline functions + * from this file to access data. + */ +struct wpabuf { + size_t size; /* total size of the allocated buffer */ + size_t used; /* length of data in the buffer */ + u8 *ext_data; /* pointer to external data; NULL if data follows + * struct wpabuf */ + /* optionally followed by the allocated buffer */ +}; + + +int wpabuf_resize(struct wpabuf **buf, size_t add_len); +struct wpabuf * wpabuf_alloc(size_t len); +struct wpabuf * wpabuf_alloc_ext_data(u8 *data, size_t len); +struct wpabuf * wpabuf_alloc_copy(const void *data, size_t len); +struct wpabuf * wpabuf_dup(const struct wpabuf *src); +void wpabuf_free(struct wpabuf *buf); +void * wpabuf_put(struct wpabuf *buf, size_t len); +struct wpabuf * wpabuf_concat(struct wpabuf *a, struct wpabuf *b); +struct wpabuf * wpabuf_zeropad(struct wpabuf *buf, size_t len); +void wpabuf_printf(struct wpabuf *buf, char *fmt, ...) PRINTF_FORMAT(2, 3); + + +/** + * wpabuf_size - Get the currently allocated size of a wpabuf buffer + * @buf: wpabuf buffer + * Returns: Currently allocated size of the buffer + */ +static inline size_t wpabuf_size(const struct wpabuf *buf) +{ + return buf->size; +} + +/** + * wpabuf_len - Get the current length of a wpabuf buffer data + * @buf: wpabuf buffer + * Returns: Currently used length of the buffer + */ +static inline size_t wpabuf_len(const struct wpabuf *buf) +{ + return buf->used; +} + +/** + * wpabuf_tailroom - Get size of available tail room in the end of the buffer + * @buf: wpabuf buffer + * Returns: Tail room (in bytes) of available space in the end of the buffer + */ +static inline size_t wpabuf_tailroom(const struct wpabuf *buf) +{ + return buf->size - buf->used; +} + +/** + * wpabuf_head - Get pointer to the head of the buffer data + * @buf: wpabuf buffer + * Returns: Pointer to the head of the buffer data + */ +static inline const void * wpabuf_head(const struct wpabuf *buf) +{ + if (buf->ext_data) + return buf->ext_data; + return buf + 1; +} + +static inline const u8 * wpabuf_head_u8(const struct wpabuf *buf) +{ + return wpabuf_head(buf); +} + +/** + * wpabuf_mhead - Get modifiable pointer to the head of the buffer data + * @buf: wpabuf buffer + * Returns: Pointer to the head of the buffer data + */ +static inline void * wpabuf_mhead(struct wpabuf *buf) +{ + if (buf->ext_data) + return buf->ext_data; + return buf + 1; +} + +static inline u8 * wpabuf_mhead_u8(struct wpabuf *buf) +{ + return wpabuf_mhead(buf); +} + +static inline void wpabuf_put_u8(struct wpabuf *buf, u8 data) +{ + u8 *pos = wpabuf_put(buf, 1); + *pos = data; +} + +static inline void wpabuf_put_le16(struct wpabuf *buf, u16 data) +{ + u8 *pos = wpabuf_put(buf, 2); + WPA_PUT_LE16(pos, data); +} + +static inline void wpabuf_put_le32(struct wpabuf *buf, u32 data) +{ + u8 *pos = wpabuf_put(buf, 4); + WPA_PUT_LE32(pos, data); +} + +static inline void wpabuf_put_be16(struct wpabuf *buf, u16 data) +{ + u8 *pos = wpabuf_put(buf, 2); + WPA_PUT_BE16(pos, data); +} + +static inline void wpabuf_put_be24(struct wpabuf *buf, u32 data) +{ + u8 *pos = wpabuf_put(buf, 3); + WPA_PUT_BE24(pos, data); +} + +static inline void wpabuf_put_be32(struct wpabuf *buf, u32 data) +{ + u8 *pos = wpabuf_put(buf, 4); + WPA_PUT_BE32(pos, data); +} + +static inline void wpabuf_put_data(struct wpabuf *buf, const void *data, + size_t len) +{ + if (data) + os_memcpy(wpabuf_put(buf, len), data, len); +} + +static inline void wpabuf_put_buf(struct wpabuf *dst, + const struct wpabuf *src) +{ + wpabuf_put_data(dst, wpabuf_head(src), wpabuf_len(src)); +} + +static inline void wpabuf_set(struct wpabuf *buf, const void *data, size_t len) +{ + buf->ext_data = (u8 *) data; + buf->size = buf->used = len; +} + +static inline void wpabuf_put_str(struct wpabuf *dst, const char *str) +{ + wpabuf_put_data(dst, str, os_strlen(str)); +} + +#endif /* WPABUF_H */ diff --git a/components/wpa_supplicant/include/wpa/wpas_glue.h b/components/wpa_supplicant/include/wpa/wpas_glue.h new file mode 100644 index 0000000000..7e254a2d7d --- /dev/null +++ b/components/wpa_supplicant/include/wpa/wpas_glue.h @@ -0,0 +1,31 @@ +/* + * WPA Supplicant - Glue code to setup EAPOL and RSN modules + * Copyright (c) 2003-2008, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef WPAS_GLUE_H +#define WPAS_GLUE_H + +u8 * wpa_sm_alloc_eapol(struct wpa_sm *sm, u8 type, + const void *data, u16 data_len, + size_t *msg_len, void **data_pos); + +int wpa_sm_mlme_setprotection(struct wpa_sm *sm, const u8 *addr, + int protect_type, int key_type); + +void wpa_sm_deauthenticate(struct wpa_sm *sm, uint8 reason_code); + +void wpa_sm_disassociate(struct wpa_sm *sm, int reason_code); + +int wpa_sm_get_beacon_ie(struct wpa_sm *sm); + +#endif /* WPAS_GLUE_H */ diff --git a/components/wpa_supplicant/include/wpa2/eap_peer/eap.h b/components/wpa_supplicant/include/wpa2/eap_peer/eap.h new file mode 100644 index 0000000000..e2cd2dd81d --- /dev/null +++ b/components/wpa_supplicant/include/wpa2/eap_peer/eap.h @@ -0,0 +1,24 @@ +/* + * EAP peer state machine functions (RFC 4137) + * Copyright (c) 2004-2012, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef EAP_H +#define EAP_H + +#include "wpa/defs.h" +#include "eap/eap_defs.h" + +struct eap_sm; + +struct eap_method_type { + int vendor; + u32 method; +}; + +const u8 * eap_get_eapKeyData(struct eap_sm *sm, size_t *len); + +#endif /* EAP_H */ diff --git a/components/wpa_supplicant/include/wpa2/eap_peer/eap_common.h b/components/wpa_supplicant/include/wpa2/eap_peer/eap_common.h new file mode 100644 index 0000000000..38c5710058 --- /dev/null +++ b/components/wpa_supplicant/include/wpa2/eap_peer/eap_common.h @@ -0,0 +1,23 @@ +/* + * EAP common peer/server definitions + * Copyright (c) 2004-2012, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef EAP_COMMON_H +#define EAP_COMMON_H + +#include "wpa/wpabuf.h" + +int eap_hdr_len_valid(const struct wpabuf *msg, size_t min_payload); +const u8 * eap_hdr_validate(int vendor, EapType eap_type, + const struct wpabuf *msg, size_t *plen); +struct wpabuf * eap_msg_alloc(int vendor, EapType type, size_t payload_len, + u8 code, u8 identifier); +void eap_update_len(struct wpabuf *msg); +u8 eap_get_id(const struct wpabuf *msg); +EapType eap_get_type(const struct wpabuf *msg); + +#endif /* EAP_COMMON_H */ diff --git a/components/wpa_supplicant/include/wpa2/eap_peer/eap_config.h b/components/wpa_supplicant/include/wpa2/eap_peer/eap_config.h new file mode 100644 index 0000000000..f35cbf43d7 --- /dev/null +++ b/components/wpa_supplicant/include/wpa2/eap_peer/eap_config.h @@ -0,0 +1,220 @@ +/* + * EAP peer configuration data + * Copyright (c) 2003-2013, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef EAP_CONFIG_H +#define EAP_CONFIG_H + +/** + * struct eap_peer_config - EAP peer configuration/credentials + */ +struct eap_peer_config { + /** + * identity - EAP Identity + * + * This field is used to set the real user identity or NAI (for + * EAP-PSK/PAX/SAKE/GPSK). + */ + u8 *identity; + + /** + * identity_len - EAP Identity length + */ + size_t identity_len; + + /** + * password - Password string for EAP + * + * This field can include either the plaintext password (default + * option) or a NtPasswordHash (16-byte MD4 hash of the unicode + * presentation of the password) if flags field has + * EAP_CONFIG_FLAGS_PASSWORD_NTHASH bit set to 1. NtPasswordHash can + * only be used with authentication mechanism that use this hash as the + * starting point for operation: MSCHAP and MSCHAPv2 (EAP-MSCHAPv2, + * EAP-TTLS/MSCHAPv2, EAP-TTLS/MSCHAP, LEAP). + * + * In addition, this field is used to configure a pre-shared key for + * EAP-PSK/PAX/SAKE/GPSK. The length of the PSK must be 16 for EAP-PSK + * and EAP-PAX and 32 for EAP-SAKE. EAP-GPSK can use a variable length + * PSK. + */ + u8 *password; + + /** + * password_len - Length of password field + */ + size_t password_len; + + /** + * ca_cert - File path to CA certificate file (PEM/DER) + * + * This file can have one or more trusted CA certificates. If ca_cert + * and ca_path are not included, server certificate will not be + * verified. This is insecure and a trusted CA certificate should + * always be configured when using EAP-TLS/TTLS/PEAP. Full path to the + * file should be used since working directory may change when + * wpa_supplicant is run in the background. + * + * Alternatively, a named configuration blob can be used by setting + * this to blob://blob_name. + * + * Alternatively, this can be used to only perform matching of the + * server certificate (SHA-256 hash of the DER encoded X.509 + * certificate). In this case, the possible CA certificates in the + * server certificate chain are ignored and only the server certificate + * is verified. This is configured with the following format: + * hash:://server/sha256/cert_hash_in_hex + * For example: "hash://server/sha256/ + * 5a1bc1296205e6fdbe3979728efe3920798885c1c4590b5f90f43222d239ca6a" + * + * On Windows, trusted CA certificates can be loaded from the system + * certificate store by setting this to cert_store://name, e.g., + * ca_cert="cert_store://CA" or ca_cert="cert_store://ROOT". + * Note that when running wpa_supplicant as an application, the user + * certificate store (My user account) is used, whereas computer store + * (Computer account) is used when running wpasvc as a service. + */ + u8 *ca_cert; + + /** + * ca_path - Directory path for CA certificate files (PEM) + * + * This path may contain multiple CA certificates in OpenSSL format. + * Common use for this is to point to system trusted CA list which is + * often installed into directory like /etc/ssl/certs. If configured, + * these certificates are added to the list of trusted CAs. ca_cert + * may also be included in that case, but it is not required. + */ + u8 *ca_path; + + /** + * client_cert - File path to client certificate file (PEM/DER) + * + * This field is used with EAP method that use TLS authentication. + * Usually, this is only configured for EAP-TLS, even though this could + * in theory be used with EAP-TTLS and EAP-PEAP, too. Full path to the + * file should be used since working directory may change when + * wpa_supplicant is run in the background. + * + * Alternatively, a named configuration blob can be used by setting + * this to blob://blob_name. + */ + u8 *client_cert; + + /** + * private_key - File path to client private key file (PEM/DER/PFX) + * + * When PKCS#12/PFX file (.p12/.pfx) is used, client_cert should be + * commented out. Both the private key and certificate will be read + * from the PKCS#12 file in this case. Full path to the file should be + * used since working directory may change when wpa_supplicant is run + * in the background. + * + * Windows certificate store can be used by leaving client_cert out and + * configuring private_key in one of the following formats: + * + * cert://substring_to_match + * + * hash://certificate_thumbprint_in_hex + * + * For example: private_key="hash://63093aa9c47f56ae88334c7b65a4" + * + * Note that when running wpa_supplicant as an application, the user + * certificate store (My user account) is used, whereas computer store + * (Computer account) is used when running wpasvc as a service. + * + * Alternatively, a named configuration blob can be used by setting + * this to blob://blob_name. + */ + u8 *private_key; + + /** + * private_key_passwd - Password for private key file + * + * If left out, this will be asked through control interface. + */ + u8 *private_key_passwd; + + char *phase1; + + /** + * pin - PIN for USIM, GSM SIM, and smartcards + * + * This field is used to configure PIN for SIM and smartcards for + * EAP-SIM and EAP-AKA. In addition, this is used with EAP-TLS if a + * smartcard is used for private key operations. + * + * If left out, this will be asked through control interface. + */ + char *pin; + + /** + * fragment_size - Maximum EAP fragment size in bytes (default 1398) + * + * This value limits the fragment size for EAP methods that support + * fragmentation (e.g., EAP-TLS and EAP-PEAP). This value should be set + * small enough to make the EAP messages fit in MTU of the network + * interface used for EAPOL. The default value is suitable for most + * cases. + */ + int fragment_size; + +#define EAP_CONFIG_FLAGS_PASSWORD_NTHASH BIT(0) +#define EAP_CONFIG_FLAGS_EXT_PASSWORD BIT(1) + /** + * flags - Network configuration flags (bitfield) + * + * This variable is used for internal flags to describe further details + * for the network parameters. + * bit 0 = password is represented as a 16-byte NtPasswordHash value + * instead of plaintext password + * bit 1 = password is stored in external storage; the value in the + * password field is the name of that external entry + */ + u32 flags; + + /** + * ocsp - Whether to use/require OCSP to check server certificate + * + * 0 = do not use OCSP stapling (TLS certificate status extension) + * 1 = try to use OCSP stapling, but not require response + * 2 = require valid OCSP stapling response + */ + int ocsp; +}; + + +/** + * struct wpa_config_blob - Named configuration blob + * + * This data structure is used to provide storage for binary objects to store + * abstract information like certificates and private keys inlined with the + * configuration data. + */ +struct wpa_config_blob { + /** + * name - Blob name + */ + char *name; + + /** + * data - Pointer to binary data + */ + u8 *data; + + /** + * len - Length of binary data + */ + size_t len; + + /** + * next - Pointer to next blob in the configuration + */ + struct wpa_config_blob *next; +}; + +#endif /* EAP_CONFIG_H */ diff --git a/components/wpa_supplicant/include/wpa2/eap_peer/eap_defs.h b/components/wpa_supplicant/include/wpa2/eap_peer/eap_defs.h new file mode 100644 index 0000000000..10995d3868 --- /dev/null +++ b/components/wpa_supplicant/include/wpa2/eap_peer/eap_defs.h @@ -0,0 +1,92 @@ +/* + * EAP server/peer: Shared EAP definitions + * Copyright (c) 2004-2007, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef EAP_DEFS_H +#define EAP_DEFS_H + +/* RFC 3748 - Extensible Authentication Protocol (EAP) */ + +#ifdef _MSC_VER +#pragma pack(push, 1) +#endif /* _MSC_VER */ + +struct eap_hdr { + u8 code; + u8 identifier; + be16 length; /* including code and identifier; network byte order */ + /* followed by length-4 octets of data */ +} STRUCT_PACKED; + + +#ifdef _MSC_VER +#pragma pack(pop) +#endif /* _MSC_VER */ + +enum { EAP_CODE_REQUEST = 1, EAP_CODE_RESPONSE = 2, EAP_CODE_SUCCESS = 3, + EAP_CODE_FAILURE = 4 }; + +/* EAP Request and Response data begins with one octet Type. Success and + * Failure do not have additional data. */ + +/* + * EAP Method Types as allocated by IANA: + * http://www.iana.org/assignments/eap-numbers + */ +typedef enum { + EAP_TYPE_NONE = 0, + EAP_TYPE_IDENTITY = 1 /* RFC 3748 */, + EAP_TYPE_NOTIFICATION = 2 /* RFC 3748 */, + EAP_TYPE_NAK = 3 /* Response only, RFC 3748 */, + EAP_TYPE_MD5 = 4, /* RFC 3748 */ + EAP_TYPE_OTP = 5 /* RFC 3748 */, + EAP_TYPE_GTC = 6, /* RFC 3748 */ + EAP_TYPE_TLS = 13 /* RFC 2716 */, + EAP_TYPE_LEAP = 17 /* Cisco proprietary */, + EAP_TYPE_SIM = 18 /* RFC 4186 */, + EAP_TYPE_TTLS = 21 /* RFC 5281 */, + EAP_TYPE_AKA = 23 /* RFC 4187 */, + EAP_TYPE_PEAP = 25 /* draft-josefsson-pppext-eap-tls-eap-06.txt */, + EAP_TYPE_MSCHAPV2 = 26 /* draft-kamath-pppext-eap-mschapv2-00.txt */, + EAP_TYPE_TLV = 33 /* draft-josefsson-pppext-eap-tls-eap-07.txt */, + EAP_TYPE_TNC = 38 /* TNC IF-T v1.0-r3; note: tentative assignment; + * type 38 has previously been allocated for + * EAP-HTTP Digest, (funk.com) */, + EAP_TYPE_FAST = 43 /* RFC 4851 */, + EAP_TYPE_PAX = 46 /* RFC 4746 */, + EAP_TYPE_PSK = 47 /* RFC 4764 */, + EAP_TYPE_SAKE = 48 /* RFC 4763 */, + EAP_TYPE_IKEV2 = 49 /* RFC 5106 */, + EAP_TYPE_AKA_PRIME = 50 /* RFC 5448 */, + EAP_TYPE_GPSK = 51 /* RFC 5433 */, + EAP_TYPE_PWD = 52 /* RFC 5931 */, + EAP_TYPE_EKE = 53 /* RFC 6124 */, + EAP_TYPE_EXPANDED = 254 /* RFC 3748 */ +} EapType; + + +/* SMI Network Management Private Enterprise Code for vendor specific types */ +enum { + EAP_VENDOR_IETF = 0, + EAP_VENDOR_MICROSOFT = 0x000137 /* Microsoft */, + EAP_VENDOR_WFA = 0x00372A /* Wi-Fi Alliance */, + EAP_VENDOR_HOSTAP = 39068 /* hostapd/wpa_supplicant project */ +}; + +struct eap_expand { + u8 vendor_id[3]; + be32 vendor_type; + u8 opcode; +} STRUCT_PACKED; + +#define EAP_VENDOR_UNAUTH_TLS EAP_VENDOR_HOSTAP +#define EAP_VENDOR_TYPE_UNAUTH_TLS 1 + +#define EAP_MSK_LEN 64 +#define EAP_EMSK_LEN 64 + +#endif /* EAP_DEFS_H */ diff --git a/components/wpa_supplicant/include/wpa2/eap_peer/eap_i.h b/components/wpa_supplicant/include/wpa2/eap_peer/eap_i.h new file mode 100644 index 0000000000..a4779d13f8 --- /dev/null +++ b/components/wpa_supplicant/include/wpa2/eap_peer/eap_i.h @@ -0,0 +1,88 @@ +/* + * EAP peer state machines internal structures (RFC 4137) + * Copyright (c) 2004-2007, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef EAP_I_H +#define EAP_I_H + +#include "wpa/wpabuf.h" +#include "eap.h" +#include "eap_common.h" +#include "eap_config.h" + +/* RFC 4137 - EAP Peer state machine */ + +typedef enum { + DECISION_FAIL, DECISION_COND_SUCC, DECISION_UNCOND_SUCC +} EapDecision; + +typedef enum { + METHOD_NONE, METHOD_INIT, METHOD_CONT, METHOD_MAY_CONT, METHOD_DONE +} EapMethodState; + +/** + * struct eap_method_ret - EAP return values from struct eap_method::process() + * + * These structure contains OUT variables for the interface between peer state + * machine and methods (RFC 4137, Sect. 4.2). eapRespData will be returned as + * the return value of struct eap_method::process() so it is not included in + * this structure. + */ +struct eap_method_ret { + /** + * ignore - Whether method decided to drop the current packed (OUT) + */ + Boolean ignore; + + /** + * methodState - Method-specific state (IN/OUT) + */ + EapMethodState methodState; + + /** + * decision - Authentication decision (OUT) + */ + EapDecision decision; + + /** + * allowNotifications - Whether method allows notifications (OUT) + */ + Boolean allowNotifications; +}; + +#define CLIENT_CERT_NAME "CLC" +#define CA_CERT_NAME "CAC" +#define PRIVATE_KEY_NAME "PVK" +#define BLOB_NAME_LEN 3 +#define BLOB_NUM 2 + +/** + * struct eap_sm - EAP state machine data + */ +struct eap_sm { + void *eap_method_priv; + + void *ssl_ctx; + + unsigned int workaround; +///////////////////////////////////////////////// + struct pbuf *outbuf; + struct wpa_config_blob blob[BLOB_NUM]; + struct eap_peer_config config; + u8 current_identifier; + u8 ownaddr[ETH_ALEN]; +#ifdef USE_WPA2_TASK +#define SIG_WPA2_NUM 2 + u8 wpa2_sig_cnt[SIG_WPA2_NUM]; +#endif + u8 finish_state; +}; + +struct eap_peer_config * eap_get_config(struct eap_sm *sm); +const struct wpa_config_blob * eap_get_config_blob(struct eap_sm *sm, const char *name); + +#endif /* EAP_I_H */ diff --git a/components/wpa_supplicant/include/wpa2/eap_peer/eap_tls.h b/components/wpa_supplicant/include/wpa2/eap_peer/eap_tls.h new file mode 100644 index 0000000000..a8a386f22c --- /dev/null +++ b/components/wpa_supplicant/include/wpa2/eap_peer/eap_tls.h @@ -0,0 +1,25 @@ +/* + * EAP peer: EAP-TLS/PEAP/TTLS/FAST common functions + * Copyright (c) 2004-2009, 2012, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef EAP_TLS_H +#define EAP_TLS_H + +#include "eap_i.h" +#include "eap_common.h" +#include "eap.h" +#include "wpa/wpabuf.h" + +void * eap_tls_init(struct eap_sm *sm); +void eap_tls_deinit(struct eap_sm *sm, void *priv); +struct wpabuf * eap_tls_process(struct eap_sm *sm, void *priv, + struct eap_method_ret *ret, + const struct wpabuf *reqData); + +u8 * eap_tls_getKey(struct eap_sm *sm, void *priv, size_t *len); + +#endif /* EAP_TLS_H */ diff --git a/components/wpa_supplicant/include/wpa2/eap_peer/eap_tls_common.h b/components/wpa_supplicant/include/wpa2/eap_peer/eap_tls_common.h new file mode 100644 index 0000000000..1a5e0f89e4 --- /dev/null +++ b/components/wpa_supplicant/include/wpa2/eap_peer/eap_tls_common.h @@ -0,0 +1,131 @@ +/* + * EAP peer: EAP-TLS/PEAP/TTLS/FAST common functions + * Copyright (c) 2004-2009, 2012, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef EAP_TLS_COMMON_H +#define EAP_TLS_COMMON_H + +/** + * struct eap_ssl_data - TLS data for EAP methods + */ +struct eap_ssl_data { + /** + * conn - TLS connection context data from tls_connection_init() + */ + struct tls_connection *conn; + + /** + * tls_out - TLS message to be sent out in fragments + */ + struct wpabuf *tls_out; + + /** + * tls_out_pos - The current position in the outgoing TLS message + */ + size_t tls_out_pos; + + /** + * tls_out_limit - Maximum fragment size for outgoing TLS messages + */ + size_t tls_out_limit; + + /** + * tls_in - Received TLS message buffer for re-assembly + */ + struct wpabuf *tls_in; + + /** + * tls_in_left - Number of remaining bytes in the incoming TLS message + */ + size_t tls_in_left; + + /** + * tls_in_total - Total number of bytes in the incoming TLS message + */ + size_t tls_in_total; + + /** + * phase2 - Whether this TLS connection is used in EAP phase 2 (tunnel) + */ + int phase2; + + /** + * include_tls_length - Whether the TLS length field is included even + * if the TLS data is not fragmented + */ + int include_tls_length; + + /** + * eap - EAP state machine allocated with eap_peer_sm_init() + */ + struct eap_sm *eap; + + /** + * ssl_ctx - TLS library context to use for the connection + */ + void *ssl_ctx; + + /** + * eap_type - EAP method used in Phase 1 (EAP_TYPE_TLS/PEAP/TTLS/FAST) + */ + u8 eap_type; +}; + + +/* EAP TLS Flags */ +#define EAP_TLS_FLAGS_LENGTH_INCLUDED 0x80 +#define EAP_TLS_FLAGS_MORE_FRAGMENTS 0x40 +#define EAP_TLS_FLAGS_START 0x20 +#define EAP_TLS_VERSION_MASK 0x07 + + /* could be up to 128 bytes, but only the first 64 bytes are used */ +#define EAP_TLS_KEY_LEN 64 + +/* dummy type used as a flag for UNAUTH-TLS */ +#define EAP_UNAUTH_TLS_TYPE 255 + + +int eap_peer_tls_ssl_init(struct eap_sm *sm, struct eap_ssl_data *data, + struct eap_peer_config *config, u8 eap_type); +void eap_peer_tls_ssl_deinit(struct eap_sm *sm, struct eap_ssl_data *data); +u8 * eap_peer_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data, + const char *label, size_t len); +u8 * eap_peer_tls_derive_session_id(struct eap_sm *sm, + struct eap_ssl_data *data, u8 eap_type, + size_t *len); +int eap_peer_tls_process_helper(struct eap_sm *sm, struct eap_ssl_data *data, + EapType eap_type, int peap_version, + u8 id, const u8 *in_data, size_t in_len, + struct wpabuf **out_data); +struct wpabuf * eap_peer_tls_build_ack(u8 id, EapType eap_type, + int peap_version); +int eap_peer_tls_reauth_init(struct eap_sm *sm, struct eap_ssl_data *data); +int eap_peer_tls_status(struct eap_sm *sm, struct eap_ssl_data *data, + char *buf, size_t buflen, int verbose); +const u8 * eap_peer_tls_process_init(struct eap_sm *sm, + struct eap_ssl_data *data, + EapType eap_type, + struct eap_method_ret *ret, + const struct wpabuf *reqData, + size_t *len, u8 *flags); +void eap_peer_tls_reset_input(struct eap_ssl_data *data); +void eap_peer_tls_reset_output(struct eap_ssl_data *data); +int eap_peer_tls_decrypt(struct eap_sm *sm, struct eap_ssl_data *data, + const struct wpabuf *in_data, + struct wpabuf **in_decrypted); +int eap_peer_tls_encrypt(struct eap_sm *sm, struct eap_ssl_data *data, + EapType eap_type, int peap_version, u8 id, + const struct wpabuf *in_data, + struct wpabuf **out_data); +int eap_peer_select_phase2_methods(struct eap_peer_config *config, + const char *prefix, + struct eap_method_type **types, + size_t *num_types); +int eap_peer_tls_phase2_nak(struct eap_method_type *types, size_t num_types, + struct eap_hdr *hdr, struct wpabuf **resp); + +#endif /* EAP_TLS_COMMON_H */ diff --git a/components/wpa_supplicant/include/wpa2/tls/asn1.h b/components/wpa_supplicant/include/wpa2/tls/asn1.h new file mode 100644 index 0000000000..6342c4cc79 --- /dev/null +++ b/components/wpa_supplicant/include/wpa2/tls/asn1.h @@ -0,0 +1,66 @@ +/* + * ASN.1 DER parsing + * Copyright (c) 2006, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef ASN1_H +#define ASN1_H + +#define ASN1_TAG_EOC 0x00 /* not used with DER */ +#define ASN1_TAG_BOOLEAN 0x01 +#define ASN1_TAG_INTEGER 0x02 +#define ASN1_TAG_BITSTRING 0x03 +#define ASN1_TAG_OCTETSTRING 0x04 +#define ASN1_TAG_NULL 0x05 +#define ASN1_TAG_OID 0x06 +#define ASN1_TAG_OBJECT_DESCRIPTOR 0x07 /* not yet parsed */ +#define ASN1_TAG_EXTERNAL 0x08 /* not yet parsed */ +#define ASN1_TAG_REAL 0x09 /* not yet parsed */ +#define ASN1_TAG_ENUMERATED 0x0A /* not yet parsed */ +#define ASN1_TAG_UTF8STRING 0x0C /* not yet parsed */ +#define ANS1_TAG_RELATIVE_OID 0x0D +#define ASN1_TAG_SEQUENCE 0x10 /* shall be constructed */ +#define ASN1_TAG_SET 0x11 +#define ASN1_TAG_NUMERICSTRING 0x12 /* not yet parsed */ +#define ASN1_TAG_PRINTABLESTRING 0x13 +#define ASN1_TAG_TG1STRING 0x14 /* not yet parsed */ +#define ASN1_TAG_VIDEOTEXSTRING 0x15 /* not yet parsed */ +#define ASN1_TAG_IA5STRING 0x16 +#define ASN1_TAG_UTCTIME 0x17 +#define ASN1_TAG_GENERALIZEDTIME 0x18 /* not yet parsed */ +#define ASN1_TAG_GRAPHICSTRING 0x19 /* not yet parsed */ +#define ASN1_TAG_VISIBLESTRING 0x1A +#define ASN1_TAG_GENERALSTRING 0x1B /* not yet parsed */ +#define ASN1_TAG_UNIVERSALSTRING 0x1C /* not yet parsed */ +#define ASN1_TAG_BMPSTRING 0x1D /* not yet parsed */ + +#define ASN1_CLASS_UNIVERSAL 0 +#define ASN1_CLASS_APPLICATION 1 +#define ASN1_CLASS_CONTEXT_SPECIFIC 2 +#define ASN1_CLASS_PRIVATE 3 + + +struct asn1_hdr { + const u8 *payload; + u8 identifier, class, constructed; + unsigned int tag, length; +}; + +#define ASN1_MAX_OID_LEN 20 +struct asn1_oid { + unsigned long oid[ASN1_MAX_OID_LEN]; + size_t len; +}; + + +int asn1_get_next(const u8 *buf, size_t len, struct asn1_hdr *hdr); +int asn1_parse_oid(const u8 *buf, size_t len, struct asn1_oid *oid); +int asn1_get_oid(const u8 *buf, size_t len, struct asn1_oid *oid, + const u8 **next); +void asn1_oid_to_str(struct asn1_oid *oid, char *buf, size_t len); +unsigned long asn1_bit_string_to_long(const u8 *buf, size_t len); + +#endif /* ASN1_H */ diff --git a/components/wpa_supplicant/include/wpa2/tls/bignum.h b/components/wpa_supplicant/include/wpa2/tls/bignum.h new file mode 100644 index 0000000000..f25e26783a --- /dev/null +++ b/components/wpa_supplicant/include/wpa2/tls/bignum.h @@ -0,0 +1,38 @@ +/* + * Big number math + * Copyright (c) 2006, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef BIGNUM_H +#define BIGNUM_H + +struct bignum; + +struct bignum * bignum_init(void); +void bignum_deinit(struct bignum *n); +size_t bignum_get_unsigned_bin_len(struct bignum *n); +int bignum_get_unsigned_bin(const struct bignum *n, u8 *buf, size_t *len); +int bignum_set_unsigned_bin(struct bignum *n, const u8 *buf, size_t len); +int bignum_cmp(const struct bignum *a, const struct bignum *b); +int bignum_cmp_d(const struct bignum *a, unsigned long b); +int bignum_add(const struct bignum *a, const struct bignum *b, + struct bignum *c); +int bignum_sub(const struct bignum *a, const struct bignum *b, + struct bignum *c); +int bignum_mul(const struct bignum *a, const struct bignum *b, + struct bignum *c); +int bignum_mulmod(const struct bignum *a, const struct bignum *b, + const struct bignum *c, struct bignum *d); +int bignum_exptmod(const struct bignum *a, const struct bignum *b, + const struct bignum *c, struct bignum *d); + +#endif /* BIGNUM_H */ diff --git a/components/wpa_supplicant/include/wpa2/tls/libtommath.h b/components/wpa_supplicant/include/wpa2/tls/libtommath.h new file mode 100644 index 0000000000..c0409b5e33 --- /dev/null +++ b/components/wpa_supplicant/include/wpa2/tls/libtommath.h @@ -0,0 +1,3443 @@ +/* + * Minimal code for RSA support from LibTomMath 0.41 + * http://libtom.org/ + * http://libtom.org/files/ltm-0.41.tar.bz2 + * This library was released in public domain by Tom St Denis. + * + * The combination in this file may not use all of the optimized algorithms + * from LibTomMath and may be considerable slower than the LibTomMath with its + * default settings. The main purpose of having this version here is to make it + * easier to build bignum.c wrapper without having to install and build an + * external library. + * + * If CONFIG_INTERNAL_LIBTOMMATH is defined, bignum.c includes this + * libtommath.c file instead of using the external LibTomMath library. + */ +#include "c_types.h" +#include "os.h" +#include "stdarg.h" + +#ifdef MEMLEAK_DEBUG +static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; +#endif + +#ifndef CHAR_BIT +#define CHAR_BIT 8 +#endif + +#define BN_MP_INVMOD_C +#define BN_S_MP_EXPTMOD_C /* Note: #undef in tommath_superclass.h; this would + * require BN_MP_EXPTMOD_FAST_C instead */ +#define BN_S_MP_MUL_DIGS_C +#define BN_MP_INVMOD_SLOW_C +#define BN_S_MP_SQR_C +#define BN_S_MP_MUL_HIGH_DIGS_C /* Note: #undef in tommath_superclass.h; this + * would require other than mp_reduce */ + +#ifdef LTM_FAST + +/* Use faster div at the cost of about 1 kB */ +#define BN_MP_MUL_D_C + +/* Include faster exptmod (Montgomery) at the cost of about 2.5 kB in code */ +#define BN_MP_EXPTMOD_FAST_C +#define BN_MP_MONTGOMERY_SETUP_C +#define BN_FAST_MP_MONTGOMERY_REDUCE_C +#define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C +#define BN_MP_MUL_2_C + +/* Include faster sqr at the cost of about 0.5 kB in code */ +#define BN_FAST_S_MP_SQR_C + +#else /* LTM_FAST */ + +#define BN_MP_DIV_SMALL +#define BN_MP_INIT_MULTI_C +#define BN_MP_CLEAR_MULTI_C +#define BN_MP_ABS_C +#endif /* LTM_FAST */ + +/* Current uses do not require support for negative exponent in exptmod, so we + * can save about 1.5 kB in leaving out invmod. */ +#define LTM_NO_NEG_EXP + +/* from tommath.h */ + +#ifndef MIN + #define MIN(x,y) ((x)<(y)?(x):(y)) +#endif + +#ifndef MAX + #define MAX(x,y) ((x)>(y)?(x):(y)) +#endif + +#define OPT_CAST(x) (x *) + +typedef unsigned long mp_digit; +typedef u64 mp_word; + +#define DIGIT_BIT 28 +#define MP_28BIT + + +#define XMALLOC os_malloc +#define XFREE os_free +#define XREALLOC os_realloc + + +#define MP_MASK ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1)) + +#define MP_LT -1 /* less than */ +#define MP_EQ 0 /* equal to */ +#define MP_GT 1 /* greater than */ + +#define MP_ZPOS 0 /* positive integer */ +#define MP_NEG 1 /* negative */ + +#define MP_OKAY 0 /* ok result */ +#define MP_MEM -2 /* out of mem */ +#define MP_VAL -3 /* invalid input */ + +#define MP_YES 1 /* yes response */ +#define MP_NO 0 /* no response */ + +typedef int mp_err; + +/* define this to use lower memory usage routines (exptmods mostly) */ +#define MP_LOW_MEM + +/* default precision */ +#ifndef MP_PREC + #ifndef MP_LOW_MEM + #define MP_PREC 32 /* default digits of precision */ + #else + #define MP_PREC 8 /* default digits of precision */ + #endif +#endif + +/* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - BITS_PER_DIGIT*2) */ +#define MP_WARRAY (1 << (sizeof(mp_word) * CHAR_BIT - 2 * DIGIT_BIT + 1)) + +/* the infamous mp_int structure */ +typedef struct { + int used, alloc, sign; + mp_digit *dp; +} mp_int; + + +/* ---> Basic Manipulations <--- */ +#define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO) +#define mp_iseven(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 0)) ? MP_YES : MP_NO) +#define mp_isodd(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? MP_YES : MP_NO) + + +/* prototypes for copied functions */ +#define s_mp_mul(a, b, c) s_mp_mul_digs(a, b, c, (a)->used + (b)->used + 1) +static int s_mp_exptmod(mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode); +static int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs); +static int s_mp_sqr(mp_int * a, mp_int * b); +static int s_mp_mul_high_digs(mp_int * a, mp_int * b, mp_int * c, int digs); + +static int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs); + +#ifdef BN_MP_INIT_MULTI_C +static int mp_init_multi(mp_int *mp, ...); +#endif +#ifdef BN_MP_CLEAR_MULTI_C +static void mp_clear_multi(mp_int *mp, ...); +#endif +static int mp_lshd(mp_int * a, int b); +static void mp_set(mp_int * a, mp_digit b); +static void mp_clamp(mp_int * a); +static void mp_exch(mp_int * a, mp_int * b); +static void mp_rshd(mp_int * a, int b); +static void mp_zero(mp_int * a); +static int mp_mod_2d(mp_int * a, int b, mp_int * c); +static int mp_div_2d(mp_int * a, int b, mp_int * c, mp_int * d); +static int mp_init_copy(mp_int * a, mp_int * b); +static int mp_mul_2d(mp_int * a, int b, mp_int * c); +#ifndef LTM_NO_NEG_EXP +static int mp_div_2(mp_int * a, mp_int * b); +static int mp_invmod(mp_int * a, mp_int * b, mp_int * c); +static int mp_invmod_slow(mp_int * a, mp_int * b, mp_int * c); +#endif /* LTM_NO_NEG_EXP */ +static int mp_copy(mp_int * a, mp_int * b); +static int mp_count_bits(mp_int * a); +static int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d); +static int mp_mod(mp_int * a, mp_int * b, mp_int * c); +static int mp_grow(mp_int * a, int size); +static int mp_cmp_mag(mp_int * a, mp_int * b); +#ifdef BN_MP_ABS_C +static int mp_abs(mp_int * a, mp_int * b); +#endif +static int mp_sqr(mp_int * a, mp_int * b); +static int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d); +static int mp_reduce_2k_setup_l(mp_int *a, mp_int *d); +static int mp_2expt(mp_int * a, int b); +static int mp_reduce_setup(mp_int * a, mp_int * b); +static int mp_reduce(mp_int * x, mp_int * m, mp_int * mu); +static int mp_init_size(mp_int * a, int size); +#ifdef BN_MP_EXPTMOD_FAST_C +static int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode); +#endif /* BN_MP_EXPTMOD_FAST_C */ +#ifdef BN_FAST_S_MP_SQR_C +static int fast_s_mp_sqr (mp_int * a, mp_int * b); +#endif /* BN_FAST_S_MP_SQR_C */ +#ifdef BN_MP_MUL_D_C +static int mp_mul_d (mp_int * a, mp_digit b, mp_int * c); +#endif /* BN_MP_MUL_D_C */ + + + +/* functions from bn_.c */ + + +/* reverse an array, used for radix code */ +static void ICACHE_FLASH_ATTR +bn_reverse (unsigned char *s, int len) +{ + int ix, iy; + unsigned char t; + + ix = 0; + iy = len - 1; + while (ix < iy) { + t = s[ix]; + s[ix] = s[iy]; + s[iy] = t; + ++ix; + --iy; + } +} + + +/* low level addition, based on HAC pp.594, Algorithm 14.7 */ +static int ICACHE_FLASH_ATTR +s_mp_add (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int *x; + int olduse, res, min, max; + + /* find sizes, we let |a| <= |b| which means we have to sort + * them. "x" will point to the input with the most digits + */ + if (a->used > b->used) { + min = b->used; + max = a->used; + x = a; + } else { + min = a->used; + max = b->used; + x = b; + } + + /* init result */ + if (c->alloc < max + 1) { + if ((res = mp_grow (c, max + 1)) != MP_OKAY) { + return res; + } + } + + /* get old used digit count and set new one */ + olduse = c->used; + c->used = max + 1; + + { + register mp_digit u, *tmpa, *tmpb, *tmpc; + register int i; + + /* alias for digit pointers */ + + /* first input */ + tmpa = a->dp; + + /* second input */ + tmpb = b->dp; + + /* destination */ + tmpc = c->dp; + + /* zero the carry */ + u = 0; + for (i = 0; i < min; i++) { + /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */ + *tmpc = *tmpa++ + *tmpb++ + u; + + /* U = carry bit of T[i] */ + u = *tmpc >> ((mp_digit)DIGIT_BIT); + + /* take away carry bit from T[i] */ + *tmpc++ &= MP_MASK; + } + + /* now copy higher words if any, that is in A+B + * if A or B has more digits add those in + */ + if (min != max) { + for (; i < max; i++) { + /* T[i] = X[i] + U */ + *tmpc = x->dp[i] + u; + + /* U = carry bit of T[i] */ + u = *tmpc >> ((mp_digit)DIGIT_BIT); + + /* take away carry bit from T[i] */ + *tmpc++ &= MP_MASK; + } + } + + /* add carry */ + *tmpc++ = u; + + /* clear digits above oldused */ + for (i = c->used; i < olduse; i++) { + *tmpc++ = 0; + } + } + + mp_clamp (c); + return MP_OKAY; +} + + +/* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */ +static int ICACHE_FLASH_ATTR +s_mp_sub (mp_int * a, mp_int * b, mp_int * c) +{ + int olduse, res, min, max; + + /* find sizes */ + min = b->used; + max = a->used; + + /* init result */ + if (c->alloc < max) { + if ((res = mp_grow (c, max)) != MP_OKAY) { + return res; + } + } + olduse = c->used; + c->used = max; + + { + register mp_digit u, *tmpa, *tmpb, *tmpc; + register int i; + + /* alias for digit pointers */ + tmpa = a->dp; + tmpb = b->dp; + tmpc = c->dp; + + /* set carry to zero */ + u = 0; + for (i = 0; i < min; i++) { + /* T[i] = A[i] - B[i] - U */ + *tmpc = *tmpa++ - *tmpb++ - u; + + /* U = carry bit of T[i] + * Note this saves performing an AND operation since + * if a carry does occur it will propagate all the way to the + * MSB. As a result a single shift is enough to get the carry + */ + u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1)); + + /* Clear carry from T[i] */ + *tmpc++ &= MP_MASK; + } + + /* now copy higher words if any, e.g. if A has more digits than B */ + for (; i < max; i++) { + /* T[i] = A[i] - U */ + *tmpc = *tmpa++ - u; + + /* U = carry bit of T[i] */ + u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1)); + + /* Clear carry from T[i] */ + *tmpc++ &= MP_MASK; + } + + /* clear digits above used (since we may not have grown result above) */ + for (i = c->used; i < olduse; i++) { + *tmpc++ = 0; + } + } + + mp_clamp (c); + return MP_OKAY; +} + + +/* init a new mp_int */ +static int ICACHE_FLASH_ATTR +mp_init (mp_int * a) +{ + int i; + + /* allocate memory required and clear it */ + a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * MP_PREC); + if (a->dp == NULL) { + return MP_MEM; + } + + /* set the digits to zero */ + for (i = 0; i < MP_PREC; i++) { + a->dp[i] = 0; + } + + /* set the used to zero, allocated digits to the default precision + * and sign to positive */ + a->used = 0; + a->alloc = MP_PREC; + a->sign = MP_ZPOS; + + return MP_OKAY; +} + + +/* clear one (frees) */ +static void ICACHE_FLASH_ATTR +mp_clear (mp_int * a) +{ + int i; + + /* only do anything if a hasn't been freed previously */ + if (a->dp != NULL) { + /* first zero the digits */ + for (i = 0; i < a->used; i++) { + a->dp[i] = 0; + } + + /* free ram */ + XFREE(a->dp); + + /* reset members to make debugging easier */ + a->dp = NULL; + a->alloc = a->used = 0; + a->sign = MP_ZPOS; + } +} + + +/* high level addition (handles signs) */ +static int ICACHE_FLASH_ATTR +mp_add (mp_int * a, mp_int * b, mp_int * c) +{ + int sa, sb, res; + + /* get sign of both inputs */ + sa = a->sign; + sb = b->sign; + + /* handle two cases, not four */ + if (sa == sb) { + /* both positive or both negative */ + /* add their magnitudes, copy the sign */ + c->sign = sa; + res = s_mp_add (a, b, c); + } else { + /* one positive, the other negative */ + /* subtract the one with the greater magnitude from */ + /* the one of the lesser magnitude. The result gets */ + /* the sign of the one with the greater magnitude. */ + if (mp_cmp_mag (a, b) == MP_LT) { + c->sign = sb; + res = s_mp_sub (b, a, c); + } else { + c->sign = sa; + res = s_mp_sub (a, b, c); + } + } + return res; +} + + +/* high level subtraction (handles signs) */ +static int ICACHE_FLASH_ATTR +mp_sub (mp_int * a, mp_int * b, mp_int * c) +{ + int sa, sb, res; + + sa = a->sign; + sb = b->sign; + + if (sa != sb) { + /* subtract a negative from a positive, OR */ + /* subtract a positive from a negative. */ + /* In either case, ADD their magnitudes, */ + /* and use the sign of the first number. */ + c->sign = sa; + res = s_mp_add (a, b, c); + } else { + /* subtract a positive from a positive, OR */ + /* subtract a negative from a negative. */ + /* First, take the difference between their */ + /* magnitudes, then... */ + if (mp_cmp_mag (a, b) != MP_LT) { + /* Copy the sign from the first */ + c->sign = sa; + /* The first has a larger or equal magnitude */ + res = s_mp_sub (a, b, c); + } else { + /* The result has the *opposite* sign from */ + /* the first number. */ + c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS; + /* The second has a larger magnitude */ + res = s_mp_sub (b, a, c); + } + } + return res; +} + + +/* high level multiplication (handles sign) */ +static int ICACHE_FLASH_ATTR +mp_mul (mp_int * a, mp_int * b, mp_int * c) +{ + int res, neg; + neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; + + /* use Toom-Cook? */ +#ifdef BN_MP_TOOM_MUL_C + if (MIN (a->used, b->used) >= TOOM_MUL_CUTOFF) { + res = mp_toom_mul(a, b, c); + } else +#endif +#ifdef BN_MP_KARATSUBA_MUL_C + /* use Karatsuba? */ + if (MIN (a->used, b->used) >= KARATSUBA_MUL_CUTOFF) { + res = mp_karatsuba_mul (a, b, c); + } else +#endif + { + /* can we use the fast multiplier? + * + * The fast multiplier can be used if the output will + * have less than MP_WARRAY digits and the number of + * digits won't affect carry propagation + */ +#ifdef BN_FAST_S_MP_MUL_DIGS_C + int digs = a->used + b->used + 1; + + if ((digs < MP_WARRAY) && + MIN(a->used, b->used) <= + (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { + res = fast_s_mp_mul_digs (a, b, c, digs); + } else +#endif +#ifdef BN_S_MP_MUL_DIGS_C + res = s_mp_mul (a, b, c); /* uses s_mp_mul_digs */ +#else +#error mp_mul could fail + res = MP_VAL; +#endif + + } + c->sign = (c->used > 0) ? neg : MP_ZPOS; + return res; +} + + +/* d = a * b (mod c) */ +static int ICACHE_FLASH_ATTR +mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) +{ + int res; + mp_int t; + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + if ((res = mp_mul (a, b, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + res = mp_mod (&t, c, d); + mp_clear (&t); + return res; +} + + +/* c = a mod b, 0 <= c < b */ +static int ICACHE_FLASH_ATTR +mp_mod (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int t; + int res; + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + if ((res = mp_div (a, b, NULL, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + + if (t.sign != b->sign) { + res = mp_add (b, &t, c); + } else { + res = MP_OKAY; + mp_exch (&t, c); + } + + mp_clear (&t); + return res; +} + + +/* this is a shell function that calls either the normal or Montgomery + * exptmod functions. Originally the call to the montgomery code was + * embedded in the normal function but that wasted a lot of stack space + * for nothing (since 99% of the time the Montgomery code would be called) + */ +static int ICACHE_FLASH_ATTR +mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) +{ + int dr; + + /* modulus P must be positive */ + if (P->sign == MP_NEG) { + return MP_VAL; + } + + /* if exponent X is negative we have to recurse */ + if (X->sign == MP_NEG) { +#ifdef LTM_NO_NEG_EXP + return MP_VAL; +#else /* LTM_NO_NEG_EXP */ +#ifdef BN_MP_INVMOD_C + mp_int tmpG, tmpX; + int err; + + /* first compute 1/G mod P */ + if ((err = mp_init(&tmpG)) != MP_OKAY) { + return err; + } + if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) { + mp_clear(&tmpG); + return err; + } + + /* now get |X| */ + if ((err = mp_init(&tmpX)) != MP_OKAY) { + mp_clear(&tmpG); + return err; + } + if ((err = mp_abs(X, &tmpX)) != MP_OKAY) { + mp_clear_multi(&tmpG, &tmpX, NULL); + return err; + } + + /* and now compute (1/G)**|X| instead of G**X [X < 0] */ + err = mp_exptmod(&tmpG, &tmpX, P, Y); + mp_clear_multi(&tmpG, &tmpX, NULL); + return err; +#else +#error mp_exptmod would always fail + /* no invmod */ + return MP_VAL; +#endif +#endif /* LTM_NO_NEG_EXP */ + } + +/* modified diminished radix reduction */ +#if defined(BN_MP_REDUCE_IS_2K_L_C) && defined(BN_MP_REDUCE_2K_L_C) && defined(BN_S_MP_EXPTMOD_C) + if (mp_reduce_is_2k_l(P) == MP_YES) { + return s_mp_exptmod(G, X, P, Y, 1); + } +#endif + +#ifdef BN_MP_DR_IS_MODULUS_C + /* is it a DR modulus? */ + dr = mp_dr_is_modulus(P); +#else + /* default to no */ + dr = 0; +#endif + +#ifdef BN_MP_REDUCE_IS_2K_C + /* if not, is it a unrestricted DR modulus? */ + if (dr == 0) { + dr = mp_reduce_is_2k(P) << 1; + } +#endif + + /* if the modulus is odd or dr != 0 use the montgomery method */ +#ifdef BN_MP_EXPTMOD_FAST_C + if (mp_isodd (P) == 1 || dr != 0) { + return mp_exptmod_fast (G, X, P, Y, dr); + } else { +#endif +#ifdef BN_S_MP_EXPTMOD_C + /* otherwise use the generic Barrett reduction technique */ + return s_mp_exptmod (G, X, P, Y, 0); +#else +#error mp_exptmod could fail + /* no exptmod for evens */ + return MP_VAL; +#endif +#ifdef BN_MP_EXPTMOD_FAST_C + } +#endif +} + + +/* compare two ints (signed)*/ +static int ICACHE_FLASH_ATTR +mp_cmp (mp_int * a, mp_int * b) +{ + /* compare based on sign */ + if (a->sign != b->sign) { + if (a->sign == MP_NEG) { + return MP_LT; + } else { + return MP_GT; + } + } + + /* compare digits */ + if (a->sign == MP_NEG) { + /* if negative compare opposite direction */ + return mp_cmp_mag(b, a); + } else { + return mp_cmp_mag(a, b); + } +} + + +/* compare a digit */ +static int ICACHE_FLASH_ATTR +mp_cmp_d(mp_int * a, mp_digit b) +{ + /* compare based on sign */ + if (a->sign == MP_NEG) { + return MP_LT; + } + + /* compare based on magnitude */ + if (a->used > 1) { + return MP_GT; + } + + /* compare the only digit of a to b */ + if (a->dp[0] > b) { + return MP_GT; + } else if (a->dp[0] < b) { + return MP_LT; + } else { + return MP_EQ; + } +} + + +#ifndef LTM_NO_NEG_EXP +/* hac 14.61, pp608 */ +static int ICACHE_FLASH_ATTR +mp_invmod (mp_int * a, mp_int * b, mp_int * c) +{ + /* b cannot be negative */ + if (b->sign == MP_NEG || mp_iszero(b) == 1) { + return MP_VAL; + } + +#ifdef BN_FAST_MP_INVMOD_C + /* if the modulus is odd we can use a faster routine instead */ + if (mp_isodd (b) == 1) { + return fast_mp_invmod (a, b, c); + } +#endif + +#ifdef BN_MP_INVMOD_SLOW_C + return mp_invmod_slow(a, b, c); +#endif + +#ifndef BN_FAST_MP_INVMOD_C +#ifndef BN_MP_INVMOD_SLOW_C +#error mp_invmod would always fail +#endif +#endif + return MP_VAL; +} +#endif /* LTM_NO_NEG_EXP */ + + +/* get the size for an unsigned equivalent */ +static int ICACHE_FLASH_ATTR +mp_unsigned_bin_size (mp_int * a) +{ + int size = mp_count_bits (a); + return (size / 8 + ((size & 7) != 0 ? 1 : 0)); +} + + +#ifndef LTM_NO_NEG_EXP +/* hac 14.61, pp608 */ +static int ICACHE_FLASH_ATTR +mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int x, y, u, v, A, B, C, D; + int res; + + /* b cannot be negative */ + if (b->sign == MP_NEG || mp_iszero(b) == 1) { + return MP_VAL; + } + + /* init temps */ + if ((res = mp_init_multi(&x, &y, &u, &v, + &A, &B, &C, &D, NULL)) != MP_OKAY) { + return res; + } + + /* x = a, y = b */ + if ((res = mp_mod(a, b, &x)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_copy (b, &y)) != MP_OKAY) { + goto LBL_ERR; + } + + /* 2. [modified] if x,y are both even then return an error! */ + if (mp_iseven (&x) == 1 && mp_iseven (&y) == 1) { + res = MP_VAL; + goto LBL_ERR; + } + + /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ + if ((res = mp_copy (&x, &u)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_copy (&y, &v)) != MP_OKAY) { + goto LBL_ERR; + } + mp_set (&A, 1); + mp_set (&D, 1); + +top: + /* 4. while u is even do */ + while (mp_iseven (&u) == 1) { + /* 4.1 u = u/2 */ + if ((res = mp_div_2 (&u, &u)) != MP_OKAY) { + goto LBL_ERR; + } + /* 4.2 if A or B is odd then */ + if (mp_isodd (&A) == 1 || mp_isodd (&B) == 1) { + /* A = (A+y)/2, B = (B-x)/2 */ + if ((res = mp_add (&A, &y, &A)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) { + goto LBL_ERR; + } + } + /* A = A/2, B = B/2 */ + if ((res = mp_div_2 (&A, &A)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_div_2 (&B, &B)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* 5. while v is even do */ + while (mp_iseven (&v) == 1) { + /* 5.1 v = v/2 */ + if ((res = mp_div_2 (&v, &v)) != MP_OKAY) { + goto LBL_ERR; + } + /* 5.2 if C or D is odd then */ + if (mp_isodd (&C) == 1 || mp_isodd (&D) == 1) { + /* C = (C+y)/2, D = (D-x)/2 */ + if ((res = mp_add (&C, &y, &C)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + /* C = C/2, D = D/2 */ + if ((res = mp_div_2 (&C, &C)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_div_2 (&D, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* 6. if u >= v then */ + if (mp_cmp (&u, &v) != MP_LT) { + /* u = u - v, A = A - C, B = B - D */ + if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sub (&A, &C, &A)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) { + goto LBL_ERR; + } + } else { + /* v - v - u, C = C - A, D = D - B */ + if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sub (&C, &A, &C)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* if not zero goto step 4 */ + if (mp_iszero (&u) == 0) + goto top; + + /* now a = C, b = D, gcd == g*v */ + + /* if v != 1 then there is no inverse */ + if (mp_cmp_d (&v, 1) != MP_EQ) { + res = MP_VAL; + goto LBL_ERR; + } + + /* if its too low */ + while (mp_cmp_d(&C, 0) == MP_LT) { + if ((res = mp_add(&C, b, &C)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* too big */ + while (mp_cmp_mag(&C, b) != MP_LT) { + if ((res = mp_sub(&C, b, &C)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* C is now the inverse */ + mp_exch (&C, c); + res = MP_OKAY; +LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &A, &B, &C, &D, NULL); + return res; +} +#endif /* LTM_NO_NEG_EXP */ + + +/* compare maginitude of two ints (unsigned) */ +static int ICACHE_FLASH_ATTR +mp_cmp_mag (mp_int * a, mp_int * b) +{ + int n; + mp_digit *tmpa, *tmpb; + + /* compare based on # of non-zero digits */ + if (a->used > b->used) { + return MP_GT; + } + + if (a->used < b->used) { + return MP_LT; + } + + /* alias for a */ + tmpa = a->dp + (a->used - 1); + + /* alias for b */ + tmpb = b->dp + (a->used - 1); + + /* compare based on digits */ + for (n = 0; n < a->used; ++n, --tmpa, --tmpb) { + if (*tmpa > *tmpb) { + return MP_GT; + } + + if (*tmpa < *tmpb) { + return MP_LT; + } + } + return MP_EQ; +} + + +/* reads a unsigned char array, assumes the msb is stored first [big endian] */ +static int ICACHE_FLASH_ATTR +mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c) +{ + int res; + + /* make sure there are at least two digits */ + if (a->alloc < 2) { + if ((res = mp_grow(a, 2)) != MP_OKAY) { + return res; + } + } + + /* zero the int */ + mp_zero (a); + + /* read the bytes in */ + while (c-- > 0) { + if ((res = mp_mul_2d (a, 8, a)) != MP_OKAY) { + return res; + } + +#ifndef MP_8BIT + a->dp[0] |= *b++; + a->used += 1; +#else + a->dp[0] = (*b & MP_MASK); + a->dp[1] |= ((*b++ >> 7U) & 1); + a->used += 2; +#endif + } + mp_clamp (a); + return MP_OKAY; +} + + +/* store in unsigned [big endian] format */ +static int ICACHE_FLASH_ATTR +mp_to_unsigned_bin (mp_int * a, unsigned char *b) +{ + int x, res; + mp_int t; + + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + + x = 0; + while (mp_iszero (&t) == 0) { +#ifndef MP_8BIT + b[x++] = (unsigned char) (t.dp[0] & 255); +#else + b[x++] = (unsigned char) (t.dp[0] | ((t.dp[1] & 0x01) << 7)); +#endif + if ((res = mp_div_2d (&t, 8, &t, NULL)) != MP_OKAY) { + mp_clear (&t); + return res; + } + } + bn_reverse (b, x); + mp_clear (&t); + return MP_OKAY; +} + + +/* shift right by a certain bit count (store quotient in c, optional remainder in d) */ +static int ICACHE_FLASH_ATTR +mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d) +{ + mp_digit D, r, rr; + int x, res; + mp_int t; + + + /* if the shift count is <= 0 then we do no work */ + if (b <= 0) { + res = mp_copy (a, c); + if (d != NULL) { + mp_zero (d); + } + return res; + } + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + /* get the remainder */ + if (d != NULL) { + if ((res = mp_mod_2d (a, b, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + } + + /* copy */ + if ((res = mp_copy (a, c)) != MP_OKAY) { + mp_clear (&t); + return res; + } + + /* shift by as many digits in the bit count */ + if (b >= (int)DIGIT_BIT) { + mp_rshd (c, b / DIGIT_BIT); + } + + /* shift any bit count < DIGIT_BIT */ + D = (mp_digit) (b % DIGIT_BIT); + if (D != 0) { + register mp_digit *tmpc, mask, shift; + + /* mask */ + mask = (((mp_digit)1) << D) - 1; + + /* shift for lsb */ + shift = DIGIT_BIT - D; + + /* alias */ + tmpc = c->dp + (c->used - 1); + + /* carry */ + r = 0; + for (x = c->used - 1; x >= 0; x--) { + /* get the lower bits of this word in a temp */ + rr = *tmpc & mask; + + /* shift the current word and mix in the carry bits from the previous word */ + *tmpc = (*tmpc >> D) | (r << shift); + --tmpc; + + /* set the carry to the carry bits of the current word found above */ + r = rr; + } + } + mp_clamp (c); + if (d != NULL) { + mp_exch (&t, d); + } + mp_clear (&t); + return MP_OKAY; +} + + +static int ICACHE_FLASH_ATTR +mp_init_copy (mp_int * a, mp_int * b) +{ + int res; + + if ((res = mp_init (a)) != MP_OKAY) { + return res; + } + return mp_copy (b, a); +} + + +/* set to zero */ +static void ICACHE_FLASH_ATTR +mp_zero (mp_int * a) +{ + int n; + mp_digit *tmp; + + a->sign = MP_ZPOS; + a->used = 0; + + tmp = a->dp; + for (n = 0; n < a->alloc; n++) { + *tmp++ = 0; + } +} + + +/* copy, b = a */ +static int ICACHE_FLASH_ATTR +mp_copy (mp_int * a, mp_int * b) +{ + int res, n; + + /* if dst == src do nothing */ + if (a == b) { + return MP_OKAY; + } + + /* grow dest */ + if (b->alloc < a->used) { + if ((res = mp_grow (b, a->used)) != MP_OKAY) { + return res; + } + } + + /* zero b and copy the parameters over */ + { + register mp_digit *tmpa, *tmpb; + + /* pointer aliases */ + + /* source */ + tmpa = a->dp; + + /* destination */ + tmpb = b->dp; + + /* copy all the digits */ + for (n = 0; n < a->used; n++) { + *tmpb++ = *tmpa++; + } + + /* clear high digits */ + for (; n < b->used; n++) { + *tmpb++ = 0; + } + } + + /* copy used count and sign */ + b->used = a->used; + b->sign = a->sign; + return MP_OKAY; +} + + +/* shift right a certain amount of digits */ +static void ICACHE_FLASH_ATTR +mp_rshd (mp_int * a, int b) +{ + int x; + + /* if b <= 0 then ignore it */ + if (b <= 0) { + return; + } + + /* if b > used then simply zero it and return */ + if (a->used <= b) { + mp_zero (a); + return; + } + + { + register mp_digit *bottom, *top; + + /* shift the digits down */ + + /* bottom */ + bottom = a->dp; + + /* top [offset into digits] */ + top = a->dp + b; + + /* this is implemented as a sliding window where + * the window is b-digits long and digits from + * the top of the window are copied to the bottom + * + * e.g. + + b-2 | b-1 | b0 | b1 | b2 | ... | bb | ----> + /\ | ----> + \-------------------/ ----> + */ + for (x = 0; x < (a->used - b); x++) { + *bottom++ = *top++; + } + + /* zero the top digits */ + for (; x < a->used; x++) { + *bottom++ = 0; + } + } + + /* remove excess digits */ + a->used -= b; +} + + +/* swap the elements of two integers, for cases where you can't simply swap the + * mp_int pointers around + */ +static void ICACHE_FLASH_ATTR +mp_exch (mp_int * a, mp_int * b) +{ + mp_int t; + + t = *a; + *a = *b; + *b = t; +} + + +/* trim unused digits + * + * This is used to ensure that leading zero digits are + * trimed and the leading "used" digit will be non-zero + * Typically very fast. Also fixes the sign if there + * are no more leading digits + */ +static void ICACHE_FLASH_ATTR +mp_clamp (mp_int * a) +{ + /* decrease used while the most significant digit is + * zero. + */ + while (a->used > 0 && a->dp[a->used - 1] == 0) { + --(a->used); + } + + /* reset the sign flag if used == 0 */ + if (a->used == 0) { + a->sign = MP_ZPOS; + } +} + + +/* grow as required */ +static int ICACHE_FLASH_ATTR +mp_grow (mp_int * a, int size) +{ + int i; + mp_digit *tmp; + + /* if the alloc size is smaller alloc more ram */ + if (a->alloc < size) { + /* ensure there are always at least MP_PREC digits extra on top */ + size += (MP_PREC * 2) - (size % MP_PREC); + + /* reallocate the array a->dp + * + * We store the return in a temporary variable + * in case the operation failed we don't want + * to overwrite the dp member of a. + */ + tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * size); + if (tmp == NULL) { + /* reallocation failed but "a" is still valid [can be freed] */ + return MP_MEM; + } + + /* reallocation succeeded so set a->dp */ + a->dp = tmp; + + /* zero excess digits */ + i = a->alloc; + a->alloc = size; + for (; i < a->alloc; i++) { + a->dp[i] = 0; + } + } + return MP_OKAY; +} + + +#ifdef BN_MP_ABS_C +/* b = |a| + * + * Simple function copies the input and fixes the sign to positive + */ +static int ICACHE_FLASH_ATTR +mp_abs (mp_int * a, mp_int * b) +{ + int res; + + /* copy a to b */ + if (a != b) { + if ((res = mp_copy (a, b)) != MP_OKAY) { + return res; + } + } + + /* force the sign of b to positive */ + b->sign = MP_ZPOS; + + return MP_OKAY; +} +#endif + + +/* set to a digit */ +static void ICACHE_FLASH_ATTR +mp_set (mp_int * a, mp_digit b) +{ + mp_zero (a); + a->dp[0] = b & MP_MASK; + a->used = (a->dp[0] != 0) ? 1 : 0; +} + + +#ifndef LTM_NO_NEG_EXP +/* b = a/2 */ +static int ICACHE_FLASH_ATTR +mp_div_2(mp_int * a, mp_int * b) +{ + int x, res, oldused; + + /* copy */ + if (b->alloc < a->used) { + if ((res = mp_grow (b, a->used)) != MP_OKAY) { + return res; + } + } + + oldused = b->used; + b->used = a->used; + { + register mp_digit r, rr, *tmpa, *tmpb; + + /* source alias */ + tmpa = a->dp + b->used - 1; + + /* dest alias */ + tmpb = b->dp + b->used - 1; + + /* carry */ + r = 0; + for (x = b->used - 1; x >= 0; x--) { + /* get the carry for the next iteration */ + rr = *tmpa & 1; + + /* shift the current digit, add in carry and store */ + *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1)); + + /* forward carry to next iteration */ + r = rr; + } + + /* zero excess digits */ + tmpb = b->dp + b->used; + for (x = b->used; x < oldused; x++) { + *tmpb++ = 0; + } + } + b->sign = a->sign; + mp_clamp (b); + return MP_OKAY; +} +#endif /* LTM_NO_NEG_EXP */ + + +/* shift left by a certain bit count */ +static int ICACHE_FLASH_ATTR +mp_mul_2d (mp_int * a, int b, mp_int * c) +{ + mp_digit d; + int res; + + /* copy */ + if (a != c) { + if ((res = mp_copy (a, c)) != MP_OKAY) { + return res; + } + } + + if (c->alloc < (int)(c->used + b/DIGIT_BIT + 1)) { + if ((res = mp_grow (c, c->used + b / DIGIT_BIT + 1)) != MP_OKAY) { + return res; + } + } + + /* shift by as many digits in the bit count */ + if (b >= (int)DIGIT_BIT) { + if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) { + return res; + } + } + + /* shift any bit count < DIGIT_BIT */ + d = (mp_digit) (b % DIGIT_BIT); + if (d != 0) { + register mp_digit *tmpc, shift, mask, r, rr; + register int x; + + /* bitmask for carries */ + mask = (((mp_digit)1) << d) - 1; + + /* shift for msbs */ + shift = DIGIT_BIT - d; + + /* alias */ + tmpc = c->dp; + + /* carry */ + r = 0; + for (x = 0; x < c->used; x++) { + /* get the higher bits of the current word */ + rr = (*tmpc >> shift) & mask; + + /* shift the current word and OR in the carry */ + *tmpc = ((*tmpc << d) | r) & MP_MASK; + ++tmpc; + + /* set the carry to the carry bits of the current word */ + r = rr; + } + + /* set final carry */ + if (r != 0) { + c->dp[(c->used)++] = r; + } + } + mp_clamp (c); + return MP_OKAY; +} + + +#ifdef BN_MP_INIT_MULTI_C +static int ICACHE_FLASH_ATTR +mp_init_multi(mp_int *mp, ...) +{ + mp_err res = MP_OKAY; /* Assume ok until proven otherwise */ + int n = 0; /* Number of ok inits */ + mp_int* cur_arg = mp; + va_list args; + + va_start(args, mp); /* init args to next argument from caller */ + while (cur_arg != NULL) { + if (mp_init(cur_arg) != MP_OKAY) { + /* Oops - error! Back-track and mp_clear what we already + succeeded in init-ing, then return error. + */ + va_list clean_args; + + /* end the current list */ + va_end(args); + + /* now start cleaning up */ + cur_arg = mp; + va_start(clean_args, mp); + while (n--) { + mp_clear(cur_arg); + cur_arg = va_arg(clean_args, mp_int*); + } + va_end(clean_args); + res = MP_MEM; + break; + } + n++; + cur_arg = va_arg(args, mp_int*); + } + va_end(args); + return res; /* Assumed ok, if error flagged above. */ +} +#endif + + +#ifdef BN_MP_CLEAR_MULTI_C +static void ICACHE_FLASH_ATTR +mp_clear_multi(mp_int *mp, ...) +{ + mp_int* next_mp = mp; + va_list args; + va_start(args, mp); + while (next_mp != NULL) { + mp_clear(next_mp); + next_mp = va_arg(args, mp_int*); + } + va_end(args); +} +#endif + + +/* shift left a certain amount of digits */ +static int ICACHE_FLASH_ATTR +mp_lshd (mp_int * a, int b) +{ + int x, res; + + /* if its less than zero return */ + if (b <= 0) { + return MP_OKAY; + } + + /* grow to fit the new digits */ + if (a->alloc < a->used + b) { + if ((res = mp_grow (a, a->used + b)) != MP_OKAY) { + return res; + } + } + + { + register mp_digit *top, *bottom; + + /* increment the used by the shift amount then copy upwards */ + a->used += b; + + /* top */ + top = a->dp + a->used - 1; + + /* base */ + bottom = a->dp + a->used - 1 - b; + + /* much like mp_rshd this is implemented using a sliding window + * except the window goes the otherway around. Copying from + * the bottom to the top. see bn_mp_rshd.c for more info. + */ + for (x = a->used - 1; x >= b; x--) { + *top-- = *bottom--; + } + + /* zero the lower digits */ + top = a->dp; + for (x = 0; x < b; x++) { + *top++ = 0; + } + } + return MP_OKAY; +} + + +/* returns the number of bits in an int */ +static int ICACHE_FLASH_ATTR +mp_count_bits (mp_int * a) +{ + int r; + mp_digit q; + + /* shortcut */ + if (a->used == 0) { + return 0; + } + + /* get number of digits and add that */ + r = (a->used - 1) * DIGIT_BIT; + + /* take the last digit and count the bits in it */ + q = a->dp[a->used - 1]; + while (q > ((mp_digit) 0)) { + ++r; + q >>= ((mp_digit) 1); + } + return r; +} + + +/* calc a value mod 2**b */ +static int ICACHE_FLASH_ATTR +mp_mod_2d (mp_int * a, int b, mp_int * c) +{ + int x, res; + + /* if b is <= 0 then zero the int */ + if (b <= 0) { + mp_zero (c); + return MP_OKAY; + } + + /* if the modulus is larger than the value than return */ + if (b >= (int) (a->used * DIGIT_BIT)) { + res = mp_copy (a, c); + return res; + } + + /* copy */ + if ((res = mp_copy (a, c)) != MP_OKAY) { + return res; + } + + /* zero digits above the last digit of the modulus */ + for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++) { + c->dp[x] = 0; + } + /* clear the digit that is not completely outside/inside the modulus */ + c->dp[b / DIGIT_BIT] &= + (mp_digit) ((((mp_digit) 1) << (((mp_digit) b) % DIGIT_BIT)) - ((mp_digit) 1)); + mp_clamp (c); + return MP_OKAY; +} + + +#ifdef BN_MP_DIV_SMALL + +/* slower bit-bang division... also smaller */ +static int ICACHE_FLASH_ATTR +mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d) +{ + mp_int ta, tb, tq, q; + int res, n, n2; + + /* is divisor zero ? */ + if (mp_iszero (b) == 1) { + return MP_VAL; + } + + /* if a < b then q=0, r = a */ + if (mp_cmp_mag (a, b) == MP_LT) { + if (d != NULL) { + res = mp_copy (a, d); + } else { + res = MP_OKAY; + } + if (c != NULL) { + mp_zero (c); + } + return res; + } + + /* init our temps */ + if ((res = mp_init_multi(&ta, &tb, &tq, &q, NULL) != MP_OKAY)) { + return res; + } + + + mp_set(&tq, 1); + n = mp_count_bits(a) - mp_count_bits(b); + if (((res = mp_abs(a, &ta)) != MP_OKAY) || + ((res = mp_abs(b, &tb)) != MP_OKAY) || + ((res = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) || + ((res = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) { + goto LBL_ERR; + } + + while (n-- >= 0) { + if (mp_cmp(&tb, &ta) != MP_GT) { + if (((res = mp_sub(&ta, &tb, &ta)) != MP_OKAY) || + ((res = mp_add(&q, &tq, &q)) != MP_OKAY)) { + goto LBL_ERR; + } + } + if (((res = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) || + ((res = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) { + goto LBL_ERR; + } + } + + /* now q == quotient and ta == remainder */ + n = a->sign; + n2 = (a->sign == b->sign ? MP_ZPOS : MP_NEG); + if (c != NULL) { + mp_exch(c, &q); + c->sign = (mp_iszero(c) == MP_YES) ? MP_ZPOS : n2; + } + if (d != NULL) { + mp_exch(d, &ta); + d->sign = (mp_iszero(d) == MP_YES) ? MP_ZPOS : n; + } +LBL_ERR: + mp_clear_multi(&ta, &tb, &tq, &q, NULL); + return res; +} + +#else + +/* integer signed division. + * c*b + d == a [e.g. a/b, c=quotient, d=remainder] + * HAC pp.598 Algorithm 14.20 + * + * Note that the description in HAC is horribly + * incomplete. For example, it doesn't consider + * the case where digits are removed from 'x' in + * the inner loop. It also doesn't consider the + * case that y has fewer than three digits, etc.. + * + * The overall algorithm is as described as + * 14.20 from HAC but fixed to treat these cases. +*/ +static int ICACHE_FLASH_ATTR +mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d) +{ + mp_int q, x, y, t1, t2; + int res, n, t, i, norm, neg; + + /* is divisor zero ? */ + if (mp_iszero (b) == 1) { + return MP_VAL; + } + + /* if a < b then q=0, r = a */ + if (mp_cmp_mag (a, b) == MP_LT) { + if (d != NULL) { + res = mp_copy (a, d); + } else { + res = MP_OKAY; + } + if (c != NULL) { + mp_zero (c); + } + return res; + } + + if ((res = mp_init_size (&q, a->used + 2)) != MP_OKAY) { + return res; + } + q.used = a->used + 2; + + if ((res = mp_init (&t1)) != MP_OKAY) { + goto LBL_Q; + } + + if ((res = mp_init (&t2)) != MP_OKAY) { + goto LBL_T1; + } + + if ((res = mp_init_copy (&x, a)) != MP_OKAY) { + goto LBL_T2; + } + + if ((res = mp_init_copy (&y, b)) != MP_OKAY) { + goto LBL_X; + } + + /* fix the sign */ + neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; + x.sign = y.sign = MP_ZPOS; + + /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */ + norm = mp_count_bits(&y) % DIGIT_BIT; + if (norm < (int)(DIGIT_BIT-1)) { + norm = (DIGIT_BIT-1) - norm; + if ((res = mp_mul_2d (&x, norm, &x)) != MP_OKAY) { + goto LBL_Y; + } + if ((res = mp_mul_2d (&y, norm, &y)) != MP_OKAY) { + goto LBL_Y; + } + } else { + norm = 0; + } + + /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */ + n = x.used - 1; + t = y.used - 1; + + /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */ + if ((res = mp_lshd (&y, n - t)) != MP_OKAY) { /* y = y*b**{n-t} */ + goto LBL_Y; + } + + while (mp_cmp (&x, &y) != MP_LT) { + ++(q.dp[n - t]); + if ((res = mp_sub (&x, &y, &x)) != MP_OKAY) { + goto LBL_Y; + } + } + + /* reset y by shifting it back down */ + mp_rshd (&y, n - t); + + /* step 3. for i from n down to (t + 1) */ + for (i = n; i >= (t + 1); i--) { + if (i > x.used) { + continue; + } + + /* step 3.1 if xi == yt then set q{i-t-1} to b-1, + * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */ + if (x.dp[i] == y.dp[t]) { + q.dp[i - t - 1] = ((((mp_digit)1) << DIGIT_BIT) - 1); + } else { + mp_word tmp; + tmp = ((mp_word) x.dp[i]) << ((mp_word) DIGIT_BIT); + tmp |= ((mp_word) x.dp[i - 1]); + tmp /= ((mp_word) y.dp[t]); + if (tmp > (mp_word) MP_MASK) + tmp = MP_MASK; + q.dp[i - t - 1] = (mp_digit) (tmp & (mp_word) (MP_MASK)); + } + + /* while (q{i-t-1} * (yt * b + y{t-1})) > + xi * b**2 + xi-1 * b + xi-2 + + do q{i-t-1} -= 1; + */ + q.dp[i - t - 1] = (q.dp[i - t - 1] + 1) & MP_MASK; + do { + q.dp[i - t - 1] = (q.dp[i - t - 1] - 1) & MP_MASK; + + /* find left hand */ + mp_zero (&t1); + t1.dp[0] = (t - 1 < 0) ? 0 : y.dp[t - 1]; + t1.dp[1] = y.dp[t]; + t1.used = 2; + if ((res = mp_mul_d (&t1, q.dp[i - t - 1], &t1)) != MP_OKAY) { + goto LBL_Y; + } + + /* find right hand */ + t2.dp[0] = (i - 2 < 0) ? 0 : x.dp[i - 2]; + t2.dp[1] = (i - 1 < 0) ? 0 : x.dp[i - 1]; + t2.dp[2] = x.dp[i]; + t2.used = 3; + } while (mp_cmp_mag(&t1, &t2) == MP_GT); + + /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */ + if ((res = mp_mul_d (&y, q.dp[i - t - 1], &t1)) != MP_OKAY) { + goto LBL_Y; + } + + if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) { + goto LBL_Y; + } + + if ((res = mp_sub (&x, &t1, &x)) != MP_OKAY) { + goto LBL_Y; + } + + /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */ + if (x.sign == MP_NEG) { + if ((res = mp_copy (&y, &t1)) != MP_OKAY) { + goto LBL_Y; + } + if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) { + goto LBL_Y; + } + if ((res = mp_add (&x, &t1, &x)) != MP_OKAY) { + goto LBL_Y; + } + + q.dp[i - t - 1] = (q.dp[i - t - 1] - 1UL) & MP_MASK; + } + } + + /* now q is the quotient and x is the remainder + * [which we have to normalize] + */ + + /* get sign before writing to c */ + x.sign = x.used == 0 ? MP_ZPOS : a->sign; + + if (c != NULL) { + mp_clamp (&q); + mp_exch (&q, c); + c->sign = neg; + } + + if (d != NULL) { + mp_div_2d (&x, norm, &x, NULL); + mp_exch (&x, d); + } + + res = MP_OKAY; + +LBL_Y:mp_clear (&y); +LBL_X:mp_clear (&x); +LBL_T2:mp_clear (&t2); +LBL_T1:mp_clear (&t1); +LBL_Q:mp_clear (&q); + return res; +} + +#endif + + +#ifdef MP_LOW_MEM + #define TAB_SIZE 32 +#else + #define TAB_SIZE 256 +#endif + +static int ICACHE_FLASH_ATTR +s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) +{ + mp_int M[TAB_SIZE], res, mu; + mp_digit buf; + int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; + int (*redux)(mp_int*,mp_int*,mp_int*); + + /* find window size */ + x = mp_count_bits (X); + if (x <= 7) { + winsize = 2; + } else if (x <= 36) { + winsize = 3; + } else if (x <= 140) { + winsize = 4; + } else if (x <= 450) { + winsize = 5; + } else if (x <= 1303) { + winsize = 6; + } else if (x <= 3529) { + winsize = 7; + } else { + winsize = 8; + } + +#ifdef MP_LOW_MEM + if (winsize > 5) { + winsize = 5; + } +#endif + + /* init M array */ + /* init first cell */ + if ((err = mp_init(&M[1])) != MP_OKAY) { + return err; + } + + /* now init the second half of the array */ + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + if ((err = mp_init(&M[x])) != MP_OKAY) { + for (y = 1<<(winsize-1); y < x; y++) { + mp_clear (&M[y]); + } + mp_clear(&M[1]); + return err; + } + } + + /* create mu, used for Barrett reduction */ + if ((err = mp_init (&mu)) != MP_OKAY) { + goto LBL_M; + } + + if (redmode == 0) { + if ((err = mp_reduce_setup (&mu, P)) != MP_OKAY) { + goto LBL_MU; + } + redux = mp_reduce; + } else { + if ((err = mp_reduce_2k_setup_l (P, &mu)) != MP_OKAY) { + goto LBL_MU; + } + redux = mp_reduce_2k_l; + } + + /* create M table + * + * The M table contains powers of the base, + * e.g. M[x] = G**x mod P + * + * The first half of the table is not + * computed though accept for M[0] and M[1] + */ + if ((err = mp_mod (G, P, &M[1])) != MP_OKAY) { + goto LBL_MU; + } + + /* compute the value at M[1<<(winsize-1)] by squaring + * M[1] (winsize-1) times + */ + if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) { + goto LBL_MU; + } + + for (x = 0; x < (winsize - 1); x++) { + /* square it */ + if ((err = mp_sqr (&M[1 << (winsize - 1)], + &M[1 << (winsize - 1)])) != MP_OKAY) { + goto LBL_MU; + } + + /* reduce modulo P */ + if ((err = redux (&M[1 << (winsize - 1)], P, &mu)) != MP_OKAY) { + goto LBL_MU; + } + } + + /* create upper table, that is M[x] = M[x-1] * M[1] (mod P) + * for x = (2**(winsize - 1) + 1) to (2**winsize - 1) + */ + for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { + if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) { + goto LBL_MU; + } + if ((err = redux (&M[x], P, &mu)) != MP_OKAY) { + goto LBL_MU; + } + } + + /* setup result */ + if ((err = mp_init (&res)) != MP_OKAY) { + goto LBL_MU; + } + mp_set (&res, 1); + + /* set initial mode and bit cnt */ + mode = 0; + bitcnt = 1; + buf = 0; + digidx = X->used - 1; + bitcpy = 0; + bitbuf = 0; + + for (;;) { + /* grab next digit as required */ + if (--bitcnt == 0) { + /* if digidx == -1 we are out of digits */ + if (digidx == -1) { + break; + } + /* read next digit and reset the bitcnt */ + buf = X->dp[digidx--]; + bitcnt = (int) DIGIT_BIT; + } + + /* grab the next msb from the exponent */ + y = (buf >> (mp_digit)(DIGIT_BIT - 1)) & 1; + buf <<= (mp_digit)1; + + /* if the bit is zero and mode == 0 then we ignore it + * These represent the leading zero bits before the first 1 bit + * in the exponent. Technically this opt is not required but it + * does lower the # of trivial squaring/reductions used + */ + if (mode == 0 && y == 0) { + continue; + } + + /* if the bit is zero and mode == 1 then we square */ + if (mode == 1 && y == 0) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, &mu)) != MP_OKAY) { + goto LBL_RES; + } + continue; + } + + /* else we add it to the window */ + bitbuf |= (y << (winsize - ++bitcpy)); + mode = 2; + + if (bitcpy == winsize) { + /* ok window is filled so square as required and multiply */ + /* square first */ + for (x = 0; x < winsize; x++) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, &mu)) != MP_OKAY) { + goto LBL_RES; + } + } + + /* then multiply */ + if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, &mu)) != MP_OKAY) { + goto LBL_RES; + } + + /* empty window and reset */ + bitcpy = 0; + bitbuf = 0; + mode = 1; + } + } + + /* if bits remain then square/multiply */ + if (mode == 2 && bitcpy > 0) { + /* square then multiply if the bit is set */ + for (x = 0; x < bitcpy; x++) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, &mu)) != MP_OKAY) { + goto LBL_RES; + } + + bitbuf <<= 1; + if ((bitbuf & (1 << winsize)) != 0) { + /* then multiply */ + if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, &mu)) != MP_OKAY) { + goto LBL_RES; + } + } + } + } + + mp_exch (&res, Y); + err = MP_OKAY; +LBL_RES:mp_clear (&res); +LBL_MU:mp_clear (&mu); +LBL_M: + mp_clear(&M[1]); + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + mp_clear (&M[x]); + } + return err; +} + + +/* computes b = a*a */ +static int ICACHE_FLASH_ATTR +mp_sqr (mp_int * a, mp_int * b) +{ + int res; + +#ifdef BN_MP_TOOM_SQR_C + /* use Toom-Cook? */ + if (a->used >= TOOM_SQR_CUTOFF) { + res = mp_toom_sqr(a, b); + /* Karatsuba? */ + } else +#endif +#ifdef BN_MP_KARATSUBA_SQR_C +if (a->used >= KARATSUBA_SQR_CUTOFF) { + res = mp_karatsuba_sqr (a, b); + } else +#endif + { +#ifdef BN_FAST_S_MP_SQR_C + /* can we use the fast comba multiplier? */ + if ((a->used * 2 + 1) < MP_WARRAY && + a->used < + (1 << (sizeof(mp_word) * CHAR_BIT - 2*DIGIT_BIT - 1))) { + res = fast_s_mp_sqr (a, b); + } else +#endif +#ifdef BN_S_MP_SQR_C + res = s_mp_sqr (a, b); +#else +#error mp_sqr could fail + res = MP_VAL; +#endif + } + b->sign = MP_ZPOS; + return res; +} + + +/* reduces a modulo n where n is of the form 2**p - d + This differs from reduce_2k since "d" can be larger + than a single digit. +*/ +static int ICACHE_FLASH_ATTR +mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d) +{ + mp_int q; + int p, res; + + if ((res = mp_init(&q)) != MP_OKAY) { + return res; + } + + p = mp_count_bits(n); +top: + /* q = a/2**p, a = a mod 2**p */ + if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) { + goto ERR; + } + + /* q = q * d */ + if ((res = mp_mul(&q, d, &q)) != MP_OKAY) { + goto ERR; + } + + /* a = a + q */ + if ((res = s_mp_add(a, &q, a)) != MP_OKAY) { + goto ERR; + } + + if (mp_cmp_mag(a, n) != MP_LT) { + s_mp_sub(a, n, a); + goto top; + } + +ERR: + mp_clear(&q); + return res; +} + + +/* determines the setup value */ +static int ICACHE_FLASH_ATTR +mp_reduce_2k_setup_l(mp_int *a, mp_int *d) +{ + int res; + mp_int tmp; + + if ((res = mp_init(&tmp)) != MP_OKAY) { + return res; + } + + if ((res = mp_2expt(&tmp, mp_count_bits(a))) != MP_OKAY) { + goto ERR; + } + + if ((res = s_mp_sub(&tmp, a, d)) != MP_OKAY) { + goto ERR; + } + +ERR: + mp_clear(&tmp); + return res; +} + + +/* computes a = 2**b + * + * Simple algorithm which zeroes the int, grows it then just sets one bit + * as required. + */ +static int ICACHE_FLASH_ATTR +mp_2expt (mp_int * a, int b) +{ + int res; + + /* zero a as per default */ + mp_zero (a); + + /* grow a to accommodate the single bit */ + if ((res = mp_grow (a, b / DIGIT_BIT + 1)) != MP_OKAY) { + return res; + } + + /* set the used count of where the bit will go */ + a->used = b / DIGIT_BIT + 1; + + /* put the single bit in its place */ + a->dp[b / DIGIT_BIT] = ((mp_digit)1) << (b % DIGIT_BIT); + + return MP_OKAY; +} + + +/* pre-calculate the value required for Barrett reduction + * For a given modulus "b" it calulates the value required in "a" + */ +static int ICACHE_FLASH_ATTR +mp_reduce_setup (mp_int * a, mp_int * b) +{ + int res; + + if ((res = mp_2expt (a, b->used * 2 * DIGIT_BIT)) != MP_OKAY) { + return res; + } + return mp_div (a, b, a, NULL); +} + + +/* reduces x mod m, assumes 0 < x < m**2, mu is + * precomputed via mp_reduce_setup. + * From HAC pp.604 Algorithm 14.42 + */ +static int ICACHE_FLASH_ATTR +mp_reduce (mp_int * x, mp_int * m, mp_int * mu) +{ + mp_int q; + int res, um = m->used; + + /* q = x */ + if ((res = mp_init_copy (&q, x)) != MP_OKAY) { + return res; + } + + /* q1 = x / b**(k-1) */ + mp_rshd (&q, um - 1); + + /* according to HAC this optimization is ok */ + if (((unsigned long) um) > (((mp_digit)1) << (DIGIT_BIT - 1))) { + if ((res = mp_mul (&q, mu, &q)) != MP_OKAY) { + goto CLEANUP; + } + } else { +#ifdef BN_S_MP_MUL_HIGH_DIGS_C + if ((res = s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) { + goto CLEANUP; + } +#elif defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C) + if ((res = fast_s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) { + goto CLEANUP; + } +#else + { +#error mp_reduce would always fail + res = MP_VAL; + goto CLEANUP; + } +#endif + } + + /* q3 = q2 / b**(k+1) */ + mp_rshd (&q, um + 1); + + /* x = x mod b**(k+1), quick (no division) */ + if ((res = mp_mod_2d (x, DIGIT_BIT * (um + 1), x)) != MP_OKAY) { + goto CLEANUP; + } + + /* q = q * m mod b**(k+1), quick (no division) */ + if ((res = s_mp_mul_digs (&q, m, &q, um + 1)) != MP_OKAY) { + goto CLEANUP; + } + + /* x = x - q */ + if ((res = mp_sub (x, &q, x)) != MP_OKAY) { + goto CLEANUP; + } + + /* If x < 0, add b**(k+1) to it */ + if (mp_cmp_d (x, 0) == MP_LT) { + mp_set (&q, 1); + if ((res = mp_lshd (&q, um + 1)) != MP_OKAY) { + goto CLEANUP; + } + if ((res = mp_add (x, &q, x)) != MP_OKAY) { + goto CLEANUP; + } + } + + /* Back off if it's too big */ + while (mp_cmp (x, m) != MP_LT) { + if ((res = s_mp_sub (x, m, x)) != MP_OKAY) { + goto CLEANUP; + } + } + +CLEANUP: + mp_clear (&q); + + return res; +} + + +/* multiplies |a| * |b| and only computes up to digs digits of result + * HAC pp. 595, Algorithm 14.12 Modified so you can control how + * many digits of output are created. + */ +static int ICACHE_FLASH_ATTR +s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) +{ + mp_int t; + int res, pa, pb, ix, iy; + mp_digit u; + mp_word r; + mp_digit tmpx, *tmpt, *tmpy; + + /* can we use the fast multiplier? */ + if (((digs) < MP_WARRAY) && + MIN (a->used, b->used) < + (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { + return fast_s_mp_mul_digs (a, b, c, digs); + } + + if ((res = mp_init_size (&t, digs)) != MP_OKAY) { + return res; + } + t.used = digs; + + /* compute the digits of the product directly */ + pa = a->used; + for (ix = 0; ix < pa; ix++) { + /* set the carry to zero */ + u = 0; + + /* limit ourselves to making digs digits of output */ + pb = MIN (b->used, digs - ix); + + /* setup some aliases */ + /* copy of the digit from a used within the nested loop */ + tmpx = a->dp[ix]; + + /* an alias for the destination shifted ix places */ + tmpt = t.dp + ix; + + /* an alias for the digits of b */ + tmpy = b->dp; + + /* compute the columns of the output and propagate the carry */ + for (iy = 0; iy < pb; iy++) { + /* compute the column as a mp_word */ + r = ((mp_word)*tmpt) + + ((mp_word)tmpx) * ((mp_word)*tmpy++) + + ((mp_word) u); + + /* the new column is the lower part of the result */ + *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* get the carry word from the result */ + u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); + } + /* set carry if it is placed below digs */ + if (ix + iy < digs) { + *tmpt = u; + } + } + + mp_clamp (&t); + mp_exch (&t, c); + + mp_clear (&t); + return MP_OKAY; +} + + +/* Fast (comba) multiplier + * + * This is the fast column-array [comba] multiplier. It is + * designed to compute the columns of the product first + * then handle the carries afterwards. This has the effect + * of making the nested loops that compute the columns very + * simple and schedulable on super-scalar processors. + * + * This has been modified to produce a variable number of + * digits of output so if say only a half-product is required + * you don't have to compute the upper half (a feature + * required for fast Barrett reduction). + * + * Based on Algorithm 14.12 on pp.595 of HAC. + * + */ +static int ICACHE_FLASH_ATTR +fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) +{ + int olduse, res, pa, ix, iz; + mp_digit W[MP_WARRAY]; + register mp_word _W; + + /* grow the destination as required */ + if (c->alloc < digs) { + if ((res = mp_grow (c, digs)) != MP_OKAY) { + return res; + } + } + + /* number of output digits to produce */ + pa = MIN(digs, a->used + b->used); + + /* clear the carry */ + _W = 0; + for (ix = 0; ix < pa; ix++) { + int tx, ty; + int iy; + mp_digit *tmpx, *tmpy; + + /* get offsets into the two bignums */ + ty = MIN(b->used-1, ix); + tx = ix - ty; + + /* setup temp aliases */ + tmpx = a->dp + tx; + tmpy = b->dp + ty; + + /* this is the number of times the loop will iterrate, essentially + while (tx++ < a->used && ty-- >= 0) { ... } + */ + iy = MIN(a->used-tx, ty+1); + + /* execute loop */ + for (iz = 0; iz < iy; ++iz) { + _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); + + } + + /* store term */ + W[ix] = ((mp_digit)_W) & MP_MASK; + + /* make next carry */ + _W = _W >> ((mp_word)DIGIT_BIT); + } + + /* setup dest */ + olduse = c->used; + c->used = pa; + + { + register mp_digit *tmpc; + tmpc = c->dp; + for (ix = 0; ix < pa+1; ix++) { + /* now extract the previous digit [below the carry] */ + *tmpc++ = W[ix]; + } + + /* clear unused digits [that existed in the old copy of c] */ + for (; ix < olduse; ix++) { + *tmpc++ = 0; + } + } + mp_clamp (c); + return MP_OKAY; +} + + +/* init an mp_init for a given size */ +static int ICACHE_FLASH_ATTR +mp_init_size (mp_int * a, int size) +{ + int x; + + /* pad size so there are always extra digits */ + size += (MP_PREC * 2) - (size % MP_PREC); + + /* alloc mem */ + a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * size); + if (a->dp == NULL) { + return MP_MEM; + } + + /* set the members */ + a->used = 0; + a->alloc = size; + a->sign = MP_ZPOS; + + /* zero the digits */ + for (x = 0; x < size; x++) { + a->dp[x] = 0; + } + + return MP_OKAY; +} + + +/* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */ +static int ICACHE_FLASH_ATTR +s_mp_sqr (mp_int * a, mp_int * b) +{ + mp_int t; + int res, ix, iy, pa; + mp_word r; + mp_digit u, tmpx, *tmpt; + + pa = a->used; + if ((res = mp_init_size (&t, 2*pa + 1)) != MP_OKAY) { + return res; + } + + /* default used is maximum possible size */ + t.used = 2*pa + 1; + + for (ix = 0; ix < pa; ix++) { + /* first calculate the digit at 2*ix */ + /* calculate double precision result */ + r = ((mp_word) t.dp[2*ix]) + + ((mp_word)a->dp[ix])*((mp_word)a->dp[ix]); + + /* store lower part in result */ + t.dp[ix+ix] = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* get the carry */ + u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + + /* left hand side of A[ix] * A[iy] */ + tmpx = a->dp[ix]; + + /* alias for where to store the results */ + tmpt = t.dp + (2*ix + 1); + + for (iy = ix + 1; iy < pa; iy++) { + /* first calculate the product */ + r = ((mp_word)tmpx) * ((mp_word)a->dp[iy]); + + /* now calculate the double precision result, note we use + * addition instead of *2 since it's easier to optimize + */ + r = ((mp_word) *tmpt) + r + r + ((mp_word) u); + + /* store lower part */ + *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* get carry */ + u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + } + /* propagate upwards */ + while (u != ((mp_digit) 0)) { + r = ((mp_word) *tmpt) + ((mp_word) u); + *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); + u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + } + } + + mp_clamp (&t); + mp_exch (&t, b); + mp_clear (&t); + return MP_OKAY; +} + + +/* multiplies |a| * |b| and does not compute the lower digs digits + * [meant to get the higher part of the product] + */ +static int ICACHE_FLASH_ATTR +s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) +{ + mp_int t; + int res, pa, pb, ix, iy; + mp_digit u; + mp_word r; + mp_digit tmpx, *tmpt, *tmpy; + + /* can we use the fast multiplier? */ +#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C + if (((a->used + b->used + 1) < MP_WARRAY) + && MIN (a->used, b->used) < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { + return fast_s_mp_mul_high_digs (a, b, c, digs); + } +#endif + + if ((res = mp_init_size (&t, a->used + b->used + 1)) != MP_OKAY) { + return res; + } + t.used = a->used + b->used + 1; + + pa = a->used; + pb = b->used; + for (ix = 0; ix < pa; ix++) { + /* clear the carry */ + u = 0; + + /* left hand side of A[ix] * B[iy] */ + tmpx = a->dp[ix]; + + /* alias to the address of where the digits will be stored */ + tmpt = &(t.dp[digs]); + + /* alias for where to read the right hand side from */ + tmpy = b->dp + (digs - ix); + + for (iy = digs - ix; iy < pb; iy++) { + /* calculate the double precision result */ + r = ((mp_word)*tmpt) + + ((mp_word)tmpx) * ((mp_word)*tmpy++) + + ((mp_word) u); + + /* get the lower part */ + *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* carry the carry */ + u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); + } + *tmpt = u; + } + mp_clamp (&t); + mp_exch (&t, c); + mp_clear (&t); + return MP_OKAY; +} + + +#ifdef BN_MP_MONTGOMERY_SETUP_C +/* setups the montgomery reduction stuff */ +static int ICACHE_FLASH_ATTR +mp_montgomery_setup (mp_int * n, mp_digit * rho) +{ + mp_digit x, b; + +/* fast inversion mod 2**k + * + * Based on the fact that + * + * XA = 1 (mod 2**n) => (X(2-XA)) A = 1 (mod 2**2n) + * => 2*X*A - X*X*A*A = 1 + * => 2*(1) - (1) = 1 + */ + b = n->dp[0]; + + if ((b & 1) == 0) { + return MP_VAL; + } + + x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ + x *= 2 - b * x; /* here x*a==1 mod 2**8 */ +#if !defined(MP_8BIT) + x *= 2 - b * x; /* here x*a==1 mod 2**16 */ +#endif +#if defined(MP_64BIT) || !(defined(MP_8BIT) || defined(MP_16BIT)) + x *= 2 - b * x; /* here x*a==1 mod 2**32 */ +#endif +#ifdef MP_64BIT + x *= 2 - b * x; /* here x*a==1 mod 2**64 */ +#endif + + /* rho = -1/m mod b */ + *rho = (unsigned long)(((mp_word)1 << ((mp_word) DIGIT_BIT)) - x) & MP_MASK; + + return MP_OKAY; +} +#endif + + +#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C +/* computes xR**-1 == x (mod N) via Montgomery Reduction + * + * This is an optimized implementation of montgomery_reduce + * which uses the comba method to quickly calculate the columns of the + * reduction. + * + * Based on Algorithm 14.32 on pp.601 of HAC. +*/ +int ICACHE_FLASH_ATTR +fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) +{ + int ix, res, olduse; + mp_word W[MP_WARRAY]; + + /* get old used count */ + olduse = x->used; + + /* grow a as required */ + if (x->alloc < n->used + 1) { + if ((res = mp_grow (x, n->used + 1)) != MP_OKAY) { + return res; + } + } + + /* first we have to get the digits of the input into + * an array of double precision words W[...] + */ + { + register mp_word *_W; + register mp_digit *tmpx; + + /* alias for the W[] array */ + _W = W; + + /* alias for the digits of x*/ + tmpx = x->dp; + + /* copy the digits of a into W[0..a->used-1] */ + for (ix = 0; ix < x->used; ix++) { + *_W++ = *tmpx++; + } + + /* zero the high words of W[a->used..m->used*2] */ + for (; ix < n->used * 2 + 1; ix++) { + *_W++ = 0; + } + } + + /* now we proceed to zero successive digits + * from the least significant upwards + */ + for (ix = 0; ix < n->used; ix++) { + /* mu = ai * m' mod b + * + * We avoid a double precision multiplication (which isn't required) + * by casting the value down to a mp_digit. Note this requires + * that W[ix-1] have the carry cleared (see after the inner loop) + */ + register mp_digit mu; + mu = (mp_digit) (((W[ix] & MP_MASK) * rho) & MP_MASK); + + /* a = a + mu * m * b**i + * + * This is computed in place and on the fly. The multiplication + * by b**i is handled by offseting which columns the results + * are added to. + * + * Note the comba method normally doesn't handle carries in the + * inner loop In this case we fix the carry from the previous + * column since the Montgomery reduction requires digits of the + * result (so far) [see above] to work. This is + * handled by fixing up one carry after the inner loop. The + * carry fixups are done in order so after these loops the + * first m->used words of W[] have the carries fixed + */ + { + register int iy; + register mp_digit *tmpn; + register mp_word *_W; + + /* alias for the digits of the modulus */ + tmpn = n->dp; + + /* Alias for the columns set by an offset of ix */ + _W = W + ix; + + /* inner loop */ + for (iy = 0; iy < n->used; iy++) { + *_W++ += ((mp_word)mu) * ((mp_word)*tmpn++); + } + } + + /* now fix carry for next digit, W[ix+1] */ + W[ix + 1] += W[ix] >> ((mp_word) DIGIT_BIT); + } + + /* now we have to propagate the carries and + * shift the words downward [all those least + * significant digits we zeroed]. + */ + { + register mp_digit *tmpx; + register mp_word *_W, *_W1; + + /* nox fix rest of carries */ + + /* alias for current word */ + _W1 = W + ix; + + /* alias for next word, where the carry goes */ + _W = W + ++ix; + + for (; ix <= n->used * 2 + 1; ix++) { + *_W++ += *_W1++ >> ((mp_word) DIGIT_BIT); + } + + /* copy out, A = A/b**n + * + * The result is A/b**n but instead of converting from an + * array of mp_word to mp_digit than calling mp_rshd + * we just copy them in the right order + */ + + /* alias for destination word */ + tmpx = x->dp; + + /* alias for shifted double precision result */ + _W = W + n->used; + + for (ix = 0; ix < n->used + 1; ix++) { + *tmpx++ = (mp_digit)(*_W++ & ((mp_word) MP_MASK)); + } + + /* zero oldused digits, if the input a was larger than + * m->used+1 we'll have to clear the digits + */ + for (; ix < olduse; ix++) { + *tmpx++ = 0; + } + } + + /* set the max used and clamp */ + x->used = n->used + 1; + mp_clamp (x); + + /* if A >= m then A = A - m */ + if (mp_cmp_mag (x, n) != MP_LT) { + return s_mp_sub (x, n, x); + } + return MP_OKAY; +} +#endif + + +#ifdef BN_MP_MUL_2_C +/* b = a*2 */ +static int ICACHE_FLASH_ATTR +mp_mul_2(mp_int * a, mp_int * b) +{ + int x, res, oldused; + + /* grow to accommodate result */ + if (b->alloc < a->used + 1) { + if ((res = mp_grow (b, a->used + 1)) != MP_OKAY) { + return res; + } + } + + oldused = b->used; + b->used = a->used; + + { + register mp_digit r, rr, *tmpa, *tmpb; + + /* alias for source */ + tmpa = a->dp; + + /* alias for dest */ + tmpb = b->dp; + + /* carry */ + r = 0; + for (x = 0; x < a->used; x++) { + + /* get what will be the *next* carry bit from the + * MSB of the current digit + */ + rr = *tmpa >> ((mp_digit)(DIGIT_BIT - 1)); + + /* now shift up this digit, add in the carry [from the previous] */ + *tmpb++ = ((*tmpa++ << ((mp_digit)1)) | r) & MP_MASK; + + /* copy the carry that would be from the source + * digit into the next iteration + */ + r = rr; + } + + /* new leading digit? */ + if (r != 0) { + /* add a MSB which is always 1 at this point */ + *tmpb = 1; + ++(b->used); + } + + /* now zero any excess digits on the destination + * that we didn't write to + */ + tmpb = b->dp + b->used; + for (x = b->used; x < oldused; x++) { + *tmpb++ = 0; + } + } + b->sign = a->sign; + return MP_OKAY; +} +#endif + + +#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C +/* + * shifts with subtractions when the result is greater than b. + * + * The method is slightly modified to shift B unconditionally up to just under + * the leading bit of b. This saves a lot of multiple precision shifting. + */ +static int ICACHE_FLASH_ATTR +mp_montgomery_calc_normalization (mp_int * a, mp_int * b) +{ + int x, bits, res; + + /* how many bits of last digit does b use */ + bits = mp_count_bits (b) % DIGIT_BIT; + + if (b->used > 1) { + if ((res = mp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1)) != MP_OKAY) { + return res; + } + } else { + mp_set(a, 1); + bits = 1; + } + + + /* now compute C = A * B mod b */ + for (x = bits - 1; x < (int)DIGIT_BIT; x++) { + if ((res = mp_mul_2 (a, a)) != MP_OKAY) { + return res; + } + if (mp_cmp_mag (a, b) != MP_LT) { + if ((res = s_mp_sub (a, b, a)) != MP_OKAY) { + return res; + } + } + } + + return MP_OKAY; +} +#endif + + +#ifdef BN_MP_EXPTMOD_FAST_C +/* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85 + * + * Uses a left-to-right k-ary sliding window to compute the modular exponentiation. + * The value of k changes based on the size of the exponent. + * + * Uses Montgomery or Diminished Radix reduction [whichever appropriate] + */ + +static int ICACHE_FLASH_ATTR +mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) +{ + mp_int M[TAB_SIZE], res; + mp_digit buf, mp; + int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; + + /* use a pointer to the reduction algorithm. This allows us to use + * one of many reduction algorithms without modding the guts of + * the code with if statements everywhere. + */ + int (*redux)(mp_int*,mp_int*,mp_digit); + + /* find window size */ + x = mp_count_bits (X); + if (x <= 7) { + winsize = 2; + } else if (x <= 36) { + winsize = 3; + } else if (x <= 140) { + winsize = 4; + } else if (x <= 450) { + winsize = 5; + } else if (x <= 1303) { + winsize = 6; + } else if (x <= 3529) { + winsize = 7; + } else { + winsize = 8; + } + +#ifdef MP_LOW_MEM + if (winsize > 5) { + winsize = 5; + } +#endif + + /* init M array */ + /* init first cell */ + if ((err = mp_init(&M[1])) != MP_OKAY) { + return err; + } + + /* now init the second half of the array */ + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + if ((err = mp_init(&M[x])) != MP_OKAY) { + for (y = 1<<(winsize-1); y < x; y++) { + mp_clear (&M[y]); + } + mp_clear(&M[1]); + return err; + } + } + + /* determine and setup reduction code */ + if (redmode == 0) { +#ifdef BN_MP_MONTGOMERY_SETUP_C + /* now setup montgomery */ + if ((err = mp_montgomery_setup (P, &mp)) != MP_OKAY) { + goto LBL_M; + } +#else + err = MP_VAL; + goto LBL_M; +#endif + + /* automatically pick the comba one if available (saves quite a few calls/ifs) */ +#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C + if (((P->used * 2 + 1) < MP_WARRAY) && + P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { + redux = fast_mp_montgomery_reduce; + } else +#endif + { +#ifdef BN_MP_MONTGOMERY_REDUCE_C + /* use slower baseline Montgomery method */ + redux = mp_montgomery_reduce; +#else + err = MP_VAL; + goto LBL_M; +#endif + } + } else if (redmode == 1) { +#if defined(BN_MP_DR_SETUP_C) && defined(BN_MP_DR_REDUCE_C) + /* setup DR reduction for moduli of the form B**k - b */ + mp_dr_setup(P, &mp); + redux = mp_dr_reduce; +#else + err = MP_VAL; + goto LBL_M; +#endif + } else { +#if defined(BN_MP_REDUCE_2K_SETUP_C) && defined(BN_MP_REDUCE_2K_C) + /* setup DR reduction for moduli of the form 2**k - b */ + if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) { + goto LBL_M; + } + redux = mp_reduce_2k; +#else + err = MP_VAL; + goto LBL_M; +#endif + } + + /* setup result */ + if ((err = mp_init (&res)) != MP_OKAY) { + goto LBL_M; + } + + /* create M table + * + + * + * The first half of the table is not computed though accept for M[0] and M[1] + */ + + if (redmode == 0) { +#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C + /* now we need R mod m */ + if ((err = mp_montgomery_calc_normalization (&res, P)) != MP_OKAY) { + goto LBL_RES; + } +#else + err = MP_VAL; + goto LBL_RES; +#endif + + /* now set M[1] to G * R mod m */ + if ((err = mp_mulmod (G, &res, P, &M[1])) != MP_OKAY) { + goto LBL_RES; + } + } else { + mp_set(&res, 1); + if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) { + goto LBL_RES; + } + } + + /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */ + if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) { + goto LBL_RES; + } + + for (x = 0; x < (winsize - 1); x++) { + if ((err = mp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)])) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&M[1 << (winsize - 1)], P, mp)) != MP_OKAY) { + goto LBL_RES; + } + } + + /* create upper table */ + for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { + if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&M[x], P, mp)) != MP_OKAY) { + goto LBL_RES; + } + } + + /* set initial mode and bit cnt */ + mode = 0; + bitcnt = 1; + buf = 0; + digidx = X->used - 1; + bitcpy = 0; + bitbuf = 0; + + for (;;) { + /* grab next digit as required */ + if (--bitcnt == 0) { + /* if digidx == -1 we are out of digits so break */ + if (digidx == -1) { + break; + } + /* read next digit and reset bitcnt */ + buf = X->dp[digidx--]; + bitcnt = (int)DIGIT_BIT; + } + + /* grab the next msb from the exponent */ + y = (mp_digit)(buf >> (DIGIT_BIT - 1)) & 1; + buf <<= (mp_digit)1; + + /* if the bit is zero and mode == 0 then we ignore it + * These represent the leading zero bits before the first 1 bit + * in the exponent. Technically this opt is not required but it + * does lower the # of trivial squaring/reductions used + */ + if (mode == 0 && y == 0) { + continue; + } + + /* if the bit is zero and mode == 1 then we square */ + if (mode == 1 && y == 0) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + continue; + } + + /* else we add it to the window */ + bitbuf |= (y << (winsize - ++bitcpy)); + mode = 2; + + if (bitcpy == winsize) { + /* ok window is filled so square as required and multiply */ + /* square first */ + for (x = 0; x < winsize; x++) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + } + + /* then multiply */ + if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + + /* empty window and reset */ + bitcpy = 0; + bitbuf = 0; + mode = 1; + } + } + + /* if bits remain then square/multiply */ + if (mode == 2 && bitcpy > 0) { + /* square then multiply if the bit is set */ + for (x = 0; x < bitcpy; x++) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + + /* get next bit of the window */ + bitbuf <<= 1; + if ((bitbuf & (1 << winsize)) != 0) { + /* then multiply */ + if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + } + } + } + + if (redmode == 0) { + /* fixup result if Montgomery reduction is used + * recall that any value in a Montgomery system is + * actually multiplied by R mod n. So we have + * to reduce one more time to cancel out the factor + * of R. + */ + if ((err = redux(&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + } + + /* swap res with Y */ + mp_exch (&res, Y); + err = MP_OKAY; +LBL_RES:mp_clear (&res); +LBL_M: + mp_clear(&M[1]); + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + mp_clear (&M[x]); + } + return err; +} +#endif + + +#ifdef BN_FAST_S_MP_SQR_C +/* the jist of squaring... + * you do like mult except the offset of the tmpx [one that + * starts closer to zero] can't equal the offset of tmpy. + * So basically you set up iy like before then you min it with + * (ty-tx) so that it never happens. You double all those + * you add in the inner loop + +After that loop you do the squares and add them in. +*/ + +static int ICACHE_FLASH_ATTR +fast_s_mp_sqr (mp_int * a, mp_int * b) +{ + int olduse, res, pa, ix, iz; + mp_digit W[MP_WARRAY], *tmpx; + mp_word W1; + + /* grow the destination as required */ + pa = a->used + a->used; + if (b->alloc < pa) { + if ((res = mp_grow (b, pa)) != MP_OKAY) { + return res; + } + } + + /* number of output digits to produce */ + W1 = 0; + for (ix = 0; ix < pa; ix++) { + int tx, ty, iy; + mp_word _W; + mp_digit *tmpy; + + /* clear counter */ + _W = 0; + + /* get offsets into the two bignums */ + ty = MIN(a->used-1, ix); + tx = ix - ty; + + /* setup temp aliases */ + tmpx = a->dp + tx; + tmpy = a->dp + ty; + + /* this is the number of times the loop will iterrate, essentially + while (tx++ < a->used && ty-- >= 0) { ... } + */ + iy = MIN(a->used-tx, ty+1); + + /* now for squaring tx can never equal ty + * we halve the distance since they approach at a rate of 2x + * and we have to round because odd cases need to be executed + */ + iy = MIN(iy, (ty-tx+1)>>1); + + /* execute loop */ + for (iz = 0; iz < iy; iz++) { + _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); + } + + /* double the inner product and add carry */ + _W = _W + _W + W1; + + /* even columns have the square term in them */ + if ((ix&1) == 0) { + _W += ((mp_word)a->dp[ix>>1])*((mp_word)a->dp[ix>>1]); + } + + /* store it */ + W[ix] = (mp_digit)(_W & MP_MASK); + + /* make next carry */ + W1 = _W >> ((mp_word)DIGIT_BIT); + } + + /* setup dest */ + olduse = b->used; + b->used = a->used+a->used; + + { + mp_digit *tmpb; + tmpb = b->dp; + for (ix = 0; ix < pa; ix++) { + *tmpb++ = W[ix] & MP_MASK; + } + + /* clear unused digits [that existed in the old copy of c] */ + for (; ix < olduse; ix++) { + *tmpb++ = 0; + } + } + mp_clamp (b); + return MP_OKAY; +} +#endif + + +#ifdef BN_MP_MUL_D_C +/* multiply by a digit */ +static int ICACHE_FLASH_ATTR +mp_mul_d (mp_int * a, mp_digit b, mp_int * c) +{ + mp_digit u, *tmpa, *tmpc; + mp_word r; + int ix, res, olduse; + + /* make sure c is big enough to hold a*b */ + if (c->alloc < a->used + 1) { + if ((res = mp_grow (c, a->used + 1)) != MP_OKAY) { + return res; + } + } + + /* get the original destinations used count */ + olduse = c->used; + + /* set the sign */ + c->sign = a->sign; + + /* alias for a->dp [source] */ + tmpa = a->dp; + + /* alias for c->dp [dest] */ + tmpc = c->dp; + + /* zero carry */ + u = 0; + + /* compute columns */ + for (ix = 0; ix < a->used; ix++) { + /* compute product and carry sum for this term */ + r = ((mp_word) u) + ((mp_word)*tmpa++) * ((mp_word)b); + + /* mask off higher bits to get a single digit */ + *tmpc++ = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* send carry into next iteration */ + u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); + } + + /* store final carry [if any] and increment ix offset */ + *tmpc++ = u; + ++ix; + + /* now zero digits above the top */ + while (ix++ < olduse) { + *tmpc++ = 0; + } + + /* set used count */ + c->used = a->used + 1; + mp_clamp(c); + + return MP_OKAY; +} +#endif diff --git a/components/wpa_supplicant/include/wpa2/tls/pkcs1.h b/components/wpa_supplicant/include/wpa2/tls/pkcs1.h new file mode 100644 index 0000000000..ed64defaaf --- /dev/null +++ b/components/wpa_supplicant/include/wpa2/tls/pkcs1.h @@ -0,0 +1,22 @@ +/* + * PKCS #1 (RSA Encryption) + * Copyright (c) 2006-2009, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef PKCS1_H +#define PKCS1_H + +int pkcs1_encrypt(int block_type, struct crypto_rsa_key *key, + int use_private, const u8 *in, size_t inlen, + u8 *out, size_t *outlen); +int pkcs1_v15_private_key_decrypt(struct crypto_rsa_key *key, + const u8 *in, size_t inlen, + u8 *out, size_t *outlen); +int pkcs1_decrypt_public_key(struct crypto_rsa_key *key, + const u8 *crypt, size_t crypt_len, + u8 *plain, size_t *plain_len); + +#endif /* PKCS1_H */ diff --git a/components/wpa_supplicant/include/wpa2/tls/pkcs5.h b/components/wpa_supplicant/include/wpa2/tls/pkcs5.h new file mode 100644 index 0000000000..20ddadc457 --- /dev/null +++ b/components/wpa_supplicant/include/wpa2/tls/pkcs5.h @@ -0,0 +1,16 @@ +/* + * PKCS #5 (Password-based Encryption) + * Copyright (c) 2009, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef PKCS5_H +#define PKCS5_H + +u8 * pkcs5_decrypt(const u8 *enc_alg, size_t enc_alg_len, + const u8 *enc_data, size_t enc_data_len, + const char *passwd, size_t *data_len); + +#endif /* PKCS5_H */ diff --git a/components/wpa_supplicant/include/wpa2/tls/pkcs8.h b/components/wpa_supplicant/include/wpa2/tls/pkcs8.h new file mode 100644 index 0000000000..bebf840ba7 --- /dev/null +++ b/components/wpa_supplicant/include/wpa2/tls/pkcs8.h @@ -0,0 +1,16 @@ +/* + * PKCS #8 (Private-key information syntax) + * Copyright (c) 2006-2009, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef PKCS8_H +#define PKCS8_H + +struct crypto_private_key * pkcs8_key_import(const u8 *buf, size_t len); +struct crypto_private_key * +pkcs8_enc_key_import(const u8 *buf, size_t len, const char *passwd); + +#endif /* PKCS8_H */ diff --git a/components/wpa_supplicant/include/wpa2/tls/rsa.h b/components/wpa_supplicant/include/wpa2/tls/rsa.h new file mode 100644 index 0000000000..c236a9df44 --- /dev/null +++ b/components/wpa_supplicant/include/wpa2/tls/rsa.h @@ -0,0 +1,23 @@ +/* + * RSA + * Copyright (c) 2006, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef RSA_H +#define RSA_H + +struct crypto_rsa_key; + +struct crypto_rsa_key * +crypto_rsa_import_public_key(const u8 *buf, size_t len); +struct crypto_rsa_key * +crypto_rsa_import_private_key(const u8 *buf, size_t len); +size_t crypto_rsa_get_modulus_len(struct crypto_rsa_key *key); +int crypto_rsa_exptmod(const u8 *in, size_t inlen, u8 *out, size_t *outlen, + struct crypto_rsa_key *key, int use_private); +void crypto_rsa_free(struct crypto_rsa_key *key); + +#endif /* RSA_H */ diff --git a/components/wpa_supplicant/include/wpa2/tls/tls.h b/components/wpa_supplicant/include/wpa2/tls/tls.h new file mode 100644 index 0000000000..983999b51d --- /dev/null +++ b/components/wpa_supplicant/include/wpa2/tls/tls.h @@ -0,0 +1,537 @@ +/* + * SSL/TLS interface definition + * Copyright (c) 2004-2013, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef TLS_H +#define TLS_H + +struct tls_connection; + +struct tls_keys { + const u8 *master_key; /* TLS master secret */ + size_t master_key_len; + const u8 *client_random; + size_t client_random_len; + const u8 *server_random; + size_t server_random_len; +}; + +enum tls_event { + TLS_CERT_CHAIN_SUCCESS, + TLS_CERT_CHAIN_FAILURE, + TLS_PEER_CERTIFICATE, + TLS_ALERT +}; + +/* + * Note: These are used as identifier with external programs and as such, the + * values must not be changed. + */ +enum tls_fail_reason { + TLS_FAIL_UNSPECIFIED = 0, + TLS_FAIL_UNTRUSTED = 1, + TLS_FAIL_REVOKED = 2, + TLS_FAIL_NOT_YET_VALID = 3, + TLS_FAIL_EXPIRED = 4, + TLS_FAIL_SUBJECT_MISMATCH = 5, + TLS_FAIL_ALTSUBJECT_MISMATCH = 6, + TLS_FAIL_BAD_CERTIFICATE = 7, + TLS_FAIL_SERVER_CHAIN_PROBE = 8 +}; + +union tls_event_data { + struct { + int depth; + const char *subject; + enum tls_fail_reason reason; + const char *reason_txt; + const struct wpabuf *cert; + } cert_fail; + + struct { + int depth; + const char *subject; + const struct wpabuf *cert; + const u8 *hash; + size_t hash_len; + } peer_cert; + + struct { + int is_local; + const char *type; + const char *description; + } alert; +}; + +struct tls_config { + const char *opensc_engine_path; + const char *pkcs11_engine_path; + const char *pkcs11_module_path; + int fips_mode; + int cert_in_cb; + + void (*event_cb)(void *ctx, enum tls_event ev, + union tls_event_data *data); + void *cb_ctx; +}; + +#define TLS_CONN_ALLOW_SIGN_RSA_MD5 BIT(0) +#define TLS_CONN_DISABLE_TIME_CHECKS BIT(1) +#define TLS_CONN_DISABLE_SESSION_TICKET BIT(2) +#define TLS_CONN_REQUEST_OCSP BIT(3) +#define TLS_CONN_REQUIRE_OCSP BIT(4) + +/** + * struct tls_connection_params - Parameters for TLS connection + * @ca_cert: File or reference name for CA X.509 certificate in PEM or DER + * format + * @ca_cert_blob: ca_cert as inlined data or %NULL if not used + * @ca_cert_blob_len: ca_cert_blob length + * @ca_path: Path to CA certificates (OpenSSL specific) + * @subject_match: String to match in the subject of the peer certificate or + * %NULL to allow all subjects + * @altsubject_match: String to match in the alternative subject of the peer + * certificate or %NULL to allow all alternative subjects + * @client_cert: File or reference name for client X.509 certificate in PEM or + * DER format + * @client_cert_blob: client_cert as inlined data or %NULL if not used + * @client_cert_blob_len: client_cert_blob length + * @private_key: File or reference name for client private key in PEM or DER + * format (traditional format (RSA PRIVATE KEY) or PKCS#8 (PRIVATE KEY) + * @private_key_blob: private_key as inlined data or %NULL if not used + * @private_key_blob_len: private_key_blob length + * @private_key_passwd: Passphrase for decrypted private key, %NULL if no + * passphrase is used. + * @dh_file: File name for DH/DSA data in PEM format, or %NULL if not used + * @dh_blob: dh_file as inlined data or %NULL if not used + * @dh_blob_len: dh_blob length + * @engine: 1 = use engine (e.g., a smartcard) for private key operations + * (this is OpenSSL specific for now) + * @engine_id: engine id string (this is OpenSSL specific for now) + * @ppin: pointer to the pin variable in the configuration + * (this is OpenSSL specific for now) + * @key_id: the private key's id when using engine (this is OpenSSL + * specific for now) + * @cert_id: the certificate's id when using engine + * @ca_cert_id: the CA certificate's id when using engine + * @flags: Parameter options (TLS_CONN_*) + * @ocsp_stapling_response: DER encoded file with cached OCSP stapling response + * or %NULL if OCSP is not enabled + * + * TLS connection parameters to be configured with tls_connection_set_params() + * and tls_global_set_params(). + * + * Certificates and private key can be configured either as a reference name + * (file path or reference to certificate store) or by providing the same data + * as a pointer to the data in memory. Only one option will be used for each + * field. + */ +struct tls_connection_params { + const char *ca_cert; + const u8 *ca_cert_blob; + size_t ca_cert_blob_len; + const char *ca_path; + const char *subject_match; + const char *altsubject_match; + const char *client_cert; + const u8 *client_cert_blob; + size_t client_cert_blob_len; + const char *private_key; + const u8 *private_key_blob; + size_t private_key_blob_len; + const char *private_key_passwd; + const char *dh_file; + const u8 *dh_blob; + size_t dh_blob_len; + + /* OpenSSL specific variables */ + int engine; + const char *engine_id; + const char *pin; + const char *key_id; + const char *cert_id; + const char *ca_cert_id; + + unsigned int flags; + const char *ocsp_stapling_response; +}; + + +/** + * tls_init - Initialize TLS library + * @conf: Configuration data for TLS library + * Returns: Context data to be used as tls_ctx in calls to other functions, + * or %NULL on failure. + * + * Called once during program startup and once for each RSN pre-authentication + * session. In other words, there can be two concurrent TLS contexts. If global + * library initialization is needed (i.e., one that is shared between both + * authentication types), the TLS library wrapper should maintain a reference + * counter and do global initialization only when moving from 0 to 1 reference. + */ +void * tls_init(void); + +/** + * tls_deinit - Deinitialize TLS library + * @tls_ctx: TLS context data from tls_init() + * + * Called once during program shutdown and once for each RSN pre-authentication + * session. If global library deinitialization is needed (i.e., one that is + * shared between both authentication types), the TLS library wrapper should + * maintain a reference counter and do global deinitialization only when moving + * from 1 to 0 references. + */ +void tls_deinit(void *tls_ctx); + +/** + * tls_get_errors - Process pending errors + * @tls_ctx: TLS context data from tls_init() + * Returns: Number of found error, 0 if no errors detected. + * + * Process all pending TLS errors. + */ +int tls_get_errors(void *tls_ctx); + +/** + * tls_connection_init - Initialize a new TLS connection + * @tls_ctx: TLS context data from tls_init() + * Returns: Connection context data, conn for other function calls + */ +struct tls_connection * tls_connection_init(void *tls_ctx); + +/** + * tls_connection_deinit - Free TLS connection data + * @tls_ctx: TLS context data from tls_init() + * @conn: Connection context data from tls_connection_init() + * + * Release all resources allocated for TLS connection. + */ +void tls_connection_deinit(void *tls_ctx, struct tls_connection *conn); + +/** + * tls_connection_established - Has the TLS connection been completed? + * @tls_ctx: TLS context data from tls_init() + * @conn: Connection context data from tls_connection_init() + * Returns: 1 if TLS connection has been completed, 0 if not. + */ +int tls_connection_established(void *tls_ctx, struct tls_connection *conn); + +/** + * tls_connection_shutdown - Shutdown TLS connection + * @tls_ctx: TLS context data from tls_init() + * @conn: Connection context data from tls_connection_init() + * Returns: 0 on success, -1 on failure + * + * Shutdown current TLS connection without releasing all resources. New + * connection can be started by using the same conn without having to call + * tls_connection_init() or setting certificates etc. again. The new + * connection should try to use session resumption. + */ +int tls_connection_shutdown(void *tls_ctx, struct tls_connection *conn); + +enum { + TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED = -3, + TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED = -2 +}; + +/** + * tls_connection_set_params - Set TLS connection parameters + * @tls_ctx: TLS context data from tls_init() + * @conn: Connection context data from tls_connection_init() + * @params: Connection parameters + * Returns: 0 on success, -1 on failure, + * TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED (-2) on possible PIN error causing + * PKCS#11 engine failure, or + * TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED (-3) on failure to verify the + * PKCS#11 engine private key. + */ +int __must_check +tls_connection_set_params(void *tls_ctx, struct tls_connection *conn, + const struct tls_connection_params *params); + +/** + * tls_global_set_params - Set TLS parameters for all TLS connection + * @tls_ctx: TLS context data from tls_init() + * @params: Global TLS parameters + * Returns: 0 on success, -1 on failure, + * TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED (-2) on possible PIN error causing + * PKCS#11 engine failure, or + * TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED (-3) on failure to verify the + * PKCS#11 engine private key. + */ +int __must_check tls_global_set_params( + void *tls_ctx, const struct tls_connection_params *params); + +/** + * tls_global_set_verify - Set global certificate verification options + * @tls_ctx: TLS context data from tls_init() + * @check_crl: 0 = do not verify CRLs, 1 = verify CRL for the user certificate, + * 2 = verify CRL for all certificates + * Returns: 0 on success, -1 on failure + */ +int __must_check tls_global_set_verify(void *tls_ctx, int check_crl); + +/** + * tls_connection_set_verify - Set certificate verification options + * @tls_ctx: TLS context data from tls_init() + * @conn: Connection context data from tls_connection_init() + * @verify_peer: 1 = verify peer certificate + * Returns: 0 on success, -1 on failure + */ +int __must_check tls_connection_set_verify(void *tls_ctx, + struct tls_connection *conn, + int verify_peer); + +/** + * tls_connection_get_keys - Get master key and random data from TLS connection + * @tls_ctx: TLS context data from tls_init() + * @conn: Connection context data from tls_connection_init() + * @keys: Structure of key/random data (filled on success) + * Returns: 0 on success, -1 on failure + */ +int __must_check tls_connection_get_keys(void *tls_ctx, + struct tls_connection *conn, + struct tls_keys *keys); + +/** + * tls_connection_prf - Use TLS-PRF to derive keying material + * @tls_ctx: TLS context data from tls_init() + * @conn: Connection context data from tls_connection_init() + * @label: Label (e.g., description of the key) for PRF + * @server_random_first: seed is 0 = client_random|server_random, + * 1 = server_random|client_random + * @out: Buffer for output data from TLS-PRF + * @out_len: Length of the output buffer + * Returns: 0 on success, -1 on failure + * + * This function is optional to implement if tls_connection_get_keys() provides + * access to master secret and server/client random values. If these values are + * not exported from the TLS library, tls_connection_prf() is required so that + * further keying material can be derived from the master secret. If not + * implemented, the function will still need to be defined, but it can just + * return -1. Example implementation of this function is in tls_prf_sha1_md5() + * when it is called with seed set to client_random|server_random (or + * server_random|client_random). + */ +int __must_check tls_connection_prf(void *tls_ctx, + struct tls_connection *conn, + const char *label, + int server_random_first, + u8 *out, size_t out_len); + +/** + * tls_connection_handshake - Process TLS handshake (client side) + * @tls_ctx: TLS context data from tls_init() + * @conn: Connection context data from tls_connection_init() + * @in_data: Input data from TLS server + * @appl_data: Pointer to application data pointer, or %NULL if dropped + * Returns: Output data, %NULL on failure + * + * The caller is responsible for freeing the returned output data. If the final + * handshake message includes application data, this is decrypted and + * appl_data (if not %NULL) is set to point this data. The caller is + * responsible for freeing appl_data. + * + * This function is used during TLS handshake. The first call is done with + * in_data == %NULL and the library is expected to return ClientHello packet. + * This packet is then send to the server and a response from server is given + * to TLS library by calling this function again with in_data pointing to the + * TLS message from the server. + * + * If the TLS handshake fails, this function may return %NULL. However, if the + * TLS library has a TLS alert to send out, that should be returned as the + * output data. In this case, tls_connection_get_failed() must return failure + * (> 0). + * + * tls_connection_established() should return 1 once the TLS handshake has been + * completed successfully. + */ +struct wpabuf * tls_connection_handshake(void *tls_ctx, + struct tls_connection *conn, + const struct wpabuf *in_data, + struct wpabuf **appl_data); + +struct wpabuf * tls_connection_handshake2(void *tls_ctx, + struct tls_connection *conn, + const struct wpabuf *in_data, + struct wpabuf **appl_data, + int *more_data_needed); + +/** + * tls_connection_server_handshake - Process TLS handshake (server side) + * @tls_ctx: TLS context data from tls_init() + * @conn: Connection context data from tls_connection_init() + * @in_data: Input data from TLS peer + * @appl_data: Pointer to application data pointer, or %NULL if dropped + * Returns: Output data, %NULL on failure + * + * The caller is responsible for freeing the returned output data. + */ +struct wpabuf * tls_connection_server_handshake(void *tls_ctx, + struct tls_connection *conn, + const struct wpabuf *in_data, + struct wpabuf **appl_data); + +/** + * tls_connection_encrypt - Encrypt data into TLS tunnel + * @tls_ctx: TLS context data from tls_init() + * @conn: Connection context data from tls_connection_init() + * @in_data: Plaintext data to be encrypted + * Returns: Encrypted TLS data or %NULL on failure + * + * This function is used after TLS handshake has been completed successfully to + * send data in the encrypted tunnel. The caller is responsible for freeing the + * returned output data. + */ +struct wpabuf * tls_connection_encrypt(void *tls_ctx, + struct tls_connection *conn, + const struct wpabuf *in_data); + +/** + * tls_connection_decrypt - Decrypt data from TLS tunnel + * @tls_ctx: TLS context data from tls_init() + * @conn: Connection context data from tls_connection_init() + * @in_data: Encrypted TLS data + * Returns: Decrypted TLS data or %NULL on failure + * + * This function is used after TLS handshake has been completed successfully to + * receive data from the encrypted tunnel. The caller is responsible for + * freeing the returned output data. + */ +struct wpabuf * tls_connection_decrypt(void *tls_ctx, + struct tls_connection *conn, + const struct wpabuf *in_data); + +struct wpabuf * tls_connection_decrypt2(void *tls_ctx, + struct tls_connection *conn, + const struct wpabuf *in_data, + int *more_data_needed); + +/** + * tls_connection_resumed - Was session resumption used + * @tls_ctx: TLS context data from tls_init() + * @conn: Connection context data from tls_connection_init() + * Returns: 1 if current session used session resumption, 0 if not + */ +int tls_connection_resumed(void *tls_ctx, struct tls_connection *conn); + +enum { + TLS_CIPHER_NONE, + TLS_CIPHER_RC4_SHA /* 0x0005 */, + TLS_CIPHER_AES128_SHA /* 0x002f */, + TLS_CIPHER_RSA_DHE_AES128_SHA /* 0x0031 */, + TLS_CIPHER_ANON_DH_AES128_SHA /* 0x0034 */ +}; + +/** + * tls_connection_set_cipher_list - Configure acceptable cipher suites + * @tls_ctx: TLS context data from tls_init() + * @conn: Connection context data from tls_connection_init() + * @ciphers: Zero (TLS_CIPHER_NONE) terminated list of allowed ciphers + * (TLS_CIPHER_*). + * Returns: 0 on success, -1 on failure + */ +int __must_check tls_connection_set_cipher_list(void *tls_ctx, + struct tls_connection *conn, + u8 *ciphers); + +/** + * tls_get_cipher - Get current cipher name + * @tls_ctx: TLS context data from tls_init() + * @conn: Connection context data from tls_connection_init() + * @buf: Buffer for the cipher name + * @buflen: buf size + * Returns: 0 on success, -1 on failure + * + * Get the name of the currently used cipher. + */ +int __must_check tls_get_cipher(void *tls_ctx, struct tls_connection *conn, + char *buf, size_t buflen); + +/** + * tls_connection_enable_workaround - Enable TLS workaround options + * @tls_ctx: TLS context data from tls_init() + * @conn: Connection context data from tls_connection_init() + * Returns: 0 on success, -1 on failure + * + * This function is used to enable connection-specific workaround options for + * buffer SSL/TLS implementations. + */ +int __must_check tls_connection_enable_workaround(void *tls_ctx, + struct tls_connection *conn); + +/** + * tls_connection_client_hello_ext - Set TLS extension for ClientHello + * @tls_ctx: TLS context data from tls_init() + * @conn: Connection context data from tls_connection_init() + * @ext_type: Extension type + * @data: Extension payload (%NULL to remove extension) + * @data_len: Extension payload length + * Returns: 0 on success, -1 on failure + */ +int __must_check tls_connection_client_hello_ext(void *tls_ctx, + struct tls_connection *conn, + int ext_type, const u8 *data, + size_t data_len); + +/** + * tls_connection_get_failed - Get connection failure status + * @tls_ctx: TLS context data from tls_init() + * @conn: Connection context data from tls_connection_init() + * + * Returns >0 if connection has failed, 0 if not. + */ +int tls_connection_get_failed(void *tls_ctx, struct tls_connection *conn); + +/** + * tls_connection_get_read_alerts - Get connection read alert status + * @tls_ctx: TLS context data from tls_init() + * @conn: Connection context data from tls_connection_init() + * Returns: Number of times a fatal read (remote end reported error) has + * happened during this connection. + */ +int tls_connection_get_read_alerts(void *tls_ctx, struct tls_connection *conn); + +/** + * tls_connection_get_write_alerts - Get connection write alert status + * @tls_ctx: TLS context data from tls_init() + * @conn: Connection context data from tls_connection_init() + * Returns: Number of times a fatal write (locally detected error) has happened + * during this connection. + */ +int tls_connection_get_write_alerts(void *tls_ctx, + struct tls_connection *conn); + +/** + * tls_connection_get_keyblock_size - Get TLS key_block size + * @tls_ctx: TLS context data from tls_init() + * @conn: Connection context data from tls_connection_init() + * Returns: Size of the key_block for the negotiated cipher suite or -1 on + * failure + */ +int tls_connection_get_keyblock_size(void *tls_ctx, + struct tls_connection *conn); + +/** + * tls_capabilities - Get supported TLS capabilities + * @tls_ctx: TLS context data from tls_init() + * Returns: Bit field of supported TLS capabilities (TLS_CAPABILITY_*) + */ +unsigned int tls_capabilities(void *tls_ctx); + +typedef int (*tls_session_ticket_cb) +(void *ctx, const u8 *ticket, size_t len, const u8 *client_random, + const u8 *server_random, u8 *master_secret); + +int __must_check tls_connection_set_session_ticket_cb( + void *tls_ctx, struct tls_connection *conn, + tls_session_ticket_cb cb, void *ctx); + +int tls_prf_sha1_md5(const u8 *secret, size_t secret_len, const char *label, + const u8 *seed, size_t seed_len, u8 *out, size_t outlen); + +#endif /* TLS_H */ diff --git a/components/wpa_supplicant/include/wpa2/tls/tlsv1_client.h b/components/wpa_supplicant/include/wpa2/tls/tlsv1_client.h new file mode 100644 index 0000000000..8ec85f1a91 --- /dev/null +++ b/components/wpa_supplicant/include/wpa2/tls/tlsv1_client.h @@ -0,0 +1,54 @@ +/* + * TLS v1.0/v1.1/v1.2 client (RFC 2246, RFC 4346, RFC 5246) + * Copyright (c) 2006-2011, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef TLSV1_CLIENT_H +#define TLSV1_CLIENT_H + +#include "tlsv1_cred.h" + +struct tlsv1_client; + +int tlsv1_client_global_init(void); +void tlsv1_client_global_deinit(void); +struct tlsv1_client * tlsv1_client_init(void); +void tlsv1_client_deinit(struct tlsv1_client *conn); +int tlsv1_client_established(struct tlsv1_client *conn); +int tlsv1_client_prf(struct tlsv1_client *conn, const char *label, + int server_random_first, u8 *out, size_t out_len); +u8 * tlsv1_client_handshake(struct tlsv1_client *conn, + const u8 *in_data, size_t in_len, + size_t *out_len, u8 **appl_data, + size_t *appl_data_len, int *need_more_data); +int tlsv1_client_encrypt(struct tlsv1_client *conn, + const u8 *in_data, size_t in_len, + u8 *out_data, size_t out_len); +struct wpabuf * tlsv1_client_decrypt(struct tlsv1_client *conn, + const u8 *in_data, size_t in_len, + int *need_more_data); +int tlsv1_client_get_cipher(struct tlsv1_client *conn, char *buf, + size_t buflen); +int tlsv1_client_shutdown(struct tlsv1_client *conn); +int tlsv1_client_resumed(struct tlsv1_client *conn); +int tlsv1_client_hello_ext(struct tlsv1_client *conn, int ext_type, + const u8 *data, size_t data_len); +int tlsv1_client_get_keys(struct tlsv1_client *conn, struct tls_keys *keys); +int tlsv1_client_get_keyblock_size(struct tlsv1_client *conn); +int tlsv1_client_set_cipher_list(struct tlsv1_client *conn, u8 *ciphers); +int tlsv1_client_set_cred(struct tlsv1_client *conn, + struct tlsv1_credentials *cred); +void tlsv1_client_set_time_checks(struct tlsv1_client *conn, int enabled); + +typedef int (*tlsv1_client_session_ticket_cb) +(void *ctx, const u8 *ticket, size_t len, const u8 *client_random, + const u8 *server_random, u8 *master_secret); + +void tlsv1_client_set_session_ticket_cb(struct tlsv1_client *conn, + tlsv1_client_session_ticket_cb cb, + void *ctx); + +#endif /* TLSV1_CLIENT_H */ diff --git a/components/wpa_supplicant/include/wpa2/tls/tlsv1_client_i.h b/components/wpa_supplicant/include/wpa2/tls/tlsv1_client_i.h new file mode 100644 index 0000000000..55fdcf8d04 --- /dev/null +++ b/components/wpa_supplicant/include/wpa2/tls/tlsv1_client_i.h @@ -0,0 +1,84 @@ +/* + * TLSv1 client - internal structures + * Copyright (c) 2006-2011, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef TLSV1_CLIENT_I_H +#define TLSV1_CLIENT_I_H + +struct tlsv1_client { + enum { + CLIENT_HELLO, SERVER_HELLO, SERVER_CERTIFICATE, + SERVER_KEY_EXCHANGE, SERVER_CERTIFICATE_REQUEST, + SERVER_HELLO_DONE, CLIENT_KEY_EXCHANGE, CHANGE_CIPHER_SPEC, + SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED, ACK_FINISHED, + ESTABLISHED, FAILED + } state; + + struct tlsv1_record_layer rl; + + u8 session_id[TLS_SESSION_ID_MAX_LEN]; + size_t session_id_len; + u8 client_random[TLS_RANDOM_LEN]; + u8 server_random[TLS_RANDOM_LEN]; + u8 master_secret[TLS_MASTER_SECRET_LEN]; + + u8 alert_level; + u8 alert_description; + + unsigned int certificate_requested:1; + unsigned int session_resumed:1; + unsigned int session_ticket_included:1; + unsigned int use_session_ticket:1; + unsigned int disable_time_checks:1; + + struct crypto_public_key *server_rsa_key; + + struct tls_verify_hash verify; + +#define MAX_CIPHER_COUNT 30 + u16 cipher_suites[MAX_CIPHER_COUNT]; + size_t num_cipher_suites; + + u16 prev_cipher_suite; + + u8 *client_hello_ext; + size_t client_hello_ext_len; + + /* The prime modulus used for Diffie-Hellman */ + u8 *dh_p; + size_t dh_p_len; + /* The generator used for Diffie-Hellman */ + u8 *dh_g; + size_t dh_g_len; + /* The server's Diffie-Hellman public value */ + u8 *dh_ys; + size_t dh_ys_len; + + struct tlsv1_credentials *cred; + + tlsv1_client_session_ticket_cb session_ticket_cb; + void *session_ticket_cb_ctx; + + struct wpabuf *partial_input; +}; + + +void tls_alert(struct tlsv1_client *conn, u8 level, u8 description); +void tlsv1_client_free_dh(struct tlsv1_client *conn); +int tls_derive_pre_master_secret(u8 *pre_master_secret); +int tls_derive_keys(struct tlsv1_client *conn, + const u8 *pre_master_secret, size_t pre_master_secret_len); +u8 * tls_send_client_hello(struct tlsv1_client *conn, size_t *out_len); +u8 * tlsv1_client_send_alert(struct tlsv1_client *conn, u8 level, + u8 description, size_t *out_len); +u8 * tlsv1_client_handshake_write(struct tlsv1_client *conn, size_t *out_len, + int no_appl_data); +int tlsv1_client_process_handshake(struct tlsv1_client *conn, u8 ct, + const u8 *buf, size_t *len, + u8 **out_data, size_t *out_len); + +#endif /* TLSV1_CLIENT_I_H */ diff --git a/components/wpa_supplicant/include/wpa2/tls/tlsv1_common.h b/components/wpa_supplicant/include/wpa2/tls/tlsv1_common.h new file mode 100644 index 0000000000..f28c0cdc47 --- /dev/null +++ b/components/wpa_supplicant/include/wpa2/tls/tlsv1_common.h @@ -0,0 +1,261 @@ +/* + * TLSv1 common definitions + * Copyright (c) 2006-2011, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef TLSV1_COMMON_H +#define TLSV1_COMMON_H + +#include "crypto/crypto.h" + +#define TLS_VERSION_1 0x0301 /* TLSv1 */ +#define TLS_VERSION_1_1 0x0302 /* TLSv1.1 */ +#define TLS_VERSION_1_2 0x0303 /* TLSv1.2 */ +#ifdef CONFIG_TLSV12 +#define TLS_VERSION TLS_VERSION_1_2 +#else /* CONFIG_TLSV12 */ +#ifdef CONFIG_TLSV11 +#define TLS_VERSION TLS_VERSION_1_1 +#else /* CONFIG_TLSV11 */ +#define TLS_VERSION TLS_VERSION_1 +#endif /* CONFIG_TLSV11 */ +#endif /* CONFIG_TLSV12 */ +#define TLS_RANDOM_LEN 32 +#define TLS_PRE_MASTER_SECRET_LEN 48 +#define TLS_MASTER_SECRET_LEN 48 +#define TLS_SESSION_ID_MAX_LEN 32 +#define TLS_VERIFY_DATA_LEN 12 + +/* HandshakeType */ +enum { + TLS_HANDSHAKE_TYPE_HELLO_REQUEST = 0, + TLS_HANDSHAKE_TYPE_CLIENT_HELLO = 1, + TLS_HANDSHAKE_TYPE_SERVER_HELLO = 2, + TLS_HANDSHAKE_TYPE_NEW_SESSION_TICKET = 4 /* RFC 4507 */, + TLS_HANDSHAKE_TYPE_CERTIFICATE = 11, + TLS_HANDSHAKE_TYPE_SERVER_KEY_EXCHANGE = 12, + TLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST = 13, + TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE = 14, + TLS_HANDSHAKE_TYPE_CERTIFICATE_VERIFY = 15, + TLS_HANDSHAKE_TYPE_CLIENT_KEY_EXCHANGE = 16, + TLS_HANDSHAKE_TYPE_FINISHED = 20, + TLS_HANDSHAKE_TYPE_CERTIFICATE_URL = 21 /* RFC 4366 */, + TLS_HANDSHAKE_TYPE_CERTIFICATE_STATUS = 22 /* RFC 4366 */ +}; + +/* CipherSuite */ +#define TLS_NULL_WITH_NULL_NULL 0x0000 /* RFC 2246 */ +#define TLS_RSA_WITH_NULL_MD5 0x0001 /* RFC 2246 */ +#define TLS_RSA_WITH_NULL_SHA 0x0002 /* RFC 2246 */ +#define TLS_RSA_EXPORT_WITH_RC4_40_MD5 0x0003 /* RFC 2246 */ +#define TLS_RSA_WITH_RC4_128_MD5 0x0004 /* RFC 2246 */ +#define TLS_RSA_WITH_RC4_128_SHA 0x0005 /* RFC 2246 */ +#define TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 0x0006 /* RFC 2246 */ +#define TLS_RSA_WITH_IDEA_CBC_SHA 0x0007 /* RFC 2246 */ +#define TLS_RSA_EXPORT_WITH_DES40_CBC_SHA 0x0008 /* RFC 2246 */ +#define TLS_RSA_WITH_DES_CBC_SHA 0x0009 /* RFC 2246 */ +#define TLS_RSA_WITH_3DES_EDE_CBC_SHA 0x000A /* RFC 2246 */ +#define TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA 0x000B /* RFC 2246 */ +#define TLS_DH_DSS_WITH_DES_CBC_SHA 0x000C /* RFC 2246 */ +#define TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA 0x000D /* RFC 2246 */ +#define TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA 0x000E /* RFC 2246 */ +#define TLS_DH_RSA_WITH_DES_CBC_SHA 0x000F /* RFC 2246 */ +#define TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA 0x0010 /* RFC 2246 */ +#define TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA 0x0011 /* RFC 2246 */ +#define TLS_DHE_DSS_WITH_DES_CBC_SHA 0x0012 /* RFC 2246 */ +#define TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA 0x0013 /* RFC 2246 */ +#define TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA 0x0014 /* RFC 2246 */ +#define TLS_DHE_RSA_WITH_DES_CBC_SHA 0x0015 /* RFC 2246 */ +#define TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA 0x0016 /* RFC 2246 */ +#define TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 0x0017 /* RFC 2246 */ +#define TLS_DH_anon_WITH_RC4_128_MD5 0x0018 /* RFC 2246 */ +#define TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA 0x0019 /* RFC 2246 */ +#define TLS_DH_anon_WITH_DES_CBC_SHA 0x001A /* RFC 2246 */ +#define TLS_DH_anon_WITH_3DES_EDE_CBC_SHA 0x001B /* RFC 2246 */ +#define TLS_RSA_WITH_AES_128_CBC_SHA 0x002F /* RFC 3268 */ +#define TLS_DH_DSS_WITH_AES_128_CBC_SHA 0x0030 /* RFC 3268 */ +#define TLS_DH_RSA_WITH_AES_128_CBC_SHA 0x0031 /* RFC 3268 */ +#define TLS_DHE_DSS_WITH_AES_128_CBC_SHA 0x0032 /* RFC 3268 */ +#define TLS_DHE_RSA_WITH_AES_128_CBC_SHA 0x0033 /* RFC 3268 */ +#define TLS_DH_anon_WITH_AES_128_CBC_SHA 0x0034 /* RFC 3268 */ +#define TLS_RSA_WITH_AES_256_CBC_SHA 0x0035 /* RFC 3268 */ +#define TLS_DH_DSS_WITH_AES_256_CBC_SHA 0x0036 /* RFC 3268 */ +#define TLS_DH_RSA_WITH_AES_256_CBC_SHA 0x0037 /* RFC 3268 */ +#define TLS_DHE_DSS_WITH_AES_256_CBC_SHA 0x0038 /* RFC 3268 */ +#define TLS_DHE_RSA_WITH_AES_256_CBC_SHA 0x0039 /* RFC 3268 */ +#define TLS_DH_anon_WITH_AES_256_CBC_SHA 0x003A /* RFC 3268 */ +#define TLS_RSA_WITH_NULL_SHA256 0x003B /* RFC 5246 */ +#define TLS_RSA_WITH_AES_128_CBC_SHA256 0x003C /* RFC 5246 */ +#define TLS_RSA_WITH_AES_256_CBC_SHA256 0x003D /* RFC 5246 */ +#define TLS_DH_DSS_WITH_AES_128_CBC_SHA256 0x003E /* RFC 5246 */ +#define TLS_DH_RSA_WITH_AES_128_CBC_SHA256 0x003F /* RFC 5246 */ +#define TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 0x0040 /* RFC 5246 */ +#define TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 0x0067 /* RFC 5246 */ +#define TLS_DH_DSS_WITH_AES_256_CBC_SHA256 0x0068 /* RFC 5246 */ +#define TLS_DH_RSA_WITH_AES_256_CBC_SHA256 0x0069 /* RFC 5246 */ +#define TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 0x006A /* RFC 5246 */ +#define TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 0x006B /* RFC 5246 */ +#define TLS_DH_anon_WITH_AES_128_CBC_SHA256 0x006C /* RFC 5246 */ +#define TLS_DH_anon_WITH_AES_256_CBC_SHA256 0x006D /* RFC 5246 */ + +/* CompressionMethod */ +#define TLS_COMPRESSION_NULL 0 + +/* HashAlgorithm */ +enum { + TLS_HASH_ALG_NONE = 0, + TLS_HASH_ALG_MD5 = 1, + TLS_HASH_ALG_SHA1 = 2, + TLS_HASH_ALG_SHA224 = 3, + TLS_HASH_ALG_SHA256 = 4, + TLS_HASH_ALG_SHA384 = 5, + TLS_HASH_ALG_SHA512 = 6 +}; + +/* SignatureAlgorithm */ +enum { + TLS_SIGN_ALG_ANONYMOUS = 0, + TLS_SIGN_ALG_RSA = 1, + TLS_SIGN_ALG_DSA = 2, + TLS_SIGN_ALG_ECDSA = 3, +}; + +/* AlertLevel */ +#define TLS_ALERT_LEVEL_WARNING 1 +#define TLS_ALERT_LEVEL_FATAL 2 + +/* AlertDescription */ +#define TLS_ALERT_CLOSE_NOTIFY 0 +#define TLS_ALERT_UNEXPECTED_MESSAGE 10 +#define TLS_ALERT_BAD_RECORD_MAC 20 +#define TLS_ALERT_DECRYPTION_FAILED 21 +#define TLS_ALERT_RECORD_OVERFLOW 22 +#define TLS_ALERT_DECOMPRESSION_FAILURE 30 +#define TLS_ALERT_HANDSHAKE_FAILURE 40 +#define TLS_ALERT_BAD_CERTIFICATE 42 +#define TLS_ALERT_UNSUPPORTED_CERTIFICATE 43 +#define TLS_ALERT_CERTIFICATE_REVOKED 44 +#define TLS_ALERT_CERTIFICATE_EXPIRED 45 +#define TLS_ALERT_CERTIFICATE_UNKNOWN 46 +#define TLS_ALERT_ILLEGAL_PARAMETER 47 +#define TLS_ALERT_UNKNOWN_CA 48 +#define TLS_ALERT_ACCESS_DENIED 49 +#define TLS_ALERT_DECODE_ERROR 50 +#define TLS_ALERT_DECRYPT_ERROR 51 +#define TLS_ALERT_EXPORT_RESTRICTION 60 +#define TLS_ALERT_PROTOCOL_VERSION 70 +#define TLS_ALERT_INSUFFICIENT_SECURITY 71 +#define TLS_ALERT_INTERNAL_ERROR 80 +#define TLS_ALERT_USER_CANCELED 90 +#define TLS_ALERT_NO_RENEGOTIATION 100 +#define TLS_ALERT_UNSUPPORTED_EXTENSION 110 /* RFC 4366 */ +#define TLS_ALERT_CERTIFICATE_UNOBTAINABLE 111 /* RFC 4366 */ +#define TLS_ALERT_UNRECOGNIZED_NAME 112 /* RFC 4366 */ +#define TLS_ALERT_BAD_CERTIFICATE_STATUS_RESPONSE 113 /* RFC 4366 */ +#define TLS_ALERT_BAD_CERTIFICATE_HASH_VALUE 114 /* RFC 4366 */ + +/* ChangeCipherSpec */ +enum { + TLS_CHANGE_CIPHER_SPEC = 1 +}; + +/* TLS Extensions */ +#define TLS_EXT_SERVER_NAME 0 /* RFC 4366 */ +#define TLS_EXT_MAX_FRAGMENT_LENGTH 1 /* RFC 4366 */ +#define TLS_EXT_CLIENT_CERTIFICATE_URL 2 /* RFC 4366 */ +#define TLS_EXT_TRUSTED_CA_KEYS 3 /* RFC 4366 */ +#define TLS_EXT_TRUNCATED_HMAC 4 /* RFC 4366 */ +#define TLS_EXT_STATUS_REQUEST 5 /* RFC 4366 */ +#define TLS_EXT_SESSION_TICKET 35 /* RFC 4507 */ + +#define TLS_EXT_PAC_OPAQUE TLS_EXT_SESSION_TICKET /* EAP-FAST terminology */ + + +typedef enum { + TLS_KEY_X_NULL, + TLS_KEY_X_RSA, + TLS_KEY_X_RSA_EXPORT, + TLS_KEY_X_DH_DSS_EXPORT, + TLS_KEY_X_DH_DSS, + TLS_KEY_X_DH_RSA_EXPORT, + TLS_KEY_X_DH_RSA, + TLS_KEY_X_DHE_DSS_EXPORT, + TLS_KEY_X_DHE_DSS, + TLS_KEY_X_DHE_RSA_EXPORT, + TLS_KEY_X_DHE_RSA, + TLS_KEY_X_DH_anon_EXPORT, + TLS_KEY_X_DH_anon +} tls_key_exchange; + +typedef enum { + TLS_CIPHER_NULL, + TLS_CIPHER_RC4_40, + TLS_CIPHER_RC4_128, + TLS_CIPHER_RC2_CBC_40, + TLS_CIPHER_IDEA_CBC, + TLS_CIPHER_DES40_CBC, + TLS_CIPHER_DES_CBC, + TLS_CIPHER_3DES_EDE_CBC, + TLS_CIPHER_AES_128_CBC, + TLS_CIPHER_AES_256_CBC +} tls_cipher; + +typedef enum { + TLS_HASH_NULL, + TLS_HASH_MD5, + TLS_HASH_SHA, + TLS_HASH_SHA256 +} tls_hash; + +struct tls_cipher_suite { + u16 suite; + tls_key_exchange key_exchange; + tls_cipher cipher; + tls_hash hash; +}; + +typedef enum { + TLS_CIPHER_STREAM, + TLS_CIPHER_BLOCK +} tls_cipher_type; + +struct tls_cipher_data { + tls_cipher cipher; + tls_cipher_type type; + size_t key_material; + size_t expanded_key_material; + size_t block_size; /* also iv_size */ + enum crypto_cipher_alg alg; +}; + + +struct tls_verify_hash { + struct crypto_hash *md5_client; + struct crypto_hash *sha1_client; + struct crypto_hash *sha256_client; + struct crypto_hash *md5_server; + struct crypto_hash *sha1_server; + struct crypto_hash *sha256_server; + struct crypto_hash *md5_cert; + struct crypto_hash *sha1_cert; + struct crypto_hash *sha256_cert; +}; + + +const struct tls_cipher_suite * tls_get_cipher_suite(u16 suite); +const struct tls_cipher_data * tls_get_cipher_data(tls_cipher cipher); +int tls_server_key_exchange_allowed(tls_cipher cipher); +int tls_parse_cert(const u8 *buf, size_t len, struct crypto_public_key **pk); +int tls_verify_hash_init(struct tls_verify_hash *verify); +void tls_verify_hash_add(struct tls_verify_hash *verify, const u8 *buf, + size_t len); +void tls_verify_hash_free(struct tls_verify_hash *verify); +int tls_version_ok(u16 ver); +const char * tls_version_str(u16 ver); +int tls_prf(u16 ver, const u8 *secret, size_t secret_len, const char *label, + const u8 *seed, size_t seed_len, u8 *out, size_t outlen); + +#endif /* TLSV1_COMMON_H */ diff --git a/components/wpa_supplicant/include/wpa2/tls/tlsv1_cred.h b/components/wpa_supplicant/include/wpa2/tls/tlsv1_cred.h new file mode 100644 index 0000000000..68fbdc9230 --- /dev/null +++ b/components/wpa_supplicant/include/wpa2/tls/tlsv1_cred.h @@ -0,0 +1,40 @@ +/* + * TLSv1 credentials + * Copyright (c) 2006-2007, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef TLSV1_CRED_H +#define TLSV1_CRED_H + +struct tlsv1_credentials { + struct x509_certificate *trusted_certs; + struct x509_certificate *cert; + struct crypto_private_key *key; + + /* Diffie-Hellman parameters */ + u8 *dh_p; /* prime */ + size_t dh_p_len; + u8 *dh_g; /* generator */ + size_t dh_g_len; +}; + + +struct tlsv1_credentials * tlsv1_cred_alloc(void); +void tlsv1_cred_free(struct tlsv1_credentials *cred); +int tlsv1_set_ca_cert(struct tlsv1_credentials *cred, const char *cert, + const u8 *cert_blob, size_t cert_blob_len, + const char *path); +int tlsv1_set_cert(struct tlsv1_credentials *cred, const char *cert, + const u8 *cert_blob, size_t cert_blob_len); +int tlsv1_set_private_key(struct tlsv1_credentials *cred, + const char *private_key, + const char *private_key_passwd, + const u8 *private_key_blob, + size_t private_key_blob_len); +int tlsv1_set_dhparams(struct tlsv1_credentials *cred, const char *dh_file, + const u8 *dh_blob, size_t dh_blob_len); + +#endif /* TLSV1_CRED_H */ diff --git a/components/wpa_supplicant/include/wpa2/tls/tlsv1_record.h b/components/wpa_supplicant/include/wpa2/tls/tlsv1_record.h new file mode 100644 index 0000000000..48abcb0d25 --- /dev/null +++ b/components/wpa_supplicant/include/wpa2/tls/tlsv1_record.h @@ -0,0 +1,71 @@ +/* + * TLSv1 Record Protocol + * Copyright (c) 2006-2011, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef TLSV1_RECORD_H +#define TLSV1_RECORD_H + +#include "crypto/crypto.h" + +#define TLS_MAX_WRITE_MAC_SECRET_LEN 32 +#define TLS_MAX_WRITE_KEY_LEN 32 +#define TLS_MAX_IV_LEN 16 +#define TLS_MAX_KEY_BLOCK_LEN (2 * (TLS_MAX_WRITE_MAC_SECRET_LEN + \ + TLS_MAX_WRITE_KEY_LEN + TLS_MAX_IV_LEN)) + +#define TLS_SEQ_NUM_LEN 8 +#define TLS_RECORD_HEADER_LEN 5 + +/* ContentType */ +enum { + TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC = 20, + TLS_CONTENT_TYPE_ALERT = 21, + TLS_CONTENT_TYPE_HANDSHAKE = 22, + TLS_CONTENT_TYPE_APPLICATION_DATA = 23 +}; + +struct tlsv1_record_layer { + u16 tls_version; + + u8 write_mac_secret[TLS_MAX_WRITE_MAC_SECRET_LEN]; + u8 read_mac_secret[TLS_MAX_WRITE_MAC_SECRET_LEN]; + u8 write_key[TLS_MAX_WRITE_KEY_LEN]; + u8 read_key[TLS_MAX_WRITE_KEY_LEN]; + u8 write_iv[TLS_MAX_IV_LEN]; + u8 read_iv[TLS_MAX_IV_LEN]; + + size_t hash_size; + size_t key_material_len; + size_t iv_size; /* also block_size */ + + enum crypto_hash_alg hash_alg; + enum crypto_cipher_alg cipher_alg; + + u8 write_seq_num[TLS_SEQ_NUM_LEN]; + u8 read_seq_num[TLS_SEQ_NUM_LEN]; + + u16 cipher_suite; + u16 write_cipher_suite; + u16 read_cipher_suite; + + struct crypto_cipher *write_cbc; + struct crypto_cipher *read_cbc; +}; + + +int tlsv1_record_set_cipher_suite(struct tlsv1_record_layer *rl, + u16 cipher_suite); +int tlsv1_record_change_write_cipher(struct tlsv1_record_layer *rl); +int tlsv1_record_change_read_cipher(struct tlsv1_record_layer *rl); +int tlsv1_record_send(struct tlsv1_record_layer *rl, u8 content_type, u8 *buf, + size_t buf_size, const u8 *payload, size_t payload_len, + size_t *out_len); +int tlsv1_record_receive(struct tlsv1_record_layer *rl, + const u8 *in_data, size_t in_len, + u8 *out_data, size_t *out_len, u8 *alert); + +#endif /* TLSV1_RECORD_H */ diff --git a/components/wpa_supplicant/include/wpa2/tls/tlsv1_server.h b/components/wpa_supplicant/include/wpa2/tls/tlsv1_server.h new file mode 100644 index 0000000000..a18c69e37c --- /dev/null +++ b/components/wpa_supplicant/include/wpa2/tls/tlsv1_server.h @@ -0,0 +1,48 @@ +/* + * TLS v1.0/v1.1/v1.2 server (RFC 2246, RFC 4346, RFC 5246) + * Copyright (c) 2006-2011, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef TLSV1_SERVER_H +#define TLSV1_SERVER_H + +#include "tlsv1_cred.h" + +struct tlsv1_server; + +int tlsv1_server_global_init(void); +void tlsv1_server_global_deinit(void); +struct tlsv1_server * tlsv1_server_init(struct tlsv1_credentials *cred); +void tlsv1_server_deinit(struct tlsv1_server *conn); +int tlsv1_server_established(struct tlsv1_server *conn); +int tlsv1_server_prf(struct tlsv1_server *conn, const char *label, + int server_random_first, u8 *out, size_t out_len); +u8 * tlsv1_server_handshake(struct tlsv1_server *conn, + const u8 *in_data, size_t in_len, size_t *out_len); +int tlsv1_server_encrypt(struct tlsv1_server *conn, + const u8 *in_data, size_t in_len, + u8 *out_data, size_t out_len); +int tlsv1_server_decrypt(struct tlsv1_server *conn, + const u8 *in_data, size_t in_len, + u8 *out_data, size_t out_len); +int tlsv1_server_get_cipher(struct tlsv1_server *conn, char *buf, + size_t buflen); +int tlsv1_server_shutdown(struct tlsv1_server *conn); +int tlsv1_server_resumed(struct tlsv1_server *conn); +int tlsv1_server_get_keys(struct tlsv1_server *conn, struct tls_keys *keys); +int tlsv1_server_get_keyblock_size(struct tlsv1_server *conn); +int tlsv1_server_set_cipher_list(struct tlsv1_server *conn, u8 *ciphers); +int tlsv1_server_set_verify(struct tlsv1_server *conn, int verify_peer); + +typedef int (*tlsv1_server_session_ticket_cb) +(void *ctx, const u8 *ticket, size_t len, const u8 *client_random, + const u8 *server_random, u8 *master_secret); + +void tlsv1_server_set_session_ticket_cb(struct tlsv1_server *conn, + tlsv1_server_session_ticket_cb cb, + void *ctx); + +#endif /* TLSV1_SERVER_H */ diff --git a/components/wpa_supplicant/include/wpa2/tls/tlsv1_server_i.h b/components/wpa_supplicant/include/wpa2/tls/tlsv1_server_i.h new file mode 100644 index 0000000000..1f61533a5a --- /dev/null +++ b/components/wpa_supplicant/include/wpa2/tls/tlsv1_server_i.h @@ -0,0 +1,71 @@ +/* + * TLSv1 server - internal structures + * Copyright (c) 2006-2007, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef TLSV1_SERVER_I_H +#define TLSV1_SERVER_I_H + +struct tlsv1_server { + enum { + CLIENT_HELLO, SERVER_HELLO, SERVER_CERTIFICATE, + SERVER_KEY_EXCHANGE, SERVER_CERTIFICATE_REQUEST, + SERVER_HELLO_DONE, CLIENT_CERTIFICATE, CLIENT_KEY_EXCHANGE, + CERTIFICATE_VERIFY, CHANGE_CIPHER_SPEC, CLIENT_FINISHED, + SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED, + ESTABLISHED, FAILED + } state; + + struct tlsv1_record_layer rl; + + u8 session_id[TLS_SESSION_ID_MAX_LEN]; + size_t session_id_len; + u8 client_random[TLS_RANDOM_LEN]; + u8 server_random[TLS_RANDOM_LEN]; + u8 master_secret[TLS_MASTER_SECRET_LEN]; + + u8 alert_level; + u8 alert_description; + + struct crypto_public_key *client_rsa_key; + + struct tls_verify_hash verify; + +#define MAX_CIPHER_COUNT 30 + u16 cipher_suites[MAX_CIPHER_COUNT]; + size_t num_cipher_suites; + + u16 cipher_suite; + + struct tlsv1_credentials *cred; + + int verify_peer; + u16 client_version; + + u8 *session_ticket; + size_t session_ticket_len; + + tlsv1_server_session_ticket_cb session_ticket_cb; + void *session_ticket_cb_ctx; + + int use_session_ticket; + + u8 *dh_secret; + size_t dh_secret_len; +}; + + +void tlsv1_server_alert(struct tlsv1_server *conn, u8 level, u8 description); +int tlsv1_server_derive_keys(struct tlsv1_server *conn, + const u8 *pre_master_secret, + size_t pre_master_secret_len); +u8 * tlsv1_server_handshake_write(struct tlsv1_server *conn, size_t *out_len); +u8 * tlsv1_server_send_alert(struct tlsv1_server *conn, u8 level, + u8 description, size_t *out_len); +int tlsv1_server_process_handshake(struct tlsv1_server *conn, u8 ct, + const u8 *buf, size_t *len); + +#endif /* TLSV1_SERVER_I_H */ diff --git a/components/wpa_supplicant/include/wpa2/tls/x509v3.h b/components/wpa_supplicant/include/wpa2/tls/x509v3.h new file mode 100644 index 0000000000..91a35baf92 --- /dev/null +++ b/components/wpa_supplicant/include/wpa2/tls/x509v3.h @@ -0,0 +1,123 @@ +/* + * X.509v3 certificate parsing and processing + * Copyright (c) 2006-2011, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef X509V3_H +#define X509V3_H + +#include "asn1.h" + +struct x509_algorithm_identifier { + struct asn1_oid oid; +}; + +struct x509_name_attr { + enum x509_name_attr_type { + X509_NAME_ATTR_NOT_USED, + X509_NAME_ATTR_DC, + X509_NAME_ATTR_CN, + X509_NAME_ATTR_C, + X509_NAME_ATTR_L, + X509_NAME_ATTR_ST, + X509_NAME_ATTR_O, + X509_NAME_ATTR_OU + } type; + char *value; +}; + +#define X509_MAX_NAME_ATTRIBUTES 20 + +struct x509_name { + struct x509_name_attr attr[X509_MAX_NAME_ATTRIBUTES]; + size_t num_attr; + char *email; /* emailAddress */ + + /* from alternative name extension */ + char *alt_email; /* rfc822Name */ + char *dns; /* dNSName */ + char *uri; /* uniformResourceIdentifier */ + u8 *ip; /* iPAddress */ + size_t ip_len; /* IPv4: 4, IPv6: 16 */ + struct asn1_oid rid; /* registeredID */ +}; + +struct x509_certificate { + struct x509_certificate *next; + enum { X509_CERT_V1 = 0, X509_CERT_V2 = 1, X509_CERT_V3 = 2 } version; + unsigned long serial_number; + struct x509_algorithm_identifier signature; + struct x509_name issuer; + struct x509_name subject; + os_time_t not_before; + os_time_t not_after; + struct x509_algorithm_identifier public_key_alg; + u8 *public_key; + size_t public_key_len; + struct x509_algorithm_identifier signature_alg; + u8 *sign_value; + size_t sign_value_len; + + /* Extensions */ + unsigned int extensions_present; +#define X509_EXT_BASIC_CONSTRAINTS (1 << 0) +#define X509_EXT_PATH_LEN_CONSTRAINT (1 << 1) +#define X509_EXT_KEY_USAGE (1 << 2) +#define X509_EXT_SUBJECT_ALT_NAME (1 << 3) +#define X509_EXT_ISSUER_ALT_NAME (1 << 4) + + /* BasicConstraints */ + int ca; /* cA */ + unsigned long path_len_constraint; /* pathLenConstraint */ + + /* KeyUsage */ + unsigned long key_usage; +#define X509_KEY_USAGE_DIGITAL_SIGNATURE (1 << 0) +#define X509_KEY_USAGE_NON_REPUDIATION (1 << 1) +#define X509_KEY_USAGE_KEY_ENCIPHERMENT (1 << 2) +#define X509_KEY_USAGE_DATA_ENCIPHERMENT (1 << 3) +#define X509_KEY_USAGE_KEY_AGREEMENT (1 << 4) +#define X509_KEY_USAGE_KEY_CERT_SIGN (1 << 5) +#define X509_KEY_USAGE_CRL_SIGN (1 << 6) +#define X509_KEY_USAGE_ENCIPHER_ONLY (1 << 7) +#define X509_KEY_USAGE_DECIPHER_ONLY (1 << 8) + + /* + * The DER format certificate follows struct x509_certificate. These + * pointers point to that buffer. + */ + const u8 *cert_start; + size_t cert_len; + const u8 *tbs_cert_start; + size_t tbs_cert_len; +}; + +enum { + X509_VALIDATE_OK, + X509_VALIDATE_BAD_CERTIFICATE, + X509_VALIDATE_UNSUPPORTED_CERTIFICATE, + X509_VALIDATE_CERTIFICATE_REVOKED, + X509_VALIDATE_CERTIFICATE_EXPIRED, + X509_VALIDATE_CERTIFICATE_UNKNOWN, + X509_VALIDATE_UNKNOWN_CA +}; + +void x509_certificate_free(struct x509_certificate *cert); +struct x509_certificate * x509_certificate_parse(const u8 *buf, size_t len); +void x509_name_string(struct x509_name *name, char *buf, size_t len); +int x509_name_compare(struct x509_name *a, struct x509_name *b); +void x509_certificate_chain_free(struct x509_certificate *cert); +int x509_certificate_check_signature(struct x509_certificate *issuer, + struct x509_certificate *cert); +int x509_certificate_chain_validate(struct x509_certificate *trusted, + struct x509_certificate *chain, + int *reason, int disable_time_checks); +struct x509_certificate * +x509_certificate_get_subject(struct x509_certificate *chain, + struct x509_name *name); +int x509_certificate_self_signed(struct x509_certificate *cert); + +#endif /* X509V3_H */ diff --git a/components/wpa_supplicant/include/wpa2/utils/base64.h b/components/wpa_supplicant/include/wpa2/utils/base64.h new file mode 100644 index 0000000000..91eb874198 --- /dev/null +++ b/components/wpa_supplicant/include/wpa2/utils/base64.h @@ -0,0 +1,17 @@ +/* + * Base64 encoding/decoding (RFC1341) + * Copyright (c) 2005, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef BASE64_H +#define BASE64_H + +unsigned char * _base64_encode(const unsigned char *src, size_t len, + size_t *out_len); +unsigned char * _base64_decode(const unsigned char *src, size_t len, + size_t *out_len); + +#endif /* BASE64_H */ diff --git a/components/wpa_supplicant/include/wpa2/utils/ext_password.h b/components/wpa_supplicant/include/wpa2/utils/ext_password.h new file mode 100644 index 0000000000..e3e46ea084 --- /dev/null +++ b/components/wpa_supplicant/include/wpa2/utils/ext_password.h @@ -0,0 +1,33 @@ +/* + * External password backend + * Copyright (c) 2012, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef EXT_PASSWORD_H +#define EXT_PASSWORD_H + +struct ext_password_data; + +#ifdef CONFIG_EXT_PASSWORD + +struct ext_password_data * ext_password_init(const char *backend, + const char *params); +void ext_password_deinit(struct ext_password_data *data); + +struct wpabuf * ext_password_get(struct ext_password_data *data, + const char *name); +void ext_password_free(struct wpabuf *pw); + +#else /* CONFIG_EXT_PASSWORD */ + +#define ext_password_init(b, p) ((void *) 1) +#define ext_password_deinit(d) do { } while (0) +#define ext_password_get(d, n) (NULL) +#define ext_password_free(p) do { } while (0) + +#endif /* CONFIG_EXT_PASSWORD */ + +#endif /* EXT_PASSWORD_H */ diff --git a/components/wpa_supplicant/include/wpa2/utils/ext_password_i.h b/components/wpa_supplicant/include/wpa2/utils/ext_password_i.h new file mode 100644 index 0000000000..043e7312c6 --- /dev/null +++ b/components/wpa_supplicant/include/wpa2/utils/ext_password_i.h @@ -0,0 +1,23 @@ +/* + * External password backend - internal definitions + * Copyright (c) 2012, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef EXT_PASSWORD_I_H +#define EXT_PASSWORD_I_H + +#include "ext_password.h" + +struct ext_password_backend { + const char *name; + void * (*init)(const char *params); + void (*deinit)(void *ctx); + struct wpabuf * (*get)(void *ctx, const char *name); +}; + +struct wpabuf * ext_password_alloc(size_t len); + +#endif /* EXT_PASSWORD_I_H */ diff --git a/components/wpa_supplicant/port/include/byteswap.h b/components/wpa_supplicant/port/include/byteswap.h new file mode 100644 index 0000000000..1a8bb8fd15 --- /dev/null +++ b/components/wpa_supplicant/port/include/byteswap.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2010 Espressif System + */ + +#ifndef BYTESWAP_H +#define BYTESWAP_H + +/* Swap bytes in 16 bit value. */ +#ifdef __GNUC__ +# define __bswap_16(x) \ + (__extension__ \ + ({ unsigned short int __bsx = (x); \ + ((((__bsx) >> 8) & 0xff) | (((__bsx) & 0xff) << 8)); })) +#else +static INLINE unsigned short int +__bswap_16 (unsigned short int __bsx) +{ + return ((((__bsx) >> 8) & 0xff) | (((__bsx) & 0xff) << 8)); +} +#endif + +/* Swap bytes in 32 bit value. */ +#ifdef __GNUC__ +# define __bswap_32(x) \ + (__extension__ \ + ({ unsigned int __bsx = (x); \ + ((((__bsx) & 0xff000000) >> 24) | (((__bsx) & 0x00ff0000) >> 8) | \ + (((__bsx) & 0x0000ff00) << 8) | (((__bsx) & 0x000000ff) << 24)); })) +#else +static INLINE unsigned int +__bswap_32 (unsigned int __bsx) +{ + return ((((__bsx) & 0xff000000) >> 24) | (((__bsx) & 0x00ff0000) >> 8) | + (((__bsx) & 0x0000ff00) << 8) | (((__bsx) & 0x000000ff) << 24)); +} +#endif + +#if defined __GNUC__ && __GNUC__ >= 2 +/* Swap bytes in 64 bit value. */ +# define __bswap_constant_64(x) \ + ((((x) & 0xff00000000000000ull) >> 56) \ + | (((x) & 0x00ff000000000000ull) >> 40) \ + | (((x) & 0x0000ff0000000000ull) >> 24) \ + | (((x) & 0x000000ff00000000ull) >> 8) \ + | (((x) & 0x00000000ff000000ull) << 8) \ + | (((x) & 0x0000000000ff0000ull) << 24) \ + | (((x) & 0x000000000000ff00ull) << 40) \ + | (((x) & 0x00000000000000ffull) << 56)) + +# define __bswap_64(x) \ + (__extension__ \ + ({ union { __extension__ unsigned long long int __ll; \ + unsigned int __l[2]; } __w, __r; \ + if (__builtin_constant_p (x)) \ + __r.__ll = __bswap_constant_64 (x); \ + else \ + { \ + __w.__ll = (x); \ + __r.__l[0] = __bswap_32 (__w.__l[1]); \ + __r.__l[1] = __bswap_32 (__w.__l[0]); \ + } \ + __r.__ll; })) +#endif + +#endif /* BYTESWAP_H */ diff --git a/components/wpa_supplicant/port/include/endian.h b/components/wpa_supplicant/port/include/endian.h new file mode 100644 index 0000000000..e2df616b79 --- /dev/null +++ b/components/wpa_supplicant/port/include/endian.h @@ -0,0 +1,229 @@ +/*- + * Copyright (c) 2002 Thomas Moestl + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _ENDIAN_H_ +#define _ENDIAN_H_ + +#include "byteswap.h" + +#ifndef BIG_ENDIAN +#define BIG_ENDIAN 4321 +#endif +#ifndef LITTLE_ENDIAN +#define LITTLE_ENDIAN 1234 +#endif + +#ifndef BYTE_ORDER +#ifdef __IEEE_LITTLE_ENDIAN +#define BYTE_ORDER LITTLE_ENDIAN +#else +#define BYTE_ORDER BIG_ENDIAN +#endif +#endif + +#define _UINT8_T_DECLARED +#ifndef _UINT8_T_DECLARED +typedef __uint8_t uint8_t; +#define _UINT8_T_DECLARED +#endif + +#define _UINT16_T_DECLARED +#ifndef _UINT16_T_DECLARED +typedef __uint16_t uint16_t; +#define _UINT16_T_DECLARED +#endif + +#define _UINT32_T_DECLARED +#ifndef _UINT32_T_DECLARED +typedef __uint32_t uint32_t; +#define _UINT32_T_DECLARED +#endif + +#define _UINT64_T_DECLARED +#ifndef _UINT64_T_DECLARED +typedef __uint64_t uint64_t; +#define _UINT64_T_DECLARED +#endif + +/* + * General byte order swapping functions. + */ +#define bswap16(x) __bswap16(x) +#define bswap32(x) __bswap32(x) +#define bswap64(x) __bswap64(x) + +/* + * Host to big endian, host to little endian, big endian to host, and little + * endian to host byte order functions as detailed in byteorder(9). + */ +#if 1 //BYTE_ORDER == _LITTLE_ENDIAN +#define __bswap16 __bswap_16 +#define __bswap32 __bswap_32 +#define htobe16(x) bswap16((x)) +#define htobe32(x) bswap32((x)) +#define htobe64(x) bswap64((x)) +#define htole16(x) ((uint16_t)(x)) +#define htole32(x) ((uint32_t)(x)) +#define htole64(x) ((uint64_t)(x)) + +#define be16toh(x) bswap16((x)) +#define be32toh(x) bswap32((x)) +#define be64toh(x) bswap64((x)) +#define le16toh(x) ((uint16_t)(x)) +#define le32toh(x) ((uint32_t)(x)) +#define le64toh(x) ((uint64_t)(x)) + +#ifndef htons +#define htons htobe16 +#endif //htons + +#else /* _BYTE_ORDER != _LITTLE_ENDIAN */ +#define htobe16(x) ((uint16_t)(x)) +#define htobe32(x) ((uint32_t)(x)) +#define htobe64(x) ((uint64_t)(x)) +#define htole16(x) bswap16((x)) +#define htole32(x) bswap32((x)) +#define htole64(x) bswap64((x)) + +#define be16toh(x) ((uint16_t)(x)) +#define be32toh(x) ((uint32_t)(x)) +#define be64toh(x) ((uint64_t)(x)) +#define le16toh(x) bswap16((x)) +#define le32toh(x) bswap32((x)) +#define le64toh(x) bswap64((x)) +#endif /* _BYTE_ORDER == _LITTLE_ENDIAN */ + +/* Alignment-agnostic encode/decode bytestream to/from little/big endian. */ + +static INLINE uint16_t +be16dec(const void *pp) +{ + uint8_t const *p = (uint8_t const *)pp; + + return ((p[0] << 8) | p[1]); +} + +static INLINE uint32_t +be32dec(const void *pp) +{ + uint8_t const *p = (uint8_t const *)pp; + + return (((unsigned)p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]); +} + +static INLINE uint64_t +be64dec(const void *pp) +{ + uint8_t const *p = (uint8_t const *)pp; + + return (((uint64_t)be32dec(p) << 32) | be32dec(p + 4)); +} + +static INLINE uint16_t +le16dec(const void *pp) +{ + uint8_t const *p = (uint8_t const *)pp; + + return ((p[1] << 8) | p[0]); +} + +static INLINE uint32_t +le32dec(const void *pp) +{ + uint8_t const *p = (uint8_t const *)pp; + + return (((unsigned)p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]); +} + +static INLINE uint64_t +le64dec(const void *pp) +{ + uint8_t const *p = (uint8_t const *)pp; + + return (((uint64_t)le32dec(p + 4) << 32) | le32dec(p)); +} + +static INLINE void +be16enc(void *pp, uint16_t u) +{ + uint8_t *p = (uint8_t *)pp; + + p[0] = (u >> 8) & 0xff; + p[1] = u & 0xff; +} + +static INLINE void +be32enc(void *pp, uint32_t u) +{ + uint8_t *p = (uint8_t *)pp; + + p[0] = (u >> 24) & 0xff; + p[1] = (u >> 16) & 0xff; + p[2] = (u >> 8) & 0xff; + p[3] = u & 0xff; +} + +static INLINE void +be64enc(void *pp, uint64_t u) +{ + uint8_t *p = (uint8_t *)pp; + + be32enc(p, (uint32_t)(u >> 32)); + be32enc(p + 4, (uint32_t)(u & 0xffffffffU)); +} + +static INLINE void +le16enc(void *pp, uint16_t u) +{ + uint8_t *p = (uint8_t *)pp; + + p[0] = u & 0xff; + p[1] = (u >> 8) & 0xff; +} + +static INLINE void +le32enc(void *pp, uint32_t u) +{ + uint8_t *p = (uint8_t *)pp; + + p[0] = u & 0xff; + p[1] = (u >> 8) & 0xff; + p[2] = (u >> 16) & 0xff; + p[3] = (u >> 24) & 0xff; +} + +static INLINE void +le64enc(void *pp, uint64_t u) +{ + uint8_t *p = (uint8_t *)pp; + + le32enc(p, (uint32_t)(u & 0xffffffffU)); + le32enc(p + 4, (uint32_t)(u >> 32)); +} + +#endif /* _ENDIAN_H_ */ diff --git a/components/wpa_supplicant/port/include/os.h b/components/wpa_supplicant/port/include/os.h new file mode 100644 index 0000000000..e6da894e92 --- /dev/null +++ b/components/wpa_supplicant/port/include/os.h @@ -0,0 +1,286 @@ +/* + * OS specific functions + * Copyright (c) 2005-2009, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef OS_H +#define OS_H +#include "esp_types.h" +#include +#include +#include +#include "rom/ets_sys.h" +#include "lwip/mem.h" +typedef long os_time_t; + +/** + * os_sleep - Sleep (sec, usec) + * @sec: Number of seconds to sleep + * @usec: Number of microseconds to sleep + */ +void os_sleep(os_time_t sec, os_time_t usec); + +struct os_time { + os_time_t sec; + os_time_t usec; +}; + +/** + * os_get_time - Get current time (sec, usec) + * @t: Pointer to buffer for the time + * Returns: 0 on success, -1 on failure + */ +int os_get_time(struct os_time *t); + + +/* Helper macros for handling struct os_time */ + +#define os_time_before(a, b) \ + ((a)->sec < (b)->sec || \ + ((a)->sec == (b)->sec && (a)->usec < (b)->usec)) + +#define os_time_sub(a, b, res) do { \ + (res)->sec = (a)->sec - (b)->sec; \ + (res)->usec = (a)->usec - (b)->usec; \ + if ((res)->usec < 0) { \ + (res)->sec--; \ + (res)->usec += 1000000; \ + } \ +} while (0) + +/** + * os_mktime - Convert broken-down time into seconds since 1970-01-01 + * @year: Four digit year + * @month: Month (1 .. 12) + * @day: Day of month (1 .. 31) + * @hour: Hour (0 .. 23) + * @min: Minute (0 .. 59) + * @sec: Second (0 .. 60) + * @t: Buffer for returning calendar time representation (seconds since + * 1970-01-01 00:00:00) + * Returns: 0 on success, -1 on failure + * + * Note: The result is in seconds from Epoch, i.e., in UTC, not in local time + * which is used by POSIX mktime(). + */ +int os_mktime(int year, int month, int day, int hour, int min, int sec, + os_time_t *t); + + +/** + * os_daemonize - Run in the background (detach from the controlling terminal) + * @pid_file: File name to write the process ID to or %NULL to skip this + * Returns: 0 on success, -1 on failure + */ +int os_daemonize(const char *pid_file); + +/** + * os_daemonize_terminate - Stop running in the background (remove pid file) + * @pid_file: File name to write the process ID to or %NULL to skip this + */ +void os_daemonize_terminate(const char *pid_file); + +/** + * os_get_random - Get cryptographically strong pseudo random data + * @buf: Buffer for pseudo random data + * @len: Length of the buffer + * Returns: 0 on success, -1 on failure + */ +int os_get_random(unsigned char *buf, size_t len); + +/** + * os_random - Get pseudo random value (not necessarily very strong) + * Returns: Pseudo random value + */ +unsigned long os_random(void); + +/** + * os_rel2abs_path - Get an absolute path for a file + * @rel_path: Relative path to a file + * Returns: Absolute path for the file or %NULL on failure + * + * This function tries to convert a relative path of a file to an absolute path + * in order for the file to be found even if current working directory has + * changed. The returned value is allocated and caller is responsible for + * freeing it. It is acceptable to just return the same path in an allocated + * buffer, e.g., return strdup(rel_path). This function is only used to find + * configuration files when os_daemonize() may have changed the current working + * directory and relative path would be pointing to a different location. + */ +char * os_rel2abs_path(const char *rel_path); + +/** + * os_program_init - Program initialization (called at start) + * Returns: 0 on success, -1 on failure + * + * This function is called when a programs starts. If there are any OS specific + * processing that is needed, it can be placed here. It is also acceptable to + * just return 0 if not special processing is needed. + */ +int os_program_init(void); + +/** + * os_program_deinit - Program deinitialization (called just before exit) + * + * This function is called just before a program exists. If there are any OS + * specific processing, e.g., freeing resourced allocated in os_program_init(), + * it should be done here. It is also acceptable for this function to do + * nothing. + */ +void os_program_deinit(void); + +/** + * os_setenv - Set environment variable + * @name: Name of the variable + * @value: Value to set to the variable + * @overwrite: Whether existing variable should be overwritten + * Returns: 0 on success, -1 on error + * + * This function is only used for wpa_cli action scripts. OS wrapper does not + * need to implement this if such functionality is not needed. + */ +int os_setenv(const char *name, const char *value, int overwrite); + +/** + * os_unsetenv - Delete environent variable + * @name: Name of the variable + * Returns: 0 on success, -1 on error + * + * This function is only used for wpa_cli action scripts. OS wrapper does not + * need to implement this if such functionality is not needed. + */ +int os_unsetenv(const char *name); + +/** + * os_readfile - Read a file to an allocated memory buffer + * @name: Name of the file to read + * @len: For returning the length of the allocated buffer + * Returns: Pointer to the allocated buffer or %NULL on failure + * + * This function allocates memory and reads the given file to this buffer. Both + * binary and text files can be read with this function. The caller is + * responsible for freeing the returned buffer with os_free(). + */ +char * os_readfile(const char *name, size_t *len); + +/* + * The following functions are wrapper for standard ANSI C or POSIX functions. + * By default, they are just defined to use the standard function name and no + * os_*.c implementation is needed for them. This avoids extra function calls + * by allowing the C pre-processor take care of the function name mapping. + * + * If the target system uses a C library that does not provide these functions, + * build_config.h can be used to define the wrappers to use a different + * function name. This can be done on function-by-function basis since the + * defines here are only used if build_config.h does not define the os_* name. + * If needed, os_*.c file can be used to implement the functions that are not + * included in the C library on the target system. Alternatively, + * OS_NO_C_LIB_DEFINES can be defined to skip all defines here in which case + * these functions need to be implemented in os_*.c file for the target system. + */ + +#ifndef os_malloc +#define os_malloc(s) malloc((s)) +#endif +#ifndef os_realloc +#define os_realloc(p, s) realloc((p), (s)) +#endif +#ifndef os_zalloc +#define os_zalloc(s) calloc(1, (s)) +#endif +#ifndef os_free +#define os_free(p) free((p)) +#endif + + +#ifndef os_strdup +#ifdef _MSC_VER +#define os_strdup(s) _strdup(s) +#else +#define os_strdup(s) strdup(s) +#endif +#endif +char * ets_strdup(const char *s); + +#ifndef os_memcpy +#define os_memcpy(d, s, n) memcpy((d), (s), (n)) +#endif +#ifndef os_memmove +#define os_memmove(d, s, n) memmove((d), (s), (n)) +#endif +#ifndef os_memset +#define os_memset(s, c, n) memset(s, c, n) +#endif +#ifndef os_memcmp +#define os_memcmp(s1, s2, n) memcmp((s1), (s2), (n)) +#endif + +#ifndef os_strlen +#define os_strlen(s) strlen(s) +#endif +#ifndef os_strcasecmp +#ifdef _MSC_VER +#define os_strcasecmp(s1, s2) _stricmp((s1), (s2)) +#else +#define os_strcasecmp(s1, s2) strcasecmp((s1), (s2)) +#endif +#endif +#ifndef os_strncasecmp +#ifdef _MSC_VER +#define os_strncasecmp(s1, s2, n) _strnicmp((s1), (s2), (n)) +#else +#define os_strncasecmp(s1, s2, n) strncasecmp((s1), (s2), (n)) +#endif +#endif +#ifndef os_strchr +#define os_strchr(s, c) strchr((s), (c)) +#endif +#ifndef os_strcmp +#define os_strcmp(s1, s2) strcmp((s1), (s2)) +#endif +#ifndef os_strncmp +#define os_strncmp(s1, s2, n) strncmp((s1), (s2), (n)) +#endif +#ifndef os_strncpy +#define os_strncpy(d, s, n) strncpy((d), (s), (n)) +#endif +#ifndef os_strrchr +//hard cold +#define os_strrchr(s, c) NULL +#endif +#ifndef os_strstr +#define os_strstr(h, n) strstr((h), (n)) +#endif + +#ifndef os_snprintf +#ifdef _MSC_VER +#define os_snprintf _snprintf +#else +#define os_snprintf vsnprintf +#endif +#endif + +/** + * os_strlcpy - Copy a string with size bound and NUL-termination + * @dest: Destination + * @src: Source + * @siz: Size of the target buffer + * Returns: Total length of the target string (length of src) (not including + * NUL-termination) + * + * This function matches in behavior with the strlcpy(3) function in OpenBSD. + */ +size_t os_strlcpy(char *dest, const char *src, size_t siz); + + + +#endif /* OS_H */ diff --git a/components/wpa_supplicant/src/crypto/aes-cbc.c b/components/wpa_supplicant/src/crypto/aes-cbc.c new file mode 100644 index 0000000000..016207795e --- /dev/null +++ b/components/wpa_supplicant/src/crypto/aes-cbc.c @@ -0,0 +1,88 @@ +/* + * AES-128 CBC + * + * Copyright (c) 2003-2007, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "crypto/includes.h" + +#include "crypto/common.h" +#include "crypto/aes.h" +#include "crypto/aes_wrap.h" + +/** + * aes_128_cbc_encrypt - AES-128 CBC encryption + * @key: Encryption key + * @iv: Encryption IV for CBC mode (16 bytes) + * @data: Data to encrypt in-place + * @data_len: Length of data in bytes (must be divisible by 16) + * Returns: 0 on success, -1 on failure + */ +int +aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) +{ + void *ctx; + u8 cbc[AES_BLOCK_SIZE]; + u8 *pos = data; + int i, j, blocks; + + ctx = aes_encrypt_init(key, 16); + if (ctx == NULL) + return -1; + os_memcpy(cbc, iv, AES_BLOCK_SIZE); + + blocks = data_len / AES_BLOCK_SIZE; + for (i = 0; i < blocks; i++) { + for (j = 0; j < AES_BLOCK_SIZE; j++) + cbc[j] ^= pos[j]; + aes_encrypt(ctx, cbc, cbc); + os_memcpy(pos, cbc, AES_BLOCK_SIZE); + pos += AES_BLOCK_SIZE; + } + aes_encrypt_deinit(ctx); + return 0; +} + + +/** + * aes_128_cbc_decrypt - AES-128 CBC decryption + * @key: Decryption key + * @iv: Decryption IV for CBC mode (16 bytes) + * @data: Data to decrypt in-place + * @data_len: Length of data in bytes (must be divisible by 16) + * Returns: 0 on success, -1 on failure + */ +int +aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) +{ + void *ctx; + u8 cbc[AES_BLOCK_SIZE], tmp[AES_BLOCK_SIZE]; + u8 *pos = data; + int i, j, blocks; + + ctx = aes_decrypt_init(key, 16); + if (ctx == NULL) + return -1; + os_memcpy(cbc, iv, AES_BLOCK_SIZE); + + blocks = data_len / AES_BLOCK_SIZE; + for (i = 0; i < blocks; i++) { + os_memcpy(tmp, pos, AES_BLOCK_SIZE); + aes_decrypt(ctx, pos, pos); + for (j = 0; j < AES_BLOCK_SIZE; j++) + pos[j] ^= cbc[j]; + os_memcpy(cbc, tmp, AES_BLOCK_SIZE); + pos += AES_BLOCK_SIZE; + } + aes_decrypt_deinit(ctx); + return 0; +} diff --git a/components/wpa_supplicant/src/crypto/aes-internal-dec.c b/components/wpa_supplicant/src/crypto/aes-internal-dec.c new file mode 100644 index 0000000000..46371c5557 --- /dev/null +++ b/components/wpa_supplicant/src/crypto/aes-internal-dec.c @@ -0,0 +1,172 @@ +/* + * AES (Rijndael) cipher - decrypt + * + * Modifications to public domain implementation: + * - support only 128-bit keys + * - cleanup + * - use C pre-processor to make it easier to change S table access + * - added option (AES_SMALL_TABLES) for reducing code size by about 8 kB at + * cost of reduced throughput (quite small difference on Pentium 4, + * 10-25% when using -O1 or -O2 optimization) + * + * Copyright (c) 2003-2005, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "crypto/includes.h" + +#include "crypto/common.h" +#include "crypto/crypto.h" +#include "crypto/aes_i.h" + + + +//static unsigned char aes_priv_buf[AES_PRIV_SIZE]; + +/** + * Expand the cipher key into the decryption key schedule. + * + * @return the number of rounds for the given cipher key size. + */ +static int rijndaelKeySetupDec(u32 rk[], const u8 cipherKey[], int keyBits) +{ + int Nr, i, j; + u32 temp; + + /* expand the cipher key: */ + Nr = rijndaelKeySetupEnc(rk, cipherKey, keyBits); + if (Nr < 0) + return Nr; + /* invert the order of the round keys: */ + for (i = 0, j = 4*Nr; i < j; i += 4, j -= 4) { + temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp; + temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; + temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; + temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; + } + /* apply the inverse MixColumn transform to all round keys but the + * first and the last: */ + for (i = 1; i < Nr; i++) { + rk += 4; + for (j = 0; j < 4; j++) { + rk[j] = TD0_(TE4((rk[j] >> 24) )) ^ + TD1_(TE4((rk[j] >> 16) & 0xff)) ^ + TD2_(TE4((rk[j] >> 8) & 0xff)) ^ + TD3_(TE4((rk[j] ) & 0xff)); + } + } + + return Nr; +} + +void * aes_decrypt_init(const u8 *key, size_t len) +{ + u32 *rk; + int res; + rk = os_malloc(AES_PRIV_SIZE); + if (rk == NULL) + return NULL; + res = rijndaelKeySetupDec(rk, key, len * 8); + if (res < 0) { + os_free(rk); + return NULL; + } + rk[AES_PRIV_NR_POS] = res; + return rk; +} + +static void rijndaelDecrypt(const u32 rk[/*44*/], int Nr, const u8 ct[16], + u8 pt[16]) +{ + u32 s0, s1, s2, s3, t0, t1, t2, t3; +#ifndef FULL_UNROLL + int r; +#endif /* ?FULL_UNROLL */ + + /* + * map byte array block to cipher state + * and add initial round key: + */ + s0 = GETU32(ct ) ^ rk[0]; + s1 = GETU32(ct + 4) ^ rk[1]; + s2 = GETU32(ct + 8) ^ rk[2]; + s3 = GETU32(ct + 12) ^ rk[3]; + +#define ROUND(i,d,s) \ +d##0 = TD0(s##0) ^ TD1(s##3) ^ TD2(s##2) ^ TD3(s##1) ^ rk[4 * i]; \ +d##1 = TD0(s##1) ^ TD1(s##0) ^ TD2(s##3) ^ TD3(s##2) ^ rk[4 * i + 1]; \ +d##2 = TD0(s##2) ^ TD1(s##1) ^ TD2(s##0) ^ TD3(s##3) ^ rk[4 * i + 2]; \ +d##3 = TD0(s##3) ^ TD1(s##2) ^ TD2(s##1) ^ TD3(s##0) ^ rk[4 * i + 3] + +#ifdef FULL_UNROLL + + ROUND(1,t,s); + ROUND(2,s,t); + ROUND(3,t,s); + ROUND(4,s,t); + ROUND(5,t,s); + ROUND(6,s,t); + ROUND(7,t,s); + ROUND(8,s,t); + ROUND(9,t,s); + if (Nr > 10) { + ROUND(10,s,t); + ROUND(11,t,s); + if (Nr > 12) { + ROUND(12,s,t); + ROUND(13,t,s); + } + } + + rk += Nr << 2; + +#else /* !FULL_UNROLL */ + + /* Nr - 1 full rounds: */ + r = Nr >> 1; + for (;;) { + ROUND(1,t,s); + rk += 8; + if (--r == 0) + break; + ROUND(0,s,t); + } + +#endif /* ?FULL_UNROLL */ + +#undef ROUND + + /* + * apply last round and + * map cipher state to byte array block: + */ + s0 = TD41(t0) ^ TD42(t3) ^ TD43(t2) ^ TD44(t1) ^ rk[0]; + PUTU32(pt , s0); + s1 = TD41(t1) ^ TD42(t0) ^ TD43(t3) ^ TD44(t2) ^ rk[1]; + PUTU32(pt + 4, s1); + s2 = TD41(t2) ^ TD42(t1) ^ TD43(t0) ^ TD44(t3) ^ rk[2]; + PUTU32(pt + 8, s2); + s3 = TD41(t3) ^ TD42(t2) ^ TD43(t1) ^ TD44(t0) ^ rk[3]; + PUTU32(pt + 12, s3); +} + +void aes_decrypt(void *ctx, const u8 *crypt, u8 *plain) +{ + u32 *rk = ctx; + rijndaelDecrypt(ctx, rk[AES_PRIV_NR_POS], crypt, plain); +} + + +void aes_decrypt_deinit(void *ctx) +{ + os_memset(ctx, 0, AES_PRIV_SIZE); + os_free(ctx); +} diff --git a/components/wpa_supplicant/src/crypto/aes-internal-enc.c b/components/wpa_supplicant/src/crypto/aes-internal-enc.c new file mode 100644 index 0000000000..7b1080c450 --- /dev/null +++ b/components/wpa_supplicant/src/crypto/aes-internal-enc.c @@ -0,0 +1,134 @@ +/* + * AES (Rijndael) cipher - encrypt + * + * Modifications to public domain implementation: + * - support only 128-bit keys + * - cleanup + * - use C pre-processor to make it easier to change S table access + * - added option (AES_SMALL_TABLES) for reducing code size by about 8 kB at + * cost of reduced throughput (quite small difference on Pentium 4, + * 10-25% when using -O1 or -O2 optimization) + * + * Copyright (c) 2003-2005, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "crypto/includes.h" +#include "crypto/common.h" +#include "crypto/crypto.h" +#include "crypto/aes_i.h" + +#include "os.h" + +void rijndaelEncrypt(const u32 rk[], int Nr, const u8 pt[16], u8 ct[16]) +{ + u32 s0, s1, s2, s3, t0, t1, t2, t3; +#ifndef FULL_UNROLL + int r; +#endif /* ?FULL_UNROLL */ + + /* + * map byte array block to cipher state + * and add initial round key: + */ + s0 = GETU32(pt ) ^ rk[0]; + s1 = GETU32(pt + 4) ^ rk[1]; + s2 = GETU32(pt + 8) ^ rk[2]; + s3 = GETU32(pt + 12) ^ rk[3]; + +#define ROUND(i,d,s) \ +d##0 = TE0(s##0) ^ TE1(s##1) ^ TE2(s##2) ^ TE3(s##3) ^ rk[4 * i]; \ +d##1 = TE0(s##1) ^ TE1(s##2) ^ TE2(s##3) ^ TE3(s##0) ^ rk[4 * i + 1]; \ +d##2 = TE0(s##2) ^ TE1(s##3) ^ TE2(s##0) ^ TE3(s##1) ^ rk[4 * i + 2]; \ +d##3 = TE0(s##3) ^ TE1(s##0) ^ TE2(s##1) ^ TE3(s##2) ^ rk[4 * i + 3] + +#ifdef FULL_UNROLL + + ROUND(1,t,s); + ROUND(2,s,t); + ROUND(3,t,s); + ROUND(4,s,t); + ROUND(5,t,s); + ROUND(6,s,t); + ROUND(7,t,s); + ROUND(8,s,t); + ROUND(9,t,s); + if (Nr > 10) { + ROUND(10,s,t); + ROUND(11,t,s); + if (Nr > 12) { + ROUND(12,s,t); + ROUND(13,t,s); + } + } + + rk += Nr << 2; + +#else /* !FULL_UNROLL */ + + /* Nr - 1 full rounds: */ + r = Nr >> 1; + for (;;) { + ROUND(1,t,s); + rk += 8; + if (--r == 0) + break; + ROUND(0,s,t); + } + +#endif /* ?FULL_UNROLL */ + +#undef ROUND + + /* + * apply last round and + * map cipher state to byte array block: + */ + s0 = TE41(t0) ^ TE42(t1) ^ TE43(t2) ^ TE44(t3) ^ rk[0]; + PUTU32(ct , s0); + s1 = TE41(t1) ^ TE42(t2) ^ TE43(t3) ^ TE44(t0) ^ rk[1]; + PUTU32(ct + 4, s1); + s2 = TE41(t2) ^ TE42(t3) ^ TE43(t0) ^ TE44(t1) ^ rk[2]; + PUTU32(ct + 8, s2); + s3 = TE41(t3) ^ TE42(t0) ^ TE43(t1) ^ TE44(t2) ^ rk[3]; + PUTU32(ct + 12, s3); +} + + +void * aes_encrypt_init(const u8 *key, size_t len) +{ + u32 *rk; + int res; + rk = os_malloc(AES_PRIV_SIZE); + if (rk == NULL) + return NULL; + res = rijndaelKeySetupEnc(rk, key, len * 8); + if (res < 0) { + os_free(rk); + return NULL; + } + rk[AES_PRIV_NR_POS] = res; + return rk; +} + + +void aes_encrypt(void *ctx, const u8 *plain, u8 *crypt) +{ + u32 *rk = ctx; + rijndaelEncrypt(ctx, rk[AES_PRIV_NR_POS], plain, crypt); +} + + +void aes_encrypt_deinit(void *ctx) +{ + os_memset(ctx, 0, AES_PRIV_SIZE); + os_free(ctx); +} diff --git a/components/wpa_supplicant/src/crypto/aes-internal.c b/components/wpa_supplicant/src/crypto/aes-internal.c new file mode 100644 index 0000000000..9618239f93 --- /dev/null +++ b/components/wpa_supplicant/src/crypto/aes-internal.c @@ -0,0 +1,854 @@ +/* + * AES (Rijndael) cipher + * + * Modifications to public domain implementation: + * - support only 128-bit keys + * - cleanup + * - use C pre-processor to make it easier to change S table access + * - added option (AES_SMALL_TABLES) for reducing code size by about 8 kB at + * cost of reduced throughput (quite small difference on Pentium 4, + * 10-25% when using -O1 or -O2 optimization) + * + * Copyright (c) 2003-2005, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "crypto/includes.h" + +//#include "wpa/common.h" +#include "crypto/common.h" +#include "crypto/crypto.h" +#include "crypto/aes_i.h" + +/* + * rijndael-alg-fst.c + * + * @version 3.0 (December 2000) + * + * Optimised ANSI C code for the Rijndael cipher (now AES) + * + * @author Vincent Rijmen + * @author Antoon Bosselaers + * @author Paulo Barreto + * + * This code is hereby placed in the public domain. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#define AES_SMALL_TABLES + +/* +Te0[x] = S [x].[02, 01, 01, 03]; +Te1[x] = S [x].[03, 02, 01, 01]; +Te2[x] = S [x].[01, 03, 02, 01]; +Te3[x] = S [x].[01, 01, 03, 02]; +Te4[x] = S [x].[01, 01, 01, 01]; + +Td0[x] = Si[x].[0e, 09, 0d, 0b]; +Td1[x] = Si[x].[0b, 0e, 09, 0d]; +Td2[x] = Si[x].[0d, 0b, 0e, 09]; +Td3[x] = Si[x].[09, 0d, 0b, 0e]; +Td4[x] = Si[x].[01, 01, 01, 01]; +*/ + +const u32 Te0[256] /* ICACHE_RODATA_ATTR */ = { + 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, + 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, + 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, + 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU, + 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, + 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, + 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, + 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU, + 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU, + 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU, + 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, + 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU, + 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU, + 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U, + 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, + 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU, + 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, + 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU, + 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU, + 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U, + 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, + 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, + 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU, + 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU, + 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U, + 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, + 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, + 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U, + 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU, + 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U, + 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, + 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU, + 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU, + 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U, + 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U, + 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, + 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, + 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U, + 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU, + 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U, + 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, + 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, + 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U, + 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU, + 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, + 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, + 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, + 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U, + 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U, + 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U, + 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, + 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, + 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU, + 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U, + 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, + 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U, + 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U, + 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U, + 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U, + 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU, + 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, + 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U, + 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U, + 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU, +}; +#ifndef AES_SMALL_TABLES +const u32 Te1[256] /* ICACHE_RODATA_ATTR */ = { + 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU, + 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U, + 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU, + 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U, + 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU, + 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U, + 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU, + 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U, + 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U, + 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU, + 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U, + 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U, + 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U, + 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU, + 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U, + 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U, + 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU, + 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U, + 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U, + 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U, + 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU, + 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU, + 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U, + 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU, + 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU, + 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U, + 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU, + 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U, + 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU, + 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U, + 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U, + 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U, + 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU, + 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U, + 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU, + 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U, + 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU, + 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U, + 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U, + 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU, + 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU, + 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU, + 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U, + 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U, + 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU, + 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U, + 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU, + 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U, + 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU, + 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U, + 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU, + 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU, + 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U, + 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU, + 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U, + 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU, + 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U, + 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U, + 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U, + 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU, + 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU, + 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U, + 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU, + 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U, +}; +const u32 Te2[256] /* ICACHE_RODATA_ATTR */ = { + 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU, + 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U, + 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU, + 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U, + 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU, + 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U, + 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU, + 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U, + 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U, + 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU, + 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U, + 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U, + 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U, + 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU, + 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U, + 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U, + 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU, + 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U, + 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U, + 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U, + 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU, + 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU, + 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U, + 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU, + 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU, + 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U, + 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU, + 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U, + 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU, + 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U, + 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U, + 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U, + 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU, + 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U, + 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU, + 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U, + 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU, + 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U, + 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U, + 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU, + 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU, + 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU, + 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U, + 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U, + 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU, + 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U, + 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU, + 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U, + 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU, + 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U, + 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU, + 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU, + 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U, + 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU, + 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U, + 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU, + 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U, + 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U, + 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U, + 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU, + 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU, + 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U, + 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU, + 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U, +}; +const u32 Te3[256] /* ICACHE_RODATA_ATTR */ = { + + 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U, + 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U, + 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U, + 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU, + 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU, + 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU, + 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U, + 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU, + 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU, + 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U, + 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U, + 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU, + 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU, + 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU, + 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU, + 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU, + 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U, + 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU, + 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU, + 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U, + 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U, + 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U, + 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U, + 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U, + 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU, + 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U, + 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU, + 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU, + 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U, + 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U, + 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U, + 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU, + 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U, + 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU, + 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU, + 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U, + 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U, + 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU, + 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U, + 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU, + 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U, + 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U, + 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U, + 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U, + 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU, + 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U, + 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU, + 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U, + 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU, + 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U, + 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU, + 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU, + 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU, + 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU, + 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U, + 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U, + 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U, + 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U, + 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U, + 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U, + 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU, + 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U, + 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU, + 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU, +}; +const u32 Te4[256] /* ICACHE_RODATA_ATTR */ = { + 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU, + 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U, + 0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU, + 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U, + 0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU, + 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U, + 0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU, + 0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U, + 0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U, + 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU, + 0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U, + 0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U, + 0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U, + 0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU, + 0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U, + 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U, + 0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU, + 0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U, + 0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U, + 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U, + 0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU, + 0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU, + 0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U, + 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU, + 0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU, + 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U, + 0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU, + 0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U, + 0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU, + 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U, + 0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U, + 0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U, + 0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU, + 0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U, + 0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU, + 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U, + 0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU, + 0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U, + 0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U, + 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU, + 0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU, + 0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU, + 0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U, + 0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U, + 0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU, + 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U, + 0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU, + 0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U, + 0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU, + 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U, + 0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU, + 0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU, + 0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U, + 0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU, + 0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U, + 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU, + 0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U, + 0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U, + 0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U, + 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU, + 0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU, + 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U, + 0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU, + 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U, +}; +#endif /* AES_SMALL_TABLES */ +const u32 Td0[256] /* ICACHE_RODATA_ATTR */ = { + 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, + 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, + 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U, + 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU, + 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U, + 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U, + 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU, + 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U, + 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU, + 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U, + 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U, + 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U, + 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U, + 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU, + 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U, + 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU, + 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U, + 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU, + 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U, + 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U, + 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U, + 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU, + 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U, + 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU, + 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U, + 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU, + 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U, + 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU, + 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU, + 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U, + 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU, + 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U, + 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU, + 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U, + 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U, + 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U, + 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU, + 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U, + 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U, + 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU, + 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U, + 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U, + 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U, + 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U, + 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U, + 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU, + 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U, + 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U, + 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U, + 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U, + 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U, + 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU, + 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU, + 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU, + 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU, + 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U, + 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U, + 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU, + 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU, + 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U, + 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU, + 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U, + 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U, + 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U, +}; +#ifndef AES_SMALL_TABLES +const u32 Td1[256] /* ICACHE_RODATA_ATTR */ = { + 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU, + 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U, + 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU, + 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U, + 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U, + 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U, + 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U, + 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U, + 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U, + 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU, + 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU, + 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU, + 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U, + 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU, + 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U, + 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U, + 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U, + 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU, + 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU, + 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U, + 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU, + 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U, + 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU, + 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU, + 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U, + 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U, + 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U, + 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU, + 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U, + 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU, + 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U, + 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U, + 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U, + 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU, + 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U, + 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U, + 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U, + 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U, + 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U, + 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U, + 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU, + 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU, + 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U, + 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU, + 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U, + 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU, + 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU, + 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U, + 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU, + 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U, + 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U, + 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U, + 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U, + 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U, + 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U, + 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U, + 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU, + 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U, + 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U, + 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU, + 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U, + 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U, + 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U, + 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U, +}; +const u32 Td2[256] /* ICACHE_RODATA_ATTR */ = { + 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U, + 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U, + 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U, + 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U, + 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU, + 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U, + 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U, + 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U, + 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U, + 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU, + 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U, + 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U, + 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU, + 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U, + 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U, + 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U, + 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U, + 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U, + 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U, + 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU, + + 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U, + 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U, + 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U, + 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U, + 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U, + 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU, + 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU, + 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U, + 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU, + 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U, + 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU, + 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU, + 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU, + 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU, + 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U, + 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U, + 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U, + 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U, + 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U, + 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U, + 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U, + 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU, + 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU, + 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U, + 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U, + 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU, + 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU, + 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U, + 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U, + 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U, + 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U, + 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U, + 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U, + 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U, + 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU, + 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U, + 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U, + 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U, + 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U, + 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U, + 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U, + 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU, + 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U, + 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U, +}; +const u32 Td3[256] /* ICACHE_RODATA_ATTR */ = { + 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU, + 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU, + 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U, + 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U, + 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU, + 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU, + 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U, + 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU, + 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U, + 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU, + 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U, + 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U, + 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U, + 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U, + 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U, + 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU, + 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU, + 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U, + 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U, + 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU, + 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU, + 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U, + 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U, + 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U, + 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U, + 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU, + 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U, + 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U, + 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU, + 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU, + 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U, + 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U, + 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U, + 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU, + 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U, + 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U, + 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U, + 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U, + 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U, + 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U, + 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U, + 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU, + 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U, + 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U, + 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU, + 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU, + 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U, + 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU, + 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U, + 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U, + 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U, + 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U, + 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U, + 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U, + 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU, + 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU, + 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU, + 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU, + 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U, + 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U, + 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U, + 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU, + 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U, + 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U, +}; +const u32 Td4[256] /* ICACHE_RODATA_ATTR */ = { + 0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U, + 0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U, + 0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU, + 0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU, + 0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U, + 0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U, + 0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U, + 0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU, + 0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U, + 0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU, + 0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU, + 0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU, + 0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U, + 0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U, + 0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U, + 0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U, + 0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U, + 0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U, + 0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU, + 0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U, + 0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U, + 0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU, + 0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U, + 0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U, + 0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U, + 0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU, + 0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U, + 0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U, + 0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU, + 0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U, + 0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U, + 0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU, + 0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U, + 0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU, + 0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU, + 0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U, + 0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U, + 0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U, + 0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U, + 0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU, + 0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U, + 0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U, + 0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU, + 0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU, + 0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU, + 0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U, + 0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU, + 0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U, + 0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U, + 0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U, + 0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U, + 0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU, + 0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U, + 0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU, + 0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU, + 0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU, + 0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU, + 0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U, + 0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU, + 0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U, + 0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU, + 0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U, + 0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U, + 0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU, +}; +const u32 rcon[] /* ICACHE_RODATA_ATTR */ = { + 0x01000000, 0x02000000, 0x04000000, 0x08000000, + 0x10000000, 0x20000000, 0x40000000, 0x80000000, + 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ +}; +#else /* AES_SMALL_TABLES */ +const u8 Td4s[256] /* ICACHE_RODATA_ATTR */ = { + 0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U, + 0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU, + 0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U, + 0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU, + 0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU, + 0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU, + 0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U, + 0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U, + 0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U, + 0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U, + 0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU, + 0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U, + 0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU, + 0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U, + 0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U, + 0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU, + 0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU, + 0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U, + 0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U, + 0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU, + 0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U, + 0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU, + 0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U, + 0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U, + 0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U, + 0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU, + 0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU, + 0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU, + 0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U, + 0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U, + 0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U, + 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU, +}; +const u8 rcons[] /* ICACHE_RODATA_ATTR */ = { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36 + /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ +}; +#endif /* AES_SMALL_TABLES */ +/** + * Expand the cipher key into the encryption key schedule. + * + * @return the number of rounds for the given cipher key size. + */ +int rijndaelKeySetupEnc(u32 rk[], const u8 cipherKey[], int keyBits) +{ + int i; + u32 temp; + + rk[0] = GETU32(cipherKey ); + rk[1] = GETU32(cipherKey + 4); + rk[2] = GETU32(cipherKey + 8); + rk[3] = GETU32(cipherKey + 12); + + if (keyBits == 128) { + for (i = 0; i < 10; i++) { + temp = rk[3]; + rk[4] = rk[0] ^ TE421(temp) ^ TE432(temp) ^ + TE443(temp) ^ TE414(temp) ^ RCON(i); + rk[5] = rk[1] ^ rk[4]; + rk[6] = rk[2] ^ rk[5]; + rk[7] = rk[3] ^ rk[6]; + rk += 4; + } + return 10; + } + + rk[4] = GETU32(cipherKey + 16); + rk[5] = GETU32(cipherKey + 20); + + if (keyBits == 192) { + for (i = 0; i < 8; i++) { + temp = rk[5]; + rk[6] = rk[0] ^ TE421(temp) ^ TE432(temp) ^ + TE443(temp) ^ TE414(temp) ^ RCON(i); + rk[7] = rk[1] ^ rk[6]; + rk[8] = rk[2] ^ rk[7]; + rk[9] = rk[3] ^ rk[8]; + if (i == 7) + return 12; + rk[10] = rk[4] ^ rk[9]; + rk[11] = rk[5] ^ rk[10]; + rk += 6; + } + } + + rk[6] = GETU32(cipherKey + 24); + rk[7] = GETU32(cipherKey + 28); + + if (keyBits == 256) { + for (i = 0; i < 7; i++) { + temp = rk[7]; + rk[8] = rk[0] ^ TE421(temp) ^ TE432(temp) ^ + TE443(temp) ^ TE414(temp) ^ RCON(i); + rk[9] = rk[1] ^ rk[8]; + rk[10] = rk[2] ^ rk[9]; + rk[11] = rk[3] ^ rk[10]; + if (i == 6) + return 14; + temp = rk[11]; + rk[12] = rk[4] ^ TE411(temp) ^ TE422(temp) ^ + TE433(temp) ^ TE444(temp); + rk[13] = rk[5] ^ rk[12]; + rk[14] = rk[6] ^ rk[13]; + rk[15] = rk[7] ^ rk[14]; + rk += 8; + } + } + + return -1; +} diff --git a/components/wpa_supplicant/src/crypto/aes-unwrap.c b/components/wpa_supplicant/src/crypto/aes-unwrap.c new file mode 100644 index 0000000000..4a92f1cd31 --- /dev/null +++ b/components/wpa_supplicant/src/crypto/aes-unwrap.c @@ -0,0 +1,80 @@ +/* + * AES key unwrap (128-bit KEK, RFC3394) + * + * Copyright (c) 2003-2007, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "crypto/includes.h" + +#include "crypto/common.h" +#include "crypto/aes.h" +#include "crypto/aes_wrap.h" + +/** + * aes_unwrap - Unwrap key with AES Key Wrap Algorithm (128-bit KEK) (RFC3394) + * @kek: Key encryption key (KEK) + * @n: Length of the plaintext key in 64-bit units; e.g., 2 = 128-bit = 16 + * bytes + * @cipher: Wrapped key to be unwrapped, (n + 1) * 64 bits + * @plain: Plaintext key, n * 64 bits + * Returns: 0 on success, -1 on failure (e.g., integrity verification failed) + */ +int +aes_unwrap(const u8 *kek, int n, const u8 *cipher, u8 *plain) +{ + u8 a[8], *r, b[16]; + int i, j; + void *ctx; + + /* 1) Initialize variables. */ + os_memcpy(a, cipher, 8); + r = plain; + os_memcpy(r, cipher + 8, 8 * n); + + ctx = aes_decrypt_init(kek, 16); + if (ctx == NULL) + return -1; + + /* 2) Compute intermediate values. + * For j = 5 to 0 + * For i = n to 1 + * B = AES-1(K, (A ^ t) | R[i]) where t = n*j+i + * A = MSB(64, B) + * R[i] = LSB(64, B) + */ + for (j = 5; j >= 0; j--) { + r = plain + (n - 1) * 8; + for (i = n; i >= 1; i--) { + os_memcpy(b, a, 8); + b[7] ^= n * j + i; + + os_memcpy(b + 8, r, 8); + aes_decrypt(ctx, b, b); + os_memcpy(a, b, 8); + os_memcpy(r, b + 8, 8); + r -= 8; + } + } + aes_decrypt_deinit(ctx); + + /* 3) Output results. + * + * These are already in @plain due to the location of temporary + * variables. Just verify that the IV matches with the expected value. + */ + for (i = 0; i < 8; i++) { + if (a[i] != 0xa6) + return -1; + } + + return 0; +} diff --git a/components/wpa_supplicant/src/crypto/aes-wrap.c b/components/wpa_supplicant/src/crypto/aes-wrap.c new file mode 100644 index 0000000000..388dd97a82 --- /dev/null +++ b/components/wpa_supplicant/src/crypto/aes-wrap.c @@ -0,0 +1,70 @@ +/* + * AES Key Wrap Algorithm (128-bit KEK) (RFC3394) + * + * Copyright (c) 2003-2007, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "crypto/includes.h" + +#include "crypto/common.h" +#include "crypto/aes.h" +#include "crypto/aes_wrap.h" + +/** + * aes_wrap - Wrap keys with AES Key Wrap Algorithm (128-bit KEK) (RFC3394) + * @kek: 16-octet Key encryption key (KEK) + * @n: Length of the plaintext key in 64-bit units; e.g., 2 = 128-bit = 16 + * bytes + * @plain: Plaintext key to be wrapped, n * 64 bits + * @cipher: Wrapped key, (n + 1) * 64 bits + * Returns: 0 on success, -1 on failure + */ +int aes_wrap(const u8 *kek, int n, const u8 *plain, u8 *cipher) +{ + u8 *a, *r, b[16]; + int i, j; + void *ctx; + + a = cipher; + r = cipher + 8; + + /* 1) Initialize variables. */ + os_memset(a, 0xa6, 8); + os_memcpy(r, plain, 8 * n); + + ctx = aes_encrypt_init(kek, 16); + if (ctx == NULL) + return -1; + + /* 2) Calculate intermediate values. + * For j = 0 to 5 + * For i=1 to n + * B = AES(K, A | R[i]) + * A = MSB(64, B) ^ t where t = (n*j)+i + * R[i] = LSB(64, B) + */ + for (j = 0; j <= 5; j++) { + r = cipher + 8; + for (i = 1; i <= n; i++) { + os_memcpy(b, a, 8); + os_memcpy(b + 8, r, 8); + aes_encrypt(ctx, b, b); + os_memcpy(a, b, 8); + a[7] ^= n * j + i; + os_memcpy(r, b + 8, 8); + r += 8; + } + } + aes_encrypt_deinit(ctx); + + /* 3) Output the results. + * + * These are already in @cipher due to the location of temporary + * variables. + */ + + return 0; +} diff --git a/components/wpa_supplicant/src/crypto/bignum.c b/components/wpa_supplicant/src/crypto/bignum.c new file mode 100644 index 0000000000..7b8446c3ba --- /dev/null +++ b/components/wpa_supplicant/src/crypto/bignum.c @@ -0,0 +1,244 @@ +/* + * Big number math + * Copyright (c) 2006, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "crypto/includes.h" +#include "crypto/common.h" +#include "wpa/wpabuf.h" +#include "wpa/wpa_debug.h" +#include "bignum.h" + +#define CONFIG_INTERNAL_LIBTOMMATH +#ifdef CONFIG_INTERNAL_LIBTOMMATH +#include "libtommath.h" +#else /* CONFIG_INTERNAL_LIBTOMMATH */ +#include +#endif /* CONFIG_INTERNAL_LIBTOMMATH */ + + +/* + * The current version is just a wrapper for LibTomMath library, so + * struct bignum is just typecast to mp_int. + */ + +/** + * bignum_init - Allocate memory for bignum + * Returns: Pointer to allocated bignum or %NULL on failure + */ +struct bignum * +bignum_init(void) +{ + struct bignum *n = (struct bignum *)os_zalloc(sizeof(mp_int)); + if (n == NULL) + return NULL; + if (mp_init((mp_int *) n) != MP_OKAY) { + os_free(n); + n = NULL; + } + return n; +} + + +/** + * bignum_deinit - Free bignum + * @n: Bignum from bignum_init() + */ +void +bignum_deinit(struct bignum *n) +{ + if (n) { + mp_clear((mp_int *) n); + os_free(n); + } +} + + +/** + * bignum_get_unsigned_bin - Get length of bignum as an unsigned binary buffer + * @n: Bignum from bignum_init() + * Returns: Length of n if written to a binary buffer + */ +size_t +bignum_get_unsigned_bin_len(struct bignum *n) +{ + return mp_unsigned_bin_size((mp_int *) n); +} + + +/** + * bignum_get_unsigned_bin - Set binary buffer to unsigned bignum + * @n: Bignum from bignum_init() + * @buf: Buffer for the binary number + * @len: Length of the buffer, can be %NULL if buffer is known to be long + * enough. Set to used buffer length on success if not %NULL. + * Returns: 0 on success, -1 on failure + */ +int +bignum_get_unsigned_bin(const struct bignum *n, u8 *buf, size_t *len) +{ + size_t need = mp_unsigned_bin_size((mp_int *) n); + if (len && need > *len) { + *len = need; + return -1; + } + if (mp_to_unsigned_bin((mp_int *) n, buf) != MP_OKAY) { + wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__); + return -1; + } + if (len) + *len = need; + return 0; +} + + +/** + * bignum_set_unsigned_bin - Set bignum based on unsigned binary buffer + * @n: Bignum from bignum_init(); to be set to the given value + * @buf: Buffer with unsigned binary value + * @len: Length of buf in octets + * Returns: 0 on success, -1 on failure + */ +int +bignum_set_unsigned_bin(struct bignum *n, const u8 *buf, size_t len) +{ + if (mp_read_unsigned_bin((mp_int *) n, (u8 *) buf, len) != MP_OKAY) { + wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__); + return -1; + } + return 0; +} + + +/** + * bignum_cmp - Signed comparison + * @a: Bignum from bignum_init() + * @b: Bignum from bignum_init() + * Returns: 0 on success, -1 on failure + */ +int +bignum_cmp(const struct bignum *a, const struct bignum *b) +{ + return mp_cmp((mp_int *) a, (mp_int *) b); +} + + +/** + * bignum_cmd_d - Compare bignum to standard integer + * @a: Bignum from bignum_init() + * @b: Small integer + * Returns: 0 on success, -1 on failure + */ +int +bignum_cmp_d(const struct bignum *a, unsigned long b) +{ + return mp_cmp_d((mp_int *) a, b); +} + + +/** + * bignum_add - c = a + b + * @a: Bignum from bignum_init() + * @b: Bignum from bignum_init() + * @c: Bignum from bignum_init(); used to store the result of a + b + * Returns: 0 on success, -1 on failure + */ +int +bignum_add(const struct bignum *a, const struct bignum *b, + struct bignum *c) +{ + if (mp_add((mp_int *) a, (mp_int *) b, (mp_int *) c) != MP_OKAY) { + wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__); + return -1; + } + return 0; +} + + +/** + * bignum_sub - c = a - b + * @a: Bignum from bignum_init() + * @b: Bignum from bignum_init() + * @c: Bignum from bignum_init(); used to store the result of a - b + * Returns: 0 on success, -1 on failure + */ +int +bignum_sub(const struct bignum *a, const struct bignum *b, + struct bignum *c) +{ + if (mp_sub((mp_int *) a, (mp_int *) b, (mp_int *) c) != MP_OKAY) { + wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__); + return -1; + } + return 0; +} + + +/** + * bignum_mul - c = a * b + * @a: Bignum from bignum_init() + * @b: Bignum from bignum_init() + * @c: Bignum from bignum_init(); used to store the result of a * b + * Returns: 0 on success, -1 on failure + */ +int +bignum_mul(const struct bignum *a, const struct bignum *b, + struct bignum *c) +{ + if (mp_mul((mp_int *) a, (mp_int *) b, (mp_int *) c) != MP_OKAY) { + wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__); + return -1; + } + return 0; +} + + +/** + * bignum_mulmod - d = a * b (mod c) + * @a: Bignum from bignum_init() + * @b: Bignum from bignum_init() + * @c: Bignum from bignum_init(); modulus + * @d: Bignum from bignum_init(); used to store the result of a * b (mod c) + * Returns: 0 on success, -1 on failure + */ +int +bignum_mulmod(const struct bignum *a, const struct bignum *b, + const struct bignum *c, struct bignum *d) +{ + if (mp_mulmod((mp_int *) a, (mp_int *) b, (mp_int *) c, (mp_int *) d) + != MP_OKAY) { + wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__); + return -1; + } + return 0; +} + + +/** + * bignum_exptmod - Modular exponentiation: d = a^b (mod c) + * @a: Bignum from bignum_init(); base + * @b: Bignum from bignum_init(); exponent + * @c: Bignum from bignum_init(); modulus + * @d: Bignum from bignum_init(); used to store the result of a^b (mod c) + * Returns: 0 on success, -1 on failure + */ +int +bignum_exptmod(const struct bignum *a, const struct bignum *b, + const struct bignum *c, struct bignum *d) +{ + if (mp_exptmod((mp_int *) a, (mp_int *) b, (mp_int *) c, (mp_int *) d) + != MP_OKAY) { + wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__); + return -1; + } + return 0; +} diff --git a/components/wpa_supplicant/src/crypto/bignum.h b/components/wpa_supplicant/src/crypto/bignum.h new file mode 100644 index 0000000000..f25e26783a --- /dev/null +++ b/components/wpa_supplicant/src/crypto/bignum.h @@ -0,0 +1,38 @@ +/* + * Big number math + * Copyright (c) 2006, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef BIGNUM_H +#define BIGNUM_H + +struct bignum; + +struct bignum * bignum_init(void); +void bignum_deinit(struct bignum *n); +size_t bignum_get_unsigned_bin_len(struct bignum *n); +int bignum_get_unsigned_bin(const struct bignum *n, u8 *buf, size_t *len); +int bignum_set_unsigned_bin(struct bignum *n, const u8 *buf, size_t len); +int bignum_cmp(const struct bignum *a, const struct bignum *b); +int bignum_cmp_d(const struct bignum *a, unsigned long b); +int bignum_add(const struct bignum *a, const struct bignum *b, + struct bignum *c); +int bignum_sub(const struct bignum *a, const struct bignum *b, + struct bignum *c); +int bignum_mul(const struct bignum *a, const struct bignum *b, + struct bignum *c); +int bignum_mulmod(const struct bignum *a, const struct bignum *b, + const struct bignum *c, struct bignum *d); +int bignum_exptmod(const struct bignum *a, const struct bignum *b, + const struct bignum *c, struct bignum *d); + +#endif /* BIGNUM_H */ diff --git a/components/wpa_supplicant/src/crypto/crypto_internal-cipher.c b/components/wpa_supplicant/src/crypto/crypto_internal-cipher.c new file mode 100644 index 0000000000..7d89795797 --- /dev/null +++ b/components/wpa_supplicant/src/crypto/crypto_internal-cipher.c @@ -0,0 +1,268 @@ +/* + * Crypto wrapper for internal crypto implementation - Cipher wrappers + * Copyright (c) 2006-2009, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +//#include "wpa/includes.h" + +//#include "wpa/common.h" +#include "crypto/common.h" +#include "crypto/crypto.h" +#include "crypto/aes.h" +#if defined(CONFIG_DES) || defined(CONFIG_DES3) +#include "crypto/des_i.h" +#endif + +#ifdef MEMLEAK_DEBUG +static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; +#endif + + +struct crypto_cipher { + enum crypto_cipher_alg alg; + union { + struct { + size_t used_bytes; + u8 key[16]; + size_t keylen; + } rc4; + struct { + u8 cbc[32]; + void *ctx_enc; + void *ctx_dec; + } aes; +#ifdef CONFIG_DES3 + struct { + struct des3_key_s key; + u8 cbc[8]; + } des3; +#endif +#ifdef CONFIG_DES + struct { + u32 ek[32]; + u32 dk[32]; + u8 cbc[8]; + } des; +#endif + } u; +}; + + +struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg, + const u8 *iv, const u8 *key, + size_t key_len) +{ + struct crypto_cipher *ctx; + + ctx = (struct crypto_cipher *)os_zalloc(sizeof(*ctx)); + if (ctx == NULL) + return NULL; + + ctx->alg = alg; + + switch (alg) { + case CRYPTO_CIPHER_ALG_RC4: + if (key_len > sizeof(ctx->u.rc4.key)) { + os_free(ctx); + return NULL; + } + ctx->u.rc4.keylen = key_len; + os_memcpy(ctx->u.rc4.key, key, key_len); + break; + case CRYPTO_CIPHER_ALG_AES: + ctx->u.aes.ctx_enc = aes_encrypt_init(key, key_len); + if (ctx->u.aes.ctx_enc == NULL) { + os_free(ctx); + return NULL; + } + ctx->u.aes.ctx_dec = aes_decrypt_init(key, key_len); + if (ctx->u.aes.ctx_dec == NULL) { + aes_encrypt_deinit(ctx->u.aes.ctx_enc); + os_free(ctx); + return NULL; + } + os_memcpy(ctx->u.aes.cbc, iv, AES_BLOCK_SIZE); + break; +#ifdef CONFIG_DES3 + case CRYPTO_CIPHER_ALG_3DES: + if (key_len != 24) { + os_free(ctx); + return NULL; + } + des3_key_setup(key, &ctx->u.des3.key); + os_memcpy(ctx->u.des3.cbc, iv, 8); + break; +#endif +#ifdef CONFIG_DES + case CRYPTO_CIPHER_ALG_DES: + if (key_len != 8) { + os_free(ctx); + return NULL; + } + des_key_setup(key, ctx->u.des.ek, ctx->u.des.dk); + os_memcpy(ctx->u.des.cbc, iv, 8); + break; +#endif + default: + os_free(ctx); + return NULL; + } + + return ctx; +} + + +int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain, + u8 *crypt, size_t len) +{ + size_t i, j, blocks; + + switch (ctx->alg) { + case CRYPTO_CIPHER_ALG_RC4: + if (plain != crypt) + os_memcpy(crypt, plain, len); + rc4_skip(ctx->u.rc4.key, ctx->u.rc4.keylen, + ctx->u.rc4.used_bytes, crypt, len); + ctx->u.rc4.used_bytes += len; + break; + case CRYPTO_CIPHER_ALG_AES: + if (len % AES_BLOCK_SIZE) + return -1; + blocks = len / AES_BLOCK_SIZE; + for (i = 0; i < blocks; i++) { + for (j = 0; j < AES_BLOCK_SIZE; j++) + ctx->u.aes.cbc[j] ^= plain[j]; + aes_encrypt(ctx->u.aes.ctx_enc, ctx->u.aes.cbc, + ctx->u.aes.cbc); + os_memcpy(crypt, ctx->u.aes.cbc, AES_BLOCK_SIZE); + plain += AES_BLOCK_SIZE; + crypt += AES_BLOCK_SIZE; + } + break; +#ifdef CONFIG_DES3 + case CRYPTO_CIPHER_ALG_3DES: + if (len % 8) + return -1; + blocks = len / 8; + for (i = 0; i < blocks; i++) { + for (j = 0; j < 8; j++) + ctx->u.des3.cbc[j] ^= plain[j]; + des3_encrypt(ctx->u.des3.cbc, &ctx->u.des3.key, + ctx->u.des3.cbc); + os_memcpy(crypt, ctx->u.des3.cbc, 8); + plain += 8; + crypt += 8; + } + break; +#endif +#ifdef CONFIG_DES + case CRYPTO_CIPHER_ALG_DES: + if (len % 8) + return -1; + blocks = len / 8; + for (i = 0; i < blocks; i++) { + for (j = 0; j < 8; j++) + ctx->u.des3.cbc[j] ^= plain[j]; + des_block_encrypt(ctx->u.des.cbc, ctx->u.des.ek, + ctx->u.des.cbc); + os_memcpy(crypt, ctx->u.des.cbc, 8); + plain += 8; + crypt += 8; + } + break; +#endif + default: + return -1; + } + + return 0; +} + + +int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt, + u8 *plain, size_t len) +{ + size_t i, j, blocks; + u8 tmp[32]; + + switch (ctx->alg) { + case CRYPTO_CIPHER_ALG_RC4: + if (plain != crypt) + os_memcpy(plain, crypt, len); + rc4_skip(ctx->u.rc4.key, ctx->u.rc4.keylen, + ctx->u.rc4.used_bytes, plain, len); + ctx->u.rc4.used_bytes += len; + break; + case CRYPTO_CIPHER_ALG_AES: + if (len % AES_BLOCK_SIZE) + return -1; + blocks = len / AES_BLOCK_SIZE; + for (i = 0; i < blocks; i++) { + os_memcpy(tmp, crypt, AES_BLOCK_SIZE); + aes_decrypt(ctx->u.aes.ctx_dec, crypt, plain); + for (j = 0; j < AES_BLOCK_SIZE; j++) + plain[j] ^= ctx->u.aes.cbc[j]; + os_memcpy(ctx->u.aes.cbc, tmp, AES_BLOCK_SIZE); + plain += AES_BLOCK_SIZE; + crypt += AES_BLOCK_SIZE; + } + break; +#ifdef CONFIG_DES3 + case CRYPTO_CIPHER_ALG_3DES: + if (len % 8) + return -1; + blocks = len / 8; + for (i = 0; i < blocks; i++) { + os_memcpy(tmp, crypt, 8); + des3_decrypt(crypt, &ctx->u.des3.key, plain); + for (j = 0; j < 8; j++) + plain[j] ^= ctx->u.des3.cbc[j]; + os_memcpy(ctx->u.des3.cbc, tmp, 8); + plain += 8; + crypt += 8; + } + break; +#endif +#ifdef CONFIG_DES + case CRYPTO_CIPHER_ALG_DES: + if (len % 8) + return -1; + blocks = len / 8; + for (i = 0; i < blocks; i++) { + os_memcpy(tmp, crypt, 8); + des_block_decrypt(crypt, ctx->u.des.dk, plain); + for (j = 0; j < 8; j++) + plain[j] ^= ctx->u.des.cbc[j]; + os_memcpy(ctx->u.des.cbc, tmp, 8); + plain += 8; + crypt += 8; + } + break; +#endif + default: + return -1; + } + + return 0; +} + + +void crypto_cipher_deinit(struct crypto_cipher *ctx) +{ + switch (ctx->alg) { + case CRYPTO_CIPHER_ALG_AES: + aes_encrypt_deinit(ctx->u.aes.ctx_enc); + aes_decrypt_deinit(ctx->u.aes.ctx_dec); + break; +#ifdef CONFIG_DES3 + case CRYPTO_CIPHER_ALG_3DES: + break; +#endif + default: + break; + } + os_free(ctx); +} diff --git a/components/wpa_supplicant/src/crypto/crypto_internal-modexp.c b/components/wpa_supplicant/src/crypto/crypto_internal-modexp.c new file mode 100644 index 0000000000..ea97857005 --- /dev/null +++ b/components/wpa_supplicant/src/crypto/crypto_internal-modexp.c @@ -0,0 +1,56 @@ +/* + * Crypto wrapper for internal crypto implementation - modexp + * Copyright (c) 2006-2009, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "crypto/includes.h" + +#include "crypto/common.h" +#include "bignum.h" +#include "crypto/crypto.h" + + +int +crypto_mod_exp(const u8 *base, size_t base_len, + const u8 *power, size_t power_len, + const u8 *modulus, size_t modulus_len, + u8 *result, size_t *result_len) +{ + struct bignum *bn_base, *bn_exp, *bn_modulus, *bn_result; + int ret = -1; + + bn_base = bignum_init(); + bn_exp = bignum_init(); + bn_modulus = bignum_init(); + bn_result = bignum_init(); + + if (bn_base == NULL || bn_exp == NULL || bn_modulus == NULL || + bn_result == NULL) + goto error; + + if (bignum_set_unsigned_bin(bn_base, base, base_len) < 0 || + bignum_set_unsigned_bin(bn_exp, power, power_len) < 0 || + bignum_set_unsigned_bin(bn_modulus, modulus, modulus_len) < 0) + goto error; + + if (bignum_exptmod(bn_base, bn_exp, bn_modulus, bn_result) < 0) + goto error; + + ret = bignum_get_unsigned_bin(bn_result, result, result_len); + +error: + bignum_deinit(bn_base); + bignum_deinit(bn_exp); + bignum_deinit(bn_modulus); + bignum_deinit(bn_result); + return ret; +} diff --git a/components/wpa_supplicant/src/crypto/crypto_internal-rsa.c b/components/wpa_supplicant/src/crypto/crypto_internal-rsa.c new file mode 100644 index 0000000000..19934f063b --- /dev/null +++ b/components/wpa_supplicant/src/crypto/crypto_internal-rsa.c @@ -0,0 +1,111 @@ +/* + * Crypto wrapper for internal crypto implementation - RSA parts + * Copyright (c) 2006-2009, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "crypto/common.h" +#include "crypto/crypto.h" + +#include "wpa/includes.h" +#include "wpa/common.h" +#include "wpa/wpa_debug.h" + +#include "wpa2/tls/rsa.h" +#include "wpa2/tls/pkcs1.h" +#include "wpa2/tls/pkcs8.h" + +/* Dummy structures; these are just typecast to struct crypto_rsa_key */ +struct crypto_public_key; +struct crypto_private_key; + + +struct crypto_public_key * crypto_public_key_import(const u8 *key, size_t len) +{ + return (struct crypto_public_key *) + crypto_rsa_import_public_key(key, len); +} + + +struct crypto_private_key * crypto_private_key_import(const u8 *key, + size_t len, + const char *passwd) +{ + struct crypto_private_key *res; + + /* First, check for possible PKCS #8 encoding */ + res = pkcs8_key_import(key, len); + if (res) + return res; + + if (passwd) { + /* Try to parse as encrypted PKCS #8 */ + res = pkcs8_enc_key_import(key, len, passwd); + if (res) + return res; + } + + /* Not PKCS#8, so try to import PKCS #1 encoded RSA private key */ + wpa_printf(MSG_DEBUG, "Trying to parse PKCS #1 encoded RSA private " + "key"); + return (struct crypto_private_key *) + crypto_rsa_import_private_key(key, len); +} + + +struct crypto_public_key * crypto_public_key_from_cert(const u8 *buf, + size_t len) +{ + /* No X.509 support in crypto_internal.c */ + return NULL; +} + + +int crypto_public_key_encrypt_pkcs1_v15(struct crypto_public_key *key, + const u8 *in, size_t inlen, + u8 *out, size_t *outlen) +{ + return pkcs1_encrypt(2, (struct crypto_rsa_key *) key, + 0, in, inlen, out, outlen); +} + + +int crypto_private_key_decrypt_pkcs1_v15(struct crypto_private_key *key, + const u8 *in, size_t inlen, + u8 *out, size_t *outlen) +{ + return pkcs1_v15_private_key_decrypt((struct crypto_rsa_key *) key, + in, inlen, out, outlen); +} + + +int crypto_private_key_sign_pkcs1(struct crypto_private_key *key, + const u8 *in, size_t inlen, + u8 *out, size_t *outlen) +{ + return pkcs1_encrypt(1, (struct crypto_rsa_key *) key, + 1, in, inlen, out, outlen); +} + + +void crypto_public_key_free(struct crypto_public_key *key) +{ + crypto_rsa_free((struct crypto_rsa_key *) key); +} + + +void crypto_private_key_free(struct crypto_private_key *key) +{ + crypto_rsa_free((struct crypto_rsa_key *) key); +} + + +int crypto_public_key_decrypt_pkcs1(struct crypto_public_key *key, + const u8 *crypt, size_t crypt_len, + u8 *plain, size_t *plain_len) +{ + return pkcs1_decrypt_public_key((struct crypto_rsa_key *) key, + crypt, crypt_len, plain, plain_len); +} diff --git a/components/wpa_supplicant/src/crypto/crypto_internal.c b/components/wpa_supplicant/src/crypto/crypto_internal.c new file mode 100644 index 0000000000..d8d59dfb9d --- /dev/null +++ b/components/wpa_supplicant/src/crypto/crypto_internal.c @@ -0,0 +1,280 @@ +/* + * Crypto wrapper for internal crypto implementation + * Copyright (c) 2006-2011, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "crypto/includes.h" +#include "crypto/common.h" +//#include "wpa/common.h" +#include "crypto/crypto.h" +//#include "crypto/sha256_i.h" +#include "crypto/sha1_i.h" +#include "crypto/md5_i.h" + +#ifdef MEMLEAK_DEBUG +static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; +#endif + + +struct crypto_hash { + enum crypto_hash_alg alg; + union { + struct MD5Context md5; + struct SHA1Context sha1; +#ifdef CONFIG_SHA256 + struct sha256_state sha256; +#endif /* CONFIG_SHA256 */ + } u; + u8 key[64]; + size_t key_len; +}; + + +struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key, + size_t key_len) +{ + struct crypto_hash *ctx; + u8 k_pad[64]; + u8 tk[32]; + size_t i; + + ctx = (struct crypto_hash *)os_zalloc(sizeof(*ctx)); + if (ctx == NULL) + return NULL; + + ctx->alg = alg; + + switch (alg) { + case CRYPTO_HASH_ALG_MD5: + MD5Init(&ctx->u.md5); + break; + case CRYPTO_HASH_ALG_SHA1: + SHA1Init(&ctx->u.sha1); + break; +#ifdef CONFIG_SHA256 + case CRYPTO_HASH_ALG_SHA256: + sha256_init(&ctx->u.sha256); + break; +#endif /* CONFIG_SHA256 */ + case CRYPTO_HASH_ALG_HMAC_MD5: + if (key_len > sizeof(k_pad)) { + MD5Init(&ctx->u.md5); + MD5Update(&ctx->u.md5, key, key_len); + MD5Final(tk, &ctx->u.md5); + key = tk; + key_len = 16; + } + os_memcpy(ctx->key, key, key_len); + ctx->key_len = key_len; + + os_memcpy(k_pad, key, key_len); + if (key_len < sizeof(k_pad)) + os_memset(k_pad + key_len, 0, sizeof(k_pad) - key_len); + for (i = 0; i < sizeof(k_pad); i++) + k_pad[i] ^= 0x36; + MD5Init(&ctx->u.md5); + MD5Update(&ctx->u.md5, k_pad, sizeof(k_pad)); + break; + case CRYPTO_HASH_ALG_HMAC_SHA1: + if (key_len > sizeof(k_pad)) { + SHA1Init(&ctx->u.sha1); + SHA1Update(&ctx->u.sha1, key, key_len); + SHA1Final(tk, &ctx->u.sha1); + key = tk; + key_len = 20; + } + os_memcpy(ctx->key, key, key_len); + ctx->key_len = key_len; + + os_memcpy(k_pad, key, key_len); + if (key_len < sizeof(k_pad)) + os_memset(k_pad + key_len, 0, sizeof(k_pad) - key_len); + for (i = 0; i < sizeof(k_pad); i++) + k_pad[i] ^= 0x36; + SHA1Init(&ctx->u.sha1); + SHA1Update(&ctx->u.sha1, k_pad, sizeof(k_pad)); + break; +#ifdef CONFIG_SHA256 + case CRYPTO_HASH_ALG_HMAC_SHA256: + if (key_len > sizeof(k_pad)) { + sha256_init(&ctx->u.sha256); + sha256_process(&ctx->u.sha256, key, key_len); + sha256_done(&ctx->u.sha256, tk); + key = tk; + key_len = 32; + } + os_memcpy(ctx->key, key, key_len); + ctx->key_len = key_len; + + os_memcpy(k_pad, key, key_len); + if (key_len < sizeof(k_pad)) + os_memset(k_pad + key_len, 0, sizeof(k_pad) - key_len); + for (i = 0; i < sizeof(k_pad); i++) + k_pad[i] ^= 0x36; + sha256_init(&ctx->u.sha256); + sha256_process(&ctx->u.sha256, k_pad, sizeof(k_pad)); + break; +#endif /* CONFIG_SHA256 */ + default: + os_free(ctx); + return NULL; + } + + return ctx; +} + + +void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len) +{ + if (ctx == NULL) + return; + + switch (ctx->alg) { + case CRYPTO_HASH_ALG_MD5: + case CRYPTO_HASH_ALG_HMAC_MD5: + MD5Update(&ctx->u.md5, data, len); + break; + case CRYPTO_HASH_ALG_SHA1: + case CRYPTO_HASH_ALG_HMAC_SHA1: + SHA1Update(&ctx->u.sha1, data, len); + break; +#ifdef CONFIG_SHA256 + case CRYPTO_HASH_ALG_SHA256: + case CRYPTO_HASH_ALG_HMAC_SHA256: + sha256_process(&ctx->u.sha256, data, len); + break; +#endif /* CONFIG_SHA256 */ + default: + break; + } +} + + +int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len) +{ + u8 k_pad[64]; + size_t i; + + if (ctx == NULL) + return -2; + + if (mac == NULL || len == NULL) { + os_free(ctx); + return 0; + } + + switch (ctx->alg) { + case CRYPTO_HASH_ALG_MD5: + if (*len < 16) { + *len = 16; + os_free(ctx); + return -1; + } + *len = 16; + MD5Final(mac, &ctx->u.md5); + break; + case CRYPTO_HASH_ALG_SHA1: + if (*len < 20) { + *len = 20; + os_free(ctx); + return -1; + } + *len = 20; + SHA1Final(mac, &ctx->u.sha1); + break; +#ifdef CONFIG_SHA256 + case CRYPTO_HASH_ALG_SHA256: + if (*len < 32) { + *len = 32; + os_free(ctx); + return -1; + } + *len = 32; + sha256_done(&ctx->u.sha256, mac); + break; +#endif /* CONFIG_SHA256 */ + case CRYPTO_HASH_ALG_HMAC_MD5: + if (*len < 16) { + *len = 16; + os_free(ctx); + return -1; + } + *len = 16; + + MD5Final(mac, &ctx->u.md5); + + os_memcpy(k_pad, ctx->key, ctx->key_len); + os_memset(k_pad + ctx->key_len, 0, + sizeof(k_pad) - ctx->key_len); + for (i = 0; i < sizeof(k_pad); i++) + k_pad[i] ^= 0x5c; + MD5Init(&ctx->u.md5); + MD5Update(&ctx->u.md5, k_pad, sizeof(k_pad)); + MD5Update(&ctx->u.md5, mac, 16); + MD5Final(mac, &ctx->u.md5); + break; + case CRYPTO_HASH_ALG_HMAC_SHA1: + if (*len < 20) { + *len = 20; + os_free(ctx); + return -1; + } + *len = 20; + + SHA1Final(mac, &ctx->u.sha1); + + os_memcpy(k_pad, ctx->key, ctx->key_len); + os_memset(k_pad + ctx->key_len, 0, + sizeof(k_pad) - ctx->key_len); + for (i = 0; i < sizeof(k_pad); i++) + k_pad[i] ^= 0x5c; + SHA1Init(&ctx->u.sha1); + SHA1Update(&ctx->u.sha1, k_pad, sizeof(k_pad)); + SHA1Update(&ctx->u.sha1, mac, 20); + SHA1Final(mac, &ctx->u.sha1); + break; +#ifdef CONFIG_SHA256 + case CRYPTO_HASH_ALG_HMAC_SHA256: + if (*len < 32) { + *len = 32; + os_free(ctx); + return -1; + } + *len = 32; + + sha256_done(&ctx->u.sha256, mac); + + os_memcpy(k_pad, ctx->key, ctx->key_len); + os_memset(k_pad + ctx->key_len, 0, + sizeof(k_pad) - ctx->key_len); + for (i = 0; i < sizeof(k_pad); i++) + k_pad[i] ^= 0x5c; + sha256_init(&ctx->u.sha256); + sha256_process(&ctx->u.sha256, k_pad, sizeof(k_pad)); + sha256_process(&ctx->u.sha256, mac, 32); + sha256_done(&ctx->u.sha256, mac); + break; +#endif /* CONFIG_SHA256 */ + default: + os_free(ctx); + return -1; + } + + os_free(ctx); + + return 0; +} + + +int crypto_global_init(void) +{ + return 0; +} + + +void crypto_global_deinit(void) +{ +} diff --git a/components/wpa_supplicant/src/crypto/dh_group5.c b/components/wpa_supplicant/src/crypto/dh_group5.c new file mode 100644 index 0000000000..710f5c7d02 --- /dev/null +++ b/components/wpa_supplicant/src/crypto/dh_group5.c @@ -0,0 +1,43 @@ +/* + * Diffie-Hellman group 5 operations + * Copyright (c) 2009, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "crypto/includes.h" + +#include "crypto/common.h" +#include "crypto/dh_groups.h" +#include "crypto/dh_group5.h" + + +void * +dh5_init(struct wpabuf **priv, struct wpabuf **publ) +{ + *publ = dh_init(dh_groups_get(5), priv); + if (*publ == 0) + return NULL; + return (void *) 1; +} + + +struct wpabuf * +dh5_derive_shared(void *ctx, const struct wpabuf *peer_public, + const struct wpabuf *own_private) +{ + return dh_derive_shared(peer_public, own_private, dh_groups_get(5)); +} + + +void +dh5_free(void *ctx) +{ +} diff --git a/components/wpa_supplicant/src/crypto/dh_groups.c b/components/wpa_supplicant/src/crypto/dh_groups.c new file mode 100644 index 0000000000..6ec9a36a90 --- /dev/null +++ b/components/wpa_supplicant/src/crypto/dh_groups.c @@ -0,0 +1,641 @@ +/* + * Diffie-Hellman groups + * Copyright (c) 2007, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "crypto/includes.h" + +#include "crypto/common.h" +#include "crypto/crypto.h" +#include "crypto/random.h" +#include "crypto/dh_groups.h" +#include "wpa/wpabuf.h" +#include "wpa/wpa_debug.h" + +extern int crypto_mod_exp(const u8 *base, size_t base_len, + const u8 *power, size_t power_len, + const u8 *modulus, size_t modulus_len, + u8 *result, size_t *result_len); + +#ifdef ALL_DH_GROUPS + +/* RFC 4306, B.1. Group 1 - 768 Bit MODP + * Generator: 2 + * Prime: 2^768 - 2 ^704 - 1 + 2^64 * { [2^638 pi] + 149686 } + */ +static const u8 dh_group1_generator[1] = { 0x02 }; +static const u8 dh_group1_prime[96] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, + 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, + 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x3A, 0x36, 0x20, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +/* RFC 4306, B.2. Group 2 - 1024 Bit MODP + * Generator: 2 + * Prime: 2^1024 - 2^960 - 1 + 2^64 * { [2^894 pi] + 129093 } + */ +static const u8 dh_group2_generator[1] = { 0x02 }; +static const u8 dh_group2_prime[128] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, + 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, + 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, + 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, + 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +#endif /* ALL_DH_GROUPS */ + +/* RFC 3526, 2. Group 5 - 1536 Bit MODP + * Generator: 2 + * Prime: 2^1536 - 2^1472 - 1 + 2^64 * { [2^1406 pi] + 741804 } + */ +static const u8 dh_group5_generator[1] = { 0x02 }; +static const u8 dh_group5_prime[192] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, + 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, + 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, + 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, + 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, + 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, + 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, + 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, + 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, + 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, + 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, + 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x23, 0x73, 0x27, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +#ifdef ALL_DH_GROUPS + +/* RFC 3526, 3. Group 14 - 2048 Bit MODP + * Generator: 2 + * Prime: 2^2048 - 2^1984 - 1 + 2^64 * { [2^1918 pi] + 124476 } + */ +static const u8 dh_group14_generator[1] = { 0x02 }; +static const u8 dh_group14_prime[256] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, + 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, + 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, + 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, + 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, + 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, + 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, + 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, + 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, + 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, + 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, + 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, + 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, + 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, + 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, + 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, + 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, + 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, + 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, + 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +/* RFC 3526, 4. Group 15 - 3072 Bit MODP + * Generator: 2 + * Prime: 2^3072 - 2^3008 - 1 + 2^64 * { [2^2942 pi] + 1690314 } + */ +static const u8 dh_group15_generator[1] = { 0x02 }; +static const u8 dh_group15_prime[384] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, + 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, + 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, + 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, + 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, + 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, + 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, + 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, + 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, + 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, + 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, + 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, + 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, + 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, + 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, + 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, + 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, + 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, + 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, + 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, + 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, + 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, + 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, + 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, + 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, + 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, + 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, + 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, + 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, + 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, + 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, + 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, + 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, + 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, + 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, + 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x3A, 0xD2, 0xCA, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +/* RFC 3526, 5. Group 16 - 4096 Bit MODP + * Generator: 2 + * Prime: 2^4096 - 2^4032 - 1 + 2^64 * { [2^3966 pi] + 240904 } + */ +static const u8 dh_group16_generator[1] = { 0x02 }; +static const u8 dh_group16_prime[512] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, + 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, + 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, + 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, + 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, + 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, + 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, + 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, + 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, + 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, + 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, + 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, + 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, + 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, + 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, + 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, + 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, + 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, + 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, + 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, + 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, + 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, + 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, + 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, + 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, + 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, + 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, + 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, + 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, + 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, + 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, + 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, + 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, + 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, + 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, + 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01, + 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7, + 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, + 0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C, + 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA, + 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, + 0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9, + 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6, + 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, + 0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2, + 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED, + 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, + 0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C, + 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9, + 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, + 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F, + 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +/* RFC 3526, 6. Group 17 - 6144 Bit MODP + * Generator: 2 + * Prime: 2^6144 - 2^6080 - 1 + 2^64 * { [2^6014 pi] + 929484 } + */ +static const u8 dh_group17_generator[1] = { 0x02 }; +static const u8 dh_group17_prime[768] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, + 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, + 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, + 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, + 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, + 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, + 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, + 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, + 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, + 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, + 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, + 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, + 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, + 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, + 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, + 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, + 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, + 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, + 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, + 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, + 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, + 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, + 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, + 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, + 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, + 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, + 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, + 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, + 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, + 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, + 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, + 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, + 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, + 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, + 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, + 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01, + 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7, + 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, + 0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C, + 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA, + 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, + 0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9, + 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6, + 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, + 0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2, + 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED, + 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, + 0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C, + 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9, + 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, + 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F, + 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x02, 0x84, 0x92, + 0x36, 0xC3, 0xFA, 0xB4, 0xD2, 0x7C, 0x70, 0x26, + 0xC1, 0xD4, 0xDC, 0xB2, 0x60, 0x26, 0x46, 0xDE, + 0xC9, 0x75, 0x1E, 0x76, 0x3D, 0xBA, 0x37, 0xBD, + 0xF8, 0xFF, 0x94, 0x06, 0xAD, 0x9E, 0x53, 0x0E, + 0xE5, 0xDB, 0x38, 0x2F, 0x41, 0x30, 0x01, 0xAE, + 0xB0, 0x6A, 0x53, 0xED, 0x90, 0x27, 0xD8, 0x31, + 0x17, 0x97, 0x27, 0xB0, 0x86, 0x5A, 0x89, 0x18, + 0xDA, 0x3E, 0xDB, 0xEB, 0xCF, 0x9B, 0x14, 0xED, + 0x44, 0xCE, 0x6C, 0xBA, 0xCE, 0xD4, 0xBB, 0x1B, + 0xDB, 0x7F, 0x14, 0x47, 0xE6, 0xCC, 0x25, 0x4B, + 0x33, 0x20, 0x51, 0x51, 0x2B, 0xD7, 0xAF, 0x42, + 0x6F, 0xB8, 0xF4, 0x01, 0x37, 0x8C, 0xD2, 0xBF, + 0x59, 0x83, 0xCA, 0x01, 0xC6, 0x4B, 0x92, 0xEC, + 0xF0, 0x32, 0xEA, 0x15, 0xD1, 0x72, 0x1D, 0x03, + 0xF4, 0x82, 0xD7, 0xCE, 0x6E, 0x74, 0xFE, 0xF6, + 0xD5, 0x5E, 0x70, 0x2F, 0x46, 0x98, 0x0C, 0x82, + 0xB5, 0xA8, 0x40, 0x31, 0x90, 0x0B, 0x1C, 0x9E, + 0x59, 0xE7, 0xC9, 0x7F, 0xBE, 0xC7, 0xE8, 0xF3, + 0x23, 0xA9, 0x7A, 0x7E, 0x36, 0xCC, 0x88, 0xBE, + 0x0F, 0x1D, 0x45, 0xB7, 0xFF, 0x58, 0x5A, 0xC5, + 0x4B, 0xD4, 0x07, 0xB2, 0x2B, 0x41, 0x54, 0xAA, + 0xCC, 0x8F, 0x6D, 0x7E, 0xBF, 0x48, 0xE1, 0xD8, + 0x14, 0xCC, 0x5E, 0xD2, 0x0F, 0x80, 0x37, 0xE0, + 0xA7, 0x97, 0x15, 0xEE, 0xF2, 0x9B, 0xE3, 0x28, + 0x06, 0xA1, 0xD5, 0x8B, 0xB7, 0xC5, 0xDA, 0x76, + 0xF5, 0x50, 0xAA, 0x3D, 0x8A, 0x1F, 0xBF, 0xF0, + 0xEB, 0x19, 0xCC, 0xB1, 0xA3, 0x13, 0xD5, 0x5C, + 0xDA, 0x56, 0xC9, 0xEC, 0x2E, 0xF2, 0x96, 0x32, + 0x38, 0x7F, 0xE8, 0xD7, 0x6E, 0x3C, 0x04, 0x68, + 0x04, 0x3E, 0x8F, 0x66, 0x3F, 0x48, 0x60, 0xEE, + 0x12, 0xBF, 0x2D, 0x5B, 0x0B, 0x74, 0x74, 0xD6, + 0xE6, 0x94, 0xF9, 0x1E, 0x6D, 0xCC, 0x40, 0x24, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +/* RFC 3526, 7. Group 18 - 8192 Bit MODP + * Generator: 2 + * Prime: 2^8192 - 2^8128 - 1 + 2^64 * { [2^8062 pi] + 4743158 } + */ +static const u8 dh_group18_generator[1] = { 0x02 }; +static const u8 dh_group18_prime[1024] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, + 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, + 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, + 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, + 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, + 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, + 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, + 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, + 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, + 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, + 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, + 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, + 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, + 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, + 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, + 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, + 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, + 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, + 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, + 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, + 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, + 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, + 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, + 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, + 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, + 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, + 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, + 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, + 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, + 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, + 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, + 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, + 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, + 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, + 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, + 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01, + 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7, + 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, + 0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C, + 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA, + 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, + 0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9, + 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6, + 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, + 0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2, + 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED, + 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, + 0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C, + 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9, + 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, + 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F, + 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x02, 0x84, 0x92, + 0x36, 0xC3, 0xFA, 0xB4, 0xD2, 0x7C, 0x70, 0x26, + 0xC1, 0xD4, 0xDC, 0xB2, 0x60, 0x26, 0x46, 0xDE, + 0xC9, 0x75, 0x1E, 0x76, 0x3D, 0xBA, 0x37, 0xBD, + 0xF8, 0xFF, 0x94, 0x06, 0xAD, 0x9E, 0x53, 0x0E, + 0xE5, 0xDB, 0x38, 0x2F, 0x41, 0x30, 0x01, 0xAE, + 0xB0, 0x6A, 0x53, 0xED, 0x90, 0x27, 0xD8, 0x31, + 0x17, 0x97, 0x27, 0xB0, 0x86, 0x5A, 0x89, 0x18, + 0xDA, 0x3E, 0xDB, 0xEB, 0xCF, 0x9B, 0x14, 0xED, + 0x44, 0xCE, 0x6C, 0xBA, 0xCE, 0xD4, 0xBB, 0x1B, + 0xDB, 0x7F, 0x14, 0x47, 0xE6, 0xCC, 0x25, 0x4B, + 0x33, 0x20, 0x51, 0x51, 0x2B, 0xD7, 0xAF, 0x42, + 0x6F, 0xB8, 0xF4, 0x01, 0x37, 0x8C, 0xD2, 0xBF, + 0x59, 0x83, 0xCA, 0x01, 0xC6, 0x4B, 0x92, 0xEC, + 0xF0, 0x32, 0xEA, 0x15, 0xD1, 0x72, 0x1D, 0x03, + 0xF4, 0x82, 0xD7, 0xCE, 0x6E, 0x74, 0xFE, 0xF6, + 0xD5, 0x5E, 0x70, 0x2F, 0x46, 0x98, 0x0C, 0x82, + 0xB5, 0xA8, 0x40, 0x31, 0x90, 0x0B, 0x1C, 0x9E, + 0x59, 0xE7, 0xC9, 0x7F, 0xBE, 0xC7, 0xE8, 0xF3, + 0x23, 0xA9, 0x7A, 0x7E, 0x36, 0xCC, 0x88, 0xBE, + 0x0F, 0x1D, 0x45, 0xB7, 0xFF, 0x58, 0x5A, 0xC5, + 0x4B, 0xD4, 0x07, 0xB2, 0x2B, 0x41, 0x54, 0xAA, + 0xCC, 0x8F, 0x6D, 0x7E, 0xBF, 0x48, 0xE1, 0xD8, + 0x14, 0xCC, 0x5E, 0xD2, 0x0F, 0x80, 0x37, 0xE0, + 0xA7, 0x97, 0x15, 0xEE, 0xF2, 0x9B, 0xE3, 0x28, + 0x06, 0xA1, 0xD5, 0x8B, 0xB7, 0xC5, 0xDA, 0x76, + 0xF5, 0x50, 0xAA, 0x3D, 0x8A, 0x1F, 0xBF, 0xF0, + 0xEB, 0x19, 0xCC, 0xB1, 0xA3, 0x13, 0xD5, 0x5C, + 0xDA, 0x56, 0xC9, 0xEC, 0x2E, 0xF2, 0x96, 0x32, + 0x38, 0x7F, 0xE8, 0xD7, 0x6E, 0x3C, 0x04, 0x68, + 0x04, 0x3E, 0x8F, 0x66, 0x3F, 0x48, 0x60, 0xEE, + 0x12, 0xBF, 0x2D, 0x5B, 0x0B, 0x74, 0x74, 0xD6, + 0xE6, 0x94, 0xF9, 0x1E, 0x6D, 0xBE, 0x11, 0x59, + 0x74, 0xA3, 0x92, 0x6F, 0x12, 0xFE, 0xE5, 0xE4, + 0x38, 0x77, 0x7C, 0xB6, 0xA9, 0x32, 0xDF, 0x8C, + 0xD8, 0xBE, 0xC4, 0xD0, 0x73, 0xB9, 0x31, 0xBA, + 0x3B, 0xC8, 0x32, 0xB6, 0x8D, 0x9D, 0xD3, 0x00, + 0x74, 0x1F, 0xA7, 0xBF, 0x8A, 0xFC, 0x47, 0xED, + 0x25, 0x76, 0xF6, 0x93, 0x6B, 0xA4, 0x24, 0x66, + 0x3A, 0xAB, 0x63, 0x9C, 0x5A, 0xE4, 0xF5, 0x68, + 0x34, 0x23, 0xB4, 0x74, 0x2B, 0xF1, 0xC9, 0x78, + 0x23, 0x8F, 0x16, 0xCB, 0xE3, 0x9D, 0x65, 0x2D, + 0xE3, 0xFD, 0xB8, 0xBE, 0xFC, 0x84, 0x8A, 0xD9, + 0x22, 0x22, 0x2E, 0x04, 0xA4, 0x03, 0x7C, 0x07, + 0x13, 0xEB, 0x57, 0xA8, 0x1A, 0x23, 0xF0, 0xC7, + 0x34, 0x73, 0xFC, 0x64, 0x6C, 0xEA, 0x30, 0x6B, + 0x4B, 0xCB, 0xC8, 0x86, 0x2F, 0x83, 0x85, 0xDD, + 0xFA, 0x9D, 0x4B, 0x7F, 0xA2, 0xC0, 0x87, 0xE8, + 0x79, 0x68, 0x33, 0x03, 0xED, 0x5B, 0xDD, 0x3A, + 0x06, 0x2B, 0x3C, 0xF5, 0xB3, 0xA2, 0x78, 0xA6, + 0x6D, 0x2A, 0x13, 0xF8, 0x3F, 0x44, 0xF8, 0x2D, + 0xDF, 0x31, 0x0E, 0xE0, 0x74, 0xAB, 0x6A, 0x36, + 0x45, 0x97, 0xE8, 0x99, 0xA0, 0x25, 0x5D, 0xC1, + 0x64, 0xF3, 0x1C, 0xC5, 0x08, 0x46, 0x85, 0x1D, + 0xF9, 0xAB, 0x48, 0x19, 0x5D, 0xED, 0x7E, 0xA1, + 0xB1, 0xD5, 0x10, 0xBD, 0x7E, 0xE7, 0x4D, 0x73, + 0xFA, 0xF3, 0x6B, 0xC3, 0x1E, 0xCF, 0xA2, 0x68, + 0x35, 0x90, 0x46, 0xF4, 0xEB, 0x87, 0x9F, 0x92, + 0x40, 0x09, 0x43, 0x8B, 0x48, 0x1C, 0x6C, 0xD7, + 0x88, 0x9A, 0x00, 0x2E, 0xD5, 0xEE, 0x38, 0x2B, + 0xC9, 0x19, 0x0D, 0xA6, 0xFC, 0x02, 0x6E, 0x47, + 0x95, 0x58, 0xE4, 0x47, 0x56, 0x77, 0xE9, 0xAA, + 0x9E, 0x30, 0x50, 0xE2, 0x76, 0x56, 0x94, 0xDF, + 0xC8, 0x1F, 0x56, 0xE8, 0x80, 0xB9, 0x6E, 0x71, + 0x60, 0xC9, 0x80, 0xDD, 0x98, 0xED, 0xD3, 0xDF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +#endif /* ALL_DH_GROUPS */ + + +#define DH_GROUP(id) \ +{ id, dh_group ## id ## _generator, sizeof(dh_group ## id ## _generator), \ +dh_group ## id ## _prime, sizeof(dh_group ## id ## _prime) } + + +static struct dh_group dh_groups[] = { + DH_GROUP(5), +#ifdef ALL_DH_GROUPS + DH_GROUP(1), + DH_GROUP(2), + DH_GROUP(14), + DH_GROUP(15), + DH_GROUP(16), + DH_GROUP(17), + DH_GROUP(18) +#endif /* ALL_DH_GROUPS */ +}; + +#define NUM_DH_GROUPS (sizeof(dh_groups) / sizeof(dh_groups[0])) + + +const struct dh_group * +dh_groups_get(int id) +{ + size_t i; + + for (i = 0; i < NUM_DH_GROUPS; i++) { + if (dh_groups[i].id == id) + return &dh_groups[i]; + } + return NULL; +} + +/** + * dh_init - Initialize Diffie-Hellman handshake + * @dh: Selected Diffie-Hellman group + * @priv: Pointer for returning Diffie-Hellman private key + * Returns: Diffie-Hellman public value + */ +struct wpabuf * +dh_init(const struct dh_group *dh, struct wpabuf **priv) +{ + struct wpabuf *pv; + size_t pv_len; + + if (dh == NULL) + return NULL; + + wpabuf_free(*priv); + *priv = wpabuf_alloc(dh->prime_len); + if (*priv == NULL) + return NULL; + + if (random_get_bytes(wpabuf_put(*priv, dh->prime_len), dh->prime_len)) + { + wpabuf_free(*priv); + *priv = NULL; + return NULL; + } + + if (os_memcmp(wpabuf_head(*priv), dh->prime, dh->prime_len) > 0) { + /* Make sure private value is smaller than prime */ + *(wpabuf_mhead_u8(*priv)) = 0; + } + wpa_hexdump_buf_key(MSG_DEBUG, "DH: private value", *priv); + + pv_len = dh->prime_len; + pv = wpabuf_alloc(pv_len); + if (pv == NULL) + return NULL; + if (crypto_mod_exp(dh->generator, dh->generator_len, + wpabuf_head(*priv), wpabuf_len(*priv), + dh->prime, dh->prime_len, wpabuf_mhead(pv), + &pv_len) < 0) { + wpabuf_free(pv); + wpa_printf(MSG_INFO, "DH: crypto_mod_exp failed"); + return NULL; + } + wpabuf_put(pv, pv_len); + wpa_hexdump_buf(MSG_DEBUG, "DH: public value", pv); + + return pv; +} + + +/** + * dh_derive_shared - Derive shared Diffie-Hellman key + * @peer_public: Diffie-Hellman public value from peer + * @own_private: Diffie-Hellman private key from dh_init() + * @dh: Selected Diffie-Hellman group + * Returns: Diffie-Hellman shared key + */ +struct wpabuf * +dh_derive_shared(const struct wpabuf *peer_public, + const struct wpabuf *own_private, + const struct dh_group *dh) +{ + struct wpabuf *shared; + size_t shared_len; + + if (dh == NULL || peer_public == NULL || own_private == NULL) + return NULL; + + shared_len = dh->prime_len; + shared = wpabuf_alloc(shared_len); + if (shared == NULL) + return NULL; + if (crypto_mod_exp(wpabuf_head(peer_public), wpabuf_len(peer_public), + wpabuf_head(own_private), wpabuf_len(own_private), + dh->prime, dh->prime_len, + wpabuf_mhead(shared), &shared_len) < 0) { + wpabuf_free(shared); + wpa_printf(MSG_INFO, "DH: crypto_mod_exp failed"); + return NULL; + } + wpabuf_put(shared, shared_len); + wpa_hexdump_buf_key(MSG_DEBUG, "DH: shared key", shared); + + return shared; +} diff --git a/components/wpa_supplicant/src/crypto/libtommath.h b/components/wpa_supplicant/src/crypto/libtommath.h new file mode 100644 index 0000000000..31f9706593 --- /dev/null +++ b/components/wpa_supplicant/src/crypto/libtommath.h @@ -0,0 +1,3440 @@ +/* + * Minimal code for RSA support from LibTomMath 0.41 + * http://libtom.org/ + * http://libtom.org/files/ltm-0.41.tar.bz2 + * This library was released in public domain by Tom St Denis. + * + * The combination in this file may not use all of the optimized algorithms + * from LibTomMath and may be considerable slower than the LibTomMath with its + * default settings. The main purpose of having this version here is to make it + * easier to build bignum.c wrapper without having to install and build an + * external library. + * + * If CONFIG_INTERNAL_LIBTOMMATH is defined, bignum.c includes this + * libtommath.c file instead of using the external LibTomMath library. + */ +//#include "c_types.h" +#include "os.h" +#include "stdarg.h" + + +#ifndef CHAR_BIT +#define CHAR_BIT 8 +#endif + +#define BN_MP_INVMOD_C +#define BN_S_MP_EXPTMOD_C /* Note: #undef in tommath_superclass.h; this would + * require BN_MP_EXPTMOD_FAST_C instead */ +#define BN_S_MP_MUL_DIGS_C +#define BN_MP_INVMOD_SLOW_C +#define BN_S_MP_SQR_C +#define BN_S_MP_MUL_HIGH_DIGS_C /* Note: #undef in tommath_superclass.h; this + * would require other than mp_reduce */ + +#ifdef LTM_FAST + +/* Use faster div at the cost of about 1 kB */ +#define BN_MP_MUL_D_C + +/* Include faster exptmod (Montgomery) at the cost of about 2.5 kB in code */ +#define BN_MP_EXPTMOD_FAST_C +#define BN_MP_MONTGOMERY_SETUP_C +#define BN_FAST_MP_MONTGOMERY_REDUCE_C +#define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C +#define BN_MP_MUL_2_C + +/* Include faster sqr at the cost of about 0.5 kB in code */ +#define BN_FAST_S_MP_SQR_C + +#else /* LTM_FAST */ + +#define BN_MP_DIV_SMALL +#define BN_MP_INIT_MULTI_C +#define BN_MP_CLEAR_MULTI_C +#define BN_MP_ABS_C +#endif /* LTM_FAST */ + +/* Current uses do not require support for negative exponent in exptmod, so we + * can save about 1.5 kB in leaving out invmod. */ +#define LTM_NO_NEG_EXP + +/* from tommath.h */ + +#ifndef MIN + #define MIN(x,y) ((x)<(y)?(x):(y)) +#endif + +#ifndef MAX + #define MAX(x,y) ((x)>(y)?(x):(y)) +#endif + +#define OPT_CAST(x) (x *) + +typedef unsigned long mp_digit; +typedef u64 mp_word; + +#define DIGIT_BIT 28 +#define MP_28BIT + + +#define XMALLOC os_malloc +#define XFREE os_free +#define XREALLOC os_realloc + + +#define MP_MASK ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1)) + +#define MP_LT -1 /* less than */ +#define MP_EQ 0 /* equal to */ +#define MP_GT 1 /* greater than */ + +#define MP_ZPOS 0 /* positive integer */ +#define MP_NEG 1 /* negative */ + +#define MP_OKAY 0 /* ok result */ +#define MP_MEM -2 /* out of mem */ +#define MP_VAL -3 /* invalid input */ + +#define MP_YES 1 /* yes response */ +#define MP_NO 0 /* no response */ + +typedef int mp_err; + +/* define this to use lower memory usage routines (exptmods mostly) */ +#define MP_LOW_MEM + +/* default precision */ +#ifndef MP_PREC + #ifndef MP_LOW_MEM + #define MP_PREC 32 /* default digits of precision */ + #else + #define MP_PREC 8 /* default digits of precision */ + #endif +#endif + +/* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - BITS_PER_DIGIT*2) */ +#define MP_WARRAY (1 << (sizeof(mp_word) * CHAR_BIT - 2 * DIGIT_BIT + 1)) + +/* the infamous mp_int structure */ +typedef struct { + int used, alloc, sign; + mp_digit *dp; +} mp_int; + + +/* ---> Basic Manipulations <--- */ +#define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO) +#define mp_iseven(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 0)) ? MP_YES : MP_NO) +#define mp_isodd(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? MP_YES : MP_NO) + + +/* prototypes for copied functions */ +#define s_mp_mul(a, b, c) s_mp_mul_digs(a, b, c, (a)->used + (b)->used + 1) +static int s_mp_exptmod(mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode); +static int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs); +static int s_mp_sqr(mp_int * a, mp_int * b); +static int s_mp_mul_high_digs(mp_int * a, mp_int * b, mp_int * c, int digs); + +static int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs); + +#ifdef BN_MP_INIT_MULTI_C +static int mp_init_multi(mp_int *mp, ...); +#endif +#ifdef BN_MP_CLEAR_MULTI_C +static void mp_clear_multi(mp_int *mp, ...); +#endif +static int mp_lshd(mp_int * a, int b); +static void mp_set(mp_int * a, mp_digit b); +static void mp_clamp(mp_int * a); +static void mp_exch(mp_int * a, mp_int * b); +static void mp_rshd(mp_int * a, int b); +static void mp_zero(mp_int * a); +static int mp_mod_2d(mp_int * a, int b, mp_int * c); +static int mp_div_2d(mp_int * a, int b, mp_int * c, mp_int * d); +static int mp_init_copy(mp_int * a, mp_int * b); +static int mp_mul_2d(mp_int * a, int b, mp_int * c); +#ifndef LTM_NO_NEG_EXP +static int mp_div_2(mp_int * a, mp_int * b); +static int mp_invmod(mp_int * a, mp_int * b, mp_int * c); +static int mp_invmod_slow(mp_int * a, mp_int * b, mp_int * c); +#endif /* LTM_NO_NEG_EXP */ +static int mp_copy(mp_int * a, mp_int * b); +static int mp_count_bits(mp_int * a); +static int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d); +static int mp_mod(mp_int * a, mp_int * b, mp_int * c); +static int mp_grow(mp_int * a, int size); +static int mp_cmp_mag(mp_int * a, mp_int * b); +#ifdef BN_MP_ABS_C +static int mp_abs(mp_int * a, mp_int * b); +#endif +static int mp_sqr(mp_int * a, mp_int * b); +static int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d); +static int mp_reduce_2k_setup_l(mp_int *a, mp_int *d); +static int mp_2expt(mp_int * a, int b); +static int mp_reduce_setup(mp_int * a, mp_int * b); +static int mp_reduce(mp_int * x, mp_int * m, mp_int * mu); +static int mp_init_size(mp_int * a, int size); +#ifdef BN_MP_EXPTMOD_FAST_C +static int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode); +#endif /* BN_MP_EXPTMOD_FAST_C */ +#ifdef BN_FAST_S_MP_SQR_C +static int fast_s_mp_sqr (mp_int * a, mp_int * b); +#endif /* BN_FAST_S_MP_SQR_C */ +#ifdef BN_MP_MUL_D_C +static int mp_mul_d (mp_int * a, mp_digit b, mp_int * c); +#endif /* BN_MP_MUL_D_C */ + + + +/* functions from bn_.c */ + + +/* reverse an array, used for radix code */ +static void +bn_reverse (unsigned char *s, int len) +{ + int ix, iy; + unsigned char t; + + ix = 0; + iy = len - 1; + while (ix < iy) { + t = s[ix]; + s[ix] = s[iy]; + s[iy] = t; + ++ix; + --iy; + } +} + + +/* low level addition, based on HAC pp.594, Algorithm 14.7 */ +static int +s_mp_add (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int *x; + int olduse, res, min, max; + + /* find sizes, we let |a| <= |b| which means we have to sort + * them. "x" will point to the input with the most digits + */ + if (a->used > b->used) { + min = b->used; + max = a->used; + x = a; + } else { + min = a->used; + max = b->used; + x = b; + } + + /* init result */ + if (c->alloc < max + 1) { + if ((res = mp_grow (c, max + 1)) != MP_OKAY) { + return res; + } + } + + /* get old used digit count and set new one */ + olduse = c->used; + c->used = max + 1; + + { + register mp_digit u, *tmpa, *tmpb, *tmpc; + register int i; + + /* alias for digit pointers */ + + /* first input */ + tmpa = a->dp; + + /* second input */ + tmpb = b->dp; + + /* destination */ + tmpc = c->dp; + + /* zero the carry */ + u = 0; + for (i = 0; i < min; i++) { + /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */ + *tmpc = *tmpa++ + *tmpb++ + u; + + /* U = carry bit of T[i] */ + u = *tmpc >> ((mp_digit)DIGIT_BIT); + + /* take away carry bit from T[i] */ + *tmpc++ &= MP_MASK; + } + + /* now copy higher words if any, that is in A+B + * if A or B has more digits add those in + */ + if (min != max) { + for (; i < max; i++) { + /* T[i] = X[i] + U */ + *tmpc = x->dp[i] + u; + + /* U = carry bit of T[i] */ + u = *tmpc >> ((mp_digit)DIGIT_BIT); + + /* take away carry bit from T[i] */ + *tmpc++ &= MP_MASK; + } + } + + /* add carry */ + *tmpc++ = u; + + /* clear digits above oldused */ + for (i = c->used; i < olduse; i++) { + *tmpc++ = 0; + } + } + + mp_clamp (c); + return MP_OKAY; +} + + +/* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */ +static int +s_mp_sub (mp_int * a, mp_int * b, mp_int * c) +{ + int olduse, res, min, max; + + /* find sizes */ + min = b->used; + max = a->used; + + /* init result */ + if (c->alloc < max) { + if ((res = mp_grow (c, max)) != MP_OKAY) { + return res; + } + } + olduse = c->used; + c->used = max; + + { + register mp_digit u, *tmpa, *tmpb, *tmpc; + register int i; + + /* alias for digit pointers */ + tmpa = a->dp; + tmpb = b->dp; + tmpc = c->dp; + + /* set carry to zero */ + u = 0; + for (i = 0; i < min; i++) { + /* T[i] = A[i] - B[i] - U */ + *tmpc = *tmpa++ - *tmpb++ - u; + + /* U = carry bit of T[i] + * Note this saves performing an AND operation since + * if a carry does occur it will propagate all the way to the + * MSB. As a result a single shift is enough to get the carry + */ + u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1)); + + /* Clear carry from T[i] */ + *tmpc++ &= MP_MASK; + } + + /* now copy higher words if any, e.g. if A has more digits than B */ + for (; i < max; i++) { + /* T[i] = A[i] - U */ + *tmpc = *tmpa++ - u; + + /* U = carry bit of T[i] */ + u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1)); + + /* Clear carry from T[i] */ + *tmpc++ &= MP_MASK; + } + + /* clear digits above used (since we may not have grown result above) */ + for (i = c->used; i < olduse; i++) { + *tmpc++ = 0; + } + } + + mp_clamp (c); + return MP_OKAY; +} + + +/* init a new mp_int */ +static int +mp_init (mp_int * a) +{ + int i; + + /* allocate memory required and clear it */ + a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * MP_PREC); + if (a->dp == NULL) { + return MP_MEM; + } + + /* set the digits to zero */ + for (i = 0; i < MP_PREC; i++) { + a->dp[i] = 0; + } + + /* set the used to zero, allocated digits to the default precision + * and sign to positive */ + a->used = 0; + a->alloc = MP_PREC; + a->sign = MP_ZPOS; + + return MP_OKAY; +} + + +/* clear one (frees) */ +static void +mp_clear (mp_int * a) +{ + int i; + + /* only do anything if a hasn't been freed previously */ + if (a->dp != NULL) { + /* first zero the digits */ + for (i = 0; i < a->used; i++) { + a->dp[i] = 0; + } + + /* free ram */ + XFREE(a->dp); + + /* reset members to make debugging easier */ + a->dp = NULL; + a->alloc = a->used = 0; + a->sign = MP_ZPOS; + } +} + + +/* high level addition (handles signs) */ +static int +mp_add (mp_int * a, mp_int * b, mp_int * c) +{ + int sa, sb, res; + + /* get sign of both inputs */ + sa = a->sign; + sb = b->sign; + + /* handle two cases, not four */ + if (sa == sb) { + /* both positive or both negative */ + /* add their magnitudes, copy the sign */ + c->sign = sa; + res = s_mp_add (a, b, c); + } else { + /* one positive, the other negative */ + /* subtract the one with the greater magnitude from */ + /* the one of the lesser magnitude. The result gets */ + /* the sign of the one with the greater magnitude. */ + if (mp_cmp_mag (a, b) == MP_LT) { + c->sign = sb; + res = s_mp_sub (b, a, c); + } else { + c->sign = sa; + res = s_mp_sub (a, b, c); + } + } + return res; +} + + +/* high level subtraction (handles signs) */ +static int +mp_sub (mp_int * a, mp_int * b, mp_int * c) +{ + int sa, sb, res; + + sa = a->sign; + sb = b->sign; + + if (sa != sb) { + /* subtract a negative from a positive, OR */ + /* subtract a positive from a negative. */ + /* In either case, ADD their magnitudes, */ + /* and use the sign of the first number. */ + c->sign = sa; + res = s_mp_add (a, b, c); + } else { + /* subtract a positive from a positive, OR */ + /* subtract a negative from a negative. */ + /* First, take the difference between their */ + /* magnitudes, then... */ + if (mp_cmp_mag (a, b) != MP_LT) { + /* Copy the sign from the first */ + c->sign = sa; + /* The first has a larger or equal magnitude */ + res = s_mp_sub (a, b, c); + } else { + /* The result has the *opposite* sign from */ + /* the first number. */ + c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS; + /* The second has a larger magnitude */ + res = s_mp_sub (b, a, c); + } + } + return res; +} + + +/* high level multiplication (handles sign) */ +static int +mp_mul (mp_int * a, mp_int * b, mp_int * c) +{ + int res, neg; + neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; + + /* use Toom-Cook? */ +#ifdef BN_MP_TOOM_MUL_C + if (MIN (a->used, b->used) >= TOOM_MUL_CUTOFF) { + res = mp_toom_mul(a, b, c); + } else +#endif +#ifdef BN_MP_KARATSUBA_MUL_C + /* use Karatsuba? */ + if (MIN (a->used, b->used) >= KARATSUBA_MUL_CUTOFF) { + res = mp_karatsuba_mul (a, b, c); + } else +#endif + { + /* can we use the fast multiplier? + * + * The fast multiplier can be used if the output will + * have less than MP_WARRAY digits and the number of + * digits won't affect carry propagation + */ +#ifdef BN_FAST_S_MP_MUL_DIGS_C + int digs = a->used + b->used + 1; + + if ((digs < MP_WARRAY) && + MIN(a->used, b->used) <= + (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { + res = fast_s_mp_mul_digs (a, b, c, digs); + } else +#endif +#ifdef BN_S_MP_MUL_DIGS_C + res = s_mp_mul (a, b, c); /* uses s_mp_mul_digs */ +#else +#error mp_mul could fail + res = MP_VAL; +#endif + + } + c->sign = (c->used > 0) ? neg : MP_ZPOS; + return res; +} + + +/* d = a * b (mod c) */ +static int +mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) +{ + int res; + mp_int t; + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + if ((res = mp_mul (a, b, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + res = mp_mod (&t, c, d); + mp_clear (&t); + return res; +} + + +/* c = a mod b, 0 <= c < b */ +static int +mp_mod (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int t; + int res; + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + if ((res = mp_div (a, b, NULL, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + + if (t.sign != b->sign) { + res = mp_add (b, &t, c); + } else { + res = MP_OKAY; + mp_exch (&t, c); + } + + mp_clear (&t); + return res; +} + + +/* this is a shell function that calls either the normal or Montgomery + * exptmod functions. Originally the call to the montgomery code was + * embedded in the normal function but that wasted a lot of stack space + * for nothing (since 99% of the time the Montgomery code would be called) + */ +static int +mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) +{ + int dr; + + /* modulus P must be positive */ + if (P->sign == MP_NEG) { + return MP_VAL; + } + + /* if exponent X is negative we have to recurse */ + if (X->sign == MP_NEG) { +#ifdef LTM_NO_NEG_EXP + return MP_VAL; +#else /* LTM_NO_NEG_EXP */ +#ifdef BN_MP_INVMOD_C + mp_int tmpG, tmpX; + int err; + + /* first compute 1/G mod P */ + if ((err = mp_init(&tmpG)) != MP_OKAY) { + return err; + } + if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) { + mp_clear(&tmpG); + return err; + } + + /* now get |X| */ + if ((err = mp_init(&tmpX)) != MP_OKAY) { + mp_clear(&tmpG); + return err; + } + if ((err = mp_abs(X, &tmpX)) != MP_OKAY) { + mp_clear_multi(&tmpG, &tmpX, NULL); + return err; + } + + /* and now compute (1/G)**|X| instead of G**X [X < 0] */ + err = mp_exptmod(&tmpG, &tmpX, P, Y); + mp_clear_multi(&tmpG, &tmpX, NULL); + return err; +#else +#error mp_exptmod would always fail + /* no invmod */ + return MP_VAL; +#endif +#endif /* LTM_NO_NEG_EXP */ + } + +/* modified diminished radix reduction */ +#if defined(BN_MP_REDUCE_IS_2K_L_C) && defined(BN_MP_REDUCE_2K_L_C) && defined(BN_S_MP_EXPTMOD_C) + if (mp_reduce_is_2k_l(P) == MP_YES) { + return s_mp_exptmod(G, X, P, Y, 1); + } +#endif + +#ifdef BN_MP_DR_IS_MODULUS_C + /* is it a DR modulus? */ + dr = mp_dr_is_modulus(P); +#else + /* default to no */ + dr = 0; +#endif + +#ifdef BN_MP_REDUCE_IS_2K_C + /* if not, is it a unrestricted DR modulus? */ + if (dr == 0) { + dr = mp_reduce_is_2k(P) << 1; + } +#endif + + /* if the modulus is odd or dr != 0 use the montgomery method */ +#ifdef BN_MP_EXPTMOD_FAST_C + if (mp_isodd (P) == 1 || dr != 0) { + return mp_exptmod_fast (G, X, P, Y, dr); + } else { +#endif +#ifdef BN_S_MP_EXPTMOD_C + /* otherwise use the generic Barrett reduction technique */ + return s_mp_exptmod (G, X, P, Y, 0); +#else +#error mp_exptmod could fail + /* no exptmod for evens */ + return MP_VAL; +#endif +#ifdef BN_MP_EXPTMOD_FAST_C + } +#endif +} + + +/* compare two ints (signed)*/ +static int +mp_cmp (mp_int * a, mp_int * b) +{ + /* compare based on sign */ + if (a->sign != b->sign) { + if (a->sign == MP_NEG) { + return MP_LT; + } else { + return MP_GT; + } + } + + /* compare digits */ + if (a->sign == MP_NEG) { + /* if negative compare opposite direction */ + return mp_cmp_mag(b, a); + } else { + return mp_cmp_mag(a, b); + } +} + + +/* compare a digit */ +static int +mp_cmp_d(mp_int * a, mp_digit b) +{ + /* compare based on sign */ + if (a->sign == MP_NEG) { + return MP_LT; + } + + /* compare based on magnitude */ + if (a->used > 1) { + return MP_GT; + } + + /* compare the only digit of a to b */ + if (a->dp[0] > b) { + return MP_GT; + } else if (a->dp[0] < b) { + return MP_LT; + } else { + return MP_EQ; + } +} + + +#ifndef LTM_NO_NEG_EXP +/* hac 14.61, pp608 */ +static int +mp_invmod (mp_int * a, mp_int * b, mp_int * c) +{ + /* b cannot be negative */ + if (b->sign == MP_NEG || mp_iszero(b) == 1) { + return MP_VAL; + } + +#ifdef BN_FAST_MP_INVMOD_C + /* if the modulus is odd we can use a faster routine instead */ + if (mp_isodd (b) == 1) { + return fast_mp_invmod (a, b, c); + } +#endif + +#ifdef BN_MP_INVMOD_SLOW_C + return mp_invmod_slow(a, b, c); +#endif + +#ifndef BN_FAST_MP_INVMOD_C +#ifndef BN_MP_INVMOD_SLOW_C +#error mp_invmod would always fail +#endif +#endif + return MP_VAL; +} +#endif /* LTM_NO_NEG_EXP */ + + +/* get the size for an unsigned equivalent */ +static int +mp_unsigned_bin_size (mp_int * a) +{ + int size = mp_count_bits (a); + return (size / 8 + ((size & 7) != 0 ? 1 : 0)); +} + + +#ifndef LTM_NO_NEG_EXP +/* hac 14.61, pp608 */ +static int +mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int x, y, u, v, A, B, C, D; + int res; + + /* b cannot be negative */ + if (b->sign == MP_NEG || mp_iszero(b) == 1) { + return MP_VAL; + } + + /* init temps */ + if ((res = mp_init_multi(&x, &y, &u, &v, + &A, &B, &C, &D, NULL)) != MP_OKAY) { + return res; + } + + /* x = a, y = b */ + if ((res = mp_mod(a, b, &x)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_copy (b, &y)) != MP_OKAY) { + goto LBL_ERR; + } + + /* 2. [modified] if x,y are both even then return an error! */ + if (mp_iseven (&x) == 1 && mp_iseven (&y) == 1) { + res = MP_VAL; + goto LBL_ERR; + } + + /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ + if ((res = mp_copy (&x, &u)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_copy (&y, &v)) != MP_OKAY) { + goto LBL_ERR; + } + mp_set (&A, 1); + mp_set (&D, 1); + +top: + /* 4. while u is even do */ + while (mp_iseven (&u) == 1) { + /* 4.1 u = u/2 */ + if ((res = mp_div_2 (&u, &u)) != MP_OKAY) { + goto LBL_ERR; + } + /* 4.2 if A or B is odd then */ + if (mp_isodd (&A) == 1 || mp_isodd (&B) == 1) { + /* A = (A+y)/2, B = (B-x)/2 */ + if ((res = mp_add (&A, &y, &A)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) { + goto LBL_ERR; + } + } + /* A = A/2, B = B/2 */ + if ((res = mp_div_2 (&A, &A)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_div_2 (&B, &B)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* 5. while v is even do */ + while (mp_iseven (&v) == 1) { + /* 5.1 v = v/2 */ + if ((res = mp_div_2 (&v, &v)) != MP_OKAY) { + goto LBL_ERR; + } + /* 5.2 if C or D is odd then */ + if (mp_isodd (&C) == 1 || mp_isodd (&D) == 1) { + /* C = (C+y)/2, D = (D-x)/2 */ + if ((res = mp_add (&C, &y, &C)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + /* C = C/2, D = D/2 */ + if ((res = mp_div_2 (&C, &C)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_div_2 (&D, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* 6. if u >= v then */ + if (mp_cmp (&u, &v) != MP_LT) { + /* u = u - v, A = A - C, B = B - D */ + if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sub (&A, &C, &A)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) { + goto LBL_ERR; + } + } else { + /* v - v - u, C = C - A, D = D - B */ + if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sub (&C, &A, &C)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* if not zero goto step 4 */ + if (mp_iszero (&u) == 0) + goto top; + + /* now a = C, b = D, gcd == g*v */ + + /* if v != 1 then there is no inverse */ + if (mp_cmp_d (&v, 1) != MP_EQ) { + res = MP_VAL; + goto LBL_ERR; + } + + /* if its too low */ + while (mp_cmp_d(&C, 0) == MP_LT) { + if ((res = mp_add(&C, b, &C)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* too big */ + while (mp_cmp_mag(&C, b) != MP_LT) { + if ((res = mp_sub(&C, b, &C)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* C is now the inverse */ + mp_exch (&C, c); + res = MP_OKAY; +LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &A, &B, &C, &D, NULL); + return res; +} +#endif /* LTM_NO_NEG_EXP */ + + +/* compare maginitude of two ints (unsigned) */ +static int +mp_cmp_mag (mp_int * a, mp_int * b) +{ + int n; + mp_digit *tmpa, *tmpb; + + /* compare based on # of non-zero digits */ + if (a->used > b->used) { + return MP_GT; + } + + if (a->used < b->used) { + return MP_LT; + } + + /* alias for a */ + tmpa = a->dp + (a->used - 1); + + /* alias for b */ + tmpb = b->dp + (a->used - 1); + + /* compare based on digits */ + for (n = 0; n < a->used; ++n, --tmpa, --tmpb) { + if (*tmpa > *tmpb) { + return MP_GT; + } + + if (*tmpa < *tmpb) { + return MP_LT; + } + } + return MP_EQ; +} + + +/* reads a unsigned char array, assumes the msb is stored first [big endian] */ +static int +mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c) +{ + int res; + + /* make sure there are at least two digits */ + if (a->alloc < 2) { + if ((res = mp_grow(a, 2)) != MP_OKAY) { + return res; + } + } + + /* zero the int */ + mp_zero (a); + + /* read the bytes in */ + while (c-- > 0) { + if ((res = mp_mul_2d (a, 8, a)) != MP_OKAY) { + return res; + } + +#ifndef MP_8BIT + a->dp[0] |= *b++; + a->used += 1; +#else + a->dp[0] = (*b & MP_MASK); + a->dp[1] |= ((*b++ >> 7U) & 1); + a->used += 2; +#endif + } + mp_clamp (a); + return MP_OKAY; +} + + +/* store in unsigned [big endian] format */ +static int +mp_to_unsigned_bin (mp_int * a, unsigned char *b) +{ + int x, res; + mp_int t; + + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + + x = 0; + while (mp_iszero (&t) == 0) { +#ifndef MP_8BIT + b[x++] = (unsigned char) (t.dp[0] & 255); +#else + b[x++] = (unsigned char) (t.dp[0] | ((t.dp[1] & 0x01) << 7)); +#endif + if ((res = mp_div_2d (&t, 8, &t, NULL)) != MP_OKAY) { + mp_clear (&t); + return res; + } + } + bn_reverse (b, x); + mp_clear (&t); + return MP_OKAY; +} + + +/* shift right by a certain bit count (store quotient in c, optional remainder in d) */ +static int +mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d) +{ + mp_digit D, r, rr; + int x, res; + mp_int t; + + + /* if the shift count is <= 0 then we do no work */ + if (b <= 0) { + res = mp_copy (a, c); + if (d != NULL) { + mp_zero (d); + } + return res; + } + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + /* get the remainder */ + if (d != NULL) { + if ((res = mp_mod_2d (a, b, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + } + + /* copy */ + if ((res = mp_copy (a, c)) != MP_OKAY) { + mp_clear (&t); + return res; + } + + /* shift by as many digits in the bit count */ + if (b >= (int)DIGIT_BIT) { + mp_rshd (c, b / DIGIT_BIT); + } + + /* shift any bit count < DIGIT_BIT */ + D = (mp_digit) (b % DIGIT_BIT); + if (D != 0) { + register mp_digit *tmpc, mask, shift; + + /* mask */ + mask = (((mp_digit)1) << D) - 1; + + /* shift for lsb */ + shift = DIGIT_BIT - D; + + /* alias */ + tmpc = c->dp + (c->used - 1); + + /* carry */ + r = 0; + for (x = c->used - 1; x >= 0; x--) { + /* get the lower bits of this word in a temp */ + rr = *tmpc & mask; + + /* shift the current word and mix in the carry bits from the previous word */ + *tmpc = (*tmpc >> D) | (r << shift); + --tmpc; + + /* set the carry to the carry bits of the current word found above */ + r = rr; + } + } + mp_clamp (c); + if (d != NULL) { + mp_exch (&t, d); + } + mp_clear (&t); + return MP_OKAY; +} + + +static int +mp_init_copy (mp_int * a, mp_int * b) +{ + int res; + + if ((res = mp_init (a)) != MP_OKAY) { + return res; + } + return mp_copy (b, a); +} + + +/* set to zero */ +static void +mp_zero (mp_int * a) +{ + int n; + mp_digit *tmp; + + a->sign = MP_ZPOS; + a->used = 0; + + tmp = a->dp; + for (n = 0; n < a->alloc; n++) { + *tmp++ = 0; + } +} + + +/* copy, b = a */ +static int +mp_copy (mp_int * a, mp_int * b) +{ + int res, n; + + /* if dst == src do nothing */ + if (a == b) { + return MP_OKAY; + } + + /* grow dest */ + if (b->alloc < a->used) { + if ((res = mp_grow (b, a->used)) != MP_OKAY) { + return res; + } + } + + /* zero b and copy the parameters over */ + { + register mp_digit *tmpa, *tmpb; + + /* pointer aliases */ + + /* source */ + tmpa = a->dp; + + /* destination */ + tmpb = b->dp; + + /* copy all the digits */ + for (n = 0; n < a->used; n++) { + *tmpb++ = *tmpa++; + } + + /* clear high digits */ + for (; n < b->used; n++) { + *tmpb++ = 0; + } + } + + /* copy used count and sign */ + b->used = a->used; + b->sign = a->sign; + return MP_OKAY; +} + + +/* shift right a certain amount of digits */ +static void +mp_rshd (mp_int * a, int b) +{ + int x; + + /* if b <= 0 then ignore it */ + if (b <= 0) { + return; + } + + /* if b > used then simply zero it and return */ + if (a->used <= b) { + mp_zero (a); + return; + } + + { + register mp_digit *bottom, *top; + + /* shift the digits down */ + + /* bottom */ + bottom = a->dp; + + /* top [offset into digits] */ + top = a->dp + b; + + /* this is implemented as a sliding window where + * the window is b-digits long and digits from + * the top of the window are copied to the bottom + * + * e.g. + + b-2 | b-1 | b0 | b1 | b2 | ... | bb | ----> + /\ | ----> + \-------------------/ ----> + */ + for (x = 0; x < (a->used - b); x++) { + *bottom++ = *top++; + } + + /* zero the top digits */ + for (; x < a->used; x++) { + *bottom++ = 0; + } + } + + /* remove excess digits */ + a->used -= b; +} + + +/* swap the elements of two integers, for cases where you can't simply swap the + * mp_int pointers around + */ +static void +mp_exch (mp_int * a, mp_int * b) +{ + mp_int t; + + t = *a; + *a = *b; + *b = t; +} + + +/* trim unused digits + * + * This is used to ensure that leading zero digits are + * trimed and the leading "used" digit will be non-zero + * Typically very fast. Also fixes the sign if there + * are no more leading digits + */ +static void +mp_clamp (mp_int * a) +{ + /* decrease used while the most significant digit is + * zero. + */ + while (a->used > 0 && a->dp[a->used - 1] == 0) { + --(a->used); + } + + /* reset the sign flag if used == 0 */ + if (a->used == 0) { + a->sign = MP_ZPOS; + } +} + + +/* grow as required */ +static int +mp_grow (mp_int * a, int size) +{ + int i; + mp_digit *tmp; + + /* if the alloc size is smaller alloc more ram */ + if (a->alloc < size) { + /* ensure there are always at least MP_PREC digits extra on top */ + size += (MP_PREC * 2) - (size % MP_PREC); + + /* reallocate the array a->dp + * + * We store the return in a temporary variable + * in case the operation failed we don't want + * to overwrite the dp member of a. + */ + tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * size); + if (tmp == NULL) { + /* reallocation failed but "a" is still valid [can be freed] */ + return MP_MEM; + } + + /* reallocation succeeded so set a->dp */ + a->dp = tmp; + + /* zero excess digits */ + i = a->alloc; + a->alloc = size; + for (; i < a->alloc; i++) { + a->dp[i] = 0; + } + } + return MP_OKAY; +} + + +#ifdef BN_MP_ABS_C +/* b = |a| + * + * Simple function copies the input and fixes the sign to positive + */ +static int +mp_abs (mp_int * a, mp_int * b) +{ + int res; + + /* copy a to b */ + if (a != b) { + if ((res = mp_copy (a, b)) != MP_OKAY) { + return res; + } + } + + /* force the sign of b to positive */ + b->sign = MP_ZPOS; + + return MP_OKAY; +} +#endif + + +/* set to a digit */ +static void +mp_set (mp_int * a, mp_digit b) +{ + mp_zero (a); + a->dp[0] = b & MP_MASK; + a->used = (a->dp[0] != 0) ? 1 : 0; +} + + +#ifndef LTM_NO_NEG_EXP +/* b = a/2 */ +static int +mp_div_2(mp_int * a, mp_int * b) +{ + int x, res, oldused; + + /* copy */ + if (b->alloc < a->used) { + if ((res = mp_grow (b, a->used)) != MP_OKAY) { + return res; + } + } + + oldused = b->used; + b->used = a->used; + { + register mp_digit r, rr, *tmpa, *tmpb; + + /* source alias */ + tmpa = a->dp + b->used - 1; + + /* dest alias */ + tmpb = b->dp + b->used - 1; + + /* carry */ + r = 0; + for (x = b->used - 1; x >= 0; x--) { + /* get the carry for the next iteration */ + rr = *tmpa & 1; + + /* shift the current digit, add in carry and store */ + *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1)); + + /* forward carry to next iteration */ + r = rr; + } + + /* zero excess digits */ + tmpb = b->dp + b->used; + for (x = b->used; x < oldused; x++) { + *tmpb++ = 0; + } + } + b->sign = a->sign; + mp_clamp (b); + return MP_OKAY; +} +#endif /* LTM_NO_NEG_EXP */ + + +/* shift left by a certain bit count */ +static int +mp_mul_2d (mp_int * a, int b, mp_int * c) +{ + mp_digit d; + int res; + + /* copy */ + if (a != c) { + if ((res = mp_copy (a, c)) != MP_OKAY) { + return res; + } + } + + if (c->alloc < (int)(c->used + b/DIGIT_BIT + 1)) { + if ((res = mp_grow (c, c->used + b / DIGIT_BIT + 1)) != MP_OKAY) { + return res; + } + } + + /* shift by as many digits in the bit count */ + if (b >= (int)DIGIT_BIT) { + if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) { + return res; + } + } + + /* shift any bit count < DIGIT_BIT */ + d = (mp_digit) (b % DIGIT_BIT); + if (d != 0) { + register mp_digit *tmpc, shift, mask, r, rr; + register int x; + + /* bitmask for carries */ + mask = (((mp_digit)1) << d) - 1; + + /* shift for msbs */ + shift = DIGIT_BIT - d; + + /* alias */ + tmpc = c->dp; + + /* carry */ + r = 0; + for (x = 0; x < c->used; x++) { + /* get the higher bits of the current word */ + rr = (*tmpc >> shift) & mask; + + /* shift the current word and OR in the carry */ + *tmpc = ((*tmpc << d) | r) & MP_MASK; + ++tmpc; + + /* set the carry to the carry bits of the current word */ + r = rr; + } + + /* set final carry */ + if (r != 0) { + c->dp[(c->used)++] = r; + } + } + mp_clamp (c); + return MP_OKAY; +} + + +#ifdef BN_MP_INIT_MULTI_C +static int +mp_init_multi(mp_int *mp, ...) +{ + mp_err res = MP_OKAY; /* Assume ok until proven otherwise */ + int n = 0; /* Number of ok inits */ + mp_int* cur_arg = mp; + va_list args; + + va_start(args, mp); /* init args to next argument from caller */ + while (cur_arg != NULL) { + if (mp_init(cur_arg) != MP_OKAY) { + /* Oops - error! Back-track and mp_clear what we already + succeeded in init-ing, then return error. + */ + va_list clean_args; + + /* end the current list */ + va_end(args); + + /* now start cleaning up */ + cur_arg = mp; + va_start(clean_args, mp); + while (n--) { + mp_clear(cur_arg); + cur_arg = va_arg(clean_args, mp_int*); + } + va_end(clean_args); + res = MP_MEM; + break; + } + n++; + cur_arg = va_arg(args, mp_int*); + } + va_end(args); + return res; /* Assumed ok, if error flagged above. */ +} +#endif + + +#ifdef BN_MP_CLEAR_MULTI_C +static void +mp_clear_multi(mp_int *mp, ...) +{ + mp_int* next_mp = mp; + va_list args; + va_start(args, mp); + while (next_mp != NULL) { + mp_clear(next_mp); + next_mp = va_arg(args, mp_int*); + } + va_end(args); +} +#endif + + +/* shift left a certain amount of digits */ +static int +mp_lshd (mp_int * a, int b) +{ + int x, res; + + /* if its less than zero return */ + if (b <= 0) { + return MP_OKAY; + } + + /* grow to fit the new digits */ + if (a->alloc < a->used + b) { + if ((res = mp_grow (a, a->used + b)) != MP_OKAY) { + return res; + } + } + + { + register mp_digit *top, *bottom; + + /* increment the used by the shift amount then copy upwards */ + a->used += b; + + /* top */ + top = a->dp + a->used - 1; + + /* base */ + bottom = a->dp + a->used - 1 - b; + + /* much like mp_rshd this is implemented using a sliding window + * except the window goes the otherway around. Copying from + * the bottom to the top. see bn_mp_rshd.c for more info. + */ + for (x = a->used - 1; x >= b; x--) { + *top-- = *bottom--; + } + + /* zero the lower digits */ + top = a->dp; + for (x = 0; x < b; x++) { + *top++ = 0; + } + } + return MP_OKAY; +} + + +/* returns the number of bits in an int */ +static int +mp_count_bits (mp_int * a) +{ + int r; + mp_digit q; + + /* shortcut */ + if (a->used == 0) { + return 0; + } + + /* get number of digits and add that */ + r = (a->used - 1) * DIGIT_BIT; + + /* take the last digit and count the bits in it */ + q = a->dp[a->used - 1]; + while (q > ((mp_digit) 0)) { + ++r; + q >>= ((mp_digit) 1); + } + return r; +} + + +/* calc a value mod 2**b */ +static int +mp_mod_2d (mp_int * a, int b, mp_int * c) +{ + int x, res; + + /* if b is <= 0 then zero the int */ + if (b <= 0) { + mp_zero (c); + return MP_OKAY; + } + + /* if the modulus is larger than the value than return */ + if (b >= (int) (a->used * DIGIT_BIT)) { + res = mp_copy (a, c); + return res; + } + + /* copy */ + if ((res = mp_copy (a, c)) != MP_OKAY) { + return res; + } + + /* zero digits above the last digit of the modulus */ + for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++) { + c->dp[x] = 0; + } + /* clear the digit that is not completely outside/inside the modulus */ + c->dp[b / DIGIT_BIT] &= + (mp_digit) ((((mp_digit) 1) << (((mp_digit) b) % DIGIT_BIT)) - ((mp_digit) 1)); + mp_clamp (c); + return MP_OKAY; +} + + +#ifdef BN_MP_DIV_SMALL + +/* slower bit-bang division... also smaller */ +static int +mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d) +{ + mp_int ta, tb, tq, q; + int res, n, n2; + + /* is divisor zero ? */ + if (mp_iszero (b) == 1) { + return MP_VAL; + } + + /* if a < b then q=0, r = a */ + if (mp_cmp_mag (a, b) == MP_LT) { + if (d != NULL) { + res = mp_copy (a, d); + } else { + res = MP_OKAY; + } + if (c != NULL) { + mp_zero (c); + } + return res; + } + + /* init our temps */ + if ((res = mp_init_multi(&ta, &tb, &tq, &q, NULL) != MP_OKAY)) { + return res; + } + + + mp_set(&tq, 1); + n = mp_count_bits(a) - mp_count_bits(b); + if (((res = mp_abs(a, &ta)) != MP_OKAY) || + ((res = mp_abs(b, &tb)) != MP_OKAY) || + ((res = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) || + ((res = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) { + goto LBL_ERR; + } + + while (n-- >= 0) { + if (mp_cmp(&tb, &ta) != MP_GT) { + if (((res = mp_sub(&ta, &tb, &ta)) != MP_OKAY) || + ((res = mp_add(&q, &tq, &q)) != MP_OKAY)) { + goto LBL_ERR; + } + } + if (((res = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) || + ((res = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) { + goto LBL_ERR; + } + } + + /* now q == quotient and ta == remainder */ + n = a->sign; + n2 = (a->sign == b->sign ? MP_ZPOS : MP_NEG); + if (c != NULL) { + mp_exch(c, &q); + c->sign = (mp_iszero(c) == MP_YES) ? MP_ZPOS : n2; + } + if (d != NULL) { + mp_exch(d, &ta); + d->sign = (mp_iszero(d) == MP_YES) ? MP_ZPOS : n; + } +LBL_ERR: + mp_clear_multi(&ta, &tb, &tq, &q, NULL); + return res; +} + +#else + +/* integer signed division. + * c*b + d == a [e.g. a/b, c=quotient, d=remainder] + * HAC pp.598 Algorithm 14.20 + * + * Note that the description in HAC is horribly + * incomplete. For example, it doesn't consider + * the case where digits are removed from 'x' in + * the inner loop. It also doesn't consider the + * case that y has fewer than three digits, etc.. + * + * The overall algorithm is as described as + * 14.20 from HAC but fixed to treat these cases. +*/ +static int +mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d) +{ + mp_int q, x, y, t1, t2; + int res, n, t, i, norm, neg; + + /* is divisor zero ? */ + if (mp_iszero (b) == 1) { + return MP_VAL; + } + + /* if a < b then q=0, r = a */ + if (mp_cmp_mag (a, b) == MP_LT) { + if (d != NULL) { + res = mp_copy (a, d); + } else { + res = MP_OKAY; + } + if (c != NULL) { + mp_zero (c); + } + return res; + } + + if ((res = mp_init_size (&q, a->used + 2)) != MP_OKAY) { + return res; + } + q.used = a->used + 2; + + if ((res = mp_init (&t1)) != MP_OKAY) { + goto LBL_Q; + } + + if ((res = mp_init (&t2)) != MP_OKAY) { + goto LBL_T1; + } + + if ((res = mp_init_copy (&x, a)) != MP_OKAY) { + goto LBL_T2; + } + + if ((res = mp_init_copy (&y, b)) != MP_OKAY) { + goto LBL_X; + } + + /* fix the sign */ + neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; + x.sign = y.sign = MP_ZPOS; + + /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */ + norm = mp_count_bits(&y) % DIGIT_BIT; + if (norm < (int)(DIGIT_BIT-1)) { + norm = (DIGIT_BIT-1) - norm; + if ((res = mp_mul_2d (&x, norm, &x)) != MP_OKAY) { + goto LBL_Y; + } + if ((res = mp_mul_2d (&y, norm, &y)) != MP_OKAY) { + goto LBL_Y; + } + } else { + norm = 0; + } + + /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */ + n = x.used - 1; + t = y.used - 1; + + /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */ + if ((res = mp_lshd (&y, n - t)) != MP_OKAY) { /* y = y*b**{n-t} */ + goto LBL_Y; + } + + while (mp_cmp (&x, &y) != MP_LT) { + ++(q.dp[n - t]); + if ((res = mp_sub (&x, &y, &x)) != MP_OKAY) { + goto LBL_Y; + } + } + + /* reset y by shifting it back down */ + mp_rshd (&y, n - t); + + /* step 3. for i from n down to (t + 1) */ + for (i = n; i >= (t + 1); i--) { + if (i > x.used) { + continue; + } + + /* step 3.1 if xi == yt then set q{i-t-1} to b-1, + * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */ + if (x.dp[i] == y.dp[t]) { + q.dp[i - t - 1] = ((((mp_digit)1) << DIGIT_BIT) - 1); + } else { + mp_word tmp; + tmp = ((mp_word) x.dp[i]) << ((mp_word) DIGIT_BIT); + tmp |= ((mp_word) x.dp[i - 1]); + tmp /= ((mp_word) y.dp[t]); + if (tmp > (mp_word) MP_MASK) + tmp = MP_MASK; + q.dp[i - t - 1] = (mp_digit) (tmp & (mp_word) (MP_MASK)); + } + + /* while (q{i-t-1} * (yt * b + y{t-1})) > + xi * b**2 + xi-1 * b + xi-2 + + do q{i-t-1} -= 1; + */ + q.dp[i - t - 1] = (q.dp[i - t - 1] + 1) & MP_MASK; + do { + q.dp[i - t - 1] = (q.dp[i - t - 1] - 1) & MP_MASK; + + /* find left hand */ + mp_zero (&t1); + t1.dp[0] = (t - 1 < 0) ? 0 : y.dp[t - 1]; + t1.dp[1] = y.dp[t]; + t1.used = 2; + if ((res = mp_mul_d (&t1, q.dp[i - t - 1], &t1)) != MP_OKAY) { + goto LBL_Y; + } + + /* find right hand */ + t2.dp[0] = (i - 2 < 0) ? 0 : x.dp[i - 2]; + t2.dp[1] = (i - 1 < 0) ? 0 : x.dp[i - 1]; + t2.dp[2] = x.dp[i]; + t2.used = 3; + } while (mp_cmp_mag(&t1, &t2) == MP_GT); + + /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */ + if ((res = mp_mul_d (&y, q.dp[i - t - 1], &t1)) != MP_OKAY) { + goto LBL_Y; + } + + if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) { + goto LBL_Y; + } + + if ((res = mp_sub (&x, &t1, &x)) != MP_OKAY) { + goto LBL_Y; + } + + /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */ + if (x.sign == MP_NEG) { + if ((res = mp_copy (&y, &t1)) != MP_OKAY) { + goto LBL_Y; + } + if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) { + goto LBL_Y; + } + if ((res = mp_add (&x, &t1, &x)) != MP_OKAY) { + goto LBL_Y; + } + + q.dp[i - t - 1] = (q.dp[i - t - 1] - 1UL) & MP_MASK; + } + } + + /* now q is the quotient and x is the remainder + * [which we have to normalize] + */ + + /* get sign before writing to c */ + x.sign = x.used == 0 ? MP_ZPOS : a->sign; + + if (c != NULL) { + mp_clamp (&q); + mp_exch (&q, c); + c->sign = neg; + } + + if (d != NULL) { + mp_div_2d (&x, norm, &x, NULL); + mp_exch (&x, d); + } + + res = MP_OKAY; + +LBL_Y:mp_clear (&y); +LBL_X:mp_clear (&x); +LBL_T2:mp_clear (&t2); +LBL_T1:mp_clear (&t1); +LBL_Q:mp_clear (&q); + return res; +} + +#endif + + +#ifdef MP_LOW_MEM + #define TAB_SIZE 32 +#else + #define TAB_SIZE 256 +#endif + +static int +s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) +{ + mp_int M[TAB_SIZE], res, mu; + mp_digit buf; + int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; + int (*redux)(mp_int*,mp_int*,mp_int*); + + /* find window size */ + x = mp_count_bits (X); + if (x <= 7) { + winsize = 2; + } else if (x <= 36) { + winsize = 3; + } else if (x <= 140) { + winsize = 4; + } else if (x <= 450) { + winsize = 5; + } else if (x <= 1303) { + winsize = 6; + } else if (x <= 3529) { + winsize = 7; + } else { + winsize = 8; + } + +#ifdef MP_LOW_MEM + if (winsize > 5) { + winsize = 5; + } +#endif + + /* init M array */ + /* init first cell */ + if ((err = mp_init(&M[1])) != MP_OKAY) { + return err; + } + + /* now init the second half of the array */ + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + if ((err = mp_init(&M[x])) != MP_OKAY) { + for (y = 1<<(winsize-1); y < x; y++) { + mp_clear (&M[y]); + } + mp_clear(&M[1]); + return err; + } + } + + /* create mu, used for Barrett reduction */ + if ((err = mp_init (&mu)) != MP_OKAY) { + goto LBL_M; + } + + if (redmode == 0) { + if ((err = mp_reduce_setup (&mu, P)) != MP_OKAY) { + goto LBL_MU; + } + redux = mp_reduce; + } else { + if ((err = mp_reduce_2k_setup_l (P, &mu)) != MP_OKAY) { + goto LBL_MU; + } + redux = mp_reduce_2k_l; + } + + /* create M table + * + * The M table contains powers of the base, + * e.g. M[x] = G**x mod P + * + * The first half of the table is not + * computed though accept for M[0] and M[1] + */ + if ((err = mp_mod (G, P, &M[1])) != MP_OKAY) { + goto LBL_MU; + } + + /* compute the value at M[1<<(winsize-1)] by squaring + * M[1] (winsize-1) times + */ + if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) { + goto LBL_MU; + } + + for (x = 0; x < (winsize - 1); x++) { + /* square it */ + if ((err = mp_sqr (&M[1 << (winsize - 1)], + &M[1 << (winsize - 1)])) != MP_OKAY) { + goto LBL_MU; + } + + /* reduce modulo P */ + if ((err = redux (&M[1 << (winsize - 1)], P, &mu)) != MP_OKAY) { + goto LBL_MU; + } + } + + /* create upper table, that is M[x] = M[x-1] * M[1] (mod P) + * for x = (2**(winsize - 1) + 1) to (2**winsize - 1) + */ + for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { + if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) { + goto LBL_MU; + } + if ((err = redux (&M[x], P, &mu)) != MP_OKAY) { + goto LBL_MU; + } + } + + /* setup result */ + if ((err = mp_init (&res)) != MP_OKAY) { + goto LBL_MU; + } + mp_set (&res, 1); + + /* set initial mode and bit cnt */ + mode = 0; + bitcnt = 1; + buf = 0; + digidx = X->used - 1; + bitcpy = 0; + bitbuf = 0; + + for (;;) { + /* grab next digit as required */ + if (--bitcnt == 0) { + /* if digidx == -1 we are out of digits */ + if (digidx == -1) { + break; + } + /* read next digit and reset the bitcnt */ + buf = X->dp[digidx--]; + bitcnt = (int) DIGIT_BIT; + } + + /* grab the next msb from the exponent */ + y = (buf >> (mp_digit)(DIGIT_BIT - 1)) & 1; + buf <<= (mp_digit)1; + + /* if the bit is zero and mode == 0 then we ignore it + * These represent the leading zero bits before the first 1 bit + * in the exponent. Technically this opt is not required but it + * does lower the # of trivial squaring/reductions used + */ + if (mode == 0 && y == 0) { + continue; + } + + /* if the bit is zero and mode == 1 then we square */ + if (mode == 1 && y == 0) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, &mu)) != MP_OKAY) { + goto LBL_RES; + } + continue; + } + + /* else we add it to the window */ + bitbuf |= (y << (winsize - ++bitcpy)); + mode = 2; + + if (bitcpy == winsize) { + /* ok window is filled so square as required and multiply */ + /* square first */ + for (x = 0; x < winsize; x++) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, &mu)) != MP_OKAY) { + goto LBL_RES; + } + } + + /* then multiply */ + if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, &mu)) != MP_OKAY) { + goto LBL_RES; + } + + /* empty window and reset */ + bitcpy = 0; + bitbuf = 0; + mode = 1; + } + } + + /* if bits remain then square/multiply */ + if (mode == 2 && bitcpy > 0) { + /* square then multiply if the bit is set */ + for (x = 0; x < bitcpy; x++) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, &mu)) != MP_OKAY) { + goto LBL_RES; + } + + bitbuf <<= 1; + if ((bitbuf & (1 << winsize)) != 0) { + /* then multiply */ + if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, &mu)) != MP_OKAY) { + goto LBL_RES; + } + } + } + } + + mp_exch (&res, Y); + err = MP_OKAY; +LBL_RES:mp_clear (&res); +LBL_MU:mp_clear (&mu); +LBL_M: + mp_clear(&M[1]); + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + mp_clear (&M[x]); + } + return err; +} + + +/* computes b = a*a */ +static int +mp_sqr (mp_int * a, mp_int * b) +{ + int res; + +#ifdef BN_MP_TOOM_SQR_C + /* use Toom-Cook? */ + if (a->used >= TOOM_SQR_CUTOFF) { + res = mp_toom_sqr(a, b); + /* Karatsuba? */ + } else +#endif +#ifdef BN_MP_KARATSUBA_SQR_C +if (a->used >= KARATSUBA_SQR_CUTOFF) { + res = mp_karatsuba_sqr (a, b); + } else +#endif + { +#ifdef BN_FAST_S_MP_SQR_C + /* can we use the fast comba multiplier? */ + if ((a->used * 2 + 1) < MP_WARRAY && + a->used < + (1 << (sizeof(mp_word) * CHAR_BIT - 2*DIGIT_BIT - 1))) { + res = fast_s_mp_sqr (a, b); + } else +#endif +#ifdef BN_S_MP_SQR_C + res = s_mp_sqr (a, b); +#else +#error mp_sqr could fail + res = MP_VAL; +#endif + } + b->sign = MP_ZPOS; + return res; +} + + +/* reduces a modulo n where n is of the form 2**p - d + This differs from reduce_2k since "d" can be larger + than a single digit. +*/ +static int +mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d) +{ + mp_int q; + int p, res; + + if ((res = mp_init(&q)) != MP_OKAY) { + return res; + } + + p = mp_count_bits(n); +top: + /* q = a/2**p, a = a mod 2**p */ + if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) { + goto ERR; + } + + /* q = q * d */ + if ((res = mp_mul(&q, d, &q)) != MP_OKAY) { + goto ERR; + } + + /* a = a + q */ + if ((res = s_mp_add(a, &q, a)) != MP_OKAY) { + goto ERR; + } + + if (mp_cmp_mag(a, n) != MP_LT) { + s_mp_sub(a, n, a); + goto top; + } + +ERR: + mp_clear(&q); + return res; +} + + +/* determines the setup value */ +static int +mp_reduce_2k_setup_l(mp_int *a, mp_int *d) +{ + int res; + mp_int tmp; + + if ((res = mp_init(&tmp)) != MP_OKAY) { + return res; + } + + if ((res = mp_2expt(&tmp, mp_count_bits(a))) != MP_OKAY) { + goto ERR; + } + + if ((res = s_mp_sub(&tmp, a, d)) != MP_OKAY) { + goto ERR; + } + +ERR: + mp_clear(&tmp); + return res; +} + + +/* computes a = 2**b + * + * Simple algorithm which zeroes the int, grows it then just sets one bit + * as required. + */ +static int +mp_2expt (mp_int * a, int b) +{ + int res; + + /* zero a as per default */ + mp_zero (a); + + /* grow a to accommodate the single bit */ + if ((res = mp_grow (a, b / DIGIT_BIT + 1)) != MP_OKAY) { + return res; + } + + /* set the used count of where the bit will go */ + a->used = b / DIGIT_BIT + 1; + + /* put the single bit in its place */ + a->dp[b / DIGIT_BIT] = ((mp_digit)1) << (b % DIGIT_BIT); + + return MP_OKAY; +} + + +/* pre-calculate the value required for Barrett reduction + * For a given modulus "b" it calulates the value required in "a" + */ +static int +mp_reduce_setup (mp_int * a, mp_int * b) +{ + int res; + + if ((res = mp_2expt (a, b->used * 2 * DIGIT_BIT)) != MP_OKAY) { + return res; + } + return mp_div (a, b, a, NULL); +} + + +/* reduces x mod m, assumes 0 < x < m**2, mu is + * precomputed via mp_reduce_setup. + * From HAC pp.604 Algorithm 14.42 + */ +static int +mp_reduce (mp_int * x, mp_int * m, mp_int * mu) +{ + mp_int q; + int res, um = m->used; + + /* q = x */ + if ((res = mp_init_copy (&q, x)) != MP_OKAY) { + return res; + } + + /* q1 = x / b**(k-1) */ + mp_rshd (&q, um - 1); + + /* according to HAC this optimization is ok */ + if (((unsigned long) um) > (((mp_digit)1) << (DIGIT_BIT - 1))) { + if ((res = mp_mul (&q, mu, &q)) != MP_OKAY) { + goto CLEANUP; + } + } else { +#ifdef BN_S_MP_MUL_HIGH_DIGS_C + if ((res = s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) { + goto CLEANUP; + } +#elif defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C) + if ((res = fast_s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) { + goto CLEANUP; + } +#else + { +#error mp_reduce would always fail + res = MP_VAL; + goto CLEANUP; + } +#endif + } + + /* q3 = q2 / b**(k+1) */ + mp_rshd (&q, um + 1); + + /* x = x mod b**(k+1), quick (no division) */ + if ((res = mp_mod_2d (x, DIGIT_BIT * (um + 1), x)) != MP_OKAY) { + goto CLEANUP; + } + + /* q = q * m mod b**(k+1), quick (no division) */ + if ((res = s_mp_mul_digs (&q, m, &q, um + 1)) != MP_OKAY) { + goto CLEANUP; + } + + /* x = x - q */ + if ((res = mp_sub (x, &q, x)) != MP_OKAY) { + goto CLEANUP; + } + + /* If x < 0, add b**(k+1) to it */ + if (mp_cmp_d (x, 0) == MP_LT) { + mp_set (&q, 1); + if ((res = mp_lshd (&q, um + 1)) != MP_OKAY) { + goto CLEANUP; + } + if ((res = mp_add (x, &q, x)) != MP_OKAY) { + goto CLEANUP; + } + } + + /* Back off if it's too big */ + while (mp_cmp (x, m) != MP_LT) { + if ((res = s_mp_sub (x, m, x)) != MP_OKAY) { + goto CLEANUP; + } + } + +CLEANUP: + mp_clear (&q); + + return res; +} + + +/* multiplies |a| * |b| and only computes up to digs digits of result + * HAC pp. 595, Algorithm 14.12 Modified so you can control how + * many digits of output are created. + */ +static int +s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) +{ + mp_int t; + int res, pa, pb, ix, iy; + mp_digit u; + mp_word r; + mp_digit tmpx, *tmpt, *tmpy; + + /* can we use the fast multiplier? */ + if (((digs) < MP_WARRAY) && + MIN (a->used, b->used) < + (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { + return fast_s_mp_mul_digs (a, b, c, digs); + } + + if ((res = mp_init_size (&t, digs)) != MP_OKAY) { + return res; + } + t.used = digs; + + /* compute the digits of the product directly */ + pa = a->used; + for (ix = 0; ix < pa; ix++) { + /* set the carry to zero */ + u = 0; + + /* limit ourselves to making digs digits of output */ + pb = MIN (b->used, digs - ix); + + /* setup some aliases */ + /* copy of the digit from a used within the nested loop */ + tmpx = a->dp[ix]; + + /* an alias for the destination shifted ix places */ + tmpt = t.dp + ix; + + /* an alias for the digits of b */ + tmpy = b->dp; + + /* compute the columns of the output and propagate the carry */ + for (iy = 0; iy < pb; iy++) { + /* compute the column as a mp_word */ + r = ((mp_word)*tmpt) + + ((mp_word)tmpx) * ((mp_word)*tmpy++) + + ((mp_word) u); + + /* the new column is the lower part of the result */ + *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* get the carry word from the result */ + u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); + } + /* set carry if it is placed below digs */ + if (ix + iy < digs) { + *tmpt = u; + } + } + + mp_clamp (&t); + mp_exch (&t, c); + + mp_clear (&t); + return MP_OKAY; +} + + +/* Fast (comba) multiplier + * + * This is the fast column-array [comba] multiplier. It is + * designed to compute the columns of the product first + * then handle the carries afterwards. This has the effect + * of making the nested loops that compute the columns very + * simple and schedulable on super-scalar processors. + * + * This has been modified to produce a variable number of + * digits of output so if say only a half-product is required + * you don't have to compute the upper half (a feature + * required for fast Barrett reduction). + * + * Based on Algorithm 14.12 on pp.595 of HAC. + * + */ +static int +fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) +{ + int olduse, res, pa, ix, iz; + mp_digit W[MP_WARRAY]; + register mp_word _W; + + /* grow the destination as required */ + if (c->alloc < digs) { + if ((res = mp_grow (c, digs)) != MP_OKAY) { + return res; + } + } + + /* number of output digits to produce */ + pa = MIN(digs, a->used + b->used); + + /* clear the carry */ + _W = 0; + for (ix = 0; ix < pa; ix++) { + int tx, ty; + int iy; + mp_digit *tmpx, *tmpy; + + /* get offsets into the two bignums */ + ty = MIN(b->used-1, ix); + tx = ix - ty; + + /* setup temp aliases */ + tmpx = a->dp + tx; + tmpy = b->dp + ty; + + /* this is the number of times the loop will iterrate, essentially + while (tx++ < a->used && ty-- >= 0) { ... } + */ + iy = MIN(a->used-tx, ty+1); + + /* execute loop */ + for (iz = 0; iz < iy; ++iz) { + _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); + + } + + /* store term */ + W[ix] = ((mp_digit)_W) & MP_MASK; + + /* make next carry */ + _W = _W >> ((mp_word)DIGIT_BIT); + } + + /* setup dest */ + olduse = c->used; + c->used = pa; + + { + register mp_digit *tmpc; + tmpc = c->dp; + for (ix = 0; ix < pa+1; ix++) { + /* now extract the previous digit [below the carry] */ + *tmpc++ = W[ix]; + } + + /* clear unused digits [that existed in the old copy of c] */ + for (; ix < olduse; ix++) { + *tmpc++ = 0; + } + } + mp_clamp (c); + return MP_OKAY; +} + + +/* init an mp_init for a given size */ +static int +mp_init_size (mp_int * a, int size) +{ + int x; + + /* pad size so there are always extra digits */ + size += (MP_PREC * 2) - (size % MP_PREC); + + /* alloc mem */ + a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * size); + if (a->dp == NULL) { + return MP_MEM; + } + + /* set the members */ + a->used = 0; + a->alloc = size; + a->sign = MP_ZPOS; + + /* zero the digits */ + for (x = 0; x < size; x++) { + a->dp[x] = 0; + } + + return MP_OKAY; +} + + +/* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */ +static int +s_mp_sqr (mp_int * a, mp_int * b) +{ + mp_int t; + int res, ix, iy, pa; + mp_word r; + mp_digit u, tmpx, *tmpt; + + pa = a->used; + if ((res = mp_init_size (&t, 2*pa + 1)) != MP_OKAY) { + return res; + } + + /* default used is maximum possible size */ + t.used = 2*pa + 1; + + for (ix = 0; ix < pa; ix++) { + /* first calculate the digit at 2*ix */ + /* calculate double precision result */ + r = ((mp_word) t.dp[2*ix]) + + ((mp_word)a->dp[ix])*((mp_word)a->dp[ix]); + + /* store lower part in result */ + t.dp[ix+ix] = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* get the carry */ + u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + + /* left hand side of A[ix] * A[iy] */ + tmpx = a->dp[ix]; + + /* alias for where to store the results */ + tmpt = t.dp + (2*ix + 1); + + for (iy = ix + 1; iy < pa; iy++) { + /* first calculate the product */ + r = ((mp_word)tmpx) * ((mp_word)a->dp[iy]); + + /* now calculate the double precision result, note we use + * addition instead of *2 since it's easier to optimize + */ + r = ((mp_word) *tmpt) + r + r + ((mp_word) u); + + /* store lower part */ + *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* get carry */ + u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + } + /* propagate upwards */ + while (u != ((mp_digit) 0)) { + r = ((mp_word) *tmpt) + ((mp_word) u); + *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); + u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + } + } + + mp_clamp (&t); + mp_exch (&t, b); + mp_clear (&t); + return MP_OKAY; +} + + +/* multiplies |a| * |b| and does not compute the lower digs digits + * [meant to get the higher part of the product] + */ +static int +s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) +{ + mp_int t; + int res, pa, pb, ix, iy; + mp_digit u; + mp_word r; + mp_digit tmpx, *tmpt, *tmpy; + + /* can we use the fast multiplier? */ +#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C + if (((a->used + b->used + 1) < MP_WARRAY) + && MIN (a->used, b->used) < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { + return fast_s_mp_mul_high_digs (a, b, c, digs); + } +#endif + + if ((res = mp_init_size (&t, a->used + b->used + 1)) != MP_OKAY) { + return res; + } + t.used = a->used + b->used + 1; + + pa = a->used; + pb = b->used; + for (ix = 0; ix < pa; ix++) { + /* clear the carry */ + u = 0; + + /* left hand side of A[ix] * B[iy] */ + tmpx = a->dp[ix]; + + /* alias to the address of where the digits will be stored */ + tmpt = &(t.dp[digs]); + + /* alias for where to read the right hand side from */ + tmpy = b->dp + (digs - ix); + + for (iy = digs - ix; iy < pb; iy++) { + /* calculate the double precision result */ + r = ((mp_word)*tmpt) + + ((mp_word)tmpx) * ((mp_word)*tmpy++) + + ((mp_word) u); + + /* get the lower part */ + *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* carry the carry */ + u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); + } + *tmpt = u; + } + mp_clamp (&t); + mp_exch (&t, c); + mp_clear (&t); + return MP_OKAY; +} + + +#ifdef BN_MP_MONTGOMERY_SETUP_C +/* setups the montgomery reduction stuff */ +static int +mp_montgomery_setup (mp_int * n, mp_digit * rho) +{ + mp_digit x, b; + +/* fast inversion mod 2**k + * + * Based on the fact that + * + * XA = 1 (mod 2**n) => (X(2-XA)) A = 1 (mod 2**2n) + * => 2*X*A - X*X*A*A = 1 + * => 2*(1) - (1) = 1 + */ + b = n->dp[0]; + + if ((b & 1) == 0) { + return MP_VAL; + } + + x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ + x *= 2 - b * x; /* here x*a==1 mod 2**8 */ +#if !defined(MP_8BIT) + x *= 2 - b * x; /* here x*a==1 mod 2**16 */ +#endif +#if defined(MP_64BIT) || !(defined(MP_8BIT) || defined(MP_16BIT)) + x *= 2 - b * x; /* here x*a==1 mod 2**32 */ +#endif +#ifdef MP_64BIT + x *= 2 - b * x; /* here x*a==1 mod 2**64 */ +#endif + + /* rho = -1/m mod b */ + *rho = (unsigned long)(((mp_word)1 << ((mp_word) DIGIT_BIT)) - x) & MP_MASK; + + return MP_OKAY; +} +#endif + + +#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C +/* computes xR**-1 == x (mod N) via Montgomery Reduction + * + * This is an optimized implementation of montgomery_reduce + * which uses the comba method to quickly calculate the columns of the + * reduction. + * + * Based on Algorithm 14.32 on pp.601 of HAC. +*/ +int +fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) +{ + int ix, res, olduse; + mp_word W[MP_WARRAY]; + + /* get old used count */ + olduse = x->used; + + /* grow a as required */ + if (x->alloc < n->used + 1) { + if ((res = mp_grow (x, n->used + 1)) != MP_OKAY) { + return res; + } + } + + /* first we have to get the digits of the input into + * an array of double precision words W[...] + */ + { + register mp_word *_W; + register mp_digit *tmpx; + + /* alias for the W[] array */ + _W = W; + + /* alias for the digits of x*/ + tmpx = x->dp; + + /* copy the digits of a into W[0..a->used-1] */ + for (ix = 0; ix < x->used; ix++) { + *_W++ = *tmpx++; + } + + /* zero the high words of W[a->used..m->used*2] */ + for (; ix < n->used * 2 + 1; ix++) { + *_W++ = 0; + } + } + + /* now we proceed to zero successive digits + * from the least significant upwards + */ + for (ix = 0; ix < n->used; ix++) { + /* mu = ai * m' mod b + * + * We avoid a double precision multiplication (which isn't required) + * by casting the value down to a mp_digit. Note this requires + * that W[ix-1] have the carry cleared (see after the inner loop) + */ + register mp_digit mu; + mu = (mp_digit) (((W[ix] & MP_MASK) * rho) & MP_MASK); + + /* a = a + mu * m * b**i + * + * This is computed in place and on the fly. The multiplication + * by b**i is handled by offseting which columns the results + * are added to. + * + * Note the comba method normally doesn't handle carries in the + * inner loop In this case we fix the carry from the previous + * column since the Montgomery reduction requires digits of the + * result (so far) [see above] to work. This is + * handled by fixing up one carry after the inner loop. The + * carry fixups are done in order so after these loops the + * first m->used words of W[] have the carries fixed + */ + { + register int iy; + register mp_digit *tmpn; + register mp_word *_W; + + /* alias for the digits of the modulus */ + tmpn = n->dp; + + /* Alias for the columns set by an offset of ix */ + _W = W + ix; + + /* inner loop */ + for (iy = 0; iy < n->used; iy++) { + *_W++ += ((mp_word)mu) * ((mp_word)*tmpn++); + } + } + + /* now fix carry for next digit, W[ix+1] */ + W[ix + 1] += W[ix] >> ((mp_word) DIGIT_BIT); + } + + /* now we have to propagate the carries and + * shift the words downward [all those least + * significant digits we zeroed]. + */ + { + register mp_digit *tmpx; + register mp_word *_W, *_W1; + + /* nox fix rest of carries */ + + /* alias for current word */ + _W1 = W + ix; + + /* alias for next word, where the carry goes */ + _W = W + ++ix; + + for (; ix <= n->used * 2 + 1; ix++) { + *_W++ += *_W1++ >> ((mp_word) DIGIT_BIT); + } + + /* copy out, A = A/b**n + * + * The result is A/b**n but instead of converting from an + * array of mp_word to mp_digit than calling mp_rshd + * we just copy them in the right order + */ + + /* alias for destination word */ + tmpx = x->dp; + + /* alias for shifted double precision result */ + _W = W + n->used; + + for (ix = 0; ix < n->used + 1; ix++) { + *tmpx++ = (mp_digit)(*_W++ & ((mp_word) MP_MASK)); + } + + /* zero oldused digits, if the input a was larger than + * m->used+1 we'll have to clear the digits + */ + for (; ix < olduse; ix++) { + *tmpx++ = 0; + } + } + + /* set the max used and clamp */ + x->used = n->used + 1; + mp_clamp (x); + + /* if A >= m then A = A - m */ + if (mp_cmp_mag (x, n) != MP_LT) { + return s_mp_sub (x, n, x); + } + return MP_OKAY; +} +#endif + + +#ifdef BN_MP_MUL_2_C +/* b = a*2 */ +static int +mp_mul_2(mp_int * a, mp_int * b) +{ + int x, res, oldused; + + /* grow to accommodate result */ + if (b->alloc < a->used + 1) { + if ((res = mp_grow (b, a->used + 1)) != MP_OKAY) { + return res; + } + } + + oldused = b->used; + b->used = a->used; + + { + register mp_digit r, rr, *tmpa, *tmpb; + + /* alias for source */ + tmpa = a->dp; + + /* alias for dest */ + tmpb = b->dp; + + /* carry */ + r = 0; + for (x = 0; x < a->used; x++) { + + /* get what will be the *next* carry bit from the + * MSB of the current digit + */ + rr = *tmpa >> ((mp_digit)(DIGIT_BIT - 1)); + + /* now shift up this digit, add in the carry [from the previous] */ + *tmpb++ = ((*tmpa++ << ((mp_digit)1)) | r) & MP_MASK; + + /* copy the carry that would be from the source + * digit into the next iteration + */ + r = rr; + } + + /* new leading digit? */ + if (r != 0) { + /* add a MSB which is always 1 at this point */ + *tmpb = 1; + ++(b->used); + } + + /* now zero any excess digits on the destination + * that we didn't write to + */ + tmpb = b->dp + b->used; + for (x = b->used; x < oldused; x++) { + *tmpb++ = 0; + } + } + b->sign = a->sign; + return MP_OKAY; +} +#endif + + +#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C +/* + * shifts with subtractions when the result is greater than b. + * + * The method is slightly modified to shift B unconditionally up to just under + * the leading bit of b. This saves a lot of multiple precision shifting. + */ +static int +mp_montgomery_calc_normalization (mp_int * a, mp_int * b) +{ + int x, bits, res; + + /* how many bits of last digit does b use */ + bits = mp_count_bits (b) % DIGIT_BIT; + + if (b->used > 1) { + if ((res = mp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1)) != MP_OKAY) { + return res; + } + } else { + mp_set(a, 1); + bits = 1; + } + + + /* now compute C = A * B mod b */ + for (x = bits - 1; x < (int)DIGIT_BIT; x++) { + if ((res = mp_mul_2 (a, a)) != MP_OKAY) { + return res; + } + if (mp_cmp_mag (a, b) != MP_LT) { + if ((res = s_mp_sub (a, b, a)) != MP_OKAY) { + return res; + } + } + } + + return MP_OKAY; +} +#endif + + +#ifdef BN_MP_EXPTMOD_FAST_C +/* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85 + * + * Uses a left-to-right k-ary sliding window to compute the modular exponentiation. + * The value of k changes based on the size of the exponent. + * + * Uses Montgomery or Diminished Radix reduction [whichever appropriate] + */ + +static int +mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) +{ + mp_int M[TAB_SIZE], res; + mp_digit buf, mp; + int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; + + /* use a pointer to the reduction algorithm. This allows us to use + * one of many reduction algorithms without modding the guts of + * the code with if statements everywhere. + */ + int (*redux)(mp_int*,mp_int*,mp_digit); + + /* find window size */ + x = mp_count_bits (X); + if (x <= 7) { + winsize = 2; + } else if (x <= 36) { + winsize = 3; + } else if (x <= 140) { + winsize = 4; + } else if (x <= 450) { + winsize = 5; + } else if (x <= 1303) { + winsize = 6; + } else if (x <= 3529) { + winsize = 7; + } else { + winsize = 8; + } + +#ifdef MP_LOW_MEM + if (winsize > 5) { + winsize = 5; + } +#endif + + /* init M array */ + /* init first cell */ + if ((err = mp_init(&M[1])) != MP_OKAY) { + return err; + } + + /* now init the second half of the array */ + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + if ((err = mp_init(&M[x])) != MP_OKAY) { + for (y = 1<<(winsize-1); y < x; y++) { + mp_clear (&M[y]); + } + mp_clear(&M[1]); + return err; + } + } + + /* determine and setup reduction code */ + if (redmode == 0) { +#ifdef BN_MP_MONTGOMERY_SETUP_C + /* now setup montgomery */ + if ((err = mp_montgomery_setup (P, &mp)) != MP_OKAY) { + goto LBL_M; + } +#else + err = MP_VAL; + goto LBL_M; +#endif + + /* automatically pick the comba one if available (saves quite a few calls/ifs) */ +#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C + if (((P->used * 2 + 1) < MP_WARRAY) && + P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { + redux = fast_mp_montgomery_reduce; + } else +#endif + { +#ifdef BN_MP_MONTGOMERY_REDUCE_C + /* use slower baseline Montgomery method */ + redux = mp_montgomery_reduce; +#else + err = MP_VAL; + goto LBL_M; +#endif + } + } else if (redmode == 1) { +#if defined(BN_MP_DR_SETUP_C) && defined(BN_MP_DR_REDUCE_C) + /* setup DR reduction for moduli of the form B**k - b */ + mp_dr_setup(P, &mp); + redux = mp_dr_reduce; +#else + err = MP_VAL; + goto LBL_M; +#endif + } else { +#if defined(BN_MP_REDUCE_2K_SETUP_C) && defined(BN_MP_REDUCE_2K_C) + /* setup DR reduction for moduli of the form 2**k - b */ + if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) { + goto LBL_M; + } + redux = mp_reduce_2k; +#else + err = MP_VAL; + goto LBL_M; +#endif + } + + /* setup result */ + if ((err = mp_init (&res)) != MP_OKAY) { + goto LBL_M; + } + + /* create M table + * + + * + * The first half of the table is not computed though accept for M[0] and M[1] + */ + + if (redmode == 0) { +#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C + /* now we need R mod m */ + if ((err = mp_montgomery_calc_normalization (&res, P)) != MP_OKAY) { + goto LBL_RES; + } +#else + err = MP_VAL; + goto LBL_RES; +#endif + + /* now set M[1] to G * R mod m */ + if ((err = mp_mulmod (G, &res, P, &M[1])) != MP_OKAY) { + goto LBL_RES; + } + } else { + mp_set(&res, 1); + if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) { + goto LBL_RES; + } + } + + /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */ + if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) { + goto LBL_RES; + } + + for (x = 0; x < (winsize - 1); x++) { + if ((err = mp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)])) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&M[1 << (winsize - 1)], P, mp)) != MP_OKAY) { + goto LBL_RES; + } + } + + /* create upper table */ + for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { + if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&M[x], P, mp)) != MP_OKAY) { + goto LBL_RES; + } + } + + /* set initial mode and bit cnt */ + mode = 0; + bitcnt = 1; + buf = 0; + digidx = X->used - 1; + bitcpy = 0; + bitbuf = 0; + + for (;;) { + /* grab next digit as required */ + if (--bitcnt == 0) { + /* if digidx == -1 we are out of digits so break */ + if (digidx == -1) { + break; + } + /* read next digit and reset bitcnt */ + buf = X->dp[digidx--]; + bitcnt = (int)DIGIT_BIT; + } + + /* grab the next msb from the exponent */ + y = (mp_digit)(buf >> (DIGIT_BIT - 1)) & 1; + buf <<= (mp_digit)1; + + /* if the bit is zero and mode == 0 then we ignore it + * These represent the leading zero bits before the first 1 bit + * in the exponent. Technically this opt is not required but it + * does lower the # of trivial squaring/reductions used + */ + if (mode == 0 && y == 0) { + continue; + } + + /* if the bit is zero and mode == 1 then we square */ + if (mode == 1 && y == 0) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + continue; + } + + /* else we add it to the window */ + bitbuf |= (y << (winsize - ++bitcpy)); + mode = 2; + + if (bitcpy == winsize) { + /* ok window is filled so square as required and multiply */ + /* square first */ + for (x = 0; x < winsize; x++) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + } + + /* then multiply */ + if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + + /* empty window and reset */ + bitcpy = 0; + bitbuf = 0; + mode = 1; + } + } + + /* if bits remain then square/multiply */ + if (mode == 2 && bitcpy > 0) { + /* square then multiply if the bit is set */ + for (x = 0; x < bitcpy; x++) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + + /* get next bit of the window */ + bitbuf <<= 1; + if ((bitbuf & (1 << winsize)) != 0) { + /* then multiply */ + if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + } + } + } + + if (redmode == 0) { + /* fixup result if Montgomery reduction is used + * recall that any value in a Montgomery system is + * actually multiplied by R mod n. So we have + * to reduce one more time to cancel out the factor + * of R. + */ + if ((err = redux(&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + } + + /* swap res with Y */ + mp_exch (&res, Y); + err = MP_OKAY; +LBL_RES:mp_clear (&res); +LBL_M: + mp_clear(&M[1]); + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + mp_clear (&M[x]); + } + return err; +} +#endif + + +#ifdef BN_FAST_S_MP_SQR_C +/* the jist of squaring... + * you do like mult except the offset of the tmpx [one that + * starts closer to zero] can't equal the offset of tmpy. + * So basically you set up iy like before then you min it with + * (ty-tx) so that it never happens. You double all those + * you add in the inner loop + +After that loop you do the squares and add them in. +*/ + +static int +fast_s_mp_sqr (mp_int * a, mp_int * b) +{ + int olduse, res, pa, ix, iz; + mp_digit W[MP_WARRAY], *tmpx; + mp_word W1; + + /* grow the destination as required */ + pa = a->used + a->used; + if (b->alloc < pa) { + if ((res = mp_grow (b, pa)) != MP_OKAY) { + return res; + } + } + + /* number of output digits to produce */ + W1 = 0; + for (ix = 0; ix < pa; ix++) { + int tx, ty, iy; + mp_word _W; + mp_digit *tmpy; + + /* clear counter */ + _W = 0; + + /* get offsets into the two bignums */ + ty = MIN(a->used-1, ix); + tx = ix - ty; + + /* setup temp aliases */ + tmpx = a->dp + tx; + tmpy = a->dp + ty; + + /* this is the number of times the loop will iterrate, essentially + while (tx++ < a->used && ty-- >= 0) { ... } + */ + iy = MIN(a->used-tx, ty+1); + + /* now for squaring tx can never equal ty + * we halve the distance since they approach at a rate of 2x + * and we have to round because odd cases need to be executed + */ + iy = MIN(iy, (ty-tx+1)>>1); + + /* execute loop */ + for (iz = 0; iz < iy; iz++) { + _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); + } + + /* double the inner product and add carry */ + _W = _W + _W + W1; + + /* even columns have the square term in them */ + if ((ix&1) == 0) { + _W += ((mp_word)a->dp[ix>>1])*((mp_word)a->dp[ix>>1]); + } + + /* store it */ + W[ix] = (mp_digit)(_W & MP_MASK); + + /* make next carry */ + W1 = _W >> ((mp_word)DIGIT_BIT); + } + + /* setup dest */ + olduse = b->used; + b->used = a->used+a->used; + + { + mp_digit *tmpb; + tmpb = b->dp; + for (ix = 0; ix < pa; ix++) { + *tmpb++ = W[ix] & MP_MASK; + } + + /* clear unused digits [that existed in the old copy of c] */ + for (; ix < olduse; ix++) { + *tmpb++ = 0; + } + } + mp_clamp (b); + return MP_OKAY; +} +#endif + + +#ifdef BN_MP_MUL_D_C +/* multiply by a digit */ +static int +mp_mul_d (mp_int * a, mp_digit b, mp_int * c) +{ + mp_digit u, *tmpa, *tmpc; + mp_word r; + int ix, res, olduse; + + /* make sure c is big enough to hold a*b */ + if (c->alloc < a->used + 1) { + if ((res = mp_grow (c, a->used + 1)) != MP_OKAY) { + return res; + } + } + + /* get the original destinations used count */ + olduse = c->used; + + /* set the sign */ + c->sign = a->sign; + + /* alias for a->dp [source] */ + tmpa = a->dp; + + /* alias for c->dp [dest] */ + tmpc = c->dp; + + /* zero carry */ + u = 0; + + /* compute columns */ + for (ix = 0; ix < a->used; ix++) { + /* compute product and carry sum for this term */ + r = ((mp_word) u) + ((mp_word)*tmpa++) * ((mp_word)b); + + /* mask off higher bits to get a single digit */ + *tmpc++ = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* send carry into next iteration */ + u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); + } + + /* store final carry [if any] and increment ix offset */ + *tmpc++ = u; + ++ix; + + /* now zero digits above the top */ + while (ix++ < olduse) { + *tmpc++ = 0; + } + + /* set used count */ + c->used = a->used + 1; + mp_clamp(c); + + return MP_OKAY; +} +#endif diff --git a/components/wpa_supplicant/src/crypto/md5-internal.c b/components/wpa_supplicant/src/crypto/md5-internal.c new file mode 100644 index 0000000000..a430e297a5 --- /dev/null +++ b/components/wpa_supplicant/src/crypto/md5-internal.c @@ -0,0 +1,298 @@ +/* + * MD5 hash implementation and interface functions + * Copyright (c) 2003-2005, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "crypto/includes.h" + +#include "crypto/common.h" +#include "crypto/md5.h" +#include "crypto/md5_i.h" +#include "crypto/crypto.h" + + +static void MD5Transform(u32 buf[4], u32 const in[16]); + + +typedef struct MD5Context MD5_CTX; + + +/** + * md5_vector - MD5 hash for data vector + * @num_elem: Number of elements in the data vector + * @addr: Pointers to the data areas + * @len: Lengths of the data blocks + * @mac: Buffer for the hash + * Returns: 0 on success, -1 of failure + */ +int +md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) +{ + MD5_CTX ctx; + size_t i; + + MD5Init(&ctx); + for (i = 0; i < num_elem; i++) + MD5Update(&ctx, addr[i], len[i]); + MD5Final(mac, &ctx); + return 0; +} + + +/* ===== start - public domain MD5 implementation ===== */ +/* + * This code implements the MD5 message-digest algorithm. + * The algorithm is due to Ron Rivest. This code was + * written by Colin Plumb in 1993, no copyright is claimed. + * This code is in the public domain; do with it what you wish. + * + * Equivalent code is available from RSA Data Security, Inc. + * This code has been tested against that, and is equivalent, + * except that you don't need to include two pages of legalese + * with every copy. + * + * To compute the message digest of a chunk of bytes, declare an + * MD5Context structure, pass it to MD5Init, call MD5Update as + * needed on buffers full of bytes, and then call MD5Final, which + * will fill a supplied 16-byte array with the digest. + */ + +#ifndef WORDS_BIGENDIAN +#define byteReverse(buf, len) /* Nothing */ +#else +/* + * Note: this code is harmless on little-endian machines. + */ +static void byteReverse(unsigned char *buf, unsigned longs) +{ + u32 t; + do { + t = (u32) ((unsigned) buf[3] << 8 | buf[2]) << 16 | + ((unsigned) buf[1] << 8 | buf[0]); + *(u32 *) buf = t; + buf += 4; + } while (--longs); +} +#endif + +/* + * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious + * initialization constants. + */ +void +MD5Init(struct MD5Context *ctx) +{ + ctx->buf[0] = 0x67452301; + ctx->buf[1] = 0xefcdab89; + ctx->buf[2] = 0x98badcfe; + ctx->buf[3] = 0x10325476; + + ctx->bits[0] = 0; + ctx->bits[1] = 0; +} + +/* + * Update context to reflect the concatenation of another buffer full + * of bytes. + */ +void +MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len) +{ + u32 t; + + /* Update bitcount */ + + t = ctx->bits[0]; + if ((ctx->bits[0] = t + ((u32) len << 3)) < t) + ctx->bits[1]++; /* Carry from low to high */ + ctx->bits[1] += len >> 29; + + t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ + + /* Handle any leading odd-sized chunks */ + + if (t) { + unsigned char *p = (unsigned char *) ctx->in + t; + + t = 64 - t; + if (len < t) { + os_memcpy(p, buf, len); + return; + } + os_memcpy(p, buf, t); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (u32 *) ctx->in); + buf += t; + len -= t; + } + /* Process data in 64-byte chunks */ + + while (len >= 64) { + os_memcpy(ctx->in, buf, 64); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (u32 *) ctx->in); + buf += 64; + len -= 64; + } + + /* Handle any remaining bytes of data. */ + + os_memcpy(ctx->in, buf, len); +} + +/* + * Final wrapup - pad to 64-byte boundary with the bit pattern + * 1 0* (64-bit count of bits processed, MSB-first) + */ +void +MD5Final(unsigned char digest[16], struct MD5Context *ctx) +{ + unsigned count; + unsigned char *p; + + /* Compute number of bytes mod 64 */ + count = (ctx->bits[0] >> 3) & 0x3F; + + /* Set the first char of padding to 0x80. This is safe since there is + always at least one byte free */ + p = ctx->in + count; + *p++ = 0x80; + + /* Bytes of padding needed to make 64 bytes */ + count = 64 - 1 - count; + + /* Pad out to 56 mod 64 */ + if (count < 8) { + /* Two lots of padding: Pad the first block to 64 bytes */ + os_memset(p, 0, count); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (u32 *) ctx->in); + + /* Now fill the next block with 56 bytes */ + os_memset(ctx->in, 0, 56); + } else { + /* Pad block to 56 bytes */ + os_memset(p, 0, count - 8); + } + byteReverse(ctx->in, 14); + + /* Append length in bits and transform */ + ((u32 *) ctx->in)[14] = ctx->bits[0]; + ((u32 *) ctx->in)[15] = ctx->bits[1]; + + MD5Transform(ctx->buf, (u32 *) ctx->in); + byteReverse((unsigned char *) ctx->buf, 4); + os_memcpy(digest, ctx->buf, 16); + os_memset(ctx, 0, sizeof(struct MD5Context)); /* In case it's sensitive */ +} + +/* The four core functions - F1 is optimized somewhat */ + +/* #define F1(x, y, z) (x & y | ~x & z) */ +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +/* This is the central step in the MD5 algorithm. */ +#define MD5STEP(f, w, x, y, z, data, s) \ + ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) + +/* + * The core of the MD5 algorithm, this alters an existing MD5 hash to + * reflect the addition of 16 longwords of new data. MD5Update blocks + * the data and converts bytes into longwords for this routine. + */ +static void +MD5Transform(u32 buf[4], u32 const in[16]) +{ + register u32 a, b, c, d; + + a = buf[0]; + b = buf[1]; + c = buf[2]; + d = buf[3]; + + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; +} +/* ===== end - public domain MD5 implementation ===== */ diff --git a/components/wpa_supplicant/src/crypto/md5.c b/components/wpa_supplicant/src/crypto/md5.c new file mode 100644 index 0000000000..3125c98311 --- /dev/null +++ b/components/wpa_supplicant/src/crypto/md5.c @@ -0,0 +1,113 @@ +/* + * MD5 hash implementation and interface functions + * Copyright (c) 2003-2005, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "crypto/includes.h" + +#include "crypto/common.h" +#include "crypto/md5.h" +#include "crypto/crypto.h" + + +/** + * hmac_md5_vector - HMAC-MD5 over data vector (RFC 2104) + * @key: Key for HMAC operations + * @key_len: Length of the key in bytes + * @num_elem: Number of elements in the data vector + * @addr: Pointers to the data areas + * @len: Lengths of the data blocks + * @mac: Buffer for the hash (16 bytes) + * Returns: 0 on success, -1 on failure + */ +int +hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem, + const u8 *addr[], const size_t *len, u8 *mac) +{ + u8 k_pad[64]; /* padding - key XORd with ipad/opad */ + u8 tk[16]; + const u8 *_addr[6]; + size_t i, _len[6]; + + if (num_elem > 5) { + /* + * Fixed limit on the number of fragments to avoid having to + * allocate memory (which could fail). + */ + return -1; + } + + /* if key is longer than 64 bytes reset it to key = MD5(key) */ + if (key_len > 64) { + if (md5_vector(1, &key, &key_len, tk)) + return -1; + key = tk; + key_len = 16; + } + + /* the HMAC_MD5 transform looks like: + * + * MD5(K XOR opad, MD5(K XOR ipad, text)) + * + * where K is an n byte key + * ipad is the byte 0x36 repeated 64 times + * opad is the byte 0x5c repeated 64 times + * and text is the data being protected */ + + /* start out by storing key in ipad */ + os_memset(k_pad, 0, sizeof(k_pad)); + os_memcpy(k_pad, key, key_len); + + /* XOR key with ipad values */ + for (i = 0; i < 64; i++) + k_pad[i] ^= 0x36; + + /* perform inner MD5 */ + _addr[0] = k_pad; + _len[0] = 64; + for (i = 0; i < num_elem; i++) { + _addr[i + 1] = addr[i]; + _len[i + 1] = len[i]; + } + if (md5_vector(1 + num_elem, _addr, _len, mac)) + return -1; + + os_memset(k_pad, 0, sizeof(k_pad)); + os_memcpy(k_pad, key, key_len); + /* XOR key with opad values */ + for (i = 0; i < 64; i++) + k_pad[i] ^= 0x5c; + + /* perform outer MD5 */ + _addr[0] = k_pad; + _len[0] = 64; + _addr[1] = mac; + _len[1] = MD5_MAC_LEN; + return md5_vector(2, _addr, _len, mac); +} + + +/** + * hmac_md5 - HMAC-MD5 over data buffer (RFC 2104) + * @key: Key for HMAC operations + * @key_len: Length of the key in bytes + * @data: Pointers to the data area + * @data_len: Length of the data area + * @mac: Buffer for the hash (16 bytes) + * Returns: 0 on success, -1 on failure + */ +int +hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len, + u8 *mac) +{ + return hmac_md5_vector(key, key_len, 1, &data, &data_len, mac); +} diff --git a/components/wpa_supplicant/src/crypto/rc4.c b/components/wpa_supplicant/src/crypto/rc4.c new file mode 100644 index 0000000000..678632297f --- /dev/null +++ b/components/wpa_supplicant/src/crypto/rc4.c @@ -0,0 +1,61 @@ +/* + * RC4 stream cipher + * Copyright (c) 2002-2005, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "crypto/includes.h" + +#include "crypto/common.h" +#include "crypto/crypto.h" + +#define S_SWAP(a,b) do { u8 t = S[a]; S[a] = S[b]; S[b] = t; } while(0) + +int +rc4_skip(const u8 *key, size_t keylen, size_t skip, + u8 *data, size_t data_len) +{ + u32 i, j, k; + u8 S[256], *pos; + size_t kpos; + + /* Setup RC4 state */ + for (i = 0; i < 256; i++) + S[i] = i; + j = 0; + kpos = 0; + for (i = 0; i < 256; i++) { + j = (j + S[i] + key[kpos]) & 0xff; + kpos++; + if (kpos >= keylen) + kpos = 0; + S_SWAP(i, j); + } + + /* Skip the start of the stream */ + i = j = 0; + for (k = 0; k < skip; k++) { + i = (i + 1) & 0xff; + j = (j + S[i]) & 0xff; + S_SWAP(i, j); + } + + /* Apply RC4 to data */ + pos = data; + for (k = 0; k < data_len; k++) { + i = (i + 1) & 0xff; + j = (j + S[i]) & 0xff; + S_SWAP(i, j); + *pos++ ^= S[(S[i] + S[j]) & 0xff]; + } + + return 0; +} diff --git a/components/wpa_supplicant/src/crypto/sha1-internal.c b/components/wpa_supplicant/src/crypto/sha1-internal.c new file mode 100644 index 0000000000..a1c255e416 --- /dev/null +++ b/components/wpa_supplicant/src/crypto/sha1-internal.c @@ -0,0 +1,313 @@ +/* + * SHA1 hash implementation and interface functions + * Copyright (c) 2003-2005, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "crypto/includes.h" + +#include "crypto/common.h" +#include "crypto/sha1.h" +#include "crypto/sha1_i.h" +#include "crypto/md5.h" +#include "crypto/crypto.h" + +typedef struct SHA1Context SHA1_CTX; + +void SHA1Transform(u32 state[5], const unsigned char buffer[64]); + + +/** + * sha1_vector - SHA-1 hash for data vector + * @num_elem: Number of elements in the data vector + * @addr: Pointers to the data areas + * @len: Lengths of the data blocks + * @mac: Buffer for the hash + * Returns: 0 on success, -1 of failure + */ +int +sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) +{ + SHA1_CTX ctx; + size_t i; + + SHA1Init(&ctx); + for (i = 0; i < num_elem; i++) + SHA1Update(&ctx, addr[i], len[i]); + SHA1Final(mac, &ctx); + return 0; +} + + +/* ===== start - public domain SHA1 implementation ===== */ + +/* +SHA-1 in C +By Steve Reid +100% Public Domain + +----------------- +Modified 7/98 +By James H. Brown +Still 100% Public Domain + +Corrected a problem which generated improper hash values on 16 bit machines +Routine SHA1Update changed from + void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int +len) +to + void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned +long len) + +The 'len' parameter was declared an int which works fine on 32 bit machines. +However, on 16 bit machines an int is too small for the shifts being done +against +it. This caused the hash function to generate incorrect values if len was +greater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update(). + +Since the file IO in main() reads 16K at a time, any file 8K or larger would +be guaranteed to generate the wrong hash (e.g. Test Vector #3, a million +"a"s). + +I also changed the declaration of variables i & j in SHA1Update to +unsigned long from unsigned int for the same reason. + +These changes should make no difference to any 32 bit implementations since +an +int and a long are the same size in those environments. + +-- +I also corrected a few compiler warnings generated by Borland C. +1. Added #include for exit() prototype +2. Removed unused variable 'j' in SHA1Final +3. Changed exit(0) to return(0) at end of main. + +ALL changes I made can be located by searching for comments containing 'JHB' +----------------- +Modified 8/98 +By Steve Reid +Still 100% public domain + +1- Removed #include and used return() instead of exit() +2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall) +3- Changed email address from steve@edmweb.com to sreid@sea-to-sky.net + +----------------- +Modified 4/01 +By Saul Kravitz +Still 100% PD +Modified to run on Compaq Alpha hardware. + +----------------- +Modified 4/01 +By Jouni Malinen +Minor changes to match the coding style used in Dynamics. + +Modified September 24, 2004 +By Jouni Malinen +Fixed alignment issue in SHA1Transform when SHA1HANDSOFF is defined. + +*/ + +/* +Test Vectors (from FIPS PUB 180-1) +"abc" + A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D +"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" + 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 +A million repetitions of "a" + 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F +*/ + +#define SHA1HANDSOFF + +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) + +/* blk0() and blk() perform the initial expand. */ +/* I got the idea of expanding during the round function from SSLeay */ +#ifndef WORDS_BIGENDIAN +#define blk0(i) (block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) | \ + (rol(block->l[i], 8) & 0x00FF00FF)) +#else +#define blk0(i) block->l[i] +#endif +#define blk(i) (block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ \ + block->l[(i + 8) & 15] ^ block->l[(i + 2) & 15] ^ block->l[i & 15], 1)) + +/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ +#define R0(v,w,x,y,z,i) \ + z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); \ + w = rol(w, 30); +#define R1(v,w,x,y,z,i) \ + z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \ + w = rol(w, 30); +#define R2(v,w,x,y,z,i) \ + z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); w = rol(w, 30); +#define R3(v,w,x,y,z,i) \ + z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \ + w = rol(w, 30); +#define R4(v,w,x,y,z,i) \ + z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \ + w=rol(w, 30); + + +#ifdef VERBOSE /* SAK */ +void SHAPrintContext(SHA1_CTX *context, char *msg) +{ + printf("%s (%d,%d) %x %x %x %x %x\n", + msg, + context->count[0], context->count[1], + context->state[0], + context->state[1], + context->state[2], + context->state[3], + context->state[4]); +} +#endif + +/* Hash a single 512-bit block. This is the core of the algorithm. */ + +void +SHA1Transform(u32 state[5], const unsigned char buffer[64]) +{ + u32 a, b, c, d, e; + typedef union { + unsigned char c[64]; + u32 l[16]; + } CHAR64LONG16; + CHAR64LONG16* block; +#ifdef SHA1HANDSOFF + CHAR64LONG16 workspace; + block = &workspace; + os_memcpy(block, buffer, 64); +#else + block = (CHAR64LONG16 *) buffer; +#endif + /* Copy context->state[] to working vars */ + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + /* 4 rounds of 20 operations each. Loop unrolled. */ + R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); + R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); + R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); + R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); + R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); + R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); + R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); + R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); + R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); + R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); + R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); + R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); + R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); + R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); + R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); + R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); + R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); + R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); + R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); + R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); + /* Add the working vars back into context.state[] */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + /* Wipe variables */ + a = b = c = d = e = 0; +#ifdef SHA1HANDSOFF + os_memset(block, 0, 64); +#endif +} + + +/* SHA1Init - Initialize new context */ + +void +SHA1Init(SHA1_CTX* context) +{ + /* SHA1 initialization constants */ + context->state[0] = 0x67452301; + context->state[1] = 0xEFCDAB89; + context->state[2] = 0x98BADCFE; + context->state[3] = 0x10325476; + context->state[4] = 0xC3D2E1F0; + context->count[0] = context->count[1] = 0; +} + + +/* Run your data through this. */ + +void +SHA1Update(SHA1_CTX* context, const void *_data, u32 len) +{ + u32 i, j; + const unsigned char *data = _data; + +#ifdef VERBOSE + SHAPrintContext(context, "before"); +#endif + j = (context->count[0] >> 3) & 63; + if ((context->count[0] += len << 3) < (len << 3)) + context->count[1]++; + context->count[1] += (len >> 29); + if ((j + len) > 63) { + os_memcpy(&context->buffer[j], data, (i = 64-j)); + SHA1Transform(context->state, context->buffer); + for ( ; i + 63 < len; i += 64) { + SHA1Transform(context->state, &data[i]); + } + j = 0; + } + else i = 0; + os_memcpy(&context->buffer[j], &data[i], len - i); +#ifdef VERBOSE + SHAPrintContext(context, "after "); +#endif +} + + +/* Add padding and return the message digest. */ + +void +SHA1Final(unsigned char digest[20], SHA1_CTX* context) +{ + u32 i; + unsigned char finalcount[8]; + + for (i = 0; i < 8; i++) { + finalcount[i] = (unsigned char) + ((context->count[(i >= 4 ? 0 : 1)] >> + ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ + } + SHA1Update(context, (unsigned char *) "\200", 1); + while ((context->count[0] & 504) != 448) { + SHA1Update(context, (unsigned char *) "\0", 1); + } + SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() + */ + for (i = 0; i < 20; i++) { + digest[i] = (unsigned char) + ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & + 255); + } + /* Wipe variables */ + i = 0; + os_memset(context->buffer, 0, 64); + os_memset(context->state, 0, 20); + os_memset(context->count, 0, 8); + os_memset(finalcount, 0, 8); +} + +/* ===== end - public domain SHA1 implementation ===== */ diff --git a/components/wpa_supplicant/src/crypto/sha1-pbkdf2.c b/components/wpa_supplicant/src/crypto/sha1-pbkdf2.c new file mode 100644 index 0000000000..915a23aa78 --- /dev/null +++ b/components/wpa_supplicant/src/crypto/sha1-pbkdf2.c @@ -0,0 +1,101 @@ +/* + * SHA1-based key derivation function (PBKDF2) for IEEE 802.11i + * Copyright (c) 2003-2005, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "crypto/includes.h" +#include "crypto/common.h" +#include "crypto/sha1.h" +#include "crypto/md5.h" +#include "crypto/crypto.h" + +static int +pbkdf2_sha1_f(const char *passphrase, const char *ssid, + size_t ssid_len, int iterations, unsigned int count, + u8 *digest) +{ + unsigned char tmp[SHA1_MAC_LEN], tmp2[SHA1_MAC_LEN]; + int i, j; + unsigned char count_buf[4]; + const u8 *addr[2]; + size_t len[2]; + size_t passphrase_len = os_strlen(passphrase); + + addr[0] = (u8 *) ssid; + len[0] = ssid_len; + addr[1] = count_buf; + len[1] = 4; + + /* F(P, S, c, i) = U1 xor U2 xor ... Uc + * U1 = PRF(P, S || i) + * U2 = PRF(P, U1) + * Uc = PRF(P, Uc-1) + */ + + count_buf[0] = (count >> 24) & 0xff; + count_buf[1] = (count >> 16) & 0xff; + count_buf[2] = (count >> 8) & 0xff; + count_buf[3] = count & 0xff; + if (hmac_sha1_vector((u8 *) passphrase, passphrase_len, 2, addr, len, + tmp)) + return -1; + os_memcpy(digest, tmp, SHA1_MAC_LEN); + + for (i = 1; i < iterations; i++) { + if (hmac_sha1((u8 *) passphrase, passphrase_len, tmp, + SHA1_MAC_LEN, tmp2)) + return -1; + os_memcpy(tmp, tmp2, SHA1_MAC_LEN); + for (j = 0; j < SHA1_MAC_LEN; j++) + digest[j] ^= tmp2[j]; + } + + return 0; +} + + +/** + * pbkdf2_sha1 - SHA1-based key derivation function (PBKDF2) for IEEE 802.11i + * @passphrase: ASCII passphrase + * @ssid: SSID + * @ssid_len: SSID length in bytes + * @iterations: Number of iterations to run + * @buf: Buffer for the generated key + * @buflen: Length of the buffer in bytes + * Returns: 0 on success, -1 of failure + * + * This function is used to derive PSK for WPA-PSK. For this protocol, + * iterations is set to 4096 and buflen to 32. This function is described in + * IEEE Std 802.11-2004, Clause H.4. The main construction is from PKCS#5 v2.0. + */ +int +pbkdf2_sha1(const char *passphrase, const char *ssid, size_t ssid_len, + int iterations, u8 *buf, size_t buflen) +{ + unsigned int count = 0; + unsigned char *pos = buf; + size_t left = buflen, plen; + unsigned char digest[SHA1_MAC_LEN]; + + while (left > 0) { + count++; + if (pbkdf2_sha1_f(passphrase, ssid, ssid_len, iterations, + count, digest)) + return -1; + plen = left > SHA1_MAC_LEN ? SHA1_MAC_LEN : left; + os_memcpy(pos, digest, plen); + pos += plen; + left -= plen; + } + + return 0; +} diff --git a/components/wpa_supplicant/src/crypto/sha1.c b/components/wpa_supplicant/src/crypto/sha1.c new file mode 100644 index 0000000000..3d6da417ac --- /dev/null +++ b/components/wpa_supplicant/src/crypto/sha1.c @@ -0,0 +1,166 @@ +/* + * SHA1 hash implementation and interface functions + * Copyright (c) 2003-2005, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "crypto/includes.h" + +#include "crypto/common.h" +#include "crypto/sha1.h" +#include "crypto/crypto.h" + + +/** + * hmac_sha1_vector - HMAC-SHA1 over data vector (RFC 2104) + * @key: Key for HMAC operations + * @key_len: Length of the key in bytes + * @num_elem: Number of elements in the data vector + * @addr: Pointers to the data areas + * @len: Lengths of the data blocks + * @mac: Buffer for the hash (20 bytes) + * Returns: 0 on success, -1 on failure + */ +int +hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem, + const u8 *addr[], const size_t *len, u8 *mac) +{ + unsigned char k_pad[64]; /* padding - key XORd with ipad/opad */ + unsigned char tk[20]; + const u8 *_addr[6]; + size_t _len[6], i; + + if (num_elem > 5) { + /* + * Fixed limit on the number of fragments to avoid having to + * allocate memory (which could fail). + */ + return -1; + } + + /* if key is longer than 64 bytes reset it to key = SHA1(key) */ + if (key_len > 64) { + if (sha1_vector(1, &key, &key_len, tk)) + return -1; + key = tk; + key_len = 20; + } + + /* the HMAC_SHA1 transform looks like: + * + * SHA1(K XOR opad, SHA1(K XOR ipad, text)) + * + * where K is an n byte key + * ipad is the byte 0x36 repeated 64 times + * opad is the byte 0x5c repeated 64 times + * and text is the data being protected */ + + /* start out by storing key in ipad */ + os_memset(k_pad, 0, sizeof(k_pad)); + os_memcpy(k_pad, key, key_len); + /* XOR key with ipad values */ + for (i = 0; i < 64; i++) + k_pad[i] ^= 0x36; + + /* perform inner SHA1 */ + _addr[0] = k_pad; + _len[0] = 64; + for (i = 0; i < num_elem; i++) { + _addr[i + 1] = addr[i]; + _len[i + 1] = len[i]; + } + if (sha1_vector(1 + num_elem, _addr, _len, mac)) + return -1; + + os_memset(k_pad, 0, sizeof(k_pad)); + os_memcpy(k_pad, key, key_len); + /* XOR key with opad values */ + for (i = 0; i < 64; i++) + k_pad[i] ^= 0x5c; + + /* perform outer SHA1 */ + _addr[0] = k_pad; + _len[0] = 64; + _addr[1] = mac; + _len[1] = SHA1_MAC_LEN; + return sha1_vector(2, _addr, _len, mac); +} + + +/** + * hmac_sha1 - HMAC-SHA1 over data buffer (RFC 2104) + * @key: Key for HMAC operations + * @key_len: Length of the key in bytes + * @data: Pointers to the data area + * @data_len: Length of the data area + * @mac: Buffer for the hash (20 bytes) + * Returns: 0 on success, -1 of failure + */ +int +hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len, + u8 *mac) +{ + return hmac_sha1_vector(key, key_len, 1, &data, &data_len, mac); +} + +/** + * sha1_prf - SHA1-based Pseudo-Random Function (PRF) (IEEE 802.11i, 8.5.1.1) + * @key: Key for PRF + * @key_len: Length of the key in bytes + * @label: A unique label for each purpose of the PRF + * @data: Extra data to bind into the key + * @data_len: Length of the data + * @buf: Buffer for the generated pseudo-random key + * @buf_len: Number of bytes of key to generate + * Returns: 0 on success, -1 of failure + * + * This function is used to derive new, cryptographically separate keys from a + * given key (e.g., PMK in IEEE 802.11i). + */ +int +sha1_prf(const u8 *key, size_t key_len, const char *label, + const u8 *data, size_t data_len, u8 *buf, size_t buf_len) +{ + u8 counter = 0; + size_t pos, plen; + u8 hash[SHA1_MAC_LEN]; + size_t label_len = os_strlen(label) + 1; + const unsigned char *addr[3]; + size_t len[3]; + + addr[0] = (u8 *) label; + len[0] = label_len; + addr[1] = data; + len[1] = data_len; + addr[2] = &counter; + len[2] = 1; + + pos = 0; + while (pos < buf_len) { + plen = buf_len - pos; + if (plen >= SHA1_MAC_LEN) { + if (hmac_sha1_vector(key, key_len, 3, addr, len, + &buf[pos])) + return -1; + pos += SHA1_MAC_LEN; + } else { + if (hmac_sha1_vector(key, key_len, 3, addr, len, + hash)) + return -1; + os_memcpy(&buf[pos], hash, plen); + break; + } + counter++; + } + + return 0; +} + diff --git a/components/wpa_supplicant/src/crypto/sha256-internal.c b/components/wpa_supplicant/src/crypto/sha256-internal.c new file mode 100644 index 0000000000..9a1fca1c17 --- /dev/null +++ b/components/wpa_supplicant/src/crypto/sha256-internal.c @@ -0,0 +1,249 @@ +/* + * SHA-256 hash implementation and interface functions + * Copyright (c) 2003-2011, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "crypto/includes.h" + +#include "crypto/common.h" +#include "crypto/sha256.h" +#include "crypto/crypto.h" + +#define SHA256_BLOCK_SIZE 64 + +struct sha256_state { + u64 length; + u32 state[8], curlen; + u8 buf[SHA256_BLOCK_SIZE]; +}; + +static void sha256_init(struct sha256_state *md); +static int sha256_process(struct sha256_state *md, const unsigned char *in, + unsigned long inlen); +static int sha256_done(struct sha256_state *md, unsigned char *out); + + +/** + * sha256_vector - SHA256 hash for data vector + * @num_elem: Number of elements in the data vector + * @addr: Pointers to the data areas + * @len: Lengths of the data blocks + * @mac: Buffer for the hash + * Returns: 0 on success, -1 of failure + */ +int +sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, + u8 *mac) +{ + struct sha256_state ctx; + size_t i; + + sha256_init(&ctx); + for (i = 0; i < num_elem; i++) + if (sha256_process(&ctx, addr[i], len[i])) + return -1; + if (sha256_done(&ctx, mac)) + return -1; + return 0; +} + + +/* ===== start - public domain SHA256 implementation ===== */ + +/* This is based on SHA256 implementation in LibTomCrypt that was released into + * public domain by Tom St Denis. */ + +/* the K array */ +static const unsigned long K[64] = { + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, + 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, + 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, + 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, + 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL, + 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, + 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, + 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, + 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL, + 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, + 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL +}; + + +/* Various logical functions */ +#define RORc(x, y) \ +( ((((unsigned long) (x) & 0xFFFFFFFFUL) >> (unsigned long) ((y) & 31)) | \ + ((unsigned long) (x) << (unsigned long) (32 - ((y) & 31)))) & 0xFFFFFFFFUL) +#define Ch(x,y,z) (z ^ (x & (y ^ z))) +#define Maj(x,y,z) (((x | y) & z) | (x & y)) +#define S(x, n) RORc((x), (n)) +#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n)) +#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22)) +#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25)) +#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3)) +#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10)) +#ifndef MIN +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) +#endif + +/* compress 512-bits */ +static int +sha256_compress(struct sha256_state *md, unsigned char *buf) +{ + u32 S[8], W[64], t0, t1; + u32 t; + int i; + + /* copy state into S */ + for (i = 0; i < 8; i++) { + S[i] = md->state[i]; + } + + /* copy the state into 512-bits into W[0..15] */ + for (i = 0; i < 16; i++) + W[i] = WPA_GET_BE32(buf + (4 * i)); + + /* fill W[16..63] */ + for (i = 16; i < 64; i++) { + W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + + W[i - 16]; + } + + /* Compress */ +#define RND(a,b,c,d,e,f,g,h,i) \ + t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ + t1 = Sigma0(a) + Maj(a, b, c); \ + d += t0; \ + h = t0 + t1; + + for (i = 0; i < 64; ++i) { + RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i); + t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4]; + S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t; + } + + /* feedback */ + for (i = 0; i < 8; i++) { + md->state[i] = md->state[i] + S[i]; + } + return 0; +} + + +/* Initialize the hash state */ +static void +sha256_init(struct sha256_state *md) +{ + md->curlen = 0; + md->length = 0; + md->state[0] = 0x6A09E667UL; + md->state[1] = 0xBB67AE85UL; + md->state[2] = 0x3C6EF372UL; + md->state[3] = 0xA54FF53AUL; + md->state[4] = 0x510E527FUL; + md->state[5] = 0x9B05688CUL; + md->state[6] = 0x1F83D9ABUL; + md->state[7] = 0x5BE0CD19UL; +} + +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful +*/ +static int +sha256_process(struct sha256_state *md, const unsigned char *in, + unsigned long inlen) +{ + unsigned long n; + + if (md->curlen >= sizeof(md->buf)) + return -1; + + while (inlen > 0) { + if (md->curlen == 0 && inlen >= SHA256_BLOCK_SIZE) { + if (sha256_compress(md, (unsigned char *) in) < 0) + return -1; + md->length += SHA256_BLOCK_SIZE * 8; + in += SHA256_BLOCK_SIZE; + inlen -= SHA256_BLOCK_SIZE; + } else { + n = MIN(inlen, (SHA256_BLOCK_SIZE - md->curlen)); + os_memcpy(md->buf + md->curlen, in, n); + md->curlen += n; + in += n; + inlen -= n; + if (md->curlen == SHA256_BLOCK_SIZE) { + if (sha256_compress(md, md->buf) < 0) + return -1; + md->length += 8 * SHA256_BLOCK_SIZE; + md->curlen = 0; + } + } + } + + return 0; +} + + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (32 bytes) + @return CRYPT_OK if successful +*/ +static int +sha256_done(struct sha256_state *md, unsigned char *out) +{ + int i; + + if (md->curlen >= sizeof(md->buf)) + return -1; + + /* increase the length of the message */ + md->length += md->curlen * 8; + + /* append the '1' bit */ + md->buf[md->curlen++] = (unsigned char) 0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->curlen > 56) { + while (md->curlen < SHA256_BLOCK_SIZE) { + md->buf[md->curlen++] = (unsigned char) 0; + } + sha256_compress(md, md->buf); + md->curlen = 0; + } + + /* pad up to 56 bytes of zeroes */ + while (md->curlen < 56) { + md->buf[md->curlen++] = (unsigned char) 0; + } + + /* store length */ + WPA_PUT_BE64(md->buf + 56, md->length); + sha256_compress(md, md->buf); + + /* copy output */ + for (i = 0; i < 8; i++) + WPA_PUT_BE32(out + (4 * i), md->state[i]); + + return 0; +} + +/* ===== end - public domain SHA256 implementation ===== */ diff --git a/components/wpa_supplicant/src/crypto/sha256.c b/components/wpa_supplicant/src/crypto/sha256.c new file mode 100644 index 0000000000..f62cc11827 --- /dev/null +++ b/components/wpa_supplicant/src/crypto/sha256.c @@ -0,0 +1,160 @@ +/* + * SHA-256 hash implementation and interface functions + * Copyright (c) 2003-2007, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "crypto/includes.h" + +#include "crypto/common.h" +#include "crypto/sha256.h" +#include "crypto/crypto.h" + + +/** + * hmac_sha256_vector - HMAC-SHA256 over data vector (RFC 2104) + * @key: Key for HMAC operations + * @key_len: Length of the key in bytes + * @num_elem: Number of elements in the data vector + * @addr: Pointers to the data areas + * @len: Lengths of the data blocks + * @mac: Buffer for the hash (32 bytes) + */ +void +hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem, + const u8 *addr[], const size_t *len, u8 *mac) +{ + unsigned char k_pad[64]; /* padding - key XORd with ipad/opad */ + unsigned char tk[32]; + const u8 *_addr[6]; + size_t _len[6], i; + + if (num_elem > 5) { + /* + * Fixed limit on the number of fragments to avoid having to + * allocate memory (which could fail). + */ + return; + } + + /* if key is longer than 64 bytes reset it to key = SHA256(key) */ + if (key_len > 64) { + sha256_vector(1, &key, &key_len, tk); + key = tk; + key_len = 32; + } + + /* the HMAC_SHA256 transform looks like: + * + * SHA256(K XOR opad, SHA256(K XOR ipad, text)) + * + * where K is an n byte key + * ipad is the byte 0x36 repeated 64 times + * opad is the byte 0x5c repeated 64 times + * and text is the data being protected */ + + /* start out by storing key in ipad */ + os_memset(k_pad, 0, sizeof(k_pad)); + os_memcpy(k_pad, key, key_len); + /* XOR key with ipad values */ + for (i = 0; i < 64; i++) + k_pad[i] ^= 0x36; + + /* perform inner SHA256 */ + _addr[0] = k_pad; + _len[0] = 64; + for (i = 0; i < num_elem; i++) { + _addr[i + 1] = addr[i]; + _len[i + 1] = len[i]; + } + sha256_vector(1 + num_elem, _addr, _len, mac); + + os_memset(k_pad, 0, sizeof(k_pad)); + os_memcpy(k_pad, key, key_len); + /* XOR key with opad values */ + for (i = 0; i < 64; i++) + k_pad[i] ^= 0x5c; + + /* perform outer SHA256 */ + _addr[0] = k_pad; + _len[0] = 64; + _addr[1] = mac; + _len[1] = SHA256_MAC_LEN; + sha256_vector(2, _addr, _len, mac); +} + + +/** + * hmac_sha256 - HMAC-SHA256 over data buffer (RFC 2104) + * @key: Key for HMAC operations + * @key_len: Length of the key in bytes + * @data: Pointers to the data area + * @data_len: Length of the data area + * @mac: Buffer for the hash (20 bytes) + */ +void +hmac_sha256(const u8 *key, size_t key_len, const u8 *data, + size_t data_len, u8 *mac) +{ + hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac); +} + + +/** + * sha256_prf - SHA256-based Pseudo-Random Function (IEEE 802.11r, 8.5.1.5.2) + * @key: Key for PRF + * @key_len: Length of the key in bytes + * @label: A unique label for each purpose of the PRF + * @data: Extra data to bind into the key + * @data_len: Length of the data + * @buf: Buffer for the generated pseudo-random key + * @buf_len: Number of bytes of key to generate + * + * This function is used to derive new, cryptographically separate keys from a + * given key. + */ +void +sha256_prf(const u8 *key, size_t key_len, const char *label, + const u8 *data, size_t data_len, u8 *buf, size_t buf_len) +{ + u16 counter = 1; + size_t pos, plen; + u8 hash[SHA256_MAC_LEN]; + const u8 *addr[4]; + size_t len[4]; + u8 counter_le[2], length_le[2]; + + addr[0] = counter_le; + len[0] = 2; + addr[1] = (u8 *) label; + len[1] = os_strlen(label); + addr[2] = data; + len[2] = data_len; + addr[3] = length_le; + len[3] = sizeof(length_le); + + WPA_PUT_LE16(length_le, buf_len * 8); + pos = 0; + while (pos < buf_len) { + plen = buf_len - pos; + WPA_PUT_LE16(counter_le, counter); + if (plen >= SHA256_MAC_LEN) { + hmac_sha256_vector(key, key_len, 4, addr, len, + &buf[pos]); + pos += SHA256_MAC_LEN; + } else { + hmac_sha256_vector(key, key_len, 4, addr, len, hash); + os_memcpy(&buf[pos], hash, plen); + break; + } + counter++; + } +} From 8089afd45315cc8e114668d4132ca6a532972dcb Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 4 Nov 2016 15:52:45 +0800 Subject: [PATCH 264/343] build fix --- components/wpa_supplicant/component.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/wpa_supplicant/component.mk b/components/wpa_supplicant/component.mk index 6e5d7e0600..cb6b06652f 100644 --- a/components/wpa_supplicant/component.mk +++ b/components/wpa_supplicant/component.mk @@ -1,6 +1,6 @@ COMPONENT_ADD_INCLUDEDIRS := include port/include COMPONENT_SRCDIRS := src/crypto -CFLAGS += -DEMBEDDED_SUPP -D__ets__ +CFLAGS += -DEMBEDDED_SUPP -D__ets__ -Wno-strict-aliasing include $(IDF_PATH)/make/component_common.mk From b981b195bebce18a197a79d559b1cdad43b21bfb Mon Sep 17 00:00:00 2001 From: Krzysztof Date: Sat, 5 Nov 2016 17:04:35 +0100 Subject: [PATCH 265/343] Fixed broken links --- CONTRIBUTING.rst | 3 ++- docs/contributor-agreement.rst | 2 +- examples/README.md | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 3bf43f6dbe..968826790a 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -39,6 +39,7 @@ If this process passes, it will be merged onto the public github repository. Legal Part ---------- -Before a contribution can be accepted, you will need to sign our `Contributor Agreement `_. You will be prompted for this automatically as part of the Pull Request process. +Before a contribution can be accepted, you will need to sign our :doc:`contributor-agreement`. You will be prompted for this automatically as part of the Pull Request process. + diff --git a/docs/contributor-agreement.rst b/docs/contributor-agreement.rst index de294740c4..a7919da8f8 100644 --- a/docs/contributor-agreement.rst +++ b/docs/contributor-agreement.rst @@ -13,7 +13,7 @@ Framework (esp-idf) ("We" or "Us"). The purpose of this contributor agreement ("Agreement") is to clarify and document the rights granted by contributors to Us. To make this document effective, please follow the instructions at -https://github.com/espressif/esp-idf/blob/master/CONTRIBUTING.md. +https://github.com/espressif/esp-idf/blob/master/CONTRIBUTING.rst. 1. DEFINITIONS ~~~~~~~~~~~~~~ diff --git a/examples/README.md b/examples/README.md index 2cf66b9d07..e4422e91bf 100644 --- a/examples/README.md +++ b/examples/README.md @@ -26,7 +26,7 @@ If you're looking for a more bare-bones project to start from, try [esp-idf-temp If you have a new example you think we'd like, please consider sending it to us as a Pull Request. -Please read the esp-idf CONTRIBUTING.md file which lays out general contribution rules. +Please read the esp-idf CONTRIBUTING.rst file which lays out general contribution rules. In addition, here are some tips for creating good examples: From 9c2ab4559dea66f3df1eff976cf28d06ba75b602 Mon Sep 17 00:00:00 2001 From: Krzysztof Date: Sat, 5 Nov 2016 17:06:55 +0100 Subject: [PATCH 266/343] Fixed section header style Please follow https://docs.python.org/devguide/documenting.html#sections --- docs/deep-sleep-stub.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/deep-sleep-stub.rst b/docs/deep-sleep-stub.rst index 983f8bbf26..7711b1ce23 100644 --- a/docs/deep-sleep-stub.rst +++ b/docs/deep-sleep-stub.rst @@ -1,12 +1,12 @@ Deep Sleep Wake Stubs ---------------------- +===================== ESP32 supports running a "deep sleep wake stub" when coming out of deep sleep. This function runs immediately as soon as the chip wakes up - before any normal initialisation, bootloader, or ESP-IDF code has run. After the wake stub runs, the SoC can go back to sleep or continue to start ESP-IDF normally. Deep sleep wake stub code is loaded into "RTC Fast Memory" and any data which it uses must also be loaded into RTC memory. RTC memory regions hold their contents during deep sleep. Rules for Wake Stubs -==================== +-------------------- Wake stub code must be carefully written: @@ -23,9 +23,9 @@ Wake stub code must be carefully written: * Wake stub code is a part of the main esp-idf app. During normal running of esp-idf, functions can call the wake stub functions or access RTC memory. It is as if these were regular parts of the app. Implementing A Stub -=================== +------------------- -The wake stub in esp-idf is called ``esp_wake_deep_sleep()``. This function runs whenever the SoC wakes from deep sleep. There is a default version of this function provided in esp-idf, but the default function is weak-linked so if your app contains a function named ``esp_wake_deep_sleep()` then this will override the default. +The wake stub in esp-idf is called ``esp_wake_deep_sleep()``. This function runs whenever the SoC wakes from deep sleep. There is a default version of this function provided in esp-idf, but the default function is weak-linked so if your app contains a function named ``esp_wake_deep_sleep()`` then this will override the default. If supplying a custom wake stub, the first thing it does should be to call ``esp_default_wake_deep_sleep()``. @@ -36,7 +36,7 @@ If you want to swap between different deep sleep stubs at runtime, it is also po All of these functions are declared in the ``esp_deepsleep.h`` header under components/esp32. Loading Code Into RTC Memory -============================ +---------------------------- Wake stub code must be resident in RTC Fast Memory. This can be done in one of two ways. @@ -53,7 +53,7 @@ The first way is simpler for very short and simple code, or for source files whe Loading Data Into RTC Memory -============================ +---------------------------- Data used by stub code must be resident in RTC Slow Memory. This memory is also used by the ULP. From adca98348ea3ffb110764e5fc1801ace643ce700 Mon Sep 17 00:00:00 2001 From: Krzysztof Date: Sat, 5 Nov 2016 17:11:40 +0100 Subject: [PATCH 267/343] Resolved issue with version / release on Read the Docs Read the Docs is building documentation referencing to specific releases on GitHub. Changing version / release in this script is breaking menu in bottom left corner Now version / release should change only for local builds and not for builds on Read the Docs --- docs/conf.py | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 8a4a275c8a..494ab3cf7f 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -75,13 +75,23 @@ copyright = u'2016, Espressif' # |version| and |release|, also used in various other places throughout the # built documents. # -# This is supposed to be "the short X.Y version", but it's the only version -# visible when you open index.html. -# Display full version to make things less confusing. -# If needed, nearest tag is returned by 'git describe --abbrev=0'. -version = run_cmd_get_output('git describe') -# The full version, including alpha/beta/rc tags. -release = run_cmd_get_output('git describe') + +# Different setup depending if script is running on ReadTheDocs or elsewhere +on_rtd = os.environ.get('READTHEDOCS') == 'True' +if on_rtd: + # The short X.Y version. + # Apparently ReadTheDocs is getting confused by other version / release + # ReadTheDocs is building specific or the latest release from GitHub. + version = '1.0' + release = '1.0' +else: + # This is supposed to be "the short X.Y version", but it's the only version + # visible when you open index.html. + # Display full version to make things less confusing. + # If needed, nearest tag is returned by 'git describe --abbrev=0'. + version = run_cmd_get_output('git describe') + # The full version, including alpha/beta/rc tags. + release = run_cmd_get_output('git describe') # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. From 7bcd68fb30c4b9d73b66aafcea005eebb618e133 Mon Sep 17 00:00:00 2001 From: Krzysztof Date: Sat, 5 Nov 2016 17:13:44 +0100 Subject: [PATCH 268/343] deep-sleep-stub added + TOC outline TOC outline to show overal planned structure --- docs/index.rst | 66 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 5 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index c973950615..42be69ee0c 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -5,7 +5,6 @@ ESP32 Programming Guide Until ESP-IDF release 1.0, this documentation is a draft. It is incomplete and may have mistakes. Please mind your step! - Contents: .. toctree:: @@ -16,8 +15,6 @@ Contents: Linux Mac OS -.. Configure - TBA - .. Connect - TBA .. toctree:: @@ -35,16 +32,74 @@ Contents: build_system openocd +.. API Reference + .. + Table of Contents Outline + .. + 1. System - TBA + 1.1. Fundamentals of multiprocessor programming with FreeRTOS - TBA + 1.2. Application startup flow - TBA + 1.3. Flash encryption and secure boot: how they work and APIs - TBA + 1.4. Lower Power Coprocessor - TBA + 1.5. Watchdogs + 1.6. ... + 2. Memeory - TBA + 2.1. Memory layout of the application (IRAM/IROM, limitations of each) - TBA + 2.2. Flash layout and partitions - TBA + 2.3. Flash access APIs - TBA + 2.4. Partition APIs - TBA + 2.5. OTA mechanism (app partitions, OTA partition) and APIs - TBA + 2.6. ... + 3. Wi-Fi + 4. Bluetooth + 4.1. BT Classic - TBA + 4.2. BLE + 5. Ethernet - TBA + 6. Interfaces + 6.1. GPIO + 6.2. ADC - TBA + 6.3. DAC - TBA + 6.4. UART - TBA + 6.5. I2C - TBA + 6.6. I2S - TBA + 6.7. SPI - TBA + 6.8. CAN - TBA + 6.9. SD Controller - TBA + 6.10. Infrared - TBA + 6.11. Pulse Counter - TBA + 6.12. PWM - TBA + 6.13. LED PWM + 6.14. ... + 7. Sensors - TBA + 7.1. Hall Sensor - TBA + 7.2. Temperature Sensor - TBA + 7.3. Touch Sensor - TBA + 8. Protocols - TBA + 9. Components + 9.1. Logging + 9.2 Non-Volatile Storage + 9.3 Virtual Filesystem + 9.3. Http sever - TBA + 10. Applications - TBA + .. + API Dcoumentation Teamplate + .. + .. toctree:: :caption: API Reference :maxdepth: 1 Wi-Fi Bluetooth + GPIO + LED Control + Logging - Non-volatile storage - Virtual filesystem + Non-Volatile Storage + Virtual Filesystem + deep-sleep-stub + Template .. toctree:: @@ -76,3 +131,4 @@ Indices * :ref:`genindex` * :ref:`search` + From 3eaf1ec907ff407a098586bca80270b9dd938b02 Mon Sep 17 00:00:00 2001 From: Krzysztof Date: Sat, 5 Nov 2016 17:18:25 +0100 Subject: [PATCH 269/343] All API Reference docs updated to match header files 1. Wi-Fi 2. Bluetooth 2. GPIO 4. LED Control 5. Logging 6. Non-Volatile Storage 7. Virtual Filesystem --- docs/Doxyfile | 2 +- docs/api/bt.rst | 16 +++-- docs/api/esp_wifi.rst | 33 +++++---- docs/api/gpio.rst | 159 ++++++++++++++++++++++++++--------------- docs/api/ledc.rst | 61 ++++++++++++++++ docs/api/log.rst | 35 +++++++++ docs/api/nvs_flash.rst | 67 +++++++++++++++++ docs/api/vfs.rst | 30 +++++--- 8 files changed, 312 insertions(+), 91 deletions(-) create mode 100644 docs/api/ledc.rst create mode 100644 docs/api/nvs_flash.rst diff --git a/docs/Doxyfile b/docs/Doxyfile index 9c53aff1f3..6ff4c45860 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -1,6 +1,6 @@ PROJECT_NAME = "ESP32 Programming Guide" -INPUT = ../components/esp32/include/esp_wifi.h ../components/driver/include/driver ../components/esp32/include/rom/gpio.h ../components/bt/include ../components/nvs_flash/include ../components/log/include ../components/vfs/include +INPUT = ../components/esp32/include/esp_wifi.h ../components/driver/include/driver ../components/bt/include ../components/nvs_flash/include ../components/log/include ../components/vfs/include WARN_NO_PARAMDOC = YES diff --git a/docs/api/bt.rst b/docs/api/bt.rst index 72ab9fbd12..7cbbb9158b 100644 --- a/docs/api/bt.rst +++ b/docs/api/bt.rst @@ -1,20 +1,22 @@ -Bluetooth API -============= +Bluetooth +========= Overview -------- -`Instructions `_ +`Instructions`_ Application Example ------------------- -`Instructions `_ +`Instructions`_ -Reference ---------- +API Reference +------------- -`Instructions `_ +`Instructions`_ + +.. _Instructions: template.html Type Definitions ^^^^^^^^^^^^^^^^ diff --git a/docs/api/esp_wifi.rst b/docs/api/esp_wifi.rst index e4ec59fc82..e417e18ca0 100644 --- a/docs/api/esp_wifi.rst +++ b/docs/api/esp_wifi.rst @@ -1,20 +1,22 @@ -Wi-Fi API -========= +Wi-Fi +===== Overview -------- -`Instructions `_ +`Instructions`_ Application Example ------------------- -`Instructions `_ +`Instructions`_ -Reference ---------- +API Reference +------------- -`Instructions `_ +`Instructions`_ + +.. _Instructions: template.html Macros ------ @@ -22,14 +24,13 @@ Macros .. doxygendefine:: WIFI_INIT_CONFIG_DEFAULT -Typedefs --------- +Type Definitions +---------------- .. doxygentypedef:: wifi_promiscuous_cb_t .. doxygentypedef:: wifi_rxcb_t .. doxygentypedef:: esp_vendor_ie_cb_t - Functions --------- @@ -42,11 +43,12 @@ Functions .. doxygenfunction:: esp_wifi_connect .. doxygenfunction:: esp_wifi_disconnect .. doxygenfunction:: esp_wifi_clear_fast_connect -.. doxygenfunction:: esp_wifi_kick_station +.. doxygenfunction:: esp_wifi_deauth_sta .. doxygenfunction:: esp_wifi_scan_start .. doxygenfunction:: esp_wifi_scan_stop -.. doxygenfunction:: esp_wifi_get_ap_num -.. doxygenfunction:: esp_wifi_get_ap_list +.. doxygenfunction:: esp_wifi_scan_get_ap_num +.. doxygenfunction:: esp_wifi_scan_get_ap_records +.. doxygenfunction:: esp_wifi_sta_get_ap_info .. doxygenfunction:: esp_wifi_set_ps .. doxygenfunction:: esp_wifi_get_ps .. doxygenfunction:: esp_wifi_set_protocol @@ -64,11 +66,12 @@ Functions .. doxygenfunction:: esp_wifi_get_promiscuous .. doxygenfunction:: esp_wifi_set_config .. doxygenfunction:: esp_wifi_get_config -.. doxygenfunction:: esp_wifi_get_station_list -.. doxygenfunction:: esp_wifi_free_station_list +.. doxygenfunction:: esp_wifi_ap_get_sta_list .. doxygenfunction:: esp_wifi_set_storage .. doxygenfunction:: esp_wifi_reg_rxcb .. doxygenfunction:: esp_wifi_set_auto_connect .. doxygenfunction:: esp_wifi_get_auto_connect .. doxygenfunction:: esp_wifi_set_vendor_ie .. doxygenfunction:: esp_wifi_set_vendor_ie_cb + + diff --git a/docs/api/gpio.rst b/docs/api/gpio.rst index 3c5c122921..72ba3e82fb 100644 --- a/docs/api/gpio.rst +++ b/docs/api/gpio.rst @@ -1,26 +1,120 @@ -GPIO API -======== +GPIO +==== Overview -------- -`Instructions `_ +`Instructions`_ Application Example ------------------- -`Instructions `_ +`Instructions`_ -Reference ---------- +API Reference +------------- -`Instructions `_ +`Instructions`_ + +.. _Instructions: template.html + +Macros +------ + +.. doxygendefine:: GPIO_SEL_0 +.. doxygendefine:: GPIO_SEL_1 +.. doxygendefine:: GPIO_SEL_2 +.. doxygendefine:: GPIO_SEL_3 +.. doxygendefine:: GPIO_SEL_4 +.. doxygendefine:: GPIO_SEL_5 +.. doxygendefine:: GPIO_SEL_6 +.. doxygendefine:: GPIO_SEL_7 +.. doxygendefine:: GPIO_SEL_8 +.. doxygendefine:: GPIO_SEL_9 +.. doxygendefine:: GPIO_SEL_10 +.. doxygendefine:: GPIO_SEL_11 +.. doxygendefine:: GPIO_SEL_12 +.. doxygendefine:: GPIO_SEL_13 +.. doxygendefine:: GPIO_SEL_14 +.. doxygendefine:: GPIO_SEL_15 +.. doxygendefine:: GPIO_SEL_16 +.. doxygendefine:: GPIO_SEL_17 +.. doxygendefine:: GPIO_SEL_18 +.. doxygendefine:: GPIO_SEL_19 +.. doxygendefine:: GPIO_SEL_21 +.. doxygendefine:: GPIO_SEL_22 +.. doxygendefine:: GPIO_SEL_23 +.. doxygendefine:: GPIO_SEL_25 +.. doxygendefine:: GPIO_SEL_26 +.. doxygendefine:: GPIO_SEL_27 +.. doxygendefine:: GPIO_SEL_32 +.. doxygendefine:: GPIO_SEL_33 +.. doxygendefine:: GPIO_SEL_34 +.. doxygendefine:: GPIO_SEL_35 +.. doxygendefine:: GPIO_SEL_36 +.. doxygendefine:: GPIO_SEL_37 +.. doxygendefine:: GPIO_SEL_38 +.. doxygendefine:: GPIO_SEL_39 +.. doxygendefine:: GPIO_PIN_REG_0 +.. doxygendefine:: GPIO_PIN_REG_1 +.. doxygendefine:: GPIO_PIN_REG_2 +.. doxygendefine:: GPIO_PIN_REG_3 +.. doxygendefine:: GPIO_PIN_REG_4 +.. doxygendefine:: GPIO_PIN_REG_5 +.. doxygendefine:: GPIO_PIN_REG_6 +.. doxygendefine:: GPIO_PIN_REG_7 +.. doxygendefine:: GPIO_PIN_REG_8 +.. doxygendefine:: GPIO_PIN_REG_9 +.. doxygendefine:: GPIO_PIN_REG_10 +.. doxygendefine:: GPIO_PIN_REG_11 +.. doxygendefine:: GPIO_PIN_REG_12 +.. doxygendefine:: GPIO_PIN_REG_13 +.. doxygendefine:: GPIO_PIN_REG_14 +.. doxygendefine:: GPIO_PIN_REG_15 +.. doxygendefine:: GPIO_PIN_REG_16 +.. doxygendefine:: GPIO_PIN_REG_17 +.. doxygendefine:: GPIO_PIN_REG_18 +.. doxygendefine:: GPIO_PIN_REG_19 +.. doxygendefine:: GPIO_PIN_REG_20 +.. doxygendefine:: GPIO_PIN_REG_21 +.. doxygendefine:: GPIO_PIN_REG_22 +.. doxygendefine:: GPIO_PIN_REG_23 +.. doxygendefine:: GPIO_PIN_REG_25 +.. doxygendefine:: GPIO_PIN_REG_26 +.. doxygendefine:: GPIO_PIN_REG_27 +.. doxygendefine:: GPIO_PIN_REG_32 +.. doxygendefine:: GPIO_PIN_REG_33 +.. doxygendefine:: GPIO_PIN_REG_34 +.. doxygendefine:: GPIO_PIN_REG_35 +.. doxygendefine:: GPIO_PIN_REG_36 +.. doxygendefine:: GPIO_PIN_REG_37 +.. doxygendefine:: GPIO_PIN_REG_38 +.. doxygendefine:: GPIO_PIN_REG_39 +.. doxygendefine:: GPIO_APP_CPU_INTR_ENA +.. doxygendefine:: GPIO_APP_CPU_NMI_INTR_ENA +.. doxygendefine:: GPIO_PRO_CPU_INTR_ENA +.. doxygendefine:: GPIO_PRO_CPU_NMI_INTR_ENA +.. doxygendefine:: GPIO_SDIO_EXT_INTR_ENA +.. doxygendefine:: GPIO_MODE_DEF_INPUT +.. doxygendefine:: GPIO_MODE_DEF_OUTPUT +.. doxygendefine:: GPIO_MODE_DEF_OD +.. doxygendefine:: GPIO_PIN_COUNT +.. doxygendefine:: GPIO_IS_VALID_GPIO +.. doxygendefine:: GPIO_IS_VALID_OUTPUT_GPIO + +Type Definitions +^^^^^^^^^^^^^^^^ + +.. doxygentypedef:: gpio_event_callback Enumerations ^^^^^^^^^^^^ +.. doxygenenum:: gpio_num_t .. doxygenenum:: gpio_int_type_t .. doxygenenum:: gpio_mode_t +.. doxygenenum:: gpio_pullup_t +.. doxygenenum:: gpio_pulldown_t .. doxygenenum:: gpio_pull_mode_t Functions @@ -37,54 +131,3 @@ Functions .. doxygenfunction:: gpio_wakeup_enable .. doxygenfunction:: gpio_wakeup_disable .. doxygenfunction:: gpio_isr_register - -*Example code:* Configuration of GPIO as an output - -.. code-block:: c - - gpio_config_t io_conf; - io_conf.intr_type = GPIO_INTR_DISABLE; //disable interrupt - io_conf.mode = GPIO_MODE_OUTPUT; //set as output mode - io_conf.pin_bit_mask = GPIO_SEL_18 | GPIO_SEL_19; //bit mask of the pins that you want to set,e.g.GPIO18/19 - io_conf.pull_down_en = 0; //disable pull-down mode - io_conf.pull_up_en = 0; //disable pull-up mode - gpio_config(&io_conf); //configure GPIO with the given settings - -*Example code:* Configuration of GPIO as an input - -.. code-block:: c - - gpio_config_t io_conf; - io_conf.intr_type = GPIO_INTR_POSEDGE; //set posedge interrupt - io_conf.mode = GPIO_MODE_INPUT; //set as input - io_conf.pin_bit_mask = GPIO_SEL_4 | GPIO_SEL_5; //bit mask of the pins that you want to set, e.g.,GPIO4/5 - io_conf.pull_down_en = 0; //disable pull-down mode - io_conf.pull_up_en = 1; //enable pull-up mode - gpio_config(&io_conf); //configure GPIO with the given settings - - -ROM GPIO functions -^^^^^^^^^^^^^^^^^^ - -.. doxygenfunction:: gpio_init -.. doxygenfunction:: gpio_output_set -.. doxygenfunction:: gpio_output_set_high -.. doxygenfunction:: gpio_input_get -.. doxygenfunction:: gpio_input_get_high -.. doxygenfunction:: gpio_intr_handler_register -.. doxygenfunction:: gpio_intr_pending -.. doxygenfunction:: gpio_intr_pending_high -.. doxygenfunction:: gpio_intr_ack -.. doxygenfunction:: gpio_intr_ack_high -.. doxygenfunction:: gpio_pin_wakeup_enable -.. doxygenfunction:: gpio_pin_wakeup_disable -.. doxygenfunction:: gpio_matrix_in -.. doxygenfunction:: gpio_matrix_out -.. doxygenfunction:: gpio_pad_select_gpio -.. doxygenfunction:: gpio_pad_set_drv -.. doxygenfunction:: gpio_pad_pullup -.. doxygenfunction:: gpio_pad_pulldown -.. doxygenfunction:: gpio_pad_unhold -.. doxygenfunction:: gpio_pad_hold - - diff --git a/docs/api/ledc.rst b/docs/api/ledc.rst new file mode 100644 index 0000000000..32b639f3f9 --- /dev/null +++ b/docs/api/ledc.rst @@ -0,0 +1,61 @@ +LED Control +=========== + +Overview +-------- + +`Instructions`_ + +Application Example +------------------- + +`Instructions`_ + +API Reference +------------- + +`Instructions`_ + +.. _Instructions: template.html + +Data Structures +^^^^^^^^^^^^^^^ + +.. doxygenstruct:: ledc_channel_config_t +.. doxygenstruct:: ledc_timer_config_t + +Macros +^^^^^^ + +.. doxygendefine:: LEDC_APB_CLK_HZ +.. doxygendefine:: LEDC_REF_CLK_HZ + +Enumerations +^^^^^^^^^^^^ + +.. doxygenenum:: ledc_mode_t +.. doxygenenum:: ledc_intr_type_t +.. doxygenenum:: ledc_duty_direction_t +.. doxygenenum:: ledc_clk_src_t +.. doxygenenum:: ledc_timer_t +.. doxygenenum:: ledc_channel_t +.. doxygenenum:: ledc_timer_bit_t + +Functions +^^^^^^^^^ + +.. doxygenfunction:: ledc_channel_config +.. doxygenfunction:: ledc_timer_config +.. doxygenfunction:: ledc_update_duty +.. doxygenfunction:: ledc_stop +.. doxygenfunction:: ledc_set_freq +.. doxygenfunction:: ledc_get_freq +.. doxygenfunction:: ledc_set_duty +.. doxygenfunction:: ledc_get_duty +.. doxygenfunction:: ledc_set_fade +.. doxygenfunction:: ledc_isr_register +.. doxygenfunction:: ledc_timer_set +.. doxygenfunction:: ledc_timer_rst +.. doxygenfunction:: ledc_timer_pause +.. doxygenfunction:: ledc_timer_resume +.. doxygenfunction:: ledc_bind_channel_timer diff --git a/docs/api/log.rst b/docs/api/log.rst index dc76a30470..49f97108aa 100644 --- a/docs/api/log.rst +++ b/docs/api/log.rst @@ -3,6 +3,33 @@ API Reference ------------- +Macros +^^^^^^ + +.. doxygendefine:: LOG_COLOR_E +.. doxygendefine:: LOG_COLOR_W +.. doxygendefine:: LOG_COLOR_I +.. doxygendefine:: LOG_COLOR_D +.. doxygendefine:: LOG_COLOR_V +.. doxygendefine:: LOG_RESET_COLOR +.. doxygendefine:: LOG_FORMAT +.. doxygendefine:: LOG_LOCAL_LEVEL +.. doxygendefine:: ESP_EARLY_LOGE +.. doxygendefine:: ESP_EARLY_LOGW +.. doxygendefine:: ESP_EARLY_LOGI +.. doxygendefine:: ESP_EARLY_LOGD +.. doxygendefine:: ESP_EARLY_LOGV +.. doxygendefine:: ESP_LOGE +.. doxygendefine:: ESP_LOGW +.. doxygendefine:: ESP_LOGI +.. doxygendefine:: ESP_LOGD +.. doxygendefine:: ESP_LOGV + +Type Definitions +^^^^^^^^^^^^^^^^ + +.. doxygentypedef:: vprintf_like_t + Enumerations ^^^^^^^^^^^^ @@ -17,3 +44,11 @@ Functions .. doxygenfunction:: esp_log_write + + + + + + + + diff --git a/docs/api/nvs_flash.rst b/docs/api/nvs_flash.rst new file mode 100644 index 0000000000..16c74fa530 --- /dev/null +++ b/docs/api/nvs_flash.rst @@ -0,0 +1,67 @@ +.. include:: ../../components/nvs_flash/README.rst + +Application Example +------------------- + +`Instructions `_ + +API Reference +------------- + +Macros +^^^^^^ + +.. doxygendefine:: ESP_ERR_NVS_BASE +.. doxygendefine:: ESP_ERR_NVS_NOT_INITIALIZED +.. doxygendefine:: ESP_ERR_NVS_NOT_FOUND +.. doxygendefine:: ESP_ERR_NVS_TYPE_MISMATCH +.. doxygendefine:: ESP_ERR_NVS_READ_ONLY +.. doxygendefine:: ESP_ERR_NVS_NOT_ENOUGH_SPACE +.. doxygendefine:: ESP_ERR_NVS_INVALID_NAME +.. doxygendefine:: ESP_ERR_NVS_INVALID_HANDLE +.. doxygendefine:: ESP_ERR_NVS_REMOVE_FAILED +.. doxygendefine:: ESP_ERR_NVS_KEY_TOO_LONG +.. doxygendefine:: ESP_ERR_NVS_PAGE_FULL +.. doxygendefine:: ESP_ERR_NVS_INVALID_STATE +.. doxygendefine:: ESP_ERR_NVS_INVALID_LENGTH + +Type Definitions +^^^^^^^^^^^^^^^^ + +.. doxygentypedef:: nvs_handle + +Enumerations +^^^^^^^^^^^^ + +.. doxygenenum:: nvs_open_mode + +Functions +^^^^^^^^^ +.. doxygenfunction:: nvs_open +.. doxygenfunction:: nvs_set_i8 +.. doxygenfunction:: nvs_set_u8 +.. doxygenfunction:: nvs_set_i16 +.. doxygenfunction:: nvs_set_u16 +.. doxygenfunction:: nvs_set_i32 +.. doxygenfunction:: nvs_set_u32 +.. doxygenfunction:: nvs_set_i64 +.. doxygenfunction:: nvs_set_u64 +.. doxygenfunction:: nvs_set_str +.. doxygenfunction:: nvs_set_blob +.. doxygenfunction:: nvs_get_i8 +.. doxygenfunction:: nvs_get_u8 +.. doxygenfunction:: nvs_get_i16 +.. doxygenfunction:: nvs_get_u16 +.. doxygenfunction:: nvs_get_i32 +.. doxygenfunction:: nvs_get_u32 +.. doxygenfunction:: nvs_get_i64 +.. doxygenfunction:: nvs_get_u64 +.. doxygenfunction:: nvs_get_str +.. doxygenfunction:: nvs_get_blob +.. doxygenfunction:: nvs_erase_key +.. doxygenfunction:: nvs_erase_all +.. doxygenfunction:: nvs_commit +.. doxygenfunction:: nvs_close +.. doxygenfunction:: nvs_flash_init +.. doxygenfunction:: nvs_flash_init_custom + diff --git a/docs/api/vfs.rst b/docs/api/vfs.rst index 97ea1a5848..122a8671ea 100644 --- a/docs/api/vfs.rst +++ b/docs/api/vfs.rst @@ -1,15 +1,19 @@ .. include:: ../../components/vfs/README.rst +Application Example +------------------- + +`Instructions `_ + API Reference ------------- -Defines -^^^^^^^ +Macros +^^^^^^ -.. doxygendefine:: ESP_VFS_PATH_MAX +.. doxygendefine:: ESP_VFS_PATH_MAX .. doxygendefine:: ESP_VFS_FLAG_DEFAULT -.. doxygendefine:: ESP_VFS_FLAG_CONTEXT_PTR - +.. doxygendefine:: ESP_VFS_FLAG_CONTEXT_PTR Structures ^^^^^^^^^^ @@ -19,9 +23,15 @@ Structures Functions ^^^^^^^^^ -.. doxygenfunction:: esp_vfs_dev_uart_register .. doxygenfunction:: esp_vfs_register - - - - +.. doxygenfunction:: esp_vfs_write +.. doxygenfunction:: esp_vfs_lseek +.. doxygenfunction:: esp_vfs_read +.. doxygenfunction:: esp_vfs_open +.. doxygenfunction:: esp_vfs_close +.. doxygenfunction:: esp_vfs_fstat +.. doxygenfunction:: esp_vfs_stat +.. doxygenfunction:: esp_vfs_link +.. doxygenfunction:: esp_vfs_unlink +.. doxygenfunction:: esp_vfs_rename +.. doxygenfunction:: esp_vfs_dev_uart_register From c3f7d15246506cac2f948565e9c9d830e6478a9a Mon Sep 17 00:00:00 2001 From: Krzysztof Date: Sat, 5 Nov 2016 17:19:31 +0100 Subject: [PATCH 270/343] Instructions to prepare documentation --- docs/api/template.rst | 87 ++++++++++++++++++------------ docs/documenting-code.rst | 111 ++++++++++++++++++++++++-------------- 2 files changed, 126 insertions(+), 72 deletions(-) diff --git a/docs/api/template.rst b/docs/api/template.rst index 0f2623c47f..3c8bcdb62c 100644 --- a/docs/api/template.rst +++ b/docs/api/template.rst @@ -1,70 +1,91 @@ -Template API -============= +Template +======== + +.. note:: + + *INSTRUCTIONS* + + 1. Use this file as a template to document API. + 2. Change the file name to the name of the header file that represents documented API. + 3. Include respective files with descriptions from the API folder using ``..include::`` + + * README.rst + * example.rst + + 4. Optionally provide description right in this file. + 5. Once done, remove all instructions like this one and any superfluous headers. Overview -------- -INSTRUCTIONS: Provide overview where and how this API may be used. For large number of functions, break down description into groups. +.. note:: -Use the folowing heading levels: + *INSTRUCTIONS* -* # with overline, for parts -* \* with overline, for chapters -* =, for sections -* -, for subsections -* ^, for subsubsections -* ", for paragraphs + 1. Provide overview where and how this API may be used. + 2. Where applicable include code snippets to illustrate functionality of particular functions. + 3. To distinguish between sections, use the following `heading levels `_: + * ``#`` with overline, for parts + * ``*`` with overline, for chapters + * ``=``, for sections + * ``-``, for subsections + * ``^``, for subsubsections + * ``"``, for paragraphs Application Example ------------------- -INSTRUCTIONS: Provide one or more pratical examples to demonstrate functionality of this API. +.. note:: + *INSTRUCTIONS* -Reference ---------- + 1. Provide one or more practical examples to demonstrate functionality of this API. + 2. Break down the code into parts and describe functionality of each part. + 3. Provide screenshots if applicable. -INSTRUCTIONS: Provide list of API memebers divided into sections. Use coresponding **.. doxygen** directices, so member documentation is auto updated. +API Reference +------------- -* Data Structures **.. doxygenstruct** -* Macros **.. doxygendefine** -* Type Definitions **.. doxygentypedef** -* Enumerations **.. doxygenenum** -* Functions **.. doxygenfunction** -* Variables **.. doxygenvariable** +.. note:: -Include code snippotes to ilustrate functionality of particular functions where applicable. Skip section hearder if empty. + *INSTRUCTIONS* + + 1. Provide list of API members divided into sections. + 2. Use corresponding ``.. doxygen..`` directives, so member documentation is auto updated. + * Data Structures -``.. doxygenstruct::`` + * Macros - ``.. doxygendefine::`` + * Type Definitions - ``.. doxygentypedef::`` + * Enumerations - ``.. doxygenenum::`` + * Functions - ``.. doxygenfunction::`` + + See `Breathe documentation `_ for additional information. + + 3. Once done remove superfluous headers. + 4. When changes are committed and documentation is build, check how this section rendered. :doc:`Correct annotations <../documenting-code>` in respective header files, if required. Data Structures ^^^^^^^^^^^^^^^ -.. Data Structures .. doxygenstruct +``.. doxygenstruct:: name_of_structure`` Macros ^^^^^^ -.. Macros .. doxygendefine +``.. doxygendefine:: name_of_macro`` Type Definitions ^^^^^^^^^^^^^^^^ -.. Type Definitions .. doxygentypedef +``.. doxygentypedef:: name_of_type`` Enumerations ^^^^^^^^^^^^ -.. Enumerations .. doxygenenum +``.. doxygenenum:: name_of_enumeration`` Functions ^^^^^^^^^ -.. Functions .. doxygenfunction - -Variables -^^^^^^^^^ - -.. Variables .. doxygenvariable - - +``.. doxygenfunction:: name_of_function`` diff --git a/docs/documenting-code.rst b/docs/documenting-code.rst index 51a0dbf7d3..72e3cea147 100644 --- a/docs/documenting-code.rst +++ b/docs/documenting-code.rst @@ -1,10 +1,18 @@ Documenting Code ================ +The purpose of this description is to provide quick summary on documentation style used in `espressif/esp-idf`_ repository and how to add new documentation. + Introduction ------------ -When documenting code for this repository, please follow `Doxygen style `_. You are doing it by inserting special commands, for instance ``@param``, into standard comments blocks like for example ``/* @param ratio this is oxygen to air ratio */``. +When documenting code for this repository, please follow `Doxygen style `_. You are doing it by inserting special commands, for instance ``@param``, into standard comments blocks, for example: + +:: + + /** + * @param ratio this is oxygen to air ratio + */ Doxygen is phrasing the code, extracting the commands together with subsequent text, and building documentation out of it. @@ -14,20 +22,19 @@ Typical comment block, that contains documentation of a function, looks like bel :align: center :alt: Sample inline code documentation -Doxygen supports couple of formatting styles. It also gives you great flexibility on level of details to include in documentation. To get the taste of available features please check data reach and very well organized `Doxygen Manual `_. +Doxygen supports couple of formatting styles. It also gives you great flexibility on level of details to include in documentation. To get familiar with available features, please check data reach and very well organized `Doxygen Manual `_. Why we need it? --------------- -The purpose of this description is to provide quick summary on documentation style used in `espressif/esp-idf `_ repository. +The ultimate goal is to ensure that all the code is consistently documented, so we can use tools like `Sphinx `_ and `Breathe `_ to aid preparation and automatic updates of API documentation when the code changes. -The ultimate goal is to ensure that all the code is consistently documented, so we can use tools like `Sphinx `_ and `Breathe `_ to aid preparation and automatic updates of API documentation when the code changes. The above piece of code renders in Sphinx like below: +With these tools the above piece of code renders like below: .. image:: _static/doc-code-documentation-rendered.png :align: center :alt: Sample inline code after rendering - Go for it! ---------- @@ -57,7 +64,7 @@ When writing code for this repository, please follow guidelines below. 6. To provide well formatted lists, break the line after command (like ``@return`` in example below). - :: + .. code-block:: c ... * @@ -70,53 +77,76 @@ When writing code for this repository, please follow guidelines below. * ... - - 7. Overview of functionality of documented header file, or group of files that make a library, should be placed in separate ``README.rst`` file. + 7. Overview of functionality of documented header file, or group of files that make a library, should be placed in the same directory in a separate ``README.rst`` file. If directory contains header files for different APIs, then the file name should be ``apiname-readme.rst``. Go one extra mile ----------------- -There are couple of tips how you can make your documentation even better and more useful to the reader. +There is couple of tips, how you can make your documentation even better and more useful to the reader. -Add code snippets to illustrate implementation. To do so, enclose the snippet using ``@code{c}`` and ``@endcode`` commands. + 1. Add code snippets to illustrate implementation. To do so, enclose snippet using ``@code{c}`` and ``@endcode`` commands. -:: + .. code-block:: c - ... - * - * @code{c} - * // Example of using nvs_get_i32: - * int32_t max_buffer_size = 4096; // default value - * esp_err_t err = nvs_get_i32(my_handle, "max_buffer_size", &max_buffer_size); - * assert(err == ESP_OK || err == ESP_ERR_NVS_NOT_FOUND); - * // if ESP_ERR_NVS_NOT_FOUND was returned, max_buffer_size will still - * // have its default value. - * @endcode - * - ... + ... + * + * @code{c} + * // Example of using nvs_get_i32: + * int32_t max_buffer_size = 4096; // default value + * esp_err_t err = nvs_get_i32(my_handle, "max_buffer_size", &max_buffer_size); + * assert(err == ESP_OK || err == ESP_ERR_NVS_NOT_FOUND); + * // if ESP_ERR_NVS_NOT_FOUND was returned, max_buffer_size will still + * // have its default value. + * @endcode + * + ... -To highlight some information use command ``@attention`` or ``@note``. Example below also shows how to use a numbered list. + The code snippet should be enclosed in a comment block of the function that it illustrates. -:: + 2. To highlight some important information use command ``@attention`` or ``@note``. - ... - * - * @attention - * 1. This API only impact WIFI_MODE_STA or WIFI_MODE_APSTA mode - * 2. If the ESP32 is connected to an AP, call esp_wifi_disconnect to disconnect. - * - ... + .. code-block:: c + ... + * + * @attention + * 1. This API only impact WIFI_MODE_STA or WIFI_MODE_APSTA mode + * 2. If the ESP32 is connected to an AP, call esp_wifi_disconnect to disconnect. + * + ... -Use markdown to make your documentation even more readable. With markdown you can add headers, links, tables and more. + Above example also shows how to use a numbered list. -:: + 3. Use markdown to make your documentation even more readable. You will add headers, links, tables and more. - ... - * - * [ESP32 Technical Reference](http://espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf) - * - ... + .. code-block:: c + + ... + * + * [ESP32 Technical Reference](http://espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf) + * + ... + + .. note:: + + Code snippets, notes, links, etc. will not make it to the documentation, if not enclosed in a comment block associated with one of documented objects. + + 5. Prepare one or more complete code examples together with description. Place them in a separate file ``example.rst`` in the same directory as the API header files. If directory contains header files for different APIs, then the file name should be ``apiname-example.rst``. + +Put it all together +------------------- + +Once all the above steps are complete, follow instruction in :doc:`api/template` and create a single file, that will merge all individual pieces of prepared documentation. Finally add a link to this file to respective ``.. toctree::`` in ``index.rst`` file located in ``/docs`` folder. + +OK, but I am new to Sphinx! +--------------------------- + +1. No worries. All the software you need is well documented. It is also open source and free. Start by checking `Sphinx `_ documentation. If you are not clear how to write using rst markup language, see `reStructuredText Primer `_. +2. Check the source files of this documentation to understand what is behind of what you see now on the screen. Sources are maintained on GitHub in `espressif/esp-idf`_ repository in `/docs `_ folder. You can go directly to the source file of this page by scrolling up and clicking the link in the top right corner. When on GitHub, see what's really inside, open source files by clicking ``Raw`` button. +3. You will likely want to see how documentation builds and looks like before posting it on the GitHub. There are two options to do so: + + * Install `Sphinx `_, `Breathe `_ and `Doxygen `_ to build it locally. You would need a Linux machine for that. + * Set up an account on `Read the Docs `_ and build documentation in the cloud. Read the Docs provides document building and hosting for free and their service works really quick and great. Wrap up ------- @@ -124,3 +154,6 @@ Wrap up We love good code that is doing cool things. We love it even better, if it is well documented, so we can quickly make it run and also do the cool things. +Go ahead, contribute your code and documentation! + +.. _espressif/esp-idf: https://github.com/espressif/esp-idf/ From d093dcbbb721a0227cced2d62365ed9eced327cf Mon Sep 17 00:00:00 2001 From: Yinling Date: Sun, 6 Nov 2016 22:43:12 +0800 Subject: [PATCH 271/343] try to checkout same branch for submodule in CI jobs --- .gitlab-ci.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ad5a13ad03..b06eccb75f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -12,12 +12,16 @@ before_script: - base64 --decode --ignore-garbage ~/.ssh/id_rsa_base64 > ~/.ssh/id_rsa - chmod 600 ~/.ssh/id_rsa - echo -e "Host gitlab.espressif.cn\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config - + # CI may download a cached project. Need to re-sync submodule + - git submodule deinit -f . # if testing master branch, use github wifi libs. # if testing other branches, use gitlab wifi libs (as maybe changes aren't merged to master yet) - test "${CI_BUILD_REF_NAME}" = "master" || sed -i "s%https://github.com/espressif/esp32-wifi-lib%ssh://git@gitlab.espressif.cn:27227/idf/esp32-wifi-lib%" .gitmodules # fetch all submodules - git submodule update --init --recursive + # try use submodule with same branch + - SUBMODULES=`cat .gitmodules | grep path | awk '{print $3}'` + - for MODULE in $SUBMODULES;do (cd $MODULE;git fetch;git checkout ${CI_BUILD_REF_NAME} || echo "using default branch";cd $CI_PROJECT_DIR); done build_template_app: stage: build From 3051c74488e8e0f44839d03ff1faeeb8a3ff9f20 Mon Sep 17 00:00:00 2001 From: Yinling Date: Sun, 6 Nov 2016 22:53:23 +0800 Subject: [PATCH 272/343] No need to deinit submodules as use clean clone by config --- .gitlab-ci.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b06eccb75f..3e88ddc638 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -12,8 +12,6 @@ before_script: - base64 --decode --ignore-garbage ~/.ssh/id_rsa_base64 > ~/.ssh/id_rsa - chmod 600 ~/.ssh/id_rsa - echo -e "Host gitlab.espressif.cn\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config - # CI may download a cached project. Need to re-sync submodule - - git submodule deinit -f . # if testing master branch, use github wifi libs. # if testing other branches, use gitlab wifi libs (as maybe changes aren't merged to master yet) - test "${CI_BUILD_REF_NAME}" = "master" || sed -i "s%https://github.com/espressif/esp32-wifi-lib%ssh://git@gitlab.espressif.cn:27227/idf/esp32-wifi-lib%" .gitmodules From 522f83ae3d71357683a62f69a139b8c1eda8f362 Mon Sep 17 00:00:00 2001 From: Yinling Date: Sun, 6 Nov 2016 22:58:31 +0800 Subject: [PATCH 273/343] remove unnecessary "git fetch" and add echo submodule path --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3e88ddc638..6f050d1fcb 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -19,7 +19,7 @@ before_script: - git submodule update --init --recursive # try use submodule with same branch - SUBMODULES=`cat .gitmodules | grep path | awk '{print $3}'` - - for MODULE in $SUBMODULES;do (cd $MODULE;git fetch;git checkout ${CI_BUILD_REF_NAME} || echo "using default branch";cd $CI_PROJECT_DIR); done + - for MODULE in $SUBMODULES;do (echo $MODULE;cd $MODULE;git checkout ${CI_BUILD_REF_NAME} || echo "using default branch";cd $CI_PROJECT_DIR); done build_template_app: stage: build From 025bb473020da4b1c2f8b53987efeb4e7ab2fea0 Mon Sep 17 00:00:00 2001 From: Krzysztof Date: Sun, 6 Nov 2016 17:41:08 +0100 Subject: [PATCH 274/343] Non-Volatile Storage (NVS) example Demonstrates how to read and write a value using NVS. The value tracks number of ESP32 module restarts. Example also shows how to use basic diagnostics if read / write operation was successful. --- examples/07_nvs_read_write/Makefile | 9 +++ examples/07_nvs_read_write/README.md | 7 +++ examples/07_nvs_read_write/main/component.mk | 10 +++ .../07_nvs_read_write/main/nvs_read_write.c | 62 +++++++++++++++++++ 4 files changed, 88 insertions(+) create mode 100644 examples/07_nvs_read_write/Makefile create mode 100644 examples/07_nvs_read_write/README.md create mode 100644 examples/07_nvs_read_write/main/component.mk create mode 100644 examples/07_nvs_read_write/main/nvs_read_write.c diff --git a/examples/07_nvs_read_write/Makefile b/examples/07_nvs_read_write/Makefile new file mode 100644 index 0000000000..3d6adb4d02 --- /dev/null +++ b/examples/07_nvs_read_write/Makefile @@ -0,0 +1,9 @@ +# +# This is a project Makefile. It is assumed the directory this Makefile resides in is a +# project subdirectory. +# + +PROJECT_NAME := nvs-read-write + +include $(IDF_PATH)/make/project.mk + diff --git a/examples/07_nvs_read_write/README.md b/examples/07_nvs_read_write/README.md new file mode 100644 index 0000000000..bac8ee8d54 --- /dev/null +++ b/examples/07_nvs_read_write/README.md @@ -0,0 +1,7 @@ +# Non-Volatile Storage (NVS) Read and Write Example + +Demonstrates how to read and write a value using NVS. The value tracks number of ESP32 module restarts. + +Example also shows how to use basic diagnostics if read / write operation was successful. + +See the README.md file in the upper level 'examples' directory for more information about examples. diff --git a/examples/07_nvs_read_write/main/component.mk b/examples/07_nvs_read_write/main/component.mk new file mode 100644 index 0000000000..24356f23ed --- /dev/null +++ b/examples/07_nvs_read_write/main/component.mk @@ -0,0 +1,10 @@ +# +# Main Makefile. This is basically the same as a component makefile. +# +# This Makefile should, at the very least, just include $(SDK_PATH)/make/component_common.mk. By default, +# this will take the sources in the src/ directory, compile them and link them into +# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable, +# please read the ESP-IDF documents if you need to do this. +# + +include $(IDF_PATH)/make/component_common.mk diff --git a/examples/07_nvs_read_write/main/nvs_read_write.c b/examples/07_nvs_read_write/main/nvs_read_write.c new file mode 100644 index 0000000000..40d330f62f --- /dev/null +++ b/examples/07_nvs_read_write/main/nvs_read_write.c @@ -0,0 +1,62 @@ +/* Non-Volatile Storage (NVS) Read and Write Example + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_system.h" +#include "nvs_flash.h" +#include "nvs.h" + +void app_main() +{ + nvs_flash_init(); + system_init(); + + nvs_handle handle_to_settings; + esp_err_t err; + int32_t restart_counter = 0; + + // Open the NVS + printf("Opening Non-Volatile Storage (NVS) ... "); + err = nvs_open("settings", NVS_READWRITE, &handle_to_settings); + printf((err != ESP_OK) ? "Failed!\n" : "OK\n"); + + // Read from the NVS + printf("Reading restart counter from NVS ... "); + err = nvs_get_i32(handle_to_settings, "restart_conter", &restart_counter); + switch (err) { + case ESP_OK: + printf("OK\n"); + printf("Restart counter = %d\n", restart_counter); + break; + case ESP_ERR_NVS_NOT_FOUND: + printf("The counter is not initialized yet!\n"); + break; + default : + printf("Error (%d) reading!\n", err); + } + + // Write to the NVS + printf("Updating restart counter in NVS ... "); + restart_counter++; + err = nvs_set_i32(handle_to_settings, "restart_conter", restart_counter); + printf((err != ESP_OK) ? "Failed!\n" : "OK\n"); + + // Close the NVS + nvs_close(handle_to_settings); + + // Restart module + for (int i = 10; i >= 0; i--) { + printf("Restarting in %d seconds...\n", i); + vTaskDelay(1000 / portTICK_RATE_MS); + } + printf("Restarting now.\n"); + fflush(stdout); + system_restart(); +} From b6dd8a55cd4d17750491f56c33d21a392bdd2840 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Mon, 7 Nov 2016 12:27:53 +0800 Subject: [PATCH 275/343] Fix build with macports/pkgconfig, silence format string warnings on OS X Extra space is needed in echo -n "-lncurses ", otherwise if pkg-config outputs a directory after that, it will result in "-lncurses-L/opt/local/lib" (without space). -Wno-format-security flag is needed on macOS to silence warnings about printf(gettext("message")) constructs. --- tools/kconfig/lxdialog/check-lxdialog.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/kconfig/lxdialog/check-lxdialog.sh b/tools/kconfig/lxdialog/check-lxdialog.sh index 48c19278a9..79df5ed4f9 100755 --- a/tools/kconfig/lxdialog/check-lxdialog.sh +++ b/tools/kconfig/lxdialog/check-lxdialog.sh @@ -6,7 +6,7 @@ ldflags() { if [ $(uname -s) == "Darwin" ]; then #OSX seems to need ncurses too - echo -n "-lncurses" + echo -n "-lncurses " fi pkg-config --libs ncursesw 2>/dev/null && exit pkg-config --libs ncurses 2>/dev/null && exit @@ -43,7 +43,7 @@ ccflags() fi if [ $(uname -s) == "Darwin" ]; then #OSX doesn't have libintl - echo -n "-DKBUILD_NO_NLS" + echo -n "-DKBUILD_NO_NLS -Wno-format-security " fi } From e452278194ff16696519444fb9132b3ffa143dc0 Mon Sep 17 00:00:00 2001 From: Wangjialin Date: Mon, 7 Nov 2016 14:16:52 +0800 Subject: [PATCH 276/343] Minor changes for driver 1. remove "\n" when calling ESP_LOGX APIs. 2. modify uart_event_t for uart rx data. 3. use MICRO for uart inverse value 4. add uart_tx_data_t for internal tx function. --- components/driver/gpio.c | 59 ++++++++++--------- components/driver/include/driver/uart.h | 39 +++++-------- components/driver/ledc.c | 78 ++++++++++++------------- components/driver/uart.c | 48 +++++++++------ 4 files changed, 114 insertions(+), 110 deletions(-) diff --git a/components/driver/gpio.c b/components/driver/gpio.c index 62a0e7faa7..b445d3df03 100644 --- a/components/driver/gpio.c +++ b/components/driver/gpio.c @@ -22,7 +22,7 @@ static const char* GPIO_TAG = "GPIO"; #define GPIO_CHECK(a, str, ret_val) if (!(a)) { \ - ESP_LOGE(GPIO_TAG,"%s:%d (%s):%s\n", __FILE__, __LINE__, __FUNCTION__, str); \ + ESP_LOGE(GPIO_TAG,"%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, str); \ return (ret_val); \ } @@ -71,15 +71,15 @@ const uint32_t GPIO_PIN_MUX_REG[GPIO_PIN_COUNT] = { esp_err_t gpio_set_intr_type(gpio_num_t gpio_num, gpio_int_type_t intr_type) { - GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error\n", ESP_ERR_INVALID_ARG); - GPIO_CHECK(intr_type < GPIO_INTR_MAX, "GPIO interrupt type error\n", ESP_ERR_INVALID_ARG); + GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); + GPIO_CHECK(intr_type < GPIO_INTR_MAX, "GPIO interrupt type error", ESP_ERR_INVALID_ARG); GPIO.pin[gpio_num].int_type = intr_type; return ESP_OK; } esp_err_t gpio_intr_enable(gpio_num_t gpio_num) { - GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error\n", ESP_ERR_INVALID_ARG); + GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); if(xPortGetCoreID() == 0) { GPIO.pin[gpio_num].int_ena = GPIO_PRO_CPU_INTR_ENA; //enable pro cpu intr } else { @@ -90,14 +90,14 @@ esp_err_t gpio_intr_enable(gpio_num_t gpio_num) esp_err_t gpio_intr_disable(gpio_num_t gpio_num) { - GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error\n", ESP_ERR_INVALID_ARG); + GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); GPIO.pin[gpio_num].int_ena = 0; //disable GPIO intr return ESP_OK; } static esp_err_t gpio_output_disable(gpio_num_t gpio_num) { - GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error\n", ESP_ERR_INVALID_ARG); + GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); if(gpio_num < 32) { GPIO.enable_w1tc = (0x1 << gpio_num); } else { @@ -108,7 +108,7 @@ static esp_err_t gpio_output_disable(gpio_num_t gpio_num) static esp_err_t gpio_output_enable(gpio_num_t gpio_num) { - GPIO_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "GPIO output gpio_num error\n", ESP_ERR_INVALID_ARG); + GPIO_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "GPIO output gpio_num error", ESP_ERR_INVALID_ARG); if(gpio_num < 32) { GPIO.enable_w1ts = (0x1 << gpio_num); } else { @@ -119,7 +119,7 @@ static esp_err_t gpio_output_enable(gpio_num_t gpio_num) esp_err_t gpio_set_level(gpio_num_t gpio_num, uint32_t level) { - GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error\n", ESP_ERR_INVALID_ARG); + GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); if(level) { if(gpio_num < 32) { GPIO.out_w1ts = (1 << gpio_num); @@ -147,8 +147,8 @@ int gpio_get_level(gpio_num_t gpio_num) esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull) { - GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error\n", ESP_ERR_INVALID_ARG); - GPIO_CHECK(pull <= GPIO_FLOATING, "GPIO pull mode error\n", ESP_ERR_INVALID_ARG); + GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); + GPIO_CHECK(pull <= GPIO_FLOATING, "GPIO pull mode error", ESP_ERR_INVALID_ARG); esp_err_t ret = ESP_OK; switch(pull) { case GPIO_PULLUP_ONLY: @@ -168,7 +168,7 @@ esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull) PIN_PULLDWN_DIS(GPIO_PIN_MUX_REG[gpio_num]); break; default: - ESP_LOGE(GPIO_TAG, "Unknown pull up/down mode,gpio_num=%u,pull=%u\n",gpio_num,pull); + ESP_LOGE(GPIO_TAG, "Unknown pull up/down mode,gpio_num=%u,pull=%u",gpio_num,pull); ret = ESP_ERR_INVALID_ARG; break; } @@ -177,9 +177,9 @@ esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull) esp_err_t gpio_set_direction(gpio_num_t gpio_num, gpio_mode_t mode) { - GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error\n", ESP_ERR_INVALID_ARG); + GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); if(gpio_num >= 34 && (mode & (GPIO_MODE_DEF_OUTPUT))) { - ESP_LOGE(GPIO_TAG, "io_num=%d can only be input\n",gpio_num); + ESP_LOGE(GPIO_TAG, "io_num=%d can only be input",gpio_num); return ESP_ERR_INVALID_ARG; } esp_err_t ret = ESP_OK; @@ -214,53 +214,56 @@ esp_err_t gpio_config(gpio_config_t *pGPIOConfig) uint64_t gpio_pin_mask = (pGPIOConfig->pin_bit_mask); uint32_t io_reg = 0; uint32_t io_num = 0; - uint64_t bit_valid = 0; + uint8_t input_en = 0; + uint8_t output_en = 0; + uint8_t od_en = 0; + uint8_t pu_en = 0; + uint8_t pd_en = 0; if(pGPIOConfig->pin_bit_mask == 0 || pGPIOConfig->pin_bit_mask >= (((uint64_t) 1) << GPIO_PIN_COUNT)) { - ESP_LOGE(GPIO_TAG, "GPIO_PIN mask error \n"); + ESP_LOGE(GPIO_TAG, "GPIO_PIN mask error "); return ESP_ERR_INVALID_ARG; } if((pGPIOConfig->mode) & (GPIO_MODE_DEF_OUTPUT)) { //GPIO 34/35/36/37/38/39 can only be used as input mode; if((gpio_pin_mask & ( GPIO_SEL_34 | GPIO_SEL_35 | GPIO_SEL_36 | GPIO_SEL_37 | GPIO_SEL_38 | GPIO_SEL_39))) { - ESP_LOGE(GPIO_TAG, "GPIO34-39 can only be used as input mode\n"); + ESP_LOGE(GPIO_TAG, "GPIO34-39 can only be used as input mode"); return ESP_ERR_INVALID_ARG; } } do { io_reg = GPIO_PIN_MUX_REG[io_num]; if(((gpio_pin_mask >> io_num) & BIT(0)) && io_reg) { - ESP_LOGI(GPIO_TAG, "Gpio%02d |Mode:",io_num); if((pGPIOConfig->mode) & GPIO_MODE_DEF_INPUT) { - ESP_LOGI(GPIO_TAG, "INPUT "); + input_en = 1; PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[io_num]); } else { PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[io_num]); } if((pGPIOConfig->mode) & GPIO_MODE_DEF_OD) { - ESP_LOGI(GPIO_TAG, "OD "); + od_en = 1; GPIO.pin[io_num].pad_driver = 1; /*0x01 Open-drain */ } else { GPIO.pin[io_num].pad_driver = 0; /*0x00 Normal gpio output */ } if((pGPIOConfig->mode) & GPIO_MODE_DEF_OUTPUT) { - ESP_LOGI(GPIO_TAG, "OUTPUT "); + output_en = 1; gpio_output_enable(io_num); } else { gpio_output_disable(io_num); } if(pGPIOConfig->pull_up_en) { - ESP_LOGI(GPIO_TAG, "PU "); + pu_en = 1; PIN_PULLUP_EN(io_reg); } else { PIN_PULLUP_DIS(io_reg); } if(pGPIOConfig->pull_down_en) { - ESP_LOGI(GPIO_TAG, "PD "); + pd_en = 1; PIN_PULLDWN_EN(io_reg); } else { PIN_PULLDWN_DIS(io_reg); } - ESP_LOGI(GPIO_TAG, "Intr:%d |\n",pGPIOConfig->intr_type); + ESP_LOGI(GPIO_TAG, "GPIO[%d]| InputEn: %d| OutputEn: %d| OpenDrain: %d| Pullup: %d| Pulldown: %d| Intr:%d ", io_num, input_en, output_en, od_en, pu_en, pd_en, pGPIOConfig->intr_type); gpio_set_intr_type(io_num, pGPIOConfig->intr_type); if(pGPIOConfig->intr_type) { gpio_intr_enable(io_num); @@ -268,8 +271,6 @@ esp_err_t gpio_config(gpio_config_t *pGPIOConfig) gpio_intr_disable(io_num); } PIN_FUNC_SELECT(io_reg, PIN_FUNC_GPIO); /*function number 2 is GPIO_FUNC for each pin */ - } else if(bit_valid && (io_reg == 0)) { - ESP_LOGW(GPIO_TAG, "io_num=%d does not exist\n",io_num); } io_num++; } while(io_num < GPIO_PIN_COUNT); @@ -278,7 +279,7 @@ esp_err_t gpio_config(gpio_config_t *pGPIOConfig) esp_err_t gpio_isr_register(uint32_t gpio_intr_num, void (*fn)(void*), void * arg) { - GPIO_CHECK(fn, "GPIO ISR null\n", ESP_ERR_INVALID_ARG); + GPIO_CHECK(fn, "GPIO ISR null", ESP_ERR_INVALID_ARG); ESP_INTR_DISABLE(gpio_intr_num); intr_matrix_set(xPortGetCoreID(), ETS_GPIO_INTR_SOURCE, gpio_intr_num); xt_set_interrupt_handler(gpio_intr_num, fn, arg); @@ -289,13 +290,13 @@ esp_err_t gpio_isr_register(uint32_t gpio_intr_num, void (*fn)(void*), void * ar /*only level interrupt can be used for wake-up function*/ esp_err_t gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type) { - GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error\n", ESP_ERR_INVALID_ARG); + GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); esp_err_t ret = ESP_OK; if((intr_type == GPIO_INTR_LOW_LEVEL) || (intr_type == GPIO_INTR_HIGH_LEVEL)) { GPIO.pin[gpio_num].int_type = intr_type; GPIO.pin[gpio_num].wakeup_enable = 0x1; } else { - ESP_LOGE(GPIO_TAG, "GPIO wakeup only support Level mode,but edge mode set. gpio_num:%u\n",gpio_num); + ESP_LOGE(GPIO_TAG, "GPIO wakeup only support Level mode,but edge mode set. gpio_num:%u",gpio_num); ret = ESP_ERR_INVALID_ARG; } return ret; @@ -303,7 +304,7 @@ esp_err_t gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type) esp_err_t gpio_wakeup_disable(gpio_num_t gpio_num) { - GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error\n", ESP_ERR_INVALID_ARG); + GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); GPIO.pin[gpio_num].wakeup_enable = 0; return ESP_OK; } diff --git a/components/driver/include/driver/uart.h b/components/driver/include/driver/uart.h index ba487d57d5..7dccf1666c 100644 --- a/components/driver/include/driver/uart.h +++ b/components/driver/include/driver/uart.h @@ -38,12 +38,18 @@ extern "C" { #define UART_BITRATE_MAX 5000000 #define UART_PIN_NO_CHANGE (-1) +#define UART_INVERSE_DISABLE (0x0) /*!< Disable UART signal inverse*/ +#define UART_INVERSE_RXD (UART_RXD_INV_M) /*!< UART RXD input inverse*/ +#define UART_INVERSE_CTS (UART_CTS_INV_M) /*!< UART CTS input inverse*/ +#define UART_INVERSE_TXD (UART_TXD_INV_M) /*!< UART TXD output inverse*/ +#define UART_INVERSE_RTS (UART_RTS_INV_M) /*!< UART RTS output inverse*/ + typedef enum { UART_DATA_5_BITS = 0x0, /*!< word length: 5bits*/ UART_DATA_6_BITS = 0x1, /*!< word length: 6bits*/ UART_DATA_7_BITS = 0x2, /*!< word length: 7bits*/ UART_DATA_8_BITS = 0x3, /*!< word length: 8bits*/ - UART_DATA_MAX_BITS = 0X4, + UART_DATA_BITS_MAX = 0X4, } uart_word_length_t; typedef enum { @@ -74,14 +80,6 @@ typedef enum { UART_HW_FLOWCTRL_MAX = 0x4, } uart_hw_flowcontrol_t; -typedef enum { - UART_INVERSE_DISABLE = 0x0, /*!< Disable UART wire output inverse*/ - UART_INVERSE_RXD = (uint32_t)UART_RXD_INV_M, /*!< UART RXD input inverse*/ - UART_INVERSE_CTS = (uint32_t)UART_CTS_INV_M, /*!< UART CTS input inverse*/ - UART_INVERSE_TXD = (uint32_t)UART_TXD_INV_M, /*!< UART TXD output inverse*/ - UART_INVERSE_RTS = (uint32_t)UART_RTS_INV_M, /*!< UART RTS output inverse*/ -} uart_inverse_t; - typedef struct { int baud_rate; /*!< UART baudrate*/ uart_word_length_t data_bits; /*!< UART byte size*/ @@ -110,14 +108,8 @@ typedef enum { } uart_event_type_t; typedef struct { - uart_event_type_t type; - union { - struct { - int brk_len; - size_t size; - uint8_t data[]; - } data; - }; + uart_event_type_t type; /*!< UART event type */ + size_t size; /*!< UART data size for UART_DATA event*/ } uart_event_t; /** @@ -225,14 +217,13 @@ esp_err_t uart_get_baudrate(uart_port_t uart_num, uint32_t* baudrate); * * @param inverse_mask Choose the wires that need to be inversed. * - * (inverse_mask should be chosen from uart_inverse_t, combine with OR-OPERATION) + * (inverse_mask should be chosen from UART_INVERSE_RXD/UART_INVERSE_TXD/UART_INVERSE_RTS/UART_INVERSE_CTS, combine with OR-OPERATION) * * @return * - ESP_OK Success * - ESP_FAIL Parameter error */ -esp_err_t uart_set_line_inverse(uart_port_t uart_no, uint32_t inverse_mask) ; - +esp_err_t uart_set_line_inverse(uart_port_t uart_no, uint32_t inverse_mask); /** * @brief Set hardware flow control. @@ -701,11 +692,13 @@ esp_err_t uart_flush(uart_port_t uart_num); * if(xQueueReceive(uart0_queue, (void * )&event, (portTickType)portMAX_DELAY)) { * ESP_LOGI(TAG, "uart[%d] event:", uart_num); * switch(event.type) { + * memset(dtmp, 0, sizeof(dtmp)); * //Event of UART receving data * case UART_DATA: - * ESP_LOGI(TAG,"data, len: %d\n", event.data.size); - * int len = uart_read_bytes(uart_num, dtmp, event.data.size, 10); - * ESP_LOGI(TAG, "uart read: %d\n", len); + * ESP_LOGI(TAG,"data, len: %d", event.size); + * int len = uart_read_bytes(uart_num, dtmp, event.size, 10); + * ESP_LOGI(TAG, "uart read: %d", len); + uart_write_bytes(uart_num, (const char*)dtmp, len); * break; * //Event of HW FIFO overflow detected * case UART_FIFO_OVF: diff --git a/components/driver/ledc.c b/components/driver/ledc.c index b9039cf626..41eb82cbdd 100644 --- a/components/driver/ledc.c +++ b/components/driver/ledc.c @@ -23,14 +23,14 @@ static const char* LEDC_TAG = "LEDC"; static portMUX_TYPE ledc_spinlock = portMUX_INITIALIZER_UNLOCKED; #define LEDC_CHECK(a, str, ret_val) if (!(a)) { \ - ESP_LOGE(LEDC_TAG,"%s:%d (%s):%s\n", __FILE__, __LINE__, __FUNCTION__, str); \ + ESP_LOGE(LEDC_TAG,"%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, str); \ return (ret_val); \ } esp_err_t ledc_timer_set(ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t div_num, uint32_t bit_num, ledc_clk_src_t clk_src) { - LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error\n", ESP_ERR_INVALID_ARG); - LEDC_CHECK(timer_sel <= LEDC_TIMER_3, "ledc timer error\n", ESP_ERR_INVALID_ARG); + LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error", ESP_ERR_INVALID_ARG); + LEDC_CHECK(timer_sel <= LEDC_TIMER_3, "ledc timer error", ESP_ERR_INVALID_ARG); portENTER_CRITICAL(&ledc_spinlock); LEDC.timer_group[speed_mode].timer[timer_sel].conf.div_num = div_num; LEDC.timer_group[speed_mode].timer[timer_sel].conf.tick_sel = clk_src; @@ -58,8 +58,8 @@ static esp_err_t ledc_duty_config(ledc_mode_t speed_mode, uint32_t channel_num, esp_err_t ledc_bind_channel_timer(ledc_mode_t speed_mode, uint32_t channel, uint32_t timer_idx) { - LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error\n", ESP_ERR_INVALID_ARG); - LEDC_CHECK(timer_idx <= LEDC_TIMER_3, "ledc timer error\n", ESP_ERR_INVALID_ARG); + LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error", ESP_ERR_INVALID_ARG); + LEDC_CHECK(timer_idx <= LEDC_TIMER_3, "ledc timer error", ESP_ERR_INVALID_ARG); portENTER_CRITICAL(&ledc_spinlock); LEDC.channel_group[speed_mode].channel[channel].conf0.timer_sel = timer_idx; portEXIT_CRITICAL(&ledc_spinlock); @@ -68,8 +68,8 @@ esp_err_t ledc_bind_channel_timer(ledc_mode_t speed_mode, uint32_t channel, uint esp_err_t ledc_timer_rst(ledc_mode_t speed_mode, uint32_t timer_sel) { - LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error\n", ESP_ERR_INVALID_ARG); - LEDC_CHECK(timer_sel <= LEDC_TIMER_3, "ledc timer error\n", ESP_ERR_INVALID_ARG); + LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error", ESP_ERR_INVALID_ARG); + LEDC_CHECK(timer_sel <= LEDC_TIMER_3, "ledc timer error", ESP_ERR_INVALID_ARG); portENTER_CRITICAL(&ledc_spinlock); LEDC.timer_group[speed_mode].timer[timer_sel].conf.rst = 1; LEDC.timer_group[speed_mode].timer[timer_sel].conf.rst = 0; @@ -79,8 +79,8 @@ esp_err_t ledc_timer_rst(ledc_mode_t speed_mode, uint32_t timer_sel) esp_err_t ledc_timer_pause(ledc_mode_t speed_mode, uint32_t timer_sel) { - LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error\n", ESP_ERR_INVALID_ARG); - LEDC_CHECK(timer_sel <= LEDC_TIMER_3, "ledc timer error\n", ESP_ERR_INVALID_ARG); + LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error", ESP_ERR_INVALID_ARG); + LEDC_CHECK(timer_sel <= LEDC_TIMER_3, "ledc timer error", ESP_ERR_INVALID_ARG); portENTER_CRITICAL(&ledc_spinlock); LEDC.timer_group[speed_mode].timer[timer_sel].conf.pause = 1; portEXIT_CRITICAL(&ledc_spinlock); @@ -89,8 +89,8 @@ esp_err_t ledc_timer_pause(ledc_mode_t speed_mode, uint32_t timer_sel) esp_err_t ledc_timer_resume(ledc_mode_t speed_mode, uint32_t timer_sel) { - LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error\n", ESP_ERR_INVALID_ARG); - LEDC_CHECK(timer_sel <= LEDC_TIMER_3, "ledc timer error\n", ESP_ERR_INVALID_ARG); + LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error", ESP_ERR_INVALID_ARG); + LEDC_CHECK(timer_sel <= LEDC_TIMER_3, "ledc timer error", ESP_ERR_INVALID_ARG); portENTER_CRITICAL(&ledc_spinlock); LEDC.timer_group[speed_mode].timer[timer_sel].conf.pause = 0; portEXIT_CRITICAL(&ledc_spinlock); @@ -99,7 +99,7 @@ esp_err_t ledc_timer_resume(ledc_mode_t speed_mode, uint32_t timer_sel) static esp_err_t ledc_enable_intr_type(ledc_mode_t speed_mode, uint32_t channel, ledc_intr_type_t type) { - LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error\n", ESP_ERR_INVALID_ARG); + LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error", ESP_ERR_INVALID_ARG); uint32_t value; uint32_t intr_type = type; portENTER_CRITICAL(&ledc_spinlock); @@ -115,7 +115,7 @@ static esp_err_t ledc_enable_intr_type(ledc_mode_t speed_mode, uint32_t channel, esp_err_t ledc_isr_register(uint32_t ledc_intr_num, void (*fn)(void*), void * arg) { - LEDC_CHECK(fn, "ledc isr null\n", ESP_ERR_INVALID_ARG); + LEDC_CHECK(fn, "ledc isr null", ESP_ERR_INVALID_ARG); portENTER_CRITICAL(&ledc_spinlock); ESP_INTR_DISABLE(ledc_intr_num); intr_matrix_set(xPortGetCoreID(), ETS_LEDC_INTR_SOURCE, ledc_intr_num); @@ -131,13 +131,13 @@ esp_err_t ledc_timer_config(ledc_timer_config_t* timer_conf) int bit_num = timer_conf->bit_num; int timer_num = timer_conf->timer_num; int speed_mode = timer_conf->speed_mode; - LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error\n", ESP_ERR_INVALID_ARG); + LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error", ESP_ERR_INVALID_ARG); if(freq_hz == 0 || bit_num == 0 || bit_num > LEDC_TIMER_15_BIT) { - ESP_LOGE(LEDC_TAG, "freq_hz=%u bit_num=%u\n", freq_hz, bit_num); + ESP_LOGE(LEDC_TAG, "freq_hz=%u bit_num=%u", freq_hz, bit_num); return ESP_ERR_INVALID_ARG; } if(timer_num > LEDC_TIMER_3) { - ESP_LOGE(LEDC_TAG, "Time Select %u\n", timer_num); + ESP_LOGE(LEDC_TAG, "Time Select %u", timer_num); return ESP_ERR_INVALID_ARG; } esp_err_t ret = ESP_OK; @@ -149,7 +149,7 @@ esp_err_t ledc_timer_config(ledc_timer_config_t* timer_conf) /*Selet the reference tick*/ div_param = ((uint64_t) LEDC_REF_CLK_HZ << 8) / freq_hz / precision; if(div_param <= 256 || div_param > LEDC_DIV_NUM_HSTIMER0_V) { - ESP_LOGE(LEDC_TAG, "div param err,div_param=%u\n", (uint32_t)div_param); + ESP_LOGE(LEDC_TAG, "div param err,div_param=%u", (uint32_t)div_param); ret = ESP_FAIL; } timer_clk_src = LEDC_REF_TICK; @@ -166,9 +166,9 @@ esp_err_t ledc_timer_config(ledc_timer_config_t* timer_conf) esp_err_t ledc_set_pin(int gpio_num, ledc_mode_t speed_mode, ledc_channel_t ledc_channel) { - LEDC_CHECK(ledc_channel <= LEDC_CHANNEL_7, "ledc channel error\n", ESP_ERR_INVALID_ARG); - LEDC_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "ledc GPIO output number error\n", ESP_ERR_INVALID_ARG); - LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error\n", ESP_ERR_INVALID_ARG); + LEDC_CHECK(ledc_channel <= LEDC_CHANNEL_7, "ledc channel error", ESP_ERR_INVALID_ARG); + LEDC_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "ledc GPIO output number error", ESP_ERR_INVALID_ARG); + LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error", ESP_ERR_INVALID_ARG); PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[gpio_num], PIN_FUNC_GPIO); gpio_set_direction(gpio_num, GPIO_MODE_OUTPUT); if(speed_mode == LEDC_HIGH_SPEED_MODE) { @@ -187,10 +187,10 @@ esp_err_t ledc_channel_config(ledc_channel_config_t* ledc_conf) uint32_t timer_select = ledc_conf->timer_sel; uint32_t intr_type = ledc_conf->intr_type; uint32_t duty = ledc_conf->duty; - LEDC_CHECK(ledc_channel <= LEDC_CHANNEL_7, "ledc channel error\n", ESP_ERR_INVALID_ARG); - LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error\n", ESP_ERR_INVALID_ARG); - LEDC_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "ledc GPIO output number error\n", ESP_ERR_INVALID_ARG); - LEDC_CHECK(timer_select <= LEDC_TIMER_3, "ledc timer error\n", ESP_ERR_INVALID_ARG); + LEDC_CHECK(ledc_channel <= LEDC_CHANNEL_7, "ledc channel error", ESP_ERR_INVALID_ARG); + LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error", ESP_ERR_INVALID_ARG); + LEDC_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "ledc GPIO output number error", ESP_ERR_INVALID_ARG); + LEDC_CHECK(timer_select <= LEDC_TIMER_3, "ledc timer error", ESP_ERR_INVALID_ARG); esp_err_t ret = ESP_OK; /*set channel parameters*/ /* channel parameters decide how the waveform looks like in one period*/ @@ -202,7 +202,7 @@ esp_err_t ledc_channel_config(ledc_channel_config_t* ledc_conf) ledc_bind_channel_timer(speed_mode, ledc_channel, timer_select); /*set interrupt type*/ ledc_enable_intr_type(speed_mode, ledc_channel, intr_type); - ESP_LOGI(LEDC_TAG, "LEDC_PWM CHANNEL %1u|GPIO %02u|Duty %04u|Time %01u\n", + ESP_LOGI(LEDC_TAG, "LEDC_PWM CHANNEL %1u|GPIO %02u|Duty %04u|Time %01u", ledc_channel, gpio_num, duty, timer_select ); /*set LEDC signal in gpio matrix*/ @@ -214,8 +214,8 @@ esp_err_t ledc_channel_config(ledc_channel_config_t* ledc_conf) esp_err_t ledc_update_duty(ledc_mode_t speed_mode, ledc_channel_t channel) { - LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error\n", ESP_ERR_INVALID_ARG); - LEDC_CHECK(channel <= LEDC_CHANNEL_7, "ledc channel error\n", ESP_ERR_INVALID_ARG); + LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error", ESP_ERR_INVALID_ARG); + LEDC_CHECK(channel <= LEDC_CHANNEL_7, "ledc channel error", ESP_ERR_INVALID_ARG); portENTER_CRITICAL(&ledc_spinlock); LEDC.channel_group[speed_mode].channel[channel].conf0.sig_out_en = 1; LEDC.channel_group[speed_mode].channel[channel].conf1.duty_start = 1; @@ -225,8 +225,8 @@ esp_err_t ledc_update_duty(ledc_mode_t speed_mode, ledc_channel_t channel) esp_err_t ledc_stop(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t idle_level) { - LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error\n", ESP_ERR_INVALID_ARG); - LEDC_CHECK(channel <= LEDC_CHANNEL_7, "ledc channel error\n", ESP_ERR_INVALID_ARG); + LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error", ESP_ERR_INVALID_ARG); + LEDC_CHECK(channel <= LEDC_CHANNEL_7, "ledc channel error", ESP_ERR_INVALID_ARG); portENTER_CRITICAL(&ledc_spinlock); LEDC.channel_group[speed_mode].channel[channel].conf0.idle_lv = idle_level & 0x1; LEDC.channel_group[speed_mode].channel[channel].conf0.sig_out_en = 0; @@ -237,11 +237,11 @@ esp_err_t ledc_stop(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t idl esp_err_t ledc_set_fade(ledc_mode_t speed_mode, uint32_t channel, uint32_t duty, ledc_duty_direction_t fade_direction, uint32_t step_num, uint32_t duty_cyle_num, uint32_t duty_scale) { - LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error\n", ESP_ERR_INVALID_ARG); - LEDC_CHECK(channel <= LEDC_CHANNEL_7, "ledc channel error\n", ESP_ERR_INVALID_ARG); - LEDC_CHECK(fade_direction <= LEDC_DUTY_DIR_INCREASE, "ledc fade direction error\n", ESP_ERR_INVALID_ARG); + LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error", ESP_ERR_INVALID_ARG); + LEDC_CHECK(channel <= LEDC_CHANNEL_7, "ledc channel error", ESP_ERR_INVALID_ARG); + LEDC_CHECK(fade_direction <= LEDC_DUTY_DIR_INCREASE, "ledc fade direction error", ESP_ERR_INVALID_ARG); if(step_num > LEDC_DUTY_NUM_HSCH0_V || duty_cyle_num > LEDC_DUTY_CYCLE_HSCH0_V || duty_scale > LEDC_DUTY_SCALE_HSCH0_V) { - ESP_LOGE(LEDC_TAG, "step_num=%u duty_cyle_num=%u duty_scale=%u\n", step_num, duty_cyle_num, duty_scale); + ESP_LOGE(LEDC_TAG, "step_num=%u duty_cyle_num=%u duty_scale=%u", step_num, duty_cyle_num, duty_scale); return ESP_ERR_INVALID_ARG; } ledc_duty_config(speed_mode, @@ -258,8 +258,8 @@ esp_err_t ledc_set_fade(ledc_mode_t speed_mode, uint32_t channel, uint32_t duty, esp_err_t ledc_set_duty(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t duty) { - LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error\n", ESP_ERR_INVALID_ARG); - LEDC_CHECK(channel <= LEDC_CHANNEL_7, "ledc channel error\n", ESP_ERR_INVALID_ARG); + LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error", ESP_ERR_INVALID_ARG); + LEDC_CHECK(channel <= LEDC_CHANNEL_7, "ledc channel error", ESP_ERR_INVALID_ARG); ledc_duty_config(speed_mode, channel, //uint32_t chan_num, 0, //uint32_t hpoint_val, @@ -274,14 +274,14 @@ esp_err_t ledc_set_duty(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t int ledc_get_duty(ledc_mode_t speed_mode, ledc_channel_t channel) { - LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error\n", (-1)); + LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error", (-1)); uint32_t duty = (LEDC.channel_group[speed_mode].channel[channel].duty_rd.duty_read >> 4); return duty; } esp_err_t ledc_set_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num, uint32_t freq_hz) { - LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error\n", ESP_ERR_INVALID_ARG); + LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error", ESP_ERR_INVALID_ARG); portENTER_CRITICAL(&ledc_spinlock); esp_err_t ret = ESP_OK; uint32_t div_num = 0; @@ -294,7 +294,7 @@ esp_err_t ledc_set_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num, uint32_t div_num = ((uint64_t) LEDC_REF_CLK_HZ << 8) / freq_hz / precision; } if(div_num <= 256 || div_num > LEDC_DIV_NUM_HSTIMER0) { - ESP_LOGE(LEDC_TAG, "div param err,div_param=%u\n", div_num); + ESP_LOGE(LEDC_TAG, "div param err,div_param=%u", div_num); ret = ESP_FAIL; } LEDC.timer_group[speed_mode].timer[timer_num].conf.div_num = div_num; @@ -304,7 +304,7 @@ esp_err_t ledc_set_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num, uint32_t uint32_t ledc_get_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num) { - LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error\n", (0)); + LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error", (0)); portENTER_CRITICAL(&ledc_spinlock); uint32_t freq = 0; uint32_t timer_source_clk = LEDC.timer_group[speed_mode].timer[timer_num].conf.tick_sel; diff --git a/components/driver/uart.c b/components/driver/uart.c index a3e0b92b2b..b961fbed71 100644 --- a/components/driver/uart.c +++ b/components/driver/uart.c @@ -31,7 +31,7 @@ static const char* UART_TAG = "UART"; #define UART_CHECK(a, str, ret) if (!(a)) { \ - ESP_LOGE(UART_TAG,"%s:%d (%s):%s\n", __FILE__, __LINE__, __FUNCTION__, str); \ + ESP_LOGE(UART_TAG,"%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, str); \ return (ret); \ } #define UART_EMPTY_THRESH_DEFAULT (10) @@ -42,6 +42,14 @@ static const char* UART_TAG = "UART"; #define UART_ENTER_CRITICAL(mux) portENTER_CRITICAL(mux) #define UART_EXIT_CRITICAL(mux) portEXIT_CRITICAL(mux) +typedef struct { + uart_event_type_t type; /*!< UART TX data type */ + struct { + int brk_len; + size_t size; + uint8_t data[0]; + } tx_data; +} uart_tx_data_t; typedef struct { uart_port_t uart_num; /*!< UART port number*/ @@ -67,7 +75,7 @@ typedef struct { RingbufHandle_t tx_ring_buf; /*!< TX ring buffer handler*/ bool tx_waiting_fifo; /*!< this flag indicates that some task is waiting for FIFO empty interrupt, used to send all data without any data buffer*/ uint8_t* tx_ptr; /*!< TX data pointer to push to FIFO in TX buffer mode*/ - uart_event_t* tx_head; /*!< TX data pointer to head of the current buffer in TX ring buffer*/ + uart_tx_data_t* tx_head; /*!< TX data pointer to head of the current buffer in TX ring buffer*/ uint32_t tx_len_tot; /*!< Total length of current item in ring buffer*/ uint32_t tx_len_cur; uint8_t tx_brk_flg; /*!< Flag to indicate to send a break signal in the end of the item sending procedure */ @@ -75,6 +83,8 @@ typedef struct { uint8_t tx_waiting_brk; /*!< Flag to indicate that TX FIFO is ready to send break signal after FIFO is empty, do not push data into TX FIFO right now.*/ } uart_obj_t; + + static uart_obj_t *p_uart_obj[UART_NUM_MAX] = {0}; static uart_dev_t* UART[UART_NUM_MAX] = {&UART0, &UART1, &UART2}; static portMUX_TYPE uart_spinlock[UART_NUM_MAX] = {portMUX_INITIALIZER_UNLOCKED, portMUX_INITIALIZER_UNLOCKED, portMUX_INITIALIZER_UNLOCKED}; @@ -82,7 +92,7 @@ static portMUX_TYPE uart_spinlock[UART_NUM_MAX] = {portMUX_INITIALIZER_UNLOCKED, esp_err_t uart_set_word_length(uart_port_t uart_num, uart_word_length_t data_bit) { UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); - UART_CHECK((data_bit < UART_DATA_MAX_BITS), "data bit error", ESP_FAIL); + UART_CHECK((data_bit < UART_DATA_BITS_MAX), "data bit error", ESP_FAIL); UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); UART[uart_num]->conf0.bit_num = data_bit; UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); @@ -366,7 +376,7 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r esp_err_t uart_set_rts(uart_port_t uart_num, int level) { UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); - UART_CHECK((UART[uart_num]->conf1.rx_flow_en != 1), "disable hw flowctrl before using sw control\n", ESP_FAIL); + UART_CHECK((UART[uart_num]->conf1.rx_flow_en != 1), "disable hw flowctrl before using sw control", ESP_FAIL); UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); UART[uart_num]->conf0.sw_rts = level & 0x1; UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); @@ -385,7 +395,7 @@ esp_err_t uart_set_dtr(uart_port_t uart_num, int level) esp_err_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_config) { UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); - UART_CHECK((uart_config), "param null\n", ESP_FAIL); + UART_CHECK((uart_config), "param null", ESP_FAIL); if(uart_num == UART_NUM_0) { periph_module_enable(PERIPH_UART0_MODULE); } else if(uart_num == UART_NUM_1) { @@ -407,7 +417,7 @@ esp_err_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_conf esp_err_t uart_intr_config(uart_port_t uart_num, const uart_intr_config_t *intr_conf) { UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); - UART_CHECK((intr_conf), "param null\n", ESP_FAIL); + UART_CHECK((intr_conf), "param null", ESP_FAIL); UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); UART[uart_num]->int_clr.val = UART_INTR_MASK; if(intr_conf->intr_enable_mask & UART_RXFIFO_TOUT_INT_ENA_M) { @@ -468,17 +478,17 @@ static void IRAM_ATTR uart_rx_intr_handler_default(void *param) while(tx_fifo_rem) { if(p_uart->tx_len_tot == 0 || p_uart->tx_ptr == NULL || p_uart->tx_len_cur == 0) { size_t size; - p_uart->tx_head = (uart_event_t*) xRingbufferReceiveFromISR(p_uart->tx_ring_buf, &size); + p_uart->tx_head = (uart_tx_data_t*) xRingbufferReceiveFromISR(p_uart->tx_ring_buf, &size); if(p_uart->tx_head) { //The first item is the data description //Get the first item to get the data information if(p_uart->tx_len_tot == 0) { p_uart->tx_ptr = NULL; - p_uart->tx_len_tot = p_uart->tx_head->data.size; + p_uart->tx_len_tot = p_uart->tx_head->tx_data.size; if(p_uart->tx_head->type == UART_DATA_BREAK) { - p_uart->tx_len_tot = p_uart->tx_head->data.size; + p_uart->tx_len_tot = p_uart->tx_head->tx_data.size; p_uart->tx_brk_flg = 1; - p_uart->tx_brk_len = p_uart->tx_head->data.brk_len; + p_uart->tx_brk_len = p_uart->tx_head->tx_data.brk_len; } //We have saved the data description from the 1st item, return buffer. vRingbufferReturnItemFromISR(p_uart->tx_ring_buf, p_uart->tx_head, &HPTaskAwoken); @@ -553,7 +563,7 @@ static void IRAM_ATTR uart_rx_intr_handler_default(void *param) uart_reg->int_clr.rxfifo_full = 1; UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); uart_event.type = UART_DATA; - uart_event.data.size = rx_fifo_len; + uart_event.size = rx_fifo_len; //If we fail to push data to ring buffer, we will have to stash the data, and send next time. //Mainly for applications that uses flow control or small ring buffer. if(pdFALSE == xRingbufferSendFromISR(p_uart->rx_ring_buf, p_uart->rx_data_buf, p_uart->rx_stash_len, &HPTaskAwoken)) { @@ -711,9 +721,9 @@ static int uart_tx_all(uart_port_t uart_num, const char* src, size_t size, bool if(p_uart_obj[uart_num]->tx_buf_size > 0) { int max_size = xRingbufferGetMaxItemSize(p_uart_obj[uart_num]->tx_ring_buf); int offset = 0; - uart_event_t evt; - evt.data.size = size; - evt.data.brk_len = brk_len; + uart_tx_data_t evt; + evt.tx_data.size = size; + evt.tx_data.brk_len = brk_len; if(brk_en) { evt.type = UART_DATA_BREAK; } else { @@ -882,12 +892,12 @@ esp_err_t uart_flush(uart_port_t uart_num) esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_buffer_size, int queue_size, int uart_intr_num, void* uart_queue) { UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); - UART_CHECK((rx_buffer_size > 0), "uart rx buffer length error\n", ESP_FAIL); + UART_CHECK((rx_buffer_size > 0), "uart rx buffer length error", ESP_FAIL); if(p_uart_obj[uart_num] == NULL) { ESP_INTR_DISABLE(uart_intr_num); p_uart_obj[uart_num] = (uart_obj_t*) malloc(sizeof(uart_obj_t)); if(p_uart_obj[uart_num] == NULL) { - ESP_LOGE(UART_TAG, "UART driver malloc error\n"); + ESP_LOGE(UART_TAG, "UART driver malloc error"); return ESP_FAIL; } p_uart_obj[uart_num]->uart_num = uart_num; @@ -909,7 +919,7 @@ esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_b if(uart_queue) { p_uart_obj[uart_num]->xQueueUart = xQueueCreate(queue_size, sizeof(uart_event_t)); *((QueueHandle_t*) uart_queue) = p_uart_obj[uart_num]->xQueueUart; - ESP_LOGI(UART_TAG, "queue free spaces: %d\n", uxQueueSpacesAvailable(p_uart_obj[uart_num]->xQueueUart)); + ESP_LOGI(UART_TAG, "queue free spaces: %d", uxQueueSpacesAvailable(p_uart_obj[uart_num]->xQueueUart)); } else { p_uart_obj[uart_num]->xQueueUart = NULL; } @@ -927,7 +937,7 @@ esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_b p_uart_obj[uart_num]->tx_buf_size = 0; } } else { - ESP_LOGE(UART_TAG, "UART driver already installed\n"); + ESP_LOGE(UART_TAG, "UART driver already installed"); return ESP_FAIL; } uart_isr_register(uart_num, uart_intr_num, uart_rx_intr_handler_default, p_uart_obj[uart_num]); @@ -951,7 +961,7 @@ esp_err_t uart_driver_delete(uart_port_t uart_num) { UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); if(p_uart_obj[uart_num] == NULL) { - ESP_LOGI(UART_TAG, "ALREADY NULL\n"); + ESP_LOGI(UART_TAG, "ALREADY NULL"); return ESP_OK; } ESP_INTR_DISABLE(p_uart_obj[uart_num]->intr_num); From 98a0387854918b73d10e00820e40a36786ee8eab Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 2 Nov 2016 17:54:47 +1100 Subject: [PATCH 277/343] bootloader_support: Move secure boot code to bootloader_support --- .../bootloader/src/main/bootloader_config.h | 1 - .../bootloader/src/main/bootloader_start.c | 7 +- .../{esp_secureboot.h => esp_secure_boot.h} | 24 +++- .../src}/secure_boot.c | 128 +++++++++--------- .../bootloader_support/src/secureboot.c | 7 - 5 files changed, 85 insertions(+), 82 deletions(-) rename components/bootloader_support/include/{esp_secureboot.h => esp_secure_boot.h} (64%) rename components/{bootloader/src/main => bootloader_support/src}/secure_boot.c (71%) delete mode 100644 components/bootloader_support/src/secureboot.c diff --git a/components/bootloader/src/main/bootloader_config.h b/components/bootloader/src/main/bootloader_config.h index 0823581824..4559d5f816 100644 --- a/components/bootloader/src/main/bootloader_config.h +++ b/components/bootloader/src/main/bootloader_config.h @@ -60,7 +60,6 @@ typedef struct { } bootloader_state_t; bool flash_encrypt(bootloader_state_t *bs); -bool secure_boot_generate_bootloader_digest(void); #ifdef __cplusplus } diff --git a/components/bootloader/src/main/bootloader_start.c b/components/bootloader/src/main/bootloader_start.c index 3bc2696a4b..59b180fd84 100644 --- a/components/bootloader/src/main/bootloader_start.c +++ b/components/bootloader/src/main/bootloader_start.c @@ -34,6 +34,7 @@ #include "sdkconfig.h" #include "esp_image_format.h" +#include "esp_secure_boot.h" #include "bootloader_flash.h" #include "bootloader_config.h" @@ -214,6 +215,7 @@ void bootloader_main() { ESP_LOGI(TAG, "Espressif ESP32 2nd stage bootloader v. %s", BOOT_VERSION); + esp_err_t err; esp_image_header_t fhdr; bootloader_state_t bs; SpiFlashOpResult spiRet1,spiRet2; @@ -308,8 +310,9 @@ void bootloader_main() if(fhdr.secure_boot_flag == 0x01) { /* Generate secure digest from this bootloader to protect future modifications */ - if (secure_boot_generate_bootloader_digest() == false){ - ESP_LOGE(TAG, "Bootloader digest generation failed. SECURE BOOT IS NOT ENABLED."); + err = esp_secure_boot_permanently_enable(); + if (err != ESP_OK){ + ESP_LOGE(TAG, "Bootloader digest generation failed (%d). SECURE BOOT IS NOT ENABLED.", err); /* Allow booting to continue, as the failure is probably due to user-configured EFUSEs for testing... */ diff --git a/components/bootloader_support/include/esp_secureboot.h b/components/bootloader_support/include/esp_secure_boot.h similarity index 64% rename from components/bootloader_support/include/esp_secureboot.h rename to components/bootloader_support/include/esp_secure_boot.h index b0097df8a6..4bf2dc8b23 100644 --- a/components/bootloader_support/include/esp_secureboot.h +++ b/components/bootloader_support/include/esp_secure_boot.h @@ -16,6 +16,7 @@ #include #include +#include "soc/efuse_reg.h" /* Support functions for secure boot features. @@ -30,21 +31,34 @@ * * @return true if secure boot is enabled. */ -bool esp_secure_boot_enabled(void); +static inline bool esp_secure_boot_enabled(void) { + return REG_GET_FIELD(EFUSE_BLK0_RDATA6_REG, EFUSE_RD_ABS_DONE_0); +} -/** @brief Enable secure boot if it isw not already enabled. +/** @brief Enable secure boot if it is not already enabled. * - * @important If this function succeeds, secure boot is permanentl + * @important If this function succeeds, secure boot is permanently * enabled on the chip via efuse. * - * This function is intended to be called from bootloader code. + * @important This function is intended to be called from bootloader code only. + * + * If secure boot is not yet enabled for bootloader, this will + * generate the secure boot digest and enable secure boot by blowing + * the EFUSE_RD_ABS_DONE_0 efuse. + * + * This function does not verify secure boot of the bootloader (the + * ROM bootloader does this.) + * + * Will fail if efuses have been part-burned in a way that indicates + * secure boot should not or could not be correctly enabled. + * * * @return ESP_ERR_INVALID_STATE if efuse state doesn't allow * secure boot to be enabled cleanly. ESP_OK if secure boot * is enabled on this chip from now on. */ -esp_err_t esp_secure_boot_enable(void); +esp_err_t esp_secure_boot_permanently_enable(void); diff --git a/components/bootloader/src/main/secure_boot.c b/components/bootloader_support/src/secure_boot.c similarity index 71% rename from components/bootloader/src/main/secure_boot.c rename to components/bootloader_support/src/secure_boot.c index 2b1b8573fc..c17aebfbea 100644 --- a/components/bootloader/src/main/secure_boot.c +++ b/components/bootloader_support/src/secure_boot.c @@ -30,72 +30,81 @@ #include "sdkconfig.h" -#include "bootloader_config.h" #include "bootloader_flash.h" #include "esp_image_format.h" +#include "esp_secure_boot.h" static const char* TAG = "secure_boot"; +#define HASH_BLOCK_SIZE 128 +#define IV_LEN HASH_BLOCK_SIZE +#define DIGEST_LEN 64 + /** * @function : secure_boot_generate - * @description: generate boot abstract & iv + * @description: generate boot digest (aka "abstract") & iv * - * @inputs: bool + * @inputs: image_len - length of image to calculate digest for */ static bool secure_boot_generate(uint32_t image_len){ - SpiFlashOpResult spiRet; - uint32_t buf[32]; + SpiFlashOpResult spiRet; + /* buffer is uint32_t not uint8_t to meet ROM SPI API signature */ + uint32_t buf[IV_LEN / sizeof(uint32_t)]; const void *image; - if (image_len % 128 != 0) { - image_len = (image_len / 128 + 1) * 128; - } - ets_secure_boot_start(); - ets_secure_boot_rd_iv(buf); - ets_secure_boot_hash(NULL); - Cache_Read_Disable(0); - /* iv stored in sec 0 */ - spiRet = SPIEraseSector(0); - if (spiRet != SPI_FLASH_RESULT_OK) - { - ESP_LOGE(TAG, SPI_ERROR_LOG); - return false; - } - Cache_Read_Enable(0); + /* hardware secure boot engine only takes full blocks, so round up the + image length. The additional data should all be 0xFF. + */ + if (image_len % HASH_BLOCK_SIZE != 0) { + image_len = (image_len / HASH_BLOCK_SIZE + 1) * HASH_BLOCK_SIZE; + } + ets_secure_boot_start(); + ets_secure_boot_rd_iv(buf); + ets_secure_boot_hash(NULL); + Cache_Read_Disable(0); + /* iv stored in sec 0 */ + spiRet = SPIEraseSector(0); + if (spiRet != SPI_FLASH_RESULT_OK) + { + ESP_LOGE(TAG, "SPI erase failed %d", spiRet); + return false; + } + Cache_Read_Enable(0); - /* write iv to flash, 0x0000, 128 bytes (1024 bits) */ + /* write iv to flash, 0x0000, 128 bytes (1024 bits) */ ESP_LOGD(TAG, "write iv to flash."); - spiRet = SPIWrite(0, buf, 128); - if (spiRet != SPI_FLASH_RESULT_OK) - { - ESP_LOGE(TAG, SPI_ERROR_LOG); - return false; - } + spiRet = SPIWrite(0, buf, IV_LEN); + if (spiRet != SPI_FLASH_RESULT_OK) + { + ESP_LOGE(TAG, "SPI write failed %d", spiRet); + return false; + } + bzero(buf, sizeof(buf)); - /* generate digest from image contents */ + /* generate digest from image contents */ image = bootloader_mmap(0x1000, image_len); if (!image) { ESP_LOGE(TAG, "bootloader_mmap(0x1000, 0x%x) failed", image_len); return false; } - for (int i = 0; i < image_len; i+=128) { - ets_secure_boot_hash(image + i/sizeof(void *)); - } + for (int i = 0; i < image_len; i+= HASH_BLOCK_SIZE) { + ets_secure_boot_hash(image + i/sizeof(void *)); + } bootloader_unmap(image); - ets_secure_boot_obtain(); - ets_secure_boot_rd_abstract(buf); - ets_secure_boot_finish(); + ets_secure_boot_obtain(); + ets_secure_boot_rd_abstract(buf); + ets_secure_boot_finish(); - ESP_LOGD(TAG, "write abstract to flash."); - spiRet = SPIWrite(0x80, buf, 64); - if (spiRet != SPI_FLASH_RESULT_OK) { - ESP_LOGE(TAG, SPI_ERROR_LOG); - return false; - } - ESP_LOGD(TAG, "write abstract to flash."); - Cache_Read_Enable(0); - return true; + ESP_LOGD(TAG, "write digest to flash."); + spiRet = SPIWrite(0x80, buf, DIGEST_LEN); + if (spiRet != SPI_FLASH_RESULT_OK) { + ESP_LOGE(TAG, "SPI write failed %d", spiRet); + return false; + } + ESP_LOGD(TAG, "write digest to flash."); + Cache_Read_Enable(0); + return true; } /* Burn values written to the efuse write registers */ @@ -109,34 +118,19 @@ static inline void burn_efuses() while (REG_READ(EFUSE_CMD_REG)); /* wait for efuse_read_cmd=0 */ } -/** - * @brief Enable secure boot if it is not already enabled. - * - * Called if the secure boot flag is set on the - * bootloader image in flash. If secure boot is not yet enabled for - * bootloader, this will generate the secure boot digest and enable - * secure boot by blowing the EFUSE_RD_ABS_DONE_0 efuse. - * - * This function does not verify secure boot of the bootloader (the - * ROM bootloader does this.) - * - * @return true if secure boot is enabled (either was already enabled, - * or is freshly enabled as a result of calling this function.) false - * implies an error occured (possibly secure boot is part-enabled.) - */ -bool secure_boot_generate_bootloader_digest(void) { +esp_err_t esp_secure_boot_permanently_enable(void) { esp_err_t err; uint32_t image_len = 0; - if (REG_READ(EFUSE_BLK0_RDATA6_REG) & EFUSE_RD_ABS_DONE_0) + if (esp_secure_boot_enabled()) { ESP_LOGI(TAG, "bootloader secure boot is already enabled, continuing.."); - return true; + return ESP_OK; } err = esp_image_basic_verify(0x1000, &image_len); if (err != ESP_OK) { ESP_LOGE(TAG, "bootloader image appears invalid! error %d", err); - return false; + return err; } uint32_t dis_reg = REG_READ(EFUSE_BLK0_RDATA0_REG); @@ -178,17 +172,17 @@ bool secure_boot_generate_bootloader_digest(void) { ESP_LOGI(TAG, "Generating secure boot digest..."); if (false == secure_boot_generate(image_len)){ ESP_LOGE(TAG, "secure boot generation failed"); - return false; + return ESP_FAIL; } ESP_LOGI(TAG, "Digest generation complete."); if (!efuse_key_read_protected) { ESP_LOGE(TAG, "Pre-loaded key is not read protected. Refusing to blow secure boot efuse."); - return false; + return ESP_ERR_INVALID_STATE; } if (!efuse_key_write_protected) { ESP_LOGE(TAG, "Pre-loaded key is not write protected. Refusing to blow secure boot efuse."); - return false; + return ESP_ERR_INVALID_STATE; } ESP_LOGI(TAG, "blowing secure boot efuse & disabling JTAG..."); @@ -200,9 +194,9 @@ bool secure_boot_generate_bootloader_digest(void) { ESP_LOGD(TAG, "after updating, EFUSE_BLK0_RDATA6 %x", after); if (after & EFUSE_RD_ABS_DONE_0) { ESP_LOGI(TAG, "secure boot is now enabled for bootloader image"); - return true; + return ESP_OK; } else { ESP_LOGE(TAG, "secure boot not enabled for bootloader image, EFUSE_RD_ABS_DONE_0 is probably write protected!"); - return false; + return ESP_ERR_INVALID_STATE; } } diff --git a/components/bootloader_support/src/secureboot.c b/components/bootloader_support/src/secureboot.c deleted file mode 100644 index e55c1f33fa..0000000000 --- a/components/bootloader_support/src/secureboot.c +++ /dev/null @@ -1,7 +0,0 @@ -#include -#include - -#include "esp_log.h" - - - From fce359b240cc3869f609256701a202c788ba4634 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 6 Oct 2016 12:51:47 +1100 Subject: [PATCH 278/343] build system: Add support for embedded arbitrary binary or text files in .rodata Simplifies examples of embedding a certificate file or a root cert. This is a much cruder mechanism than the full flash filesystem we want eventually, but still sometimes useful. --- docs/build_system.rst | 22 +++++++ examples/04_https_request/main/cert.c | 44 -------------- examples/04_https_request/main/component.mk | 9 ++- .../main/https_request_main.c | 18 +++++- .../main/server_root_cert.pem | 27 +++++++++ make/component_common.mk | 57 ++++++++++++++++--- 6 files changed, 117 insertions(+), 60 deletions(-) delete mode 100644 examples/04_https_request/main/cert.c create mode 100644 examples/04_https_request/main/server_root_cert.pem diff --git a/docs/build_system.rst b/docs/build_system.rst index 34db487e0a..85ebfe46d5 100644 --- a/docs/build_system.rst +++ b/docs/build_system.rst @@ -280,6 +280,28 @@ component and resides under the component path. Because logo.h is a generated file, it needs to be cleaned when make clean is called which why it is added to the COMPONENT_EXTRA_CLEAN variable. +Embedding Binary Data +===================== + +Sometimes you have a file with some binary or text data that you'd like to make available to your component - but you don't want to reformat the file as C source. + +You can set a variable COMPONENT_EMBED_FILES in component.mk, giving the names of the files to embed in this way:: + + COMPONENT_EMBED_FILES := server_root_cert.der + +Or if the file is a string, you can use the variable COMPONENT_EMBED_TXTFILES. This will embed the contents of the text file as a null-terminated string:: + + COMPONENT_EMBED_TXTFILES := server_root_cert.pem + +The file's contents will be added to the .rodata section in flash, and are available via symbol names as follows:: + + extern const uint8_t server_root_cert_pem_start[] asm("_binary_server_root_cert_pem_start"); + extern const uint8_t server_root_cert_pem_end[] asm("_binary_server_root_cert_pem_end"); + +The names are generated from the full name of the file, as given in COMPONENT_EMBED_FILES. Characters /, ., etc. are replaced with underscores. The _binary prefix in the symbol name is added by objcopy and is the same for both text and binary files. + +For an example of using this technique, see examples/04_https_request - the certificate file contents are loaded from the text .pem file at compile time. + Cosmetic Improvements ===================== diff --git a/examples/04_https_request/main/cert.c b/examples/04_https_request/main/cert.c deleted file mode 100644 index 7acc438ef3..0000000000 --- a/examples/04_https_request/main/cert.c +++ /dev/null @@ -1,44 +0,0 @@ -/* This is the CA certificate for the CA trust chain of - www.howsmyssl.com in PEM format, as dumped via: - - openssl s_client -showcerts -connect www.howsmyssl.com:443 -#include -#include - -/* - 1 s:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3 - i:/O=Digital Signature Trust Co./CN=DST Root CA X3 - */ -const char *server_root_cert = "-----BEGIN CERTIFICATE-----\r\n" -"MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/\r\n" -"MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT\r\n" -"DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow\r\n" -"SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT\r\n" -"GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC\r\n" -"AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF\r\n" -"q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8\r\n" -"SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0\r\n" -"Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA\r\n" -"a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj\r\n" -"/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T\r\n" -"AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG\r\n" -"CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv\r\n" -"bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k\r\n" -"c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw\r\n" -"VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC\r\n" -"ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz\r\n" -"MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu\r\n" -"Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF\r\n" -"AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo\r\n" -"uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/\r\n" -"wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu\r\n" -"X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG\r\n" -"PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6\r\n" -"KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==\r\n" -"-----END CERTIFICATE-----\r\n"; - - diff --git a/examples/04_https_request/main/component.mk b/examples/04_https_request/main/component.mk index 24356f23ed..7fbfcc55d2 100644 --- a/examples/04_https_request/main/component.mk +++ b/examples/04_https_request/main/component.mk @@ -1,10 +1,9 @@ # # Main Makefile. This is basically the same as a component makefile. # -# This Makefile should, at the very least, just include $(SDK_PATH)/make/component_common.mk. By default, -# this will take the sources in the src/ directory, compile them and link them into -# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable, -# please read the ESP-IDF documents if you need to do this. -# + +# embed files from the "certs" directory as binary data symbols +# in the app +COMPONENT_EMBED_TXTFILES := server_root_cert.pem include $(IDF_PATH)/make/component_common.mk diff --git a/examples/04_https_request/main/https_request_main.c b/examples/04_https_request/main/https_request_main.c index 0c8b2463f8..7f302409d8 100644 --- a/examples/04_https_request/main/https_request_main.c +++ b/examples/04_https_request/main/https_request_main.c @@ -74,8 +74,18 @@ static const char *REQUEST = "GET " WEB_URL " HTTP/1.1\n" "User-Agent: esp-idf/1.0 esp32\n" "\n"; -/* Root cert for howsmyssl.com, found in cert.c */ -extern const char *server_root_cert; +/* Root cert for howsmyssl.com, taken from server_root_cert.pem + + The PEM file was extracted from the output of this command: + openssl s_client -showcerts -connect www.howsmyssl.com:443 > $$(notdir $$<) ) + $$(Q) $$(OBJCOPY) $(OBJCOPY_EMBED_ARGS) $$(notdir $$<) $$@ + $$(Q) rm $$(notdir $$<) +endef + +# generate targets to embed binary & text files +$(foreach binfile,$(COMPONENT_EMBED_FILES), $(eval $(call GenerateEmbedTarget,$(binfile),bin))) + +$(foreach txtfile,$(COMPONENT_EMBED_TXTFILES), $(eval $(call GenerateEmbedTarget,$(txtfile),txt))) + +# generate targets to create binary embed directories +$(foreach bindir,$(sort $(dir $(COMPONENT_EMBED_FILES))), $(eval $(call GenerateBuildDirTarget,$(bindir)))) From d12078b6926dcb72a5f31e6a0e43cf2f036b04e0 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 8 Nov 2016 11:55:48 +0800 Subject: [PATCH 279/343] Revert "Merge branch 'feature/ci_checkout_same_branch_for_submodule' into 'master'" This reverts merge request !178 --- .gitlab-ci.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2f65fdfc00..1e09b55c44 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -13,14 +13,12 @@ before_script: - base64 --decode --ignore-garbage ~/.ssh/id_rsa_base64 > ~/.ssh/id_rsa - chmod 600 ~/.ssh/id_rsa - echo -e "Host gitlab.espressif.cn\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config + # if testing master branch, use github wifi libs. # if testing other branches, use gitlab wifi libs (as maybe changes aren't merged to master yet) - test "${CI_BUILD_REF_NAME}" = "master" || sed -i "s%https://github.com/espressif/esp32-wifi-lib%ssh://git@gitlab.espressif.cn:27227/idf/esp32-wifi-lib%" .gitmodules # fetch all submodules - git submodule update --init --recursive - # try use submodule with same branch - - SUBMODULES=`cat .gitmodules | grep path | awk '{print $3}'` - - for MODULE in $SUBMODULES;do (echo $MODULE;cd $MODULE;git checkout ${CI_BUILD_REF_NAME} || echo "using default branch";cd $CI_PROJECT_DIR); done build_template_app: stage: build From 178db4bdd91c37b2fd633930c8df44233b496e1c Mon Sep 17 00:00:00 2001 From: Liu Zhi Fu Date: Tue, 8 Nov 2016 13:30:35 +0800 Subject: [PATCH 280/343] esp32: merge bt/wifi coexist code 1. Modify makefile to add coexist lib 2. Update bt/wifi coexist lib --- components/esp32/component.mk | 2 +- components/esp32/lib | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/esp32/component.mk b/components/esp32/component.mk index e91020c3e6..c658787d87 100644 --- a/components/esp32/component.mk +++ b/components/esp32/component.mk @@ -10,7 +10,7 @@ COMPONENT_SRCDIRS := . hwcrypto -LIBS := core net80211 phy rtc pp wpa smartconfig +LIBS := core net80211 phy rtc pp wpa smartconfig coexist LINKER_SCRIPTS += -T esp32_out.ld -T esp32.common.ld -T esp32.rom.ld -T esp32.peripherals.ld diff --git a/components/esp32/lib b/components/esp32/lib index b3090d8854..a1ab74c2a6 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit b3090d885413fb78c86e7b88116cdb5c8c5e9e68 +Subproject commit a1ab74c2a6122693ee87f08306364fc7a016ced7 From 1418f886eb5c04913923daaf89c36b85daea59b9 Mon Sep 17 00:00:00 2001 From: Wangjialin Date: Tue, 8 Nov 2016 14:19:31 +0800 Subject: [PATCH 281/343] Only fix rmt_mem_t struct definition error. --- components/esp32/include/soc/rmt_struct.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/components/esp32/include/soc/rmt_struct.h b/components/esp32/include/soc/rmt_struct.h index fb4c21055e..511fefa267 100644 --- a/components/esp32/include/soc/rmt_struct.h +++ b/components/esp32/include/soc/rmt_struct.h @@ -231,11 +231,10 @@ typedef volatile struct { struct { union { struct { - uint32_t level1: 1; - uint32_t duration1: 15; - uint32_t level0: 1; uint32_t duration0: 15; - + uint32_t level0: 1; + uint32_t duration1: 15; + uint32_t level1: 1; }; uint32_t val; } data[64]; From 7340a77689943629d4364fef787272da7fffb768 Mon Sep 17 00:00:00 2001 From: Liu Zhi Fu Date: Tue, 8 Nov 2016 15:28:20 +0800 Subject: [PATCH 282/343] esp32: remove libcrypto according to review comments --- components/esp32/lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp32/lib b/components/esp32/lib index a1ab74c2a6..596a82d4e0 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit a1ab74c2a6122693ee87f08306364fc7a016ced7 +Subproject commit 596a82d4e0122432a51d3ec5a62975db9fd38179 From cb5f7690a4ab654a5a5e0a60a59e3acc99cc31ab Mon Sep 17 00:00:00 2001 From: Liu Zhi Fu Date: Tue, 8 Nov 2016 17:34:46 +0800 Subject: [PATCH 283/343] esp32/make: add detailed return error code for wifi APIs 1. Add detailed return error code for wifi APIs 2. Add description about error code in esp_wifi.h 3. Modify esp_wifi_reg_rxcb to esp_wifi_internal_reg_rxcb 4. Modify esp_wifi_set_sta_ip to esp_wifi_internal_set_sta_ip 5. Mark system_init as deprecated API --- components/esp32/event_default_handlers.c | 12 +- components/esp32/include/esp_err.h | 2 + components/esp32/include/esp_system.h | 10 +- components/esp32/include/esp_wifi.h | 291 ++++++++++++------- components/esp32/include/esp_wifi_internal.h | 33 ++- components/esp32/lib | 2 +- make/project.mk | 3 +- 7 files changed, 241 insertions(+), 112 deletions(-) diff --git a/components/esp32/event_default_handlers.c b/components/esp32/event_default_handlers.c index 37ba634041..a2bb3ccea3 100644 --- a/components/esp32/event_default_handlers.c +++ b/components/esp32/event_default_handlers.c @@ -18,6 +18,7 @@ #include "esp_err.h" #include "esp_wifi.h" +#include "esp_wifi_internal.h" #include "esp_event.h" #include "esp_event_loop.h" #include "esp_task.h" @@ -76,8 +77,7 @@ static system_event_handle_t g_system_event_handle_table[] = { static esp_err_t system_event_sta_got_ip_default(system_event_t *event) { - extern esp_err_t esp_wifi_set_sta_ip(void); - WIFI_API_CALL_CHECK("esp_wifi_set_sta_ip", esp_wifi_set_sta_ip(), ESP_OK); + WIFI_API_CALL_CHECK("esp_wifi_internal_set_sta_ip", esp_wifi_internal_set_sta_ip(), ESP_OK); ESP_LOGI(TAG, "ip: " IPSTR ", mask: " IPSTR ", gw: " IPSTR, IP2STR(&event->event_info.got_ip.ip_info.ip), @@ -92,7 +92,7 @@ esp_err_t system_event_ap_start_handle_default(system_event_t *event) tcpip_adapter_ip_info_t ap_ip; uint8_t ap_mac[6]; - WIFI_API_CALL_CHECK("esp_wifi_reg_rxcb", esp_wifi_reg_rxcb(WIFI_IF_AP, (wifi_rxcb_t)tcpip_adapter_ap_input), ESP_OK); + WIFI_API_CALL_CHECK("esp_wifi_internal_reg_rxcb", esp_wifi_internal_reg_rxcb(WIFI_IF_AP, (wifi_rxcb_t)tcpip_adapter_ap_input), ESP_OK); WIFI_API_CALL_CHECK("esp_wifi_mac_get", esp_wifi_get_mac(WIFI_IF_AP, ap_mac), ESP_OK); tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &ap_ip); @@ -103,7 +103,7 @@ esp_err_t system_event_ap_start_handle_default(system_event_t *event) esp_err_t system_event_ap_stop_handle_default(system_event_t *event) { - WIFI_API_CALL_CHECK("esp_wifi_reg_rxcb", esp_wifi_reg_rxcb(WIFI_IF_AP, NULL), ESP_OK); + WIFI_API_CALL_CHECK("esp_wifi_internal_reg_rxcb", esp_wifi_internal_reg_rxcb(WIFI_IF_AP, NULL), ESP_OK); tcpip_adapter_stop(TCPIP_ADAPTER_IF_AP); @@ -133,7 +133,7 @@ esp_err_t system_event_sta_connected_handle_default(system_event_t *event) { tcpip_adapter_dhcp_status_t status; - WIFI_API_CALL_CHECK("esp_wifi_reg_rxcb", esp_wifi_reg_rxcb(WIFI_IF_STA, (wifi_rxcb_t)tcpip_adapter_sta_input), ESP_OK); + WIFI_API_CALL_CHECK("esp_wifi_internal_reg_rxcb", esp_wifi_internal_reg_rxcb(WIFI_IF_STA, (wifi_rxcb_t)tcpip_adapter_sta_input), ESP_OK); tcpip_adapter_up(TCPIP_ADAPTER_IF_STA); @@ -165,7 +165,7 @@ esp_err_t system_event_sta_connected_handle_default(system_event_t *event) esp_err_t system_event_sta_disconnected_handle_default(system_event_t *event) { tcpip_adapter_down(TCPIP_ADAPTER_IF_STA); - WIFI_API_CALL_CHECK("esp_wifi_reg_rxcb", esp_wifi_reg_rxcb(WIFI_IF_STA, NULL), ESP_OK); + WIFI_API_CALL_CHECK("esp_wifi_internal_reg_rxcb", esp_wifi_internal_reg_rxcb(WIFI_IF_STA, NULL), ESP_OK); return ESP_OK; } diff --git a/components/esp32/include/esp_err.h b/components/esp32/include/esp_err.h index af9d2ec33a..dc2c6c2d77 100644 --- a/components/esp32/include/esp_err.h +++ b/components/esp32/include/esp_err.h @@ -34,6 +34,8 @@ typedef int32_t esp_err_t; #define ESP_ERR_INVALID_SIZE 0x104 #define ESP_ERR_NOT_FOUND 0x105 +#define ESP_ERR_WIFI_BASE 0x3000 /*!< Starting number of WiFi error codes */ + /** * Macro which can be used to check the error code, * and terminate the program in case the code is not ESP_OK. diff --git a/components/esp32/include/esp_system.h b/components/esp32/include/esp_system.h index 8c6564c55b..d416e23d07 100644 --- a/components/esp32/include/esp_system.h +++ b/components/esp32/include/esp_system.h @@ -16,7 +16,6 @@ #define __ESP_SYSTEM_H__ #include -#include #include "esp_err.h" #include "esp_deepsleep.h" @@ -33,6 +32,13 @@ extern "C" { * @{ */ +/** + * @attention application don't need to call this function anymore. It do nothing and will + * be removed in future version. + */ +void system_init(void) __attribute__ ((deprecated)); + + /** * @brief Get information of the SDK version. * @@ -170,8 +176,6 @@ bool system_rtc_mem_write(uint16_t dst, const void *src, uint16_t n); esp_err_t system_efuse_read_mac(uint8_t mac[6]); -void system_init(void); - /** * @} */ diff --git a/components/esp32/include/esp_wifi.h b/components/esp32/include/esp_wifi.h index 80ced5dc61..8e2c1df558 100644 --- a/components/esp32/include/esp_wifi.h +++ b/components/esp32/include/esp_wifi.h @@ -70,6 +70,23 @@ extern "C" { #endif +#define ESP_ERR_WIFI_OK ESP_OK /*!< No error */ +#define ESP_ERR_WIFI_FAIL ESP_FAIL /*!< General fail code */ +#define ESP_ERR_WIFI_NO_MEM ESP_ERR_NO_MEM /*!< Out of memory */ +#define ESP_ERR_WIFI_ARG ESP_ERR_INVALID_ARG /*!< Invalid argument */ +#define ESP_ERR_WIFI_NOT_INIT (ESP_ERR_WIFI_BASE + 1) /*!< WiFi driver is not installed by esp_wifi_init */ +#define ESP_ERR_WIFI_NOT_START (ESP_ERR_WIFI_BASE + 2) /*!< WiFi driver is not started by esp_wifi_start */ +#define ESP_ERR_WIFI_NOT_SUPPORT (ESP_ERR_WIFI_BASE + 3) /*!< WiFi API doesn't support */ +#define ESP_ERR_WIFI_IF (ESP_ERR_WIFI_BASE + 4) /*!< WiFi interface error */ +#define ESP_ERR_WIFI_MODE (ESP_ERR_WIFI_BASE + 5) /*!< WiFi mode error */ +#define ESP_ERR_WIFI_STATE (ESP_ERR_WIFI_BASE + 6) /*!< WiFi internal state error */ +#define ESP_ERR_WIFI_CONN (ESP_ERR_WIFI_BASE + 7) /*!< WiFi internal control block of station or soft-AP error */ +#define ESP_ERR_WIFI_NVS (ESP_ERR_WIFI_BASE + 8) /*!< WiFi internal NVS module error */ +#define ESP_ERR_WIFI_MAC (ESP_ERR_WIFI_BASE + 9) /*!< MAC address is invalid */ +#define ESP_ERR_WIFI_SSID (ESP_ERR_WIFI_BASE + 10) /*!< SSID is invalid */ +#define ESP_ERR_WIFI_PASSWORD (ESP_ERR_WIFI_BASE + 11) /*!< Passord is invalid */ +#define ESP_ERR_WIFI_TIMEOUT (ESP_ERR_WIFI_BASE + 12) /*!< Timeout error */ + typedef struct { system_event_handler_t event_handler; /**< WiFi event handler */ } wifi_init_config_t; @@ -92,8 +109,10 @@ typedef struct { * * @param wifi_init_config_t *config : provide WiFi init configuration * - * @return ESP_OK : succeed - * @return others : fail + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_NO_MEM : out of memory + * - others : refer to error code esp_err.h */ esp_err_t esp_wifi_init(wifi_init_config_t *config); @@ -104,7 +123,6 @@ esp_err_t esp_wifi_init(wifi_init_config_t *config); * @attention 1. This API should be called if you want to remove WiFi driver from the system * * @return ESP_OK : succeed - * @return others : fail */ esp_err_t esp_wifi_deinit(void); @@ -116,8 +134,11 @@ esp_err_t esp_wifi_deinit(void); * * @param wifi_mode_t mode : WiFi operating modes: * - * @return ESP_OK : succeed - * @return others : fail + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_NOT_INIT : WiFi is not initialized by eps_wifi_init + * - ESP_ERR_WIFI_ARG : invalid argument + * - others : refer to error code in esp_err.h */ esp_err_t esp_wifi_set_mode(wifi_mode_t mode); @@ -126,8 +147,10 @@ esp_err_t esp_wifi_set_mode(wifi_mode_t mode); * * @param wifi_mode_t *mode : store current WiFi mode * - * @return ESP_OK : succeed - * @return others : fail + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_NOT_INIT : WiFi is not initialized by eps_wifi_init + * - ESP_ERR_WIFI_ARG : invalid argument */ esp_err_t esp_wifi_get_mode(wifi_mode_t *mode); @@ -139,8 +162,13 @@ esp_err_t esp_wifi_get_mode(wifi_mode_t *mode); * * @param null * - * @return ESP_OK : succeed - * @return others : fail + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_NOT_INIT : WiFi is not initialized by eps_wifi_init + * - ESP_ERR_WIFI_ARG : invalid argument + * - ESP_ERR_WIFI_NO_MEM : out of memory + * - ESP_ERR_WIFI_CONN : WiFi internal error, station or soft-AP control block wrong + * - ESP_ERR_WIFI_FAIL : other WiFi internal errors */ esp_err_t esp_wifi_start(void); @@ -152,8 +180,9 @@ esp_err_t esp_wifi_start(void); * * @param null * - * @return ESP_OK : succeed - * @return others : fail + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_NOT_INIT : WiFi is not initialized by eps_wifi_init */ esp_err_t esp_wifi_stop(void); @@ -165,8 +194,12 @@ esp_err_t esp_wifi_stop(void); * * @param null * - * @return ESP_OK : succeed - * @return others : fail + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_NOT_INIT : WiFi is not initialized by eps_wifi_init + * - ESP_ERR_WIFI_NOT_START : WiFi is not started by esp_wifi_start + * - ESP_ERR_WIFI_CONN : WiFi internal error, station or soft-AP control block wrong + * - ESP_ERR_WIFI_SSID : SSID of AP which station connects is invalid */ esp_err_t esp_wifi_connect(void); @@ -175,8 +208,11 @@ esp_err_t esp_wifi_connect(void); * * @param null * - * @return ESP_OK : succeed - * @return others : fail + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_NOT_INIT : WiFi is not initialized by eps_wifi_init + * - ESP_ERR_WIFI_NOT_START : WiFi is not started by esp_wifi_start + * - ESP_ERR_WIFI_FAIL : other WiFi internal errors */ esp_err_t esp_wifi_disconnect(void); @@ -185,8 +221,9 @@ esp_err_t esp_wifi_disconnect(void); * * @param null * - * @return ESP_OK : succeed - * @return others : fail + * @return + * - ESP_OK : succeed + * - others : fail */ esp_err_t esp_wifi_clear_fast_connect(void); @@ -195,8 +232,12 @@ esp_err_t esp_wifi_clear_fast_connect(void); * * @param uint16_t aid : when aid is 0, deauthenticate all stations, otherwise deauthenticate station whose associated id is aid * - * @return ESP_OK : succeed - * @return others : fail + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_NOT_INIT : WiFi is not initialized by eps_wifi_init + * - ESP_ERR_WIFI_NOT_START : WiFi is not started by esp_wifi_start + * - ESP_ERR_WIFI_ARG : invalid argument + * - ESP_ERR_WIFI_MODE : WiFi mode is wrong */ esp_err_t esp_wifi_deauth_sta(uint16_t aid); @@ -211,8 +252,12 @@ esp_err_t esp_wifi_deauth_sta(uint16_t aid); * @param bool block : if block is true, this API will block the caller until the scan is done, otherwise * it will return immediately * - * @return ESP_OK : succeed - * @return others : fail + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_NOT_INIT : WiFi is not initialized by eps_wifi_init + * - ESP_ERR_WIFI_NOT_START : WiFi is not started by esp_wifi_start + * - ESP_ERR_WIFI_TIMEOUT : blocking scan is timeout + * - others : refer to error code in esp_err.h */ esp_err_t esp_wifi_scan_start(wifi_scan_config_t *conf, bool block); @@ -220,8 +265,10 @@ esp_err_t esp_wifi_scan_start(wifi_scan_config_t *conf, bool block); * @brief Stop the scan in process * * @param null - * @return ESP_OK : succeed - * @return others : fail + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_NOT_INIT : WiFi is not initialized by eps_wifi_init + * - ESP_ERR_WIFI_NOT_START : WiFi is not started by esp_wifi_start */ esp_err_t esp_wifi_scan_stop(void); @@ -232,8 +279,11 @@ esp_err_t esp_wifi_scan_stop(void); * * @attention This API can only be called when the scan is completed, otherwise it may get wrong value * - * @return ESP_OK : succeed - * @return others : fail + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_NOT_INIT : WiFi is not initialized by eps_wifi_init + * - ESP_ERR_WIFI_NOT_START : WiFi is not started by esp_wifi_start + * - ESP_ERR_WIFI_ARG : invalid argument */ esp_err_t esp_wifi_scan_get_ap_num(uint16_t *number); @@ -244,8 +294,12 @@ esp_err_t esp_wifi_scan_get_ap_num(uint16_t *number); the actual AP number this API returns * @param wifi_ap_record_t *ap_records: wifi_ap_record_t array to hold the found APs * - * @return ESP_OK : succeed - * @return others : fail + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_NOT_INIT : WiFi is not initialized by eps_wifi_init + * - ESP_ERR_WIFI_NOT_START : WiFi is not started by esp_wifi_start + * - ESP_ERR_WIFI_ARG : invalid argument + * - ESP_ERR_WIFI_NO_MEM : out of memory */ esp_err_t esp_wifi_scan_get_ap_records(uint16_t *number, wifi_ap_record_t *ap_records); @@ -255,8 +309,9 @@ esp_err_t esp_wifi_scan_get_ap_records(uint16_t *number, wifi_ap_record_t *ap_re * * @param wifi_ap_record_t *ap_info: the wifi_ap_record_t to hold station assocated AP * - * @return ESP_OK : succeed - * @return others : fail + * @return + * - ESP_OK : succeed + * - others : fail */ esp_err_t esp_wifi_sta_get_ap_info(wifi_ap_record_t *ap_info); @@ -265,8 +320,7 @@ esp_err_t esp_wifi_sta_get_ap_info(wifi_ap_record_t *ap_info); * * @param wifi_ps_type_t type : power save type * - * @return ESP_OK : succeed - * @return others : fail + * @return ESP_ERR_WIFI_NOT_SUPPORT : not support yet */ esp_err_t esp_wifi_set_ps(wifi_ps_type_t type); @@ -275,8 +329,7 @@ esp_err_t esp_wifi_set_ps(wifi_ps_type_t type); * * @param wifi_ps_type_t *type : store current power save type * - * @return ESP_OK : succeed - * @return others : fail + * @return ESP_ERR_WIFI_NOT_SUPPORT : not support yet */ esp_err_t esp_wifi_get_ps(wifi_ps_type_t *type); @@ -289,8 +342,11 @@ esp_err_t esp_wifi_get_ps(wifi_ps_type_t *type); * @param wifi_interface_t ifx : interfaces * @param uint8_t protocol : WiFi protocol bitmap * - * @return ESP_OK : succeed - * @return others : fail + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_NOT_INIT : WiFi is not initialized by eps_wifi_init + * - ESP_ERR_WIFI_IF : invalid interface + * - others : refer to erro code in esp_err.h */ esp_err_t esp_wifi_set_protocol(wifi_interface_t ifx, uint8_t protocol_bitmap); @@ -300,8 +356,12 @@ esp_err_t esp_wifi_set_protocol(wifi_interface_t ifx, uint8_t protocol_bitmap); * @param wifi_interface_t ifx : interfaces * @param uint8_t protocol : store current WiFi protocol bitmap of interface ifx * - * @return ESP_OK : succeed - * @return others : fail + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_NOT_INIT : WiFi is not initialized by eps_wifi_init + * - ESP_ERR_WIFI_IF : invalid interface + * - ESP_ERR_WIFI_ARG : invalid argument + * - others : refer to error code in esp_err.h */ esp_err_t esp_wifi_get_protocol(wifi_interface_t ifx, uint8_t *protocol_bitmap); @@ -314,8 +374,12 @@ esp_err_t esp_wifi_get_protocol(wifi_interface_t ifx, uint8_t *protocol_bitmap); * @param wifi_interface_t ifx : interface to be configured * @param wifi_bandwidth_t bw : bandwidth * - * @return ESP_OK : succeed - * @return others : fail + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_NOT_INIT : WiFi is not initialized by eps_wifi_init + * - ESP_ERR_WIFI_IF : invalid interface + * - ESP_ERR_WIFI_ARG : invalid argument + * - others : refer to error code in esp_err.h */ esp_err_t esp_wifi_set_bandwidth(wifi_interface_t ifx, wifi_bandwidth_t bw); @@ -327,8 +391,11 @@ esp_err_t esp_wifi_set_bandwidth(wifi_interface_t ifx, wifi_bandwidth_t bw); * @param wifi_interface_t ifx : interface to be configured * @param wifi_bandwidth_t *bw : store bandwidth of interface ifx * - * @return ESP_OK : succeed - * @return others : fail + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_NOT_INIT : WiFi is not initialized by eps_wifi_init + * - ESP_ERR_WIFI_IF : invalid interface + * - ESP_ERR_WIFI_ARG : invalid argument */ esp_err_t esp_wifi_get_bandwidth(wifi_interface_t ifx, wifi_bandwidth_t *bw); @@ -340,8 +407,11 @@ esp_err_t esp_wifi_get_bandwidth(wifi_interface_t ifx, wifi_bandwidth_t *bw); * @param uint8_t primary : for HT20, primary is the channel number, for HT40, primary is the primary channel * @param wifi_second_chan_t second : for HT20, second is ignored, for HT40, second is the second channel * - * @return ESP_OK : succeed - * @return others : fail + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_NOT_INIT : WiFi is not initialized by eps_wifi_init + * - ESP_ERR_WIFI_IF : invalid interface + * - ESP_ERR_WIFI_ARG : invalid argument */ esp_err_t esp_wifi_set_channel(uint8_t primary, wifi_second_chan_t second); @@ -353,8 +423,10 @@ esp_err_t esp_wifi_set_channel(uint8_t primary, wifi_second_chan_t second); * @param uint8_t *primary : store current primary channel * @param wifi_second_chan_t *second : store current second channel * - * @return ESP_OK : succeed - * @return others : fail + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_NOT_INIT : WiFi is not initialized by eps_wifi_init + * - ESP_ERR_WIFI_ARG : invalid argument */ esp_err_t esp_wifi_get_channel(uint8_t *primary, wifi_second_chan_t *second); @@ -364,8 +436,11 @@ esp_err_t esp_wifi_get_channel(uint8_t *primary, wifi_second_chan_t *second); * * @param wifi_country_t country : country type * - * @return ESP_OK : succeed - * @return others : fail + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_NOT_INIT : WiFi is not initialized by eps_wifi_init + * - ESP_ERR_WIFI_ARG : invalid argument + * - others : refer to error code in esp_err.h */ esp_err_t esp_wifi_set_country(wifi_country_t country); @@ -374,8 +449,10 @@ esp_err_t esp_wifi_set_country(wifi_country_t country); * * @param wifi_country_t country : store current country * - * @return ESP_OK : succeed - * @return others : fail + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_NOT_INIT : WiFi is not initialized by eps_wifi_init + * - ESP_ERR_WIFI_ARG : invalid argument */ esp_err_t esp_wifi_get_country(wifi_country_t *country); @@ -390,8 +467,14 @@ esp_err_t esp_wifi_get_country(wifi_country_t *country); * @param wifi_interface_t ifx : interface * @param uint8 mac[6]: the MAC address. * - * @return true : succeed - * @return false : fail + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_NOT_INIT : WiFi is not initialized by eps_wifi_init + * - ESP_ERR_WIFI_ARG : invalid argument + * - ESP_ERR_WIFI_IF : invalid interface + * - ESP_ERR_WIFI_MAC : invalid mac address + * - ESP_ERR_WIFI_MODE : WiFi mode is wrong + * - others : refer to error code in esp_err.h */ esp_err_t esp_wifi_set_mac(wifi_interface_t ifx, uint8_t mac[6]); @@ -400,8 +483,11 @@ esp_err_t esp_wifi_set_mac(wifi_interface_t ifx, uint8_t mac[6]); * * @param uint8_t mac[6] : store mac of this interface ifx * - * @return ESP_OK : succeed - * @return others : fail + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_NOT_INIT : WiFi is not initialized by eps_wifi_init + * - ESP_ERR_WIFI_ARG : invalid argument + * - ESP_ERR_WIFI_IF : invalid interface */ esp_err_t esp_wifi_get_mac(wifi_interface_t ifx, uint8_t mac[6]); @@ -413,8 +499,7 @@ esp_err_t esp_wifi_get_mac(wifi_interface_t ifx, uint8_t mac[6]); * @param void *buf : the data received * @param uint16_t len : data length * - * @return ESP_OK : succeed - * @return others : fail + * @return none */ typedef void (* wifi_promiscuous_cb_t)(void *buf, uint16_t len); @@ -425,8 +510,9 @@ typedef void (* wifi_promiscuous_cb_t)(void *buf, uint16_t len); * * @param wifi_promiscuous_cb_t cb : callback * - * @return ESP_OK : succeed - * @return others : fail + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_NOT_INIT : WiFi is not initialized by eps_wifi_init */ esp_err_t esp_wifi_set_promiscuous_rx_cb(wifi_promiscuous_cb_t cb); @@ -435,8 +521,9 @@ esp_err_t esp_wifi_set_promiscuous_rx_cb(wifi_promiscuous_cb_t cb); * * @param bool promiscuous : false - disable / true - enable * - * @return ESP_OK : succeed - * @return others : fail + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_NOT_INIT : WiFi is not initialized by eps_wifi_init */ esp_err_t esp_wifi_set_promiscuous(bool en); @@ -445,8 +532,10 @@ esp_err_t esp_wifi_set_promiscuous(bool en); * * @param bool *enable : store the current status of promiscuous mode * - * @return ESP_OK : succeed - * @return others : fail + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_NOT_INIT : WiFi is not initialized by eps_wifi_init + * - ESP_ERR_WIFI_ARG : invalid argument */ esp_err_t esp_wifi_get_promiscuous(bool *en); @@ -461,8 +550,15 @@ esp_err_t esp_wifi_get_promiscuous(bool *en); * @param wifi_interface_t ifx : interface * @param wifi_config_t *conf : station or soft-AP configuration * - * @return ESP_OK : succeed - * @return others : fail + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_NOT_INIT : WiFi is not initialized by eps_wifi_init + * - ESP_ERR_WIFI_ARG : invalid argument + * - ESP_ERR_WIFI_IF : invalid interface + * - ESP_ERR_WIFI_MODE : invalid mode + * - ESP_ERR_WIFI_PASSWORD : invalid password + * - ESP_ERR_WIFI_NVS : WiFi internal NVS error + * - others : refer to the erro code in esp_err.h */ esp_err_t esp_wifi_set_config(wifi_interface_t ifx, wifi_config_t *conf); @@ -472,8 +568,11 @@ esp_err_t esp_wifi_set_config(wifi_interface_t ifx, wifi_config_t *conf); * @param wifi_interface_t ifx : interface * @param wifi_config_t *conf : station or soft-AP configuration * - * @return ESP_OK : succeed - * @return others : fail + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_NOT_INIT : WiFi is not initialized by eps_wifi_init + * - ESP_ERR_WIFI_ARG : invalid argument + * - ESP_ERR_WIFI_IF : invalid interface */ esp_err_t esp_wifi_get_config(wifi_interface_t ifx, wifi_config_t *conf); @@ -484,8 +583,12 @@ esp_err_t esp_wifi_get_config(wifi_interface_t ifx, wifi_config_t *conf); * * @param wifi_sta_list_t *sta: station list * - * @return ESP_OK : succeed - * @return others : fail + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_NOT_INIT : WiFi is not initialized by eps_wifi_init + * - ESP_ERR_WIFI_ARG : invalid argument + * - ESP_ERR_WIFI_MODE : WiFi mode is wrong + * - ESP_ERR_WIFI_CONN : WiFi internal error, the station/soft-AP control block is invalid */ esp_err_t esp_wifi_ap_get_sta_list(wifi_sta_list_t *sta); @@ -497,42 +600,24 @@ esp_err_t esp_wifi_ap_get_sta_list(wifi_sta_list_t *sta); * * @param wifi_storage_t storage : storage type * - * @return ESP_OK : succeed - * @return others : fail + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_NOT_INIT : WiFi is not initialized by eps_wifi_init + * - ESP_ERR_WIFI_ARG : invalid argument */ esp_err_t esp_wifi_set_storage(wifi_storage_t storage); -/** - * @brief The WiFi RX callback function - * - * Each time the WiFi need to forward the packets to high layer, the callback function will be called - * - */ -typedef esp_err_t (*wifi_rxcb_t)(void *buffer, uint16_t len, void *eb); - -/** - * @brief Set the WiFi RX callback - * - * @attention 1. Currently we support only one RX callback for each interface - * - * @param wifi_interface_t ifx : interface - * @param wifi_rxcb_t fn : WiFi RX callback - * - * @return ESP_OK : succeed - * @return others : fail - */ -esp_err_t esp_wifi_reg_rxcb(wifi_interface_t ifx, wifi_rxcb_t fn); - /** * @brief Set auto connect * The default value is true * - * @attention 1. - * * @param bool en : true - enable auto connect / false - disable auto connect * - * @return ESP_OK : succeed - * @return others : fail + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_NOT_INIT : WiFi is not initialized by eps_wifi_init + * - ESP_ERR_WIFI_MODE : WiFi internal error, the station/soft-AP control block is invalid + * - others : refer to error code in esp_err.h */ esp_err_t esp_wifi_set_auto_connect(bool en); @@ -541,8 +626,10 @@ esp_err_t esp_wifi_set_auto_connect(bool en); * * @param bool *en : store current auto connect configuration * - * @return ESP_OK : succeed - * @return others : fail + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_NOT_INIT : WiFi is not initialized by eps_wifi_init + * - ESP_ERR_WIFI_ARG : invalid argument */ esp_err_t esp_wifi_get_auto_connect(bool *en); @@ -559,8 +646,11 @@ esp_err_t esp_wifi_get_auto_connect(bool *en); 1 - WIFI_VND_IE_ID_1 * @param uint8_t *vnd_ie : pointer to a vendor specific element * - * @return ESP_OK : succeed - * @return others : fail + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_NOT_INIT : WiFi is not initialized by eps_wifi_init + * - ESP_ERR_WIFI_ARG : invalid argument + * - ESP_ERR_WIFI_NO_MEM : out of memory */ esp_err_t esp_wifi_set_vendor_ie(bool enable, wifi_vendor_ie_type_t type, wifi_vendor_ie_id_t idx, uint8_t *vnd_ie); @@ -584,8 +674,9 @@ typedef void (*esp_vendor_ie_cb_t) (void *ctx, wifi_vendor_ie_type_t type, const * @param esp_vendor_ie_cb_t cb : callback function * @param void *ctx : reserved * - * @return ESP_OK : succeed - * @return others : fail + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_NOT_INIT : WiFi is not initialized by eps_wifi_init */ esp_err_t esp_wifi_set_vendor_ie_cb(esp_vendor_ie_cb_t cb, void *ctx); diff --git a/components/esp32/include/esp_wifi_internal.h b/components/esp32/include/esp_wifi_internal.h index 217d5f6d1f..9aa05dc716 100644 --- a/components/esp32/include/esp_wifi_internal.h +++ b/components/esp32/include/esp_wifi_internal.h @@ -71,7 +71,38 @@ void esp_wifi_internal_free_rx_buffer(void* buffer); * @return True : success transmit the buffer to wifi driver * False : failed to transmit the buffer to wifi driver */ -bool esp_wifi_internal_tx(wifi_interface_t wifi_if, void *buffer, u16_t len); +int esp_wifi_internal_tx(wifi_interface_t wifi_if, void *buffer, u16_t len); + +/** + * @brief The WiFi RX callback function + * + * Each time the WiFi need to forward the packets to high layer, the callback function will be called + * + */ +typedef esp_err_t (*wifi_rxcb_t)(void *buffer, uint16_t len, void *eb); + +/** + * @brief Set the WiFi RX callback + * + * @attention 1. Currently we support only one RX callback for each interface + * + * @param wifi_interface_t ifx : interface + * @param wifi_rxcb_t fn : WiFi RX callback + * + * @return ESP_OK : succeed + * @return others : fail + */ +esp_err_t esp_wifi_internal_reg_rxcb(wifi_interface_t ifx, wifi_rxcb_t fn); + +/** + * @brief Notify WIFI driver that the station got ip successfully + * + * @param none + * + * @return ESP_OK : succeed + * @return others : fail + */ +esp_err_t esp_wifi_internal_set_sta_ip(void); #ifdef __cplusplus } diff --git a/components/esp32/lib b/components/esp32/lib index 596a82d4e0..66236c85b3 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit 596a82d4e0122432a51d3ec5a62975db9fd38179 +Subproject commit 66236c85b3ef1a6d756d4e7d58cc6a1180e31365 diff --git a/make/project.mk b/make/project.mk index 67e2e92bdb..a60a3958fe 100644 --- a/make/project.mk +++ b/make/project.mk @@ -166,7 +166,8 @@ CPPFLAGS := -DESP_PLATFORM $(CPPFLAGS) COMMON_WARNING_FLAGS = -Wall -Werror \ -Wno-error=unused-function \ -Wno-error=unused-but-set-variable \ - -Wno-error=unused-variable + -Wno-error=unused-variable \ + -Wno-error=deprecated-declarations # Flags which control code generation and dependency generation, both for C and C++ COMMON_FLAGS = \ From 8dee0a3f6d5a0bed87ed1da032cd394703e66a83 Mon Sep 17 00:00:00 2001 From: Liu Zhi Fu Date: Tue, 8 Nov 2016 19:19:28 +0800 Subject: [PATCH 284/343] esp32: modify the code according to review comments 1. Adjust error code definition 2. Refractor the comments for esp_wifi_internal_tx --- components/esp32/include/esp_err.h | 1 + components/esp32/include/esp_wifi.h | 21 ++++++++++---------- components/esp32/include/esp_wifi_internal.h | 9 +++++---- components/esp32/lib | 2 +- 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/components/esp32/include/esp_err.h b/components/esp32/include/esp_err.h index dc2c6c2d77..f8271ba259 100644 --- a/components/esp32/include/esp_err.h +++ b/components/esp32/include/esp_err.h @@ -33,6 +33,7 @@ typedef int32_t esp_err_t; #define ESP_ERR_INVALID_STATE 0x103 #define ESP_ERR_INVALID_SIZE 0x104 #define ESP_ERR_NOT_FOUND 0x105 +#define ESP_ERR_NOT_SUPPORTED 0x106 #define ESP_ERR_WIFI_BASE 0x3000 /*!< Starting number of WiFi error codes */ diff --git a/components/esp32/include/esp_wifi.h b/components/esp32/include/esp_wifi.h index 8e2c1df558..88ea0d9a65 100644 --- a/components/esp32/include/esp_wifi.h +++ b/components/esp32/include/esp_wifi.h @@ -74,18 +74,19 @@ extern "C" { #define ESP_ERR_WIFI_FAIL ESP_FAIL /*!< General fail code */ #define ESP_ERR_WIFI_NO_MEM ESP_ERR_NO_MEM /*!< Out of memory */ #define ESP_ERR_WIFI_ARG ESP_ERR_INVALID_ARG /*!< Invalid argument */ +#define ESP_ERR_WIFI_NOT_SUPPORT ESP_ERR_NOT_SUPPORTED /*!< Indicates that API is not supported yet */ + #define ESP_ERR_WIFI_NOT_INIT (ESP_ERR_WIFI_BASE + 1) /*!< WiFi driver is not installed by esp_wifi_init */ #define ESP_ERR_WIFI_NOT_START (ESP_ERR_WIFI_BASE + 2) /*!< WiFi driver is not started by esp_wifi_start */ -#define ESP_ERR_WIFI_NOT_SUPPORT (ESP_ERR_WIFI_BASE + 3) /*!< WiFi API doesn't support */ -#define ESP_ERR_WIFI_IF (ESP_ERR_WIFI_BASE + 4) /*!< WiFi interface error */ -#define ESP_ERR_WIFI_MODE (ESP_ERR_WIFI_BASE + 5) /*!< WiFi mode error */ -#define ESP_ERR_WIFI_STATE (ESP_ERR_WIFI_BASE + 6) /*!< WiFi internal state error */ -#define ESP_ERR_WIFI_CONN (ESP_ERR_WIFI_BASE + 7) /*!< WiFi internal control block of station or soft-AP error */ -#define ESP_ERR_WIFI_NVS (ESP_ERR_WIFI_BASE + 8) /*!< WiFi internal NVS module error */ -#define ESP_ERR_WIFI_MAC (ESP_ERR_WIFI_BASE + 9) /*!< MAC address is invalid */ -#define ESP_ERR_WIFI_SSID (ESP_ERR_WIFI_BASE + 10) /*!< SSID is invalid */ -#define ESP_ERR_WIFI_PASSWORD (ESP_ERR_WIFI_BASE + 11) /*!< Passord is invalid */ -#define ESP_ERR_WIFI_TIMEOUT (ESP_ERR_WIFI_BASE + 12) /*!< Timeout error */ +#define ESP_ERR_WIFI_IF (ESP_ERR_WIFI_BASE + 3) /*!< WiFi interface error */ +#define ESP_ERR_WIFI_MODE (ESP_ERR_WIFI_BASE + 4) /*!< WiFi mode error */ +#define ESP_ERR_WIFI_STATE (ESP_ERR_WIFI_BASE + 5) /*!< WiFi internal state error */ +#define ESP_ERR_WIFI_CONN (ESP_ERR_WIFI_BASE + 6) /*!< WiFi internal control block of station or soft-AP error */ +#define ESP_ERR_WIFI_NVS (ESP_ERR_WIFI_BASE + 7) /*!< WiFi internal NVS module error */ +#define ESP_ERR_WIFI_MAC (ESP_ERR_WIFI_BASE + 8) /*!< MAC address is invalid */ +#define ESP_ERR_WIFI_SSID (ESP_ERR_WIFI_BASE + 9) /*!< SSID is invalid */ +#define ESP_ERR_WIFI_PASSWORD (ESP_ERR_WIFI_BASE + 10) /*!< Passord is invalid */ +#define ESP_ERR_WIFI_TIMEOUT (ESP_ERR_WIFI_BASE + 11) /*!< Timeout error */ typedef struct { system_event_handler_t event_handler; /**< WiFi event handler */ diff --git a/components/esp32/include/esp_wifi_internal.h b/components/esp32/include/esp_wifi_internal.h index 9aa05dc716..2015b5063d 100644 --- a/components/esp32/include/esp_wifi_internal.h +++ b/components/esp32/include/esp_wifi_internal.h @@ -62,14 +62,15 @@ void esp_wifi_internal_free_rx_buffer(void* buffer); /** * @brief transmit the buffer via wifi driver * - * @attention1 TODO should modify the return type from bool to int - * * @param wifi_interface_t wifi_if : wifi interface id * @param void *buffer : the buffer to be tansmit * @param u16_t len : the length of buffer * - * @return True : success transmit the buffer to wifi driver - * False : failed to transmit the buffer to wifi driver + * @return + * - ERR_OK : Successfully transmit the buffer to wifi driver + * - ERR_MEM : Out of memory + * - ERR_IF : WiFi driver error + * - ERR_ARG : Invalid argument */ int esp_wifi_internal_tx(wifi_interface_t wifi_if, void *buffer, u16_t len); diff --git a/components/esp32/lib b/components/esp32/lib index 66236c85b3..76f9109806 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit 66236c85b3ef1a6d756d4e7d58cc6a1180e31365 +Subproject commit 76f91098061b0052fe1bb67e85001014f39b84a0 From bdd7fb7a137c4b6e2bacc95976f6c901f590e9ed Mon Sep 17 00:00:00 2001 From: Xia Xiao Tian Date: Mon, 7 Nov 2016 14:59:35 +0800 Subject: [PATCH 285/343] Add wps API --- components/esp32/component.mk | 2 +- components/esp32/include/esp_wps.h | 131 +++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 components/esp32/include/esp_wps.h diff --git a/components/esp32/component.mk b/components/esp32/component.mk index c658787d87..e483b58ee7 100644 --- a/components/esp32/component.mk +++ b/components/esp32/component.mk @@ -10,7 +10,7 @@ COMPONENT_SRCDIRS := . hwcrypto -LIBS := core net80211 phy rtc pp wpa smartconfig coexist +LIBS := core net80211 phy rtc pp wpa smartconfig coexist wps LINKER_SCRIPTS += -T esp32_out.ld -T esp32.common.ld -T esp32.rom.ld -T esp32.peripherals.ld diff --git a/components/esp32/include/esp_wps.h b/components/esp32/include/esp_wps.h new file mode 100644 index 0000000000..1588d36191 --- /dev/null +++ b/components/esp32/include/esp_wps.h @@ -0,0 +1,131 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef __ESP_WPS_H__ +#define __ESP_WPS_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup WiFi_APIs WiFi Related APIs + * @brief WiFi APIs + */ + +/** @addtogroup WiFi_APIs + * @{ + */ + +/** \defgroup WPS_APIs WPS APIs + * @brief ESP32 WPS APIs + * + * WPS can only be used when ESP32 station is enabled. + * + */ + +/** @addtogroup WPS_APIs + * @{ + */ + +typedef enum wps_type { + WPS_TYPE_DISABLE = 0, + WPS_TYPE_PBC, + WPS_TYPE_PIN, + WPS_TYPE_DISPLAY, + WPS_TYPE_MAX, +} WPS_TYPE_t; + +enum wps_cb_status { + WPS_CB_ST_SUCCESS = 0, /**< WPS succeed */ + WPS_CB_ST_FAILED, /**< WPS fail */ + WPS_CB_ST_TIMEOUT, /**< WPS timeout, fail */ + WPS_CB_ST_WEP, /**< WPS failed because that WEP is not supported */ + WPS_CB_ST_SCAN_ERR, /**< can not find the target WPS AP */ +}; + +/** + * @brief Enable Wi-Fi WPS function. + * + * @attention WPS can only be used when ESP32 station is enabled. + * + * @param WPS_TYPE_t wps_type : WPS type, so far only WPS_TYPE_PBC and WPS_TYPE_PIN is supported + * + * @return true : succeed + * @return false : fail + */ +bool esp_wifi_wps_enable(WPS_TYPE_t wps_type); + +/** + * @brief Disable Wi-Fi WPS function and release resource it taken. + * + * @param null + * + * @return true : succeed + * @return false : fail + */ +bool esp_wifi_wps_disable(void); + +/** + * @brief WPS starts to work. + * + * @attention WPS can only be used when ESP32 station is enabled. + * + * @param null + * + * @return true : WPS starts to work successfully, but does not mean WPS succeed. + * @return false : fail + */ +bool esp_wifi_wps_start(void); + +/** + * @brief WPS callback. + * + * @param int status : status of WPS, enum wps_cb_status. + * - If parameter status == WPS_CB_ST_SUCCESS in WPS callback, it means WPS got AP's + * information, user can call wifi_wps_disable to disable WPS and release resource, + * then call wifi_station_connect to connect to target AP. + * - Otherwise, it means that WPS fail, user can create a timer to retry WPS by + * wifi_wps_start after a while, or call wifi_wps_disable to disable WPS and release resource. + * + * @return null + */ +typedef void (*wps_st_cb_t)(int status); + +/** + * @brief Set WPS callback. + * + * @attention WPS can only be used when ESP32 station is enabled. + * + * @param wps_st_cb_t cb : callback. + * + * @return true : WPS starts to work successfully, but does not mean WPS succeed. + * @return false : fail + */ +bool esp_wifi_set_wps_cb(wps_st_cb_t cb); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ESP_WPS_H__ */ From 13b3c916f306ab97877c5331cc9a15a6296616f7 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Mon, 7 Nov 2016 14:26:21 +0800 Subject: [PATCH 286/343] vfs: check error code returned by FS driver open function Fixes https://github.com/espressif/esp-idf/issues/78 --- components/vfs/vfs.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/components/vfs/vfs.c b/components/vfs/vfs.c index bf26968ff7..b60c60a818 100644 --- a/components/vfs/vfs.c +++ b/components/vfs/vfs.c @@ -151,6 +151,10 @@ int esp_vfs_open(struct _reent *r, const char * path, int flags, int mode) const char* path_within_vfs = translate_path(vfs, path); int ret; CHECK_AND_CALL(ret, r, vfs, open, path_within_vfs, flags, mode); + if (ret < 0) { + return ret; + } + assert(ret >= vfs->vfs.fd_offset); return ret - vfs->vfs.fd_offset + (vfs->offset << VFS_INDEX_S); } From aa0cd0ab474e6ba27dced833ef5ea440a3eabeb2 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 8 Nov 2016 09:02:30 +0800 Subject: [PATCH 287/343] spi_flash: add missing volatile qualifier for lock flags http://esp32.com/viewtopic.php?f=14&t=419&p=1901 --- components/spi_flash/cache_utils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/spi_flash/cache_utils.c b/components/spi_flash/cache_utils.c index 6ae47bdb3e..904007b316 100644 --- a/components/spi_flash/cache_utils.c +++ b/components/spi_flash/cache_utils.c @@ -38,8 +38,8 @@ static uint32_t s_flash_op_cache_state[2]; #ifndef CONFIG_FREERTOS_UNICORE static SemaphoreHandle_t s_flash_op_mutex; -static bool s_flash_op_can_start = false; -static bool s_flash_op_complete = false; +static volatile bool s_flash_op_can_start = false; +static volatile bool s_flash_op_complete = false; void spi_flash_init_lock() { From 3f8d9d71e2c10e5ebdf3b07f3d527d74411bc35a Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 8 Nov 2016 09:05:05 +0800 Subject: [PATCH 288/343] lwip: fix duplicate definition of O_NONBLOCK LwIP will define O_NONBLOCK in sockets.h if it isn't defined yet. If sys/fcntl.h is included after socket.h, there will be duplicate definition. Work around by including sys/fcntl.h into lwipopts.h. https://github.com/espressif/esp-idf/issues/75 --- components/lwip/include/lwip/port/lwipopts.h | 1 + 1 file changed, 1 insertion(+) diff --git a/components/lwip/include/lwip/port/lwipopts.h b/components/lwip/include/lwip/port/lwipopts.h index f705887508..d06e756850 100755 --- a/components/lwip/include/lwip/port/lwipopts.h +++ b/components/lwip/include/lwip/port/lwipopts.h @@ -35,6 +35,7 @@ #include #include #include +#include #include "esp_task.h" #include "sdkconfig.h" From 6dd3681115668fc18a7a13624ffe7c5e60a3c513 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 8 Nov 2016 09:08:23 +0800 Subject: [PATCH 289/343] fix order of creation of standard streams With existing order, file descriptors assigned to stdin, stdout, stderr didn't match standard assignment. https://github.com/espressif/esp-idf/issues/67 --- components/esp32/cpu_start.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp32/cpu_start.c b/components/esp32/cpu_start.c index 2688cd7f81..a96fdee950 100644 --- a/components/esp32/cpu_start.c +++ b/components/esp32/cpu_start.c @@ -177,9 +177,9 @@ void start_cpu0_default(void) esp_vfs_dev_uart_register(); esp_reent_init(_GLOBAL_REENT); const char* default_uart_dev = "/dev/uart/0"; + _GLOBAL_REENT->_stdin = fopen(default_uart_dev, "r"); _GLOBAL_REENT->_stdout = fopen(default_uart_dev, "w"); _GLOBAL_REENT->_stderr = fopen(default_uart_dev, "w"); - _GLOBAL_REENT->_stdin = fopen(default_uart_dev, "r"); do_global_ctors(); #if !CONFIG_FREERTOS_UNICORE esp_crosscore_int_init(); From d29935b9cefa723d977a3be8b6b0a27d1449edf6 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 8 Nov 2016 10:33:21 +0800 Subject: [PATCH 290/343] newlib: fix `_times_r` syscall implementation tms_cstime should only take system time in child processes into account, so has to be zero. https://github.com/espressif/esp-idf/issues/81 --- components/newlib/time.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/newlib/time.c b/components/newlib/time.c index 5f60e1d7b2..0d7b6b7474 100644 --- a/components/newlib/time.c +++ b/components/newlib/time.c @@ -112,7 +112,7 @@ void esp_setup_time_syscalls() clock_t IRAM_ATTR _times_r(struct _reent *r, struct tms *ptms) { clock_t t = xTaskGetTickCount() * (portTICK_PERIOD_MS * CLK_TCK / 1000); - ptms->tms_cstime = t; + ptms->tms_cstime = 0; ptms->tms_cutime = 0; ptms->tms_stime = t; ptms->tms_utime = 0; From f142da3cede379d044a222712c6800fcdebafb94 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 8 Nov 2016 10:35:46 +0800 Subject: [PATCH 291/343] driver/gpio: fix interrupt type names in comment block https://github.com/espressif/esp-idf/issues/56 --- components/driver/include/driver/gpio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/driver/include/driver/gpio.h b/components/driver/include/driver/gpio.h index 7106489d6c..1b2b758564 100644 --- a/components/driver/include/driver/gpio.h +++ b/components/driver/include/driver/gpio.h @@ -313,7 +313,7 @@ esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull); * * @param gpio_num GPIO number. * - * @param intr_type GPIO wake-up type. Only GPIO_INTR_LOLEVEL\GPIO_INTR_HILEVEL can be used + * @param intr_type GPIO wake-up type. Only GPIO_INTR_LOW_LEVEL\GPIO_INTR_HIGH_LEVEL can be used. * * @return * - ESP_OK Success From 1e4f185d29dd603e54846e1d2a9c10e16418799d Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 8 Nov 2016 11:24:44 +0800 Subject: [PATCH 292/343] wifi: use MACSTR and MAC2STR in logging statements Fixes https://github.com/espressif/esp-idf/issues/49 --- components/esp32/event_default_handlers.c | 27 ++++++++++------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/components/esp32/event_default_handlers.c b/components/esp32/event_default_handlers.c index a2bb3ccea3..b41d8be055 100644 --- a/components/esp32/event_default_handlers.c +++ b/components/esp32/event_default_handlers.c @@ -22,6 +22,7 @@ #include "esp_event.h" #include "esp_event_loop.h" #include "esp_task.h" +#include "rom/ets_sys.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -196,16 +197,14 @@ static esp_err_t esp_system_event_debug(system_event_t *event) } case SYSTEM_EVENT_STA_CONNECTED: { system_event_sta_connected_t *connected = &event->event_info.connected; - ESP_LOGD(TAG, "SYSTEM_EVENT_STA_CONNECTED, ssid:%s, ssid_len:%d, bssid:%02x:%02x:%02x:%02x:%02x:%02x, channel:%d, authmode:%d", \ - connected->ssid, connected->ssid_len, connected->bssid[0], connected->bssid[0], connected->bssid[1], \ - connected->bssid[3], connected->bssid[4], connected->bssid[5], connected->channel, connected->authmode); + ESP_LOGD(TAG, "SYSTEM_EVENT_STA_CONNECTED, ssid:%s, ssid_len:%d, bssid:" MACSTR ", channel:%d, authmode:%d", \ + connected->ssid, connected->ssid_len, MAC2STR(connected->bssid), connected->channel, connected->authmode); break; } case SYSTEM_EVENT_STA_DISCONNECTED: { system_event_sta_disconnected_t *disconnected = &event->event_info.disconnected; - ESP_LOGD(TAG, "SYSTEM_EVENT_STA_DISCONNECTED, ssid:%s, ssid_len:%d, bssid:%02x:%02x:%02x:%02x:%02x:%02x, reason:%d", \ - disconnected->ssid, disconnected->ssid_len, disconnected->bssid[0], disconnected->bssid[0], disconnected->bssid[1], \ - disconnected->bssid[3], disconnected->bssid[4], disconnected->bssid[5], disconnected->reason); + ESP_LOGD(TAG, "SYSTEM_EVENT_STA_DISCONNECTED, ssid:%s, ssid_len:%d, bssid:" MACSTR ", reason:%d", \ + disconnected->ssid, disconnected->ssid_len, MAC2STR(disconnected->bssid), disconnected->reason); break; } case SYSTEM_EVENT_STA_AUTHMODE_CHANGE: { @@ -231,23 +230,21 @@ static esp_err_t esp_system_event_debug(system_event_t *event) } case SYSTEM_EVENT_AP_STACONNECTED: { system_event_ap_staconnected_t *staconnected = &event->event_info.sta_connected; - ESP_LOGD(TAG, "SYSTEM_EVENT_AP_STACONNECTED, mac:%02x:%02x:%02x:%02x:%02x:%02x, aid:%d", \ - staconnected->mac[0], staconnected->mac[0], staconnected->mac[1], \ - staconnected->mac[3], staconnected->mac[4], staconnected->mac[5], staconnected->aid); + ESP_LOGD(TAG, "SYSTEM_EVENT_AP_STACONNECTED, mac:" MACSTR ", aid:%d", \ + MAC2STR(staconnected->mac), staconnected->aid); break; } case SYSTEM_EVENT_AP_STADISCONNECTED: { system_event_ap_stadisconnected_t *stadisconnected = &event->event_info.sta_disconnected; - ESP_LOGD(TAG, "SYSTEM_EVENT_AP_STADISCONNECTED, mac:%02x:%02x:%02x:%02x:%02x:%02x, aid:%d", \ - stadisconnected->mac[0], stadisconnected->mac[0], stadisconnected->mac[1], \ - stadisconnected->mac[3], stadisconnected->mac[4], stadisconnected->mac[5], stadisconnected->aid); + ESP_LOGD(TAG, "SYSTEM_EVENT_AP_STADISCONNECTED, mac:" MACSTR ", aid:%d", \ + MAC2STR(stadisconnected->mac), stadisconnected->aid); break; } case SYSTEM_EVENT_AP_PROBEREQRECVED: { system_event_ap_probe_req_rx_t *ap_probereqrecved = &event->event_info.ap_probereqrecved; - ESP_LOGD(TAG, "SYSTEM_EVENT_AP_PROBEREQRECVED, rssi:%d, mac:%02x:%02x:%02x:%02x:%02x:%02x", \ - ap_probereqrecved->rssi, ap_probereqrecved->mac[0], ap_probereqrecved->mac[0], ap_probereqrecved->mac[1], \ - ap_probereqrecved->mac[3], ap_probereqrecved->mac[4], ap_probereqrecved->mac[5]); + ESP_LOGD(TAG, "SYSTEM_EVENT_AP_PROBEREQRECVED, rssi:%d, mac:" MACSTR, \ + ap_probereqrecved->rssi, \ + MAC2STR(ap_probereqrecved->mac)); break; } default: { From 81b18aa8d588156862559e0b22a86506fc6dac1a Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 8 Nov 2016 11:25:40 +0800 Subject: [PATCH 293/343] bootloader: move some functions out of IRAM when building in bootloader mode Fixes https://github.com/espressif/esp-idf/issues/80 --- components/log/log.c | 15 ++++++++++----- components/spi_flash/spi_flash_rom_patch.c | 10 ++++++++-- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/components/log/log.c b/components/log/log.c index a2b41d7e62..9670b82dfd 100644 --- a/components/log/log.c +++ b/components/log/log.c @@ -284,7 +284,15 @@ static inline void heap_swap(int i, int j) } #endif //BOOTLOADER_BUILD -IRAM_ATTR uint32_t esp_log_early_timestamp() + +#ifndef BOOTLOADER_BUILD +#define ATTR IRAM_ATTR +#else +#define ATTR +#endif // BOOTLOADER_BUILD + + +uint32_t ATTR esp_log_early_timestamp() { return xthal_get_ccount() / (CPU_CLK_FREQ_ROM / 1000); } @@ -305,9 +313,6 @@ uint32_t IRAM_ATTR esp_log_timestamp() #else -uint32_t IRAM_ATTR esp_log_timestamp() -{ - return esp_log_early_timestamp(); -} +uint32_t esp_log_timestamp() __attribute__((alias("esp_log_early_timestamp"))); #endif //BOOTLOADER_BUILD diff --git a/components/spi_flash/spi_flash_rom_patch.c b/components/spi_flash/spi_flash_rom_patch.c index 7e23beaea2..36e5bf8236 100644 --- a/components/spi_flash/spi_flash_rom_patch.c +++ b/components/spi_flash/spi_flash_rom_patch.c @@ -19,9 +19,15 @@ static const uint32_t STATUS_QIE_BIT = (1 << 9); /* Quad Enable */ #define SPI_IDX 1 #define OTH_IDX 0 +#ifndef BOOTLOADER_BUILD +#define ATTR IRAM_ATTR +#else +#define ATTR +#endif // BOOTLOADER_BUILD + extern SpiFlashChip SPI_flashchip_data; -static void IRAM_ATTR Wait_SPI_Idle(void) +static void ATTR Wait_SPI_Idle(void) { /* Wait for SPI state machine to be idle */ while((REG_READ(SPI_EXT2_REG(SPI_IDX)) & SPI_ST)) { @@ -42,7 +48,7 @@ static void IRAM_ATTR Wait_SPI_Idle(void) about interrupts, CPU coordination, flash mapping. However some of the functions in esp_spi_flash.c call it. */ -SpiFlashOpResult IRAM_ATTR SPIUnlock(void) +SpiFlashOpResult ATTR SPIUnlock(void) { uint32_t status; From c5793521a015cd061bc5b10d5bd8cc87cc3b6723 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 8 Nov 2016 12:00:38 +1100 Subject: [PATCH 294/343] build system: Fix bootloader-flash target ESP32 forum thread: http://esp32.com/viewtopic.php?f=2&t=407&p=1902#p1902 --- components/bootloader/Makefile.projbuild | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/bootloader/Makefile.projbuild b/components/bootloader/Makefile.projbuild index 50c95f9fec..0b460059e8 100644 --- a/components/bootloader/Makefile.projbuild +++ b/components/bootloader/Makefile.projbuild @@ -33,7 +33,7 @@ clean: bootloader-clean bootloader: $(BOOTLOADER_BIN) @echo "Bootloader built. Default flash command is:" - @echo "$(ESPTOOLPY_WRITE_FLASH) 0x1000 $(BOOTLOADER_BIN)" + @echo "$(ESPTOOLPY_WRITE_FLASH) 0x1000 $^" all_binaries: $(BOOTLOADER_BIN) @@ -41,7 +41,7 @@ ESPTOOL_ALL_FLASH_ARGS += 0x1000 $(BOOTLOADER_BIN) # bootloader-flash calls flash in the bootloader dummy project bootloader-flash: $(BOOTLOADER_BIN) - $(BOOTLOADER_MAKE) flash + $(ESPTOOLPY_WRITE_FLASH) 0x1000 $^ # synchronise the project level config to the bootloader's # config From cc072f1d8ab4858775fc36341fc29283765e619a Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 8 Nov 2016 20:26:12 +0800 Subject: [PATCH 295/343] wpa_supplicant: clean up unused variable warning --- components/wpa_supplicant/src/crypto/libtommath.h | 1 + 1 file changed, 1 insertion(+) diff --git a/components/wpa_supplicant/src/crypto/libtommath.h b/components/wpa_supplicant/src/crypto/libtommath.h index 31f9706593..1010f9f63f 100644 --- a/components/wpa_supplicant/src/crypto/libtommath.h +++ b/components/wpa_supplicant/src/crypto/libtommath.h @@ -668,6 +668,7 @@ mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) } else { #endif #ifdef BN_S_MP_EXPTMOD_C + (void) dr; /* otherwise use the generic Barrett reduction technique */ return s_mp_exptmod (G, X, P, Y, 0); #else From 830e5caf4de6c211ff0321d6d74010bafca35a0b Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 9 Nov 2016 12:51:55 +1100 Subject: [PATCH 296/343] build system: Replace get_variable target w/ component_project_vars.mk generated makefiles Reduces number of make invocations, allows variables exported in project to be seen in all component make processes, not just the main ones. Also makes a no-op build about 3x faster than it was. --- components/bootloader/src/main/component.mk | 2 +- components/bt/component.mk | 4 +- components/esp32/component.mk | 6 +- components/newlib/component.mk | 2 +- make/common.mk | 6 -- make/component_common.mk | 23 ++++-- make/project.mk | 86 ++++++++++----------- make/project_config.mk | 2 +- 8 files changed, 66 insertions(+), 65 deletions(-) diff --git a/components/bootloader/src/main/component.mk b/components/bootloader/src/main/component.mk index 8c8ea4cb63..bd1dcf4d90 100644 --- a/components/bootloader/src/main/component.mk +++ b/components/bootloader/src/main/component.mk @@ -7,6 +7,6 @@ # please read the esp-idf build system document if you need to do this. # -COMPONENT_ADD_LDFLAGS := -L $(abspath .) -lmain -T esp32.bootloader.ld -T $(IDF_PATH)/components/esp32/ld/esp32.rom.ld +COMPONENT_ADD_LDFLAGS := -L $(COMPONENT_PATH) -lmain -T esp32.bootloader.ld -T $(IDF_PATH)/components/esp32/ld/esp32.rom.ld include $(IDF_PATH)/make/component_common.mk diff --git a/components/bt/component.mk b/components/bt/component.mk index e88651aa13..5addee2ceb 100644 --- a/components/bt/component.mk +++ b/components/bt/component.mk @@ -2,15 +2,13 @@ # Component Makefile # -#COMPONENT_ADD_INCLUDEDIRS := - COMPONENT_ADD_INCLUDEDIRS := include CFLAGS += -Wno-error=unused-label -Wno-error=return-type -Wno-error=missing-braces -Wno-error=pointer-sign -Wno-error=parentheses LIBS := btdm_app -COMPONENT_ADD_LDFLAGS := -lbt -L$(abspath lib) \ +COMPONENT_ADD_LDFLAGS := -lbt -L $(COMPONENT_PATH)/lib \ $(addprefix -l,$(LIBS)) \ $(LINKER_SCRIPTS) diff --git a/components/esp32/component.mk b/components/esp32/component.mk index c658787d87..7e22b65183 100644 --- a/components/esp32/component.mk +++ b/components/esp32/component.mk @@ -15,10 +15,10 @@ LIBS := core net80211 phy rtc pp wpa smartconfig coexist LINKER_SCRIPTS += -T esp32_out.ld -T esp32.common.ld -T esp32.rom.ld -T esp32.peripherals.ld COMPONENT_ADD_LDFLAGS := -lesp32 \ - $(abspath libhal.a) \ - -L$(abspath lib) \ + $(COMPONENT_PATH)/libhal.a \ + -L$(COMPONENT_PATH)/lib \ $(addprefix -l,$(LIBS)) \ - -L $(abspath ld) \ + -L $(COMPONENT_PATH)/ld \ $(LINKER_SCRIPTS) include $(IDF_PATH)/make/component_common.mk diff --git a/components/newlib/component.mk b/components/newlib/component.mk index 3731b5ef0e..0648946c20 100644 --- a/components/newlib/component.mk +++ b/components/newlib/component.mk @@ -1,4 +1,4 @@ -COMPONENT_ADD_LDFLAGS := $(abspath lib/libc.a) $(abspath lib/libm.a) -lnewlib +COMPONENT_ADD_LDFLAGS := $(COMPONENT_PATH)/lib/libc.a $(COMPONENT_PATH)/lib/libm.a -lnewlib COMPONENT_ADD_INCLUDEDIRS := include platform_include diff --git a/make/common.mk b/make/common.mk index 2b7376a4db..6183cfbc46 100644 --- a/make/common.mk +++ b/make/common.mk @@ -2,12 +2,6 @@ # and component makefiles # -# Include project config file, if it exists. -# -# (Note that we only rebuild auto.conf automatically for some targets, -# see project_config.mk for details.) --include $(BUILD_DIR_BASE)/include/config/auto.conf - #Handling of V=1/VERBOSE=1 flag # # if V=1, $(summary) does nothing and $(details) will echo extra details diff --git a/make/component_common.mk b/make/component_common.mk index bf2eace019..3177ca6e30 100644 --- a/make/component_common.mk +++ b/make/component_common.mk @@ -58,10 +58,19 @@ COMPONENT_ADD_LDFLAGS ?= -l$(COMPONENT_NAME) OWN_INCLUDES:=$(abspath $(addprefix $(COMPONENT_PATH)/,$(COMPONENT_ADD_INCLUDEDIRS) $(COMPONENT_PRIV_INCLUDEDIRS))) COMPONENT_INCLUDES := $(OWN_INCLUDES) $(filter-out $(OWN_INCLUDES),$(COMPONENT_INCLUDES)) -#This target is used to collect variable values from inside project.mk -# see project.mk GetVariable macro for details. -get_variable: - @echo "$(GET_VARIABLE)=$(call $(GET_VARIABLE)) " +# This target is used to take component.mk variables COMPONENT_ADD_INCLUDEDIRS, +# COMPONENT_ADD_LDFLAGS and COMPONENT_DEPENDS and inject them into the project +# makefile level. +# +# The target here has no dependencies, as the parent target in +# project.mk evaluates dependencies before calling down to here. See +# GenerateProjectVarsTarget in project.mk. +component_project_vars.mk:: + $(details) "Rebuilding component project variables list $(abspath $@)" + @echo "# Automatically generated build file. Do not edit." > $@ + @echo "COMPONENT_INCLUDES += $(addprefix $(COMPONENT_PATH)/,$(COMPONENT_ADD_INCLUDEDIRS))" >> $@ + @echo "COMPONENT_LDFLAGS += $(COMPONENT_ADD_LDFLAGS)" >> $@ + @echo "$(COMPONENT_NAME)-build: $(addsuffix -build,$(COMPONENT_DEPENDS))" >> $@ #Targets for build/clean. Use builtin recipe if component Makefile #hasn't defined its own. @@ -77,10 +86,12 @@ $(COMPONENT_LIBRARY): $(COMPONENT_OBJS) $(Q) $(AR) cru $@ $(COMPONENT_OBJS) endif +CLEAN_FILES = $(COMPONENT_LIBRARY) $(COMPONENT_OBJS) $(COMPONENT_OBJS:.o=.d) $(COMPONENT_EXTRA_CLEAN) component_project_vars.mk + ifeq ("$(COMPONENT_OWNCLEANTARGET)", "") clean: - $(summary) RM $(COMPONENT_LIBRARY) $(COMPONENT_OBJS) $(COMPONENT_OBJS:.o=.d) $(COMPONENT_EXTRA_CLEAN) - $(Q) rm -f $(COMPONENT_LIBRARY) $(COMPONENT_OBJS) $(COMPONENT_OBJS:.o=.d) $(COMPONENT_EXTRA_CLEAN) + $(summary) RM $(CLEAN_FILES) + $(Q) rm -f $(CLEAN_FILES) endif #Include all dependency files already generated diff --git a/make/project.mk b/make/project.mk index a60a3958fe..ac02261869 100644 --- a/make/project.mk +++ b/make/project.mk @@ -48,11 +48,22 @@ PROJECT_PATH := $(abspath $(dir $(firstword $(MAKEFILE_LIST)))) export PROJECT_PATH endif +COMMON_MAKEFILES := $(abspath $(IDF_PATH)/make/project.mk $(IDF_PATH)/make/common.mk $(IDF_PATH)/make/component_common.mk) +export COMMON_MAKEFILES + #The directory where we put all objects/libraries/binaries. The project Makefile can #configure this if needed. BUILD_DIR_BASE ?= $(PROJECT_PATH)/build export BUILD_DIR_BASE +# Include project config file, if it exists. +# +# (Note that we only rebuild auto.conf automatically for some targets, +# see project_config.mk for details.) +SDKCONFIG_MAKEFILE := $(BUILD_DIR_BASE)/include/config/auto.conf +-include $(SDKCONFIG_MAKEFILE) +export $(filter CONFIG_%,$(.VARIABLES)) + #Component directories. These directories are searched for components. #The project Makefile can override these component dirs, or define extra component directories. COMPONENT_DIRS ?= $(PROJECT_PATH)/components $(EXTRA_COMPONENT_DIRS) $(IDF_PATH)/components @@ -87,48 +98,33 @@ COMPONENT_PATHS_BUILDABLE := $(foreach cp,$(COMPONENT_PATHS),$(if $(wildcard $(c # LDFLAGS args (COMPONENT_LDFLAGS) supplied by each component. COMPONENT_INCLUDES := COMPONENT_LDFLAGS := -# -# Also add any inter-component dependencies for each component. -# Extract a variable from a child make process +# include paths for generated "component project variables" targets with +# COMPONENT_INCLUDES, COMPONENT_LDFLAGS & dependency targets # -# $(1) - path to directory to invoke make in -# $(2) - name of variable to print via the get_variable target (passed in GET_VARIABLE) +# See component_project_vars.mk target in component_common.mk +COMPONENT_PROJECT_VARS := $(addsuffix /component_project_vars.mk,$(notdir $(COMPONENT_PATHS_BUILDABLE))) +COMPONENT_PROJECT_VARS := $(addprefix $(BUILD_DIR_BASE)/,$(COMPONENT_PROJECT_VARS)) +include $(COMPONENT_PROJECT_VARS) + + +# Generate a target to rebuild component_project_vars.mk for a component +# $(1) - component directory +# $(2) - component name only # -# needs 'sed' processing of stdout because make sometimes echoes other stuff on stdout, -# even if asked not to. -# -# Debugging this? Replace $(shell with $(error and you'll see the full command as-run. -define GetVariable -$(shell "$(MAKE)" -s --no-print-directory -C $(1) -f component.mk get_variable PROJECT_PATH=$(PROJECT_PATH) GET_VARIABLE=$(2) | sed -En "s/^$(2)=(.+)/\1/p" ) +# Rebuilds if component.mk, makefiles or sdkconfig changes. +define GenerateProjectVarsTarget +$(BUILD_DIR_BASE)/$(2)/component_project_vars.mk: $(1)/component.mk $(COMMON_MAKEFILES) $(if $(MAKE_RESTARTS),,$(SDKCONFIG_MAKEFILE)) $(BUILD_DIR_BASE)/$(2) + $(Q) +$(MAKE) -C $(BUILD_DIR_BASE)/$(2) -f $(1)/component.mk component_project_vars.mk COMPONENT_PATH=$(1) endef +$(foreach comp,$(COMPONENT_PATHS_BUILDABLE), $(eval $(call GenerateProjectVarsTarget,$(comp),$(notdir $(comp))))) -COMPONENT_INCLUDES := $(abspath $(foreach comp,$(COMPONENT_PATHS_BUILDABLE),$(addprefix $(comp)/, \ - $(call GetVariable,$(comp),COMPONENT_ADD_INCLUDEDIRS)))) - -#Also add project include path, for sdk includes +#Also add project include path, for top-level includes COMPONENT_INCLUDES += $(abspath $(BUILD_DIR_BASE)/include/) + export COMPONENT_INCLUDES - -#COMPONENT_LDFLAGS has a list of all flags that are needed to link the components together. It's collected -#in the same way as COMPONENT_INCLUDES is. -COMPONENT_LDFLAGS := $(foreach comp,$(COMPONENT_PATHS_BUILDABLE), \ - $(call GetVariable,$(comp),COMPONENT_ADD_LDFLAGS)) export COMPONENT_LDFLAGS -# Generate component dependency targets from dependencies lists -# each component gains a target of its own -build with dependencies -# of the names of any other components (-build) that need building first -# -# the actual targets (that invoke submakes) are generated below by -# GenerateComponentTarget macro. -define GenerateComponentDependencies -# $(1) = component path -.PHONY: $$(notdir $(1)) -$$(notdir $(1))-build: $(addsuffix -build,$(call GetVariable,$(1),COMPONENT_DEPENDS)) -endef -$(foreach comp,$(COMPONENT_PATHS_BUILDABLE), $(eval $(call GenerateComponentDependencies,$(comp)))) - #Make sure submakes can also use this. export PROJECT_PATH @@ -242,7 +238,7 @@ COMPONENT_PATH := $(1) endef $(foreach componentpath,$(COMPONENT_PATHS),$(eval $(call includeProjBuildMakefile,$(componentpath)))) -# once we know component paths, we can include the config +# once we know component paths, we can include the config generation targets include $(IDF_PATH)/make/project_config.mk # A "component" library is any library in the LDFLAGS where @@ -269,29 +265,31 @@ $(BUILD_DIR_BASE): define GenerateComponentPhonyTarget # $(1) - path to component dir -# $(2) - target to generate (build, clean) -.PHONY: $(notdir $(1))-$(2) -$(notdir $(1))-$(2): | $(BUILD_DIR_BASE)/$(notdir $(1)) - $(Q) +$(MAKE) -C $(BUILD_DIR_BASE)/$(notdir $(1)) -f $(1)/component.mk COMPONENT_BUILD_DIR=$(BUILD_DIR_BASE)/$(notdir $(1)) $(2) +# $(2) - name of component +# $(3) - target to generate (build, clean) +.PHONY: $(2)-$(3) +$(2)-$(3): | $(BUILD_DIR_BASE)/$(2) + $(Q) +$(MAKE) -C $(BUILD_DIR_BASE)/$(2) -f $(1)/component.mk COMPONENT_PATH=$(1) COMPONENT_BUILD_DIR=$(BUILD_DIR_BASE)/$(2) $(3) endef define GenerateComponentTargets # $(1) - path to component dir -$(BUILD_DIR_BASE)/$(notdir $(1)): - @mkdir -p $(BUILD_DIR_BASE)/$(notdir $(1)) +# $(2) - name of component +$(BUILD_DIR_BASE)/$(2): + @mkdir -p $(BUILD_DIR_BASE)/$(2) # tell make it can build any component's library by invoking the recursive -build target # (this target exists for all components even ones which don't build libraries, but it's # only invoked for the targets whose libraries appear in COMPONENT_LIBRARIES and hence the # APP_ELF dependencies.) -$(BUILD_DIR_BASE)/$(notdir $(1))/lib$(notdir $(1)).a: $(notdir $(1))-build +$(BUILD_DIR_BASE)/$(2)/lib$(2).a: $(2)-build $(details) "Target '$$^' responsible for '$$@'" # echo which build target built this file endef -$(foreach component,$(COMPONENT_PATHS_BUILDABLE),$(eval $(call GenerateComponentTargets,$(component)))) +$(foreach component,$(COMPONENT_PATHS_BUILDABLE),$(eval $(call GenerateComponentTargets,$(component),$(notdir $(component))))) -$(foreach component,$(COMPONENT_PATHS_BUILDABLE),$(eval $(call GenerateComponentPhonyTarget,$(component),build))) -$(foreach component,$(COMPONENT_PATHS_BUILDABLE),$(eval $(call GenerateComponentPhonyTarget,$(component),clean))) +$(foreach component,$(COMPONENT_PATHS_BUILDABLE),$(eval $(call GenerateComponentPhonyTarget,$(component),$(notdir $(component)),build))) +$(foreach component,$(COMPONENT_PATHS_BUILDABLE),$(eval $(call GenerateComponentPhonyTarget,$(component),$(notdir $(component)),clean))) app-clean: $(addsuffix -clean,$(notdir $(COMPONENT_PATHS_BUILDABLE))) $(summary) RM $(APP_ELF) diff --git a/make/project_config.mk b/make/project_config.mk index 7ca83ce5af..4d0f6c2059 100644 --- a/make/project_config.mk +++ b/make/project_config.mk @@ -37,7 +37,7 @@ defconfig: $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig $(BUILD_DIR_BASE) # Work out of whether we have to build the Kconfig makefile # (auto.conf), or if we're in a situation where we don't need it -NON_CONFIG_TARGETS := clean %-clean get_variable help menuconfig defconfig +NON_CONFIG_TARGETS := clean %-clean help menuconfig defconfig AUTO_CONF_REGEN_TARGET := $(BUILD_DIR_BASE)/include/config/auto.conf # disable AUTO_CONF_REGEN_TARGET if all targets are non-config targets From 155f912433d93882f55f6f813ce72b3623cd073a Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 9 Nov 2016 14:26:50 +1100 Subject: [PATCH 297/343] build system: Don't build an sdkconfig for bootloader, share the top-level one This works because all CONFIG variables are exported into child make processes. --- components/bootloader/Makefile.projbuild | 16 ++++------------ components/bootloader/src/Makefile | 7 +++++-- make/component_common.mk | 2 +- make/project.mk | 10 +++++++++- 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/components/bootloader/Makefile.projbuild b/components/bootloader/Makefile.projbuild index 0b460059e8..5bcd77b36f 100644 --- a/components/bootloader/Makefile.projbuild +++ b/components/bootloader/Makefile.projbuild @@ -13,21 +13,18 @@ ifndef IS_BOOTLOADER_BUILD BOOTLOADER_COMPONENT_PATH := $(COMPONENT_PATH) BOOTLOADER_BUILD_DIR=$(abspath $(BUILD_DIR_BASE)/bootloader) BOOTLOADER_BIN=$(BOOTLOADER_BUILD_DIR)/bootloader.bin -BOOTLOADER_SDKCONFIG=$(BOOTLOADER_BUILD_DIR)/sdkconfig # Custom recursive make for bootloader sub-project BOOTLOADER_MAKE=+$(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src \ - V=$(V) SDKCONFIG=$(BOOTLOADER_SDKCONFIG) \ - BUILD_DIR_BASE=$(BOOTLOADER_BUILD_DIR) \ + V=$(V) BUILD_DIR_BASE=$(BOOTLOADER_BUILD_DIR) \ .PHONY: bootloader-clean bootloader-flash bootloader $(BOOTLOADER_BIN) -$(BOOTLOADER_BIN): | $(BOOTLOADER_BUILD_DIR)/sdkconfig +$(BOOTLOADER_BIN): $(Q) $(BOOTLOADER_MAKE) $@ bootloader-clean: - $(Q) $(BOOTLOADER_MAKE) app-clean config-clean - $(Q) rm -f $(BOOTLOADER_SDKCONFIG) $(BOOTLOADER_SDKCONFIG).old + $(Q) $(BOOTLOADER_MAKE) app-clean clean: bootloader-clean @@ -43,15 +40,10 @@ ESPTOOL_ALL_FLASH_ARGS += 0x1000 $(BOOTLOADER_BIN) bootloader-flash: $(BOOTLOADER_BIN) $(ESPTOOLPY_WRITE_FLASH) 0x1000 $^ -# synchronise the project level config to the bootloader's -# config -$(BOOTLOADER_SDKCONFIG): $(PROJECT_PATH)/sdkconfig | $(BOOTLOADER_BUILD_DIR) - $(Q) cp $< $@ - $(BOOTLOADER_BUILD_DIR): $(Q) mkdir -p $@ else -CFLAGS += -D BOOTLOADER_BUILD=1 -I $(IDF_PATH)/components/esp32/include +CFLAGS += -D BOOTLOADER_BUILD=1 -I $(IDF_PATH)/components/esp32/include endif diff --git a/components/bootloader/src/Makefile b/components/bootloader/src/Makefile index add9c15d61..3a939a8857 100644 --- a/components/bootloader/src/Makefile +++ b/components/bootloader/src/Makefile @@ -4,6 +4,9 @@ # PROJECT_NAME := bootloader + +#We cannot include the esp32 component directly but we need its includes. +#This is fixed by adding CFLAGS from Makefile.projbuild COMPONENTS := esptool_py bootloader log spi_flash # The bootloader pseudo-component is also included in this build, for its Kconfig.projbuild to be included. @@ -12,7 +15,7 @@ COMPONENTS := esptool_py bootloader log spi_flash IS_BOOTLOADER_BUILD := 1 export IS_BOOTLOADER_BUILD -#We cannot include the esp32 component directly but we need its includes. -#This is fixed by adding CFLAGS from Makefile.projbuild +# include the top-level "project" include directory, for sdkconfig.h +CFLAGS += -I$(BUILD_DIR_BASE)/../include include $(IDF_PATH)/make/project.mk diff --git a/make/component_common.mk b/make/component_common.mk index 3177ca6e30..9db57bf948 100644 --- a/make/component_common.mk +++ b/make/component_common.mk @@ -66,7 +66,7 @@ COMPONENT_INCLUDES := $(OWN_INCLUDES) $(filter-out $(OWN_INCLUDES),$(COMPONENT_I # project.mk evaluates dependencies before calling down to here. See # GenerateProjectVarsTarget in project.mk. component_project_vars.mk:: - $(details) "Rebuilding component project variables list $(abspath $@)" + $(details) "Building component project variables list $(abspath $@)" @echo "# Automatically generated build file. Do not edit." > $@ @echo "COMPONENT_INCLUDES += $(addprefix $(COMPONENT_PATH)/,$(COMPONENT_ADD_INCLUDEDIRS))" >> $@ @echo "COMPONENT_LDFLAGS += $(COMPONENT_ADD_LDFLAGS)" >> $@ diff --git a/make/project.mk b/make/project.mk index ac02261869..deaf987709 100644 --- a/make/project.mk +++ b/make/project.mk @@ -56,13 +56,17 @@ export COMMON_MAKEFILES BUILD_DIR_BASE ?= $(PROJECT_PATH)/build export BUILD_DIR_BASE +ifndef IS_BOOTLOADER_BUILD # Include project config file, if it exists. +# (bootloader build doesn't need this, config is exported from top-level) # # (Note that we only rebuild auto.conf automatically for some targets, # see project_config.mk for details.) +# SDKCONFIG_MAKEFILE := $(BUILD_DIR_BASE)/include/config/auto.conf -include $(SDKCONFIG_MAKEFILE) export $(filter CONFIG_%,$(.VARIABLES)) +endif #Component directories. These directories are searched for components. #The project Makefile can override these component dirs, or define extra component directories. @@ -114,7 +118,7 @@ include $(COMPONENT_PROJECT_VARS) # # Rebuilds if component.mk, makefiles or sdkconfig changes. define GenerateProjectVarsTarget -$(BUILD_DIR_BASE)/$(2)/component_project_vars.mk: $(1)/component.mk $(COMMON_MAKEFILES) $(if $(MAKE_RESTARTS),,$(SDKCONFIG_MAKEFILE)) $(BUILD_DIR_BASE)/$(2) +$(BUILD_DIR_BASE)/$(2)/component_project_vars.mk: $(1)/component.mk $(COMMON_MAKEFILES) $(SDKCONFIG) | $(BUILD_DIR_BASE)/$(2) $(Q) +$(MAKE) -C $(BUILD_DIR_BASE)/$(2) -f $(1)/component.mk component_project_vars.mk COMPONENT_PATH=$(1) endef $(foreach comp,$(COMPONENT_PATHS_BUILDABLE), $(eval $(call GenerateProjectVarsTarget,$(comp),$(notdir $(comp))))) @@ -238,8 +242,12 @@ COMPONENT_PATH := $(1) endef $(foreach componentpath,$(COMPONENT_PATHS),$(eval $(call includeProjBuildMakefile,$(componentpath)))) +ifndef IS_BOOTLOADER_BUILD # once we know component paths, we can include the config generation targets +# +# (bootloader build doesn't need this, config is exported from top-level) include $(IDF_PATH)/make/project_config.mk +endif # A "component" library is any library in the LDFLAGS where # the name of the library is also a name of the component From d7e57eb66830ce0b6b8f9a168b7af67efc34ec38 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 9 Nov 2016 17:25:57 +1100 Subject: [PATCH 298/343] build system: Refactor the three component-target-related macros into one --- make/project.mk | 45 ++++++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/make/project.mk b/make/project.mk index deaf987709..17d9e99c0c 100644 --- a/make/project.mk +++ b/make/project.mk @@ -111,18 +111,6 @@ COMPONENT_PROJECT_VARS := $(addsuffix /component_project_vars.mk,$(notdir $(COMP COMPONENT_PROJECT_VARS := $(addprefix $(BUILD_DIR_BASE)/,$(COMPONENT_PROJECT_VARS)) include $(COMPONENT_PROJECT_VARS) - -# Generate a target to rebuild component_project_vars.mk for a component -# $(1) - component directory -# $(2) - component name only -# -# Rebuilds if component.mk, makefiles or sdkconfig changes. -define GenerateProjectVarsTarget -$(BUILD_DIR_BASE)/$(2)/component_project_vars.mk: $(1)/component.mk $(COMMON_MAKEFILES) $(SDKCONFIG) | $(BUILD_DIR_BASE)/$(2) - $(Q) +$(MAKE) -C $(BUILD_DIR_BASE)/$(2) -f $(1)/component.mk component_project_vars.mk COMPONENT_PATH=$(1) -endef -$(foreach comp,$(COMPONENT_PATHS_BUILDABLE), $(eval $(call GenerateProjectVarsTarget,$(comp),$(notdir $(comp))))) - #Also add project include path, for top-level includes COMPONENT_INCLUDES += $(abspath $(BUILD_DIR_BASE)/include/) @@ -271,34 +259,45 @@ all_binaries: $(APP_BIN) $(BUILD_DIR_BASE): mkdir -p $(BUILD_DIR_BASE) -define GenerateComponentPhonyTarget -# $(1) - path to component dir -# $(2) - name of component -# $(3) - target to generate (build, clean) -.PHONY: $(2)-$(3) -$(2)-$(3): | $(BUILD_DIR_BASE)/$(2) - $(Q) +$(MAKE) -C $(BUILD_DIR_BASE)/$(2) -f $(1)/component.mk COMPONENT_PATH=$(1) COMPONENT_BUILD_DIR=$(BUILD_DIR_BASE)/$(2) $(3) +# Macro for the recursive sub-make for each component +# $(1) - component directory +# $(2) - component name only +# +# Is recursively expanded by the GenerateComponentTargets macro +define ComponentMake +$(Q) +$(MAKE) -C $(BUILD_DIR_BASE)/$(2) -f $(1)/component.mk COMPONENT_PATH=$(1) COMPONENT_BUILD_DIR=$(BUILD_DIR_BASE)/$(2) endef define GenerateComponentTargets # $(1) - path to component dir # $(2) - name of component +.PHONY: $(2)-build $(2)-clean + +$(2)-build: + $(call ComponentMake,$(1),$(2)) build + +$(2)-clean: + $(call ComponentMake,$(1),$(2)) clean + $(BUILD_DIR_BASE)/$(2): @mkdir -p $(BUILD_DIR_BASE)/$(2) -# tell make it can build any component's library by invoking the recursive -build target +# tell make it can build any component's library by invoking the -build target # (this target exists for all components even ones which don't build libraries, but it's # only invoked for the targets whose libraries appear in COMPONENT_LIBRARIES and hence the # APP_ELF dependencies.) $(BUILD_DIR_BASE)/$(2)/lib$(2).a: $(2)-build $(details) "Target '$$^' responsible for '$$@'" # echo which build target built this file + +# add a target to generate the component_project_vars.mk files +# that are used to inject variables into project make pass (see +# component_project_vars.mk target in component_common.mk). +$(BUILD_DIR_BASE)/$(2)/component_project_vars.mk: $(1)/component.mk $(COMMON_MAKEFILES) $(SDKCONFIG) | $(BUILD_DIR_BASE)/$(2) + $(call ComponentMake,$(1),$(2)) component_project_vars.mk endef $(foreach component,$(COMPONENT_PATHS_BUILDABLE),$(eval $(call GenerateComponentTargets,$(component),$(notdir $(component))))) -$(foreach component,$(COMPONENT_PATHS_BUILDABLE),$(eval $(call GenerateComponentPhonyTarget,$(component),$(notdir $(component)),build))) -$(foreach component,$(COMPONENT_PATHS_BUILDABLE),$(eval $(call GenerateComponentPhonyTarget,$(component),$(notdir $(component)),clean))) - app-clean: $(addsuffix -clean,$(notdir $(COMPONENT_PATHS_BUILDABLE))) $(summary) RM $(APP_ELF) $(Q) rm -f $(APP_ELF) $(APP_BIN) $(APP_MAP) From 3b96f68afd4e998f987fcc1a22810b5902b25b7e Mon Sep 17 00:00:00 2001 From: Xia Xiao Tian Date: Wed, 9 Nov 2016 17:27:12 +0800 Subject: [PATCH 299/343] 1. Add wps event processing. 2. Change wps API return type and value. --- components/esp32/event_default_handlers.c | 20 +++++++ components/esp32/include/esp_event.h | 9 +++ components/esp32/include/esp_wps.h | 71 ++++++++--------------- 3 files changed, 54 insertions(+), 46 deletions(-) diff --git a/components/esp32/event_default_handlers.c b/components/esp32/event_default_handlers.c index a2bb3ccea3..497c437163 100644 --- a/components/esp32/event_default_handlers.c +++ b/components/esp32/event_default_handlers.c @@ -67,6 +67,10 @@ static system_event_handle_t g_system_event_handle_table[] = { {SYSTEM_EVENT_STA_DISCONNECTED, system_event_sta_disconnected_handle_default}, {SYSTEM_EVENT_STA_AUTHMODE_CHANGE, NULL}, {SYSTEM_EVENT_STA_GOT_IP, system_event_sta_got_ip_default}, + {SYSTEM_EVENT_STA_WPS_ER_SUCCESS, NULL}, + {SYSTEM_EVENT_STA_WPS_ER_FAILED, NULL}, + {SYSTEM_EVENT_STA_WPS_ER_TIMEOUT, NULL}, + {SYSTEM_EVENT_STA_WPS_ER_PIN, NULL}, {SYSTEM_EVENT_AP_START, system_event_ap_start_handle_default}, {SYSTEM_EVENT_AP_STOP, system_event_ap_stop_handle_default}, {SYSTEM_EVENT_AP_STACONNECTED, NULL}, @@ -221,6 +225,22 @@ static esp_err_t esp_system_event_debug(system_event_t *event) IP2STR(&got_ip->ip_info.gw)); break; } + case SYSTEM_EVENT_STA_WPS_ER_SUCCESS: { + ESP_LOGD(TAG, "SYSTEM_EVENT_STA_WPS_ER_SUCCESS"); + break; + } + case SYSTEM_EVENT_STA_WPS_ER_FAILED: { + ESP_LOGD(TAG, "SYSTEM_EVENT_STA_WPS_ER_FAILED"); + break; + } + case SYSTEM_EVENT_STA_WPS_ER_TIMEOUT: { + ESP_LOGD(TAG, "SYSTEM_EVENT_STA_WPS_ER_TIMEOUT"); + break; + } + case SYSTEM_EVENT_STA_WPS_ER_PIN: { + ESP_LOGD(TAG, "SYSTEM_EVENT_STA_WPS_ER_PIN"); + break; + } case SYSTEM_EVENT_AP_START: { ESP_LOGD(TAG, "SYSTEM_EVENT_AP_START"); break; diff --git a/components/esp32/include/esp_event.h b/components/esp32/include/esp_event.h index 0ca4ca90ba..481c5effd5 100644 --- a/components/esp32/include/esp_event.h +++ b/components/esp32/include/esp_event.h @@ -35,6 +35,10 @@ typedef enum { SYSTEM_EVENT_STA_DISCONNECTED, /**< ESP32 station disconnected from AP */ SYSTEM_EVENT_STA_AUTHMODE_CHANGE, /**< the auth mode of AP connected by ESP32 station changed */ SYSTEM_EVENT_STA_GOT_IP, /**< ESP32 station got IP from connected AP */ + SYSTEM_EVENT_STA_WPS_ER_SUCCESS, /**< ESP32 station wps succeeds in enrollee mode */ + SYSTEM_EVENT_STA_WPS_ER_FAILED, /**< ESP32 station wps fails in enrollee mode */ + SYSTEM_EVENT_STA_WPS_ER_TIMEOUT, /**< ESP32 station wps timeout in enrollee mode */ + SYSTEM_EVENT_STA_WPS_ER_PIN, /**< ESP32 station wps pin code in enrollee mode */ SYSTEM_EVENT_AP_START, /**< ESP32 soft-AP start */ SYSTEM_EVENT_AP_STOP, /**< ESP32 soft-AP stop */ SYSTEM_EVENT_AP_STACONNECTED, /**< a station connected to ESP32 soft-AP */ @@ -73,6 +77,10 @@ typedef struct { tcpip_adapter_ip_info_t ip_info; } system_event_sta_got_ip_t; +typedef struct { + uint8_t pin_code; /**< PIN code of station in enrollee mode */ +}system_event_sta_wps_er_pin_t; + typedef struct { uint8_t mac[6]; /**< MAC address of the station connected to ESP32 soft-AP */ uint8_t aid; /**< the aid that ESP32 soft-AP gives to the station connected to */ @@ -94,6 +102,7 @@ typedef union { system_event_sta_scan_done_t scan_done; /**< ESP32 station scan (APs) done */ system_event_sta_authmode_change_t auth_change; /**< the auth mode of AP ESP32 station connected to changed */ system_event_sta_got_ip_t got_ip; /**< ESP32 station got IP */ + system_event_sta_wps_er_pin_t sta_er_pin; system_event_ap_staconnected_t sta_connected; /**< a station connected to ESP32 soft-AP */ system_event_ap_stadisconnected_t sta_disconnected; /**< a station disconnected to ESP32 soft-AP */ system_event_ap_probe_req_rx_t ap_probereqrecved; /**< ESP32 soft-AP receive probe request packet */ diff --git a/components/esp32/include/esp_wps.h b/components/esp32/include/esp_wps.h index 1588d36191..2ea7e194bb 100644 --- a/components/esp32/include/esp_wps.h +++ b/components/esp32/include/esp_wps.h @@ -16,6 +16,7 @@ #define __ESP_WPS_H__ #include +#include "esp_err.h" #ifdef __cplusplus extern "C" { @@ -40,43 +41,43 @@ extern "C" { * @{ */ +#define ESP_ERR_WIFI_REGISTRAR (ESP_ERR_WIFI_BASE + 51) /*!< WPS registrar is not supported */ +#define ESP_ERR_WIFI_WPS_TYPE (ESP_ERR_WIFI_BASE + 52) /*!< WPS type error */ +#define ESP_ERR_WIFI_WPS_SM (ESP_ERR_WIFI_BASE + 53) /*!< WPS state machine is not initialized */ + typedef enum wps_type { WPS_TYPE_DISABLE = 0, WPS_TYPE_PBC, WPS_TYPE_PIN, - WPS_TYPE_DISPLAY, WPS_TYPE_MAX, -} WPS_TYPE_t; - -enum wps_cb_status { - WPS_CB_ST_SUCCESS = 0, /**< WPS succeed */ - WPS_CB_ST_FAILED, /**< WPS fail */ - WPS_CB_ST_TIMEOUT, /**< WPS timeout, fail */ - WPS_CB_ST_WEP, /**< WPS failed because that WEP is not supported */ - WPS_CB_ST_SCAN_ERR, /**< can not find the target WPS AP */ -}; +} wps_type_t; /** * @brief Enable Wi-Fi WPS function. * * @attention WPS can only be used when ESP32 station is enabled. * - * @param WPS_TYPE_t wps_type : WPS type, so far only WPS_TYPE_PBC and WPS_TYPE_PIN is supported + * @param wps_type_t wps_type : WPS type, so far only WPS_TYPE_PBC and WPS_TYPE_PIN is supported * - * @return true : succeed - * @return false : fail + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_WPS_TYPE : wps type is invalid + * - ESP_ERR_WIFI_WPS_MODE : wifi is not in station mode or sniffer mode is on + * - ESP_ERR_WIFI_WPS_SM : wps state machine is not initialized + * - ESP_ERR_WIFI_FAIL : wps initialization fails */ -bool esp_wifi_wps_enable(WPS_TYPE_t wps_type); +esp_err_t esp_wifi_wps_enable(wps_type_t wps_type); /** * @brief Disable Wi-Fi WPS function and release resource it taken. * * @param null * - * @return true : succeed - * @return false : fail + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_WPS_MODE : wifi is not in station mode or sniffer mode is on */ -bool esp_wifi_wps_disable(void); +esp_err_t esp_wifi_wps_disable(void); /** * @brief WPS starts to work. @@ -85,36 +86,14 @@ bool esp_wifi_wps_disable(void); * * @param null * - * @return true : WPS starts to work successfully, but does not mean WPS succeed. - * @return false : fail + * @return + * - ESP_OK : succeed + * - ESP_ERR_WIFI_WPS_TYPE : wps type is invalid + * - ESP_ERR_WIFI_WPS_MODE : wifi is not in station mode or sniffer mode is on + * - ESP_ERR_WIFI_WPS_SM : wps state machine is not initialized + * - ESP_ERR_WIFI_FAIL : wps initialization fails */ -bool esp_wifi_wps_start(void); - -/** - * @brief WPS callback. - * - * @param int status : status of WPS, enum wps_cb_status. - * - If parameter status == WPS_CB_ST_SUCCESS in WPS callback, it means WPS got AP's - * information, user can call wifi_wps_disable to disable WPS and release resource, - * then call wifi_station_connect to connect to target AP. - * - Otherwise, it means that WPS fail, user can create a timer to retry WPS by - * wifi_wps_start after a while, or call wifi_wps_disable to disable WPS and release resource. - * - * @return null - */ -typedef void (*wps_st_cb_t)(int status); - -/** - * @brief Set WPS callback. - * - * @attention WPS can only be used when ESP32 station is enabled. - * - * @param wps_st_cb_t cb : callback. - * - * @return true : WPS starts to work successfully, but does not mean WPS succeed. - * @return false : fail - */ -bool esp_wifi_set_wps_cb(wps_st_cb_t cb); +esp_err_t esp_wifi_wps_start(void); /** * @} From 2f0efe151084f9c77e4c1f6dce9e5711b02ba7a7 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 9 Nov 2016 20:38:16 +1100 Subject: [PATCH 300/343] build system: Fix defconfig vs menuconfig regression in 155f9124 --- make/build_examples.sh | 2 +- make/project_config.mk | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/make/build_examples.sh b/make/build_examples.sh index d264862874..53cba23b1e 100755 --- a/make/build_examples.sh +++ b/make/build_examples.sh @@ -22,7 +22,7 @@ for example in ${IDF_PATH}/examples/*; do pushd ${EXAMPLE_NUM}/`basename ${example}` # can't do "make defconfig all" as this will trip menuconfig # sometimes - make defconfig && make || RESULT=$? + make defconfig V=1 && make V=1 || RESULT=$? popd EXAMPLE_NUM=$(( $EXAMPLE_NUM + 1 )) done diff --git a/make/project_config.mk b/make/project_config.mk index 4d0f6c2059..555086fb8d 100644 --- a/make/project_config.mk +++ b/make/project_config.mk @@ -21,13 +21,17 @@ KCONFIG_TOOL_ENV=KCONFIG_AUTOHEADER=$(abspath $(BUILD_DIR_BASE)/include/sdkconfi COMPONENT_KCONFIGS="$(COMPONENT_KCONFIGS)" KCONFIG_CONFIG=$(SDKCONFIG) \ COMPONENT_KCONFIGS_PROJBUILD="$(COMPONENT_KCONFIGS_PROJBUILD)" -menuconfig: $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig $(BUILD_DIR_BASE) +menuconfig: $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig $(summary) MENUCONFIG $(Q) $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig ifeq ("$(wildcard $(SDKCONFIG))","") -#No sdkconfig found. Need to run menuconfig to make this if we need it. +ifeq ("$(filter defconfig,$(MAKECMDGOALS))","") +# if not configuration is present and defconfig is not a target, run makeconfig $(SDKCONFIG): menuconfig +else +$(SDKCONFIG): defconfig +endif endif defconfig: $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig $(BUILD_DIR_BASE) From c441d3630c267e047327a7afd29c56cf683cbc56 Mon Sep 17 00:00:00 2001 From: Xia Xiao Tian Date: Wed, 9 Nov 2016 18:15:10 +0800 Subject: [PATCH 301/343] change pin code value type and wps API comments. --- components/esp32/include/esp_event.h | 2 +- components/esp32/include/esp_wps.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/components/esp32/include/esp_event.h b/components/esp32/include/esp_event.h index 481c5effd5..3b2b54acca 100644 --- a/components/esp32/include/esp_event.h +++ b/components/esp32/include/esp_event.h @@ -78,7 +78,7 @@ typedef struct { } system_event_sta_got_ip_t; typedef struct { - uint8_t pin_code; /**< PIN code of station in enrollee mode */ + uint8_t pin_code[8]; /**< PIN code of station in enrollee mode */ }system_event_sta_wps_er_pin_t; typedef struct { diff --git a/components/esp32/include/esp_wps.h b/components/esp32/include/esp_wps.h index 2ea7e194bb..0a413a1978 100644 --- a/components/esp32/include/esp_wps.h +++ b/components/esp32/include/esp_wps.h @@ -63,7 +63,6 @@ typedef enum wps_type { * - ESP_OK : succeed * - ESP_ERR_WIFI_WPS_TYPE : wps type is invalid * - ESP_ERR_WIFI_WPS_MODE : wifi is not in station mode or sniffer mode is on - * - ESP_ERR_WIFI_WPS_SM : wps state machine is not initialized * - ESP_ERR_WIFI_FAIL : wps initialization fails */ esp_err_t esp_wifi_wps_enable(wps_type_t wps_type); From f1938a909ae8fd94be5a4f97a6485a0206327aec Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 10 Nov 2016 10:29:42 +1100 Subject: [PATCH 302/343] build system: Generated makefiles should contain environment-variable-relative paths where possible Means that moving directories around then partial building should succeed when possible. --- make/component_common.mk | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/make/component_common.mk b/make/component_common.mk index 9db57bf948..a9598a23ba 100644 --- a/make/component_common.mk +++ b/make/component_common.mk @@ -58,19 +58,33 @@ COMPONENT_ADD_LDFLAGS ?= -l$(COMPONENT_NAME) OWN_INCLUDES:=$(abspath $(addprefix $(COMPONENT_PATH)/,$(COMPONENT_ADD_INCLUDEDIRS) $(COMPONENT_PRIV_INCLUDEDIRS))) COMPONENT_INCLUDES := $(OWN_INCLUDES) $(filter-out $(OWN_INCLUDES),$(COMPONENT_INCLUDES)) -# This target is used to take component.mk variables COMPONENT_ADD_INCLUDEDIRS, -# COMPONENT_ADD_LDFLAGS and COMPONENT_DEPENDS and inject them into the project -# makefile level. +# macro to generate relative paths inside component_project_vars.mk, whenever possible +# ie put literal $(IDF_PATH), $(PROJECT_PATH) and $(BUILD_DIR_BASE) into the generated +# makefiles where possible. +# +# This means if directories move (breaking absolute paths), don't need to 'make clean' +define MakeRelativePath +$(subst $(IDF_PATH),$$(IDF_PATH),$(subst $(PROJECT_PATH),$$(PROJECT_PATH),$(subst $(BUILD_DIR_BASE),\$$(BUILD_DIR_BASE),$(1)))) +endef + +# This target generates component_project_vars.mk for the +# component. This is used to take component.mk variables +# COMPONENT_ADD_INCLUDEDIRS, COMPONENT_ADD_LDFLAGS and +# COMPONENT_DEPENDS and inject those into the project makefile. # # The target here has no dependencies, as the parent target in # project.mk evaluates dependencies before calling down to here. See -# GenerateProjectVarsTarget in project.mk. +# GenerateComponentTargets macro in project.mk. +# +# If you are thinking of editing the output of this makefile for a +# component-specific feature, please don't! What you want is a +# Makefile.projbuild for your component (see docs/build-system.rst for more.) component_project_vars.mk:: $(details) "Building component project variables list $(abspath $@)" - @echo "# Automatically generated build file. Do not edit." > $@ - @echo "COMPONENT_INCLUDES += $(addprefix $(COMPONENT_PATH)/,$(COMPONENT_ADD_INCLUDEDIRS))" >> $@ - @echo "COMPONENT_LDFLAGS += $(COMPONENT_ADD_LDFLAGS)" >> $@ - @echo "$(COMPONENT_NAME)-build: $(addsuffix -build,$(COMPONENT_DEPENDS))" >> $@ + @echo '# Automatically generated build file. Do not edit.' > $@ + @echo 'COMPONENT_INCLUDES += $(call MakeRelativePath,$(addprefix $(COMPONENT_PATH)/,$(COMPONENT_ADD_INCLUDEDIRS)))' >> $@ + @echo 'COMPONENT_LDFLAGS += $(call MakeRelativePath,$(COMPONENT_ADD_LDFLAGS))' >> $@ + @echo '$(COMPONENT_NAME)-build: $(addsuffix -build,$(COMPONENT_DEPENDS))' >> $@ #Targets for build/clean. Use builtin recipe if component Makefile #hasn't defined its own. From 208e83def7839c0b317a37f54d9c46cfe91421ef Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 10 Nov 2016 13:20:55 +1100 Subject: [PATCH 303/343] build system: Refactor component.mk to not need component_common.mk New makefile component_wrapper.mk allows some variables to be set before component.mk is evaluated. This properly fixes problems with sdkconfig being hard to access in all phases of the build. Including component_common.mk is no longer necessary and will print a deprecation warning for components which use it. --- components/bootloader/Makefile.projbuild | 2 +- components/bootloader/src/main/component.mk | 9 +- components/bt/component.mk | 2 - components/driver/component.mk | 6 - components/esp32/component.mk | 10 -- components/expat/component.mk | 6 - components/freertos/component.mk | 1 - components/json/component.mk | 6 - components/log/component.mk | 6 +- components/lwip/component.mk | 1 - components/mbedtls/component.mk | 1 - components/newlib/component.mk | 1 - components/nghttp/component.mk | 2 - components/nvs_flash/component.mk | 1 - components/openssl/component.mk | 1 - components/spi_flash/component.mk | 1 - components/tcpip_adapter/component.mk | 2 +- components/vfs/component.mk | 6 +- components/wpa_supplicant/component.mk | 2 - components/xtensa-debug-module/component.mk | 3 +- examples/01_hello_world/main/component.mk | 7 +- examples/02_blink/main/component.mk | 8 +- examples/03_http_request/main/component.mk | 8 +- examples/04_https_request/main/component.mk | 7 +- examples/05_ble_adv/main/component.mk | 8 +- examples/06_sntp/main/component.mk | 8 +- make/common.mk | 12 +- make/component_common.mk | 136 +--------------- make/component_wrapper.mk | 169 ++++++++++++++++++++ make/project.mk | 110 +++++++------ make/project_config.mk | 4 +- 31 files changed, 261 insertions(+), 285 deletions(-) create mode 100644 make/component_wrapper.mk diff --git a/components/bootloader/Makefile.projbuild b/components/bootloader/Makefile.projbuild index 5bcd77b36f..c03288d107 100644 --- a/components/bootloader/Makefile.projbuild +++ b/components/bootloader/Makefile.projbuild @@ -20,7 +20,7 @@ BOOTLOADER_MAKE=+$(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src \ .PHONY: bootloader-clean bootloader-flash bootloader $(BOOTLOADER_BIN) -$(BOOTLOADER_BIN): +$(BOOTLOADER_BIN): $(SDKCONFIG_MAKEFILE) $(Q) $(BOOTLOADER_MAKE) $@ bootloader-clean: diff --git a/components/bootloader/src/main/component.mk b/components/bootloader/src/main/component.mk index bd1dcf4d90..01b07b9498 100644 --- a/components/bootloader/src/main/component.mk +++ b/components/bootloader/src/main/component.mk @@ -1,12 +1,9 @@ # -# Main Makefile. This is basically the same as a component makefile. +# Main bootloader Makefile. # -# This Makefile should, at the very least, just include $(IDF_PATH)/make/component_common.mk. By default, -# this will take the sources in the src/ directory, compile them and link them into -# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable, -# please read the esp-idf build system document if you need to do this. +# This is basically the same as a component makefile, but in the case of the bootloader +# we pull in bootloader-specific linker arguments. # COMPONENT_ADD_LDFLAGS := -L $(COMPONENT_PATH) -lmain -T esp32.bootloader.ld -T $(IDF_PATH)/components/esp32/ld/esp32.rom.ld -include $(IDF_PATH)/make/component_common.mk diff --git a/components/bt/component.mk b/components/bt/component.mk index 5addee2ceb..91620ddc14 100644 --- a/components/bt/component.mk +++ b/components/bt/component.mk @@ -12,8 +12,6 @@ COMPONENT_ADD_LDFLAGS := -lbt -L $(COMPONENT_PATH)/lib \ $(addprefix -l,$(LIBS)) \ $(LINKER_SCRIPTS) -include $(IDF_PATH)/make/component_common.mk - ALL_LIB_FILES := $(patsubst %,$(COMPONENT_PATH)/lib/lib%.a,$(LIBS)) $(COMPONENT_LIBRARY): $(ALL_LIB_FILES) diff --git a/components/driver/component.mk b/components/driver/component.mk index a19b131ef5..a208f6ae20 100644 --- a/components/driver/component.mk +++ b/components/driver/component.mk @@ -1,14 +1,8 @@ # # Component Makefile # -# This Makefile should, at the very least, just include $(SDK_PATH)/make/component.mk. By default, -# this will take the sources in this directory, compile them and link them into -# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable, -# please read the SDK documents if you need to do this. -# COMPONENT_ADD_INCLUDEDIRS := include COMPONENT_PRIV_INCLUDEDIRS := include/driver -include $(IDF_PATH)/make/component_common.mk diff --git a/components/esp32/component.mk b/components/esp32/component.mk index 7e22b65183..3866d3e4b9 100644 --- a/components/esp32/component.mk +++ b/components/esp32/component.mk @@ -1,12 +1,6 @@ # # Component Makefile # -# This Makefile should, at the very least, just include $(IDF_PATH)/make/component_common.mk. By default, -# this will take the sources in this directory, compile them and link them into -# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable, -# please read the esp-idf build system document if you need to do this. -# --include include/config/auto.conf COMPONENT_SRCDIRS := . hwcrypto @@ -21,8 +15,6 @@ COMPONENT_ADD_LDFLAGS := -lesp32 \ -L $(COMPONENT_PATH)/ld \ $(LINKER_SCRIPTS) -include $(IDF_PATH)/make/component_common.mk - ALL_LIB_FILES := $(patsubst %,$(COMPONENT_PATH)/lib/lib%.a,$(LIBS)) # automatically trigger a git submodule update @@ -44,8 +36,6 @@ $(COMPONENT_LIBRARY): $(ALL_LIB_FILES) # saves us from having to add the target to a Makefile.projbuild $(COMPONENT_LIBRARY): esp32_out.ld -# .. is BUILD_DIR_BASE here, as component makefiles -# are evaluated with CWD=component build dir esp32_out.ld: $(COMPONENT_PATH)/ld/esp32.ld ../include/sdkconfig.h $(CC) -I ../include -C -P -x c -E $< -o $@ diff --git a/components/expat/component.mk b/components/expat/component.mk index 907b358a87..0ee1199d1b 100644 --- a/components/expat/component.mk +++ b/components/expat/component.mk @@ -1,15 +1,9 @@ # # Component Makefile # -# This Makefile should, at the very least, just include $(SDK_PATH)/Makefile. By default, -# this will take the sources in this directory, compile them and link them into -# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable, -# please read the SDK documents if you need to do this. -# COMPONENT_ADD_INCLUDEDIRS := port/include include/expat COMPONENT_SRCDIRS := library port CFLAGS += -Wno-unused-function -DHAVE_EXPAT_CONFIG_H -include $(IDF_PATH)/make/component_common.mk diff --git a/components/freertos/component.mk b/components/freertos/component.mk index 6702d1b95c..0240ea235f 100644 --- a/components/freertos/component.mk +++ b/components/freertos/component.mk @@ -6,4 +6,3 @@ COMPONENT_ADD_LDFLAGS = -l$(COMPONENT_NAME) -Wl,--undefined=uxTopUsedPriority COMPONENT_ADD_INCLUDEDIRS := include COMPONENT_PRIV_INCLUDEDIRS := include/freertos -include $(IDF_PATH)/make/component_common.mk diff --git a/components/json/component.mk b/components/json/component.mk index 311a902f99..2dd6ea8b87 100644 --- a/components/json/component.mk +++ b/components/json/component.mk @@ -1,13 +1,7 @@ # # Component Makefile # -# This Makefile should, at the very least, just include $(SDK_PATH)/Makefile. By default, -# this will take the sources in this directory, compile them and link them into -# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable, -# please read the SDK documents if you need to do this. -# COMPONENT_ADD_INCLUDEDIRS := include port/include COMPONENT_SRCDIRS := library port -include $(IDF_PATH)/make/component_common.mk diff --git a/components/log/component.mk b/components/log/component.mk index ef497a7ecb..c2c4c03a1a 100755 --- a/components/log/component.mk +++ b/components/log/component.mk @@ -1,3 +1,5 @@ -COMPONENT_ADD_INCLUDEDIRS := include +# +# Component Makefile +# +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) -include $(IDF_PATH)/make/component_common.mk diff --git a/components/lwip/component.mk b/components/lwip/component.mk index 5d15020047..49fc644ae4 100644 --- a/components/lwip/component.mk +++ b/components/lwip/component.mk @@ -8,4 +8,3 @@ COMPONENT_SRCDIRS := api apps/sntp apps core/ipv4 core/ipv6 core netif port/free CFLAGS += -Wno-address -Wno-unused-variable -Wno-unused-but-set-variable -include $(IDF_PATH)/make/component_common.mk diff --git a/components/mbedtls/component.mk b/components/mbedtls/component.mk index 98838d4d7b..bd7209a926 100644 --- a/components/mbedtls/component.mk +++ b/components/mbedtls/component.mk @@ -6,4 +6,3 @@ COMPONENT_ADD_INCLUDEDIRS := port/include include COMPONENT_SRCDIRS := library port -include $(IDF_PATH)/make/component_common.mk diff --git a/components/newlib/component.mk b/components/newlib/component.mk index 0648946c20..4f567242b6 100644 --- a/components/newlib/component.mk +++ b/components/newlib/component.mk @@ -2,4 +2,3 @@ COMPONENT_ADD_LDFLAGS := $(COMPONENT_PATH)/lib/libc.a $(COMPONENT_PATH)/lib/libm COMPONENT_ADD_INCLUDEDIRS := include platform_include -include $(IDF_PATH)/make/component_common.mk diff --git a/components/nghttp/component.mk b/components/nghttp/component.mk index a4dca5cf70..d2cd0455f5 100644 --- a/components/nghttp/component.mk +++ b/components/nghttp/component.mk @@ -5,5 +5,3 @@ COMPONENT_ADD_INCLUDEDIRS := port/include include COMPONENT_SRCDIRS := library port - -include $(IDF_PATH)/make/component_common.mk \ No newline at end of file diff --git a/components/nvs_flash/component.mk b/components/nvs_flash/component.mk index 02ff8cf038..a905ca689e 100755 --- a/components/nvs_flash/component.mk +++ b/components/nvs_flash/component.mk @@ -6,4 +6,3 @@ COMPONENT_ADD_INCLUDEDIRS := include COMPONENT_SRCDIRS := src -include $(IDF_PATH)/make/component_common.mk diff --git a/components/openssl/component.mk b/components/openssl/component.mk index 2dfcc6b38d..be40549d20 100644 --- a/components/openssl/component.mk +++ b/components/openssl/component.mk @@ -7,4 +7,3 @@ COMPONENT_PRIV_INCLUDEDIRS := include/internal include/platform include/openssl COMPONENT_SRCDIRS := library platform -include $(IDF_PATH)/make/component_common.mk diff --git a/components/spi_flash/component.mk b/components/spi_flash/component.mk index 459da06419..d511eedb8e 100755 --- a/components/spi_flash/component.mk +++ b/components/spi_flash/component.mk @@ -5,4 +5,3 @@ ifdef IS_BOOTLOADER_BUILD COMPONENT_OBJS := spi_flash_rom_patch.o endif -include $(IDF_PATH)/make/component_common.mk diff --git a/components/tcpip_adapter/component.mk b/components/tcpip_adapter/component.mk index a57ae0b12b..c2c4c03a1a 100755 --- a/components/tcpip_adapter/component.mk +++ b/components/tcpip_adapter/component.mk @@ -1,5 +1,5 @@ # # Component Makefile # +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) -include $(IDF_PATH)/make/component_common.mk diff --git a/components/vfs/component.mk b/components/vfs/component.mk index fccf88db8a..c2c4c03a1a 100755 --- a/components/vfs/component.mk +++ b/components/vfs/component.mk @@ -1 +1,5 @@ -include $(IDF_PATH)/make/component_common.mk +# +# Component Makefile +# +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) + diff --git a/components/wpa_supplicant/component.mk b/components/wpa_supplicant/component.mk index cb6b06652f..b01eb83be9 100644 --- a/components/wpa_supplicant/component.mk +++ b/components/wpa_supplicant/component.mk @@ -2,5 +2,3 @@ COMPONENT_ADD_INCLUDEDIRS := include port/include COMPONENT_SRCDIRS := src/crypto CFLAGS += -DEMBEDDED_SUPP -D__ets__ -Wno-strict-aliasing - -include $(IDF_PATH)/make/component_common.mk diff --git a/components/xtensa-debug-module/component.mk b/components/xtensa-debug-module/component.mk index a57ae0b12b..308f64f0ea 100755 --- a/components/xtensa-debug-module/component.mk +++ b/components/xtensa-debug-module/component.mk @@ -1,5 +1,4 @@ # # Component Makefile # - -include $(IDF_PATH)/make/component_common.mk +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) diff --git a/examples/01_hello_world/main/component.mk b/examples/01_hello_world/main/component.mk index 24356f23ed..4d3b30caf3 100644 --- a/examples/01_hello_world/main/component.mk +++ b/examples/01_hello_world/main/component.mk @@ -1,10 +1,5 @@ # # Main Makefile. This is basically the same as a component makefile. # -# This Makefile should, at the very least, just include $(SDK_PATH)/make/component_common.mk. By default, -# this will take the sources in the src/ directory, compile them and link them into -# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable, -# please read the ESP-IDF documents if you need to do this. -# +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) -include $(IDF_PATH)/make/component_common.mk diff --git a/examples/02_blink/main/component.mk b/examples/02_blink/main/component.mk index 24356f23ed..b4fa72791c 100644 --- a/examples/02_blink/main/component.mk +++ b/examples/02_blink/main/component.mk @@ -1,10 +1,4 @@ # # Main Makefile. This is basically the same as a component makefile. # -# This Makefile should, at the very least, just include $(SDK_PATH)/make/component_common.mk. By default, -# this will take the sources in the src/ directory, compile them and link them into -# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable, -# please read the ESP-IDF documents if you need to do this. -# - -include $(IDF_PATH)/make/component_common.mk +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) diff --git a/examples/03_http_request/main/component.mk b/examples/03_http_request/main/component.mk index 24356f23ed..b4fa72791c 100644 --- a/examples/03_http_request/main/component.mk +++ b/examples/03_http_request/main/component.mk @@ -1,10 +1,4 @@ # # Main Makefile. This is basically the same as a component makefile. # -# This Makefile should, at the very least, just include $(SDK_PATH)/make/component_common.mk. By default, -# this will take the sources in the src/ directory, compile them and link them into -# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable, -# please read the ESP-IDF documents if you need to do this. -# - -include $(IDF_PATH)/make/component_common.mk +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) diff --git a/examples/04_https_request/main/component.mk b/examples/04_https_request/main/component.mk index 24356f23ed..4d3b30caf3 100644 --- a/examples/04_https_request/main/component.mk +++ b/examples/04_https_request/main/component.mk @@ -1,10 +1,5 @@ # # Main Makefile. This is basically the same as a component makefile. # -# This Makefile should, at the very least, just include $(SDK_PATH)/make/component_common.mk. By default, -# this will take the sources in the src/ directory, compile them and link them into -# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable, -# please read the ESP-IDF documents if you need to do this. -# +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) -include $(IDF_PATH)/make/component_common.mk diff --git a/examples/05_ble_adv/main/component.mk b/examples/05_ble_adv/main/component.mk index 24356f23ed..b4fa72791c 100644 --- a/examples/05_ble_adv/main/component.mk +++ b/examples/05_ble_adv/main/component.mk @@ -1,10 +1,4 @@ # # Main Makefile. This is basically the same as a component makefile. # -# This Makefile should, at the very least, just include $(SDK_PATH)/make/component_common.mk. By default, -# this will take the sources in the src/ directory, compile them and link them into -# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable, -# please read the ESP-IDF documents if you need to do this. -# - -include $(IDF_PATH)/make/component_common.mk +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) diff --git a/examples/06_sntp/main/component.mk b/examples/06_sntp/main/component.mk index 24356f23ed..b4fa72791c 100644 --- a/examples/06_sntp/main/component.mk +++ b/examples/06_sntp/main/component.mk @@ -1,10 +1,4 @@ # # Main Makefile. This is basically the same as a component makefile. # -# This Makefile should, at the very least, just include $(SDK_PATH)/make/component_common.mk. By default, -# this will take the sources in the src/ directory, compile them and link them into -# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable, -# please read the ESP-IDF documents if you need to do this. -# - -include $(IDF_PATH)/make/component_common.mk +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) diff --git a/make/common.mk b/make/common.mk index 6183cfbc46..779811f1ad 100644 --- a/make/common.mk +++ b/make/common.mk @@ -1,7 +1,15 @@ -# Functionality common to both top-level project makefile -# and component makefiles +# Functionality common to both top-level project makefile (project.mk) +# and component makefiles (component_wrapper.mk) # +# Include project config makefile, if it exists. +# +# (Note that we only rebuild this makefile automatically for some +# targets, see project_config.mk for details.) +SDKCONFIG_MAKEFILE ?= $(abspath $(BUILD_DIR_BASE)/include/config/auto.conf) +-include $(SDKCONFIG_MAKEFILE) +export SDKCONFIG_MAKEFILE # sub-makes (like bootloader) will reuse this path + #Handling of V=1/VERBOSE=1 flag # # if V=1, $(summary) does nothing and $(details) will echo extra details diff --git a/make/component_common.mk b/make/component_common.mk index a9598a23ba..32af3c7c06 100644 --- a/make/component_common.mk +++ b/make/component_common.mk @@ -1,135 +1,3 @@ -# Component common makefile -# -# This Makefile gets included in the Makefile of all the components to set the correct include paths etc. -# PWD is the build directory of the component and the top Makefile is the one in the -# component source dir. -# -# The way the Makefile differentiates between those two is by looking at the environment -# variable PROJECT_PATH. If this is set (to the basepath of the project), we're building a -# component and its Makefile has included this makefile. If not, we're building the entire project. -# +$(warning Deprecated feature: It is no longer necessary to include component_common.mk.) +$(warning The line "include $$(IDF_PATH)/make/component_common.mk" can be removed from component.mk files.) -# -# This Makefile requires the environment variable IDF_PATH to be set -# to the top-level directory where ESP-IDF is located (the directory -# containing this 'make' directory). -# - -ifeq ("$(PROJECT_PATH)","") -$(error Make was invoked from $(CURDIR). However please do not run make from the sdk or a component directory; invoke make from the project directory. See the ESP-IDF README for details.) -endif - -# Find the path to the component -COMPONENT_PATH := $(abspath $(dir $(firstword $(MAKEFILE_LIST)))) -export COMPONENT_PATH - -include $(IDF_PATH)/make/common.mk - -#Some of these options are overridable by the component's component.mk Makefile - -#Name of the component -COMPONENT_NAME ?= $(lastword $(subst /, ,$(realpath $(COMPONENT_PATH)))) - -#Absolute path of the .a file -COMPONENT_LIBRARY := lib$(COMPONENT_NAME).a - -#Source dirs a component has. Default to root directory of component. -COMPONENT_SRCDIRS ?= . - -#Object files which need to be linked into the library -#By default we take all .c/.S files in the component directory. -ifeq ("$(COMPONENT_OBJS)", "") -#Find all source files in all COMPONENT_SRCDIRS -COMPONENT_OBJS := $(foreach compsrcdir,$(COMPONENT_SRCDIRS),$(patsubst %.c,%.o,$(wildcard $(COMPONENT_PATH)/$(compsrcdir)/*.c))) -COMPONENT_OBJS += $(foreach compsrcdir,$(COMPONENT_SRCDIRS),$(patsubst %.cpp,%.o,$(wildcard $(COMPONENT_PATH)/$(compsrcdir)/*.cpp))) -COMPONENT_OBJS += $(foreach compsrcdir,$(COMPONENT_SRCDIRS),$(patsubst %.S,%.o,$(wildcard $(COMPONENT_PATH)/$(compsrcdir)/*.S))) -#Make relative by removing COMPONENT_PATH from all found object paths -COMPONENT_OBJS := $(patsubst $(COMPONENT_PATH)/%,%,$(COMPONENT_OBJS)) -endif - -#By default, include only the include/ dir. -COMPONENT_ADD_INCLUDEDIRS ?= include -COMPONENT_ADD_LDFLAGS ?= -l$(COMPONENT_NAME) - -#If we're called to compile something, we'll get passed the COMPONENT_INCLUDES -#variable with all the include dirs from all the components in random order. This -#means we can accidentally grab a header from another component before grabbing our own. -#To make sure that does not happen, re-order the includes so ours come first. -OWN_INCLUDES:=$(abspath $(addprefix $(COMPONENT_PATH)/,$(COMPONENT_ADD_INCLUDEDIRS) $(COMPONENT_PRIV_INCLUDEDIRS))) -COMPONENT_INCLUDES := $(OWN_INCLUDES) $(filter-out $(OWN_INCLUDES),$(COMPONENT_INCLUDES)) - -# macro to generate relative paths inside component_project_vars.mk, whenever possible -# ie put literal $(IDF_PATH), $(PROJECT_PATH) and $(BUILD_DIR_BASE) into the generated -# makefiles where possible. -# -# This means if directories move (breaking absolute paths), don't need to 'make clean' -define MakeRelativePath -$(subst $(IDF_PATH),$$(IDF_PATH),$(subst $(PROJECT_PATH),$$(PROJECT_PATH),$(subst $(BUILD_DIR_BASE),\$$(BUILD_DIR_BASE),$(1)))) -endef - -# This target generates component_project_vars.mk for the -# component. This is used to take component.mk variables -# COMPONENT_ADD_INCLUDEDIRS, COMPONENT_ADD_LDFLAGS and -# COMPONENT_DEPENDS and inject those into the project makefile. -# -# The target here has no dependencies, as the parent target in -# project.mk evaluates dependencies before calling down to here. See -# GenerateComponentTargets macro in project.mk. -# -# If you are thinking of editing the output of this makefile for a -# component-specific feature, please don't! What you want is a -# Makefile.projbuild for your component (see docs/build-system.rst for more.) -component_project_vars.mk:: - $(details) "Building component project variables list $(abspath $@)" - @echo '# Automatically generated build file. Do not edit.' > $@ - @echo 'COMPONENT_INCLUDES += $(call MakeRelativePath,$(addprefix $(COMPONENT_PATH)/,$(COMPONENT_ADD_INCLUDEDIRS)))' >> $@ - @echo 'COMPONENT_LDFLAGS += $(call MakeRelativePath,$(COMPONENT_ADD_LDFLAGS))' >> $@ - @echo '$(COMPONENT_NAME)-build: $(addsuffix -build,$(COMPONENT_DEPENDS))' >> $@ - -#Targets for build/clean. Use builtin recipe if component Makefile -#hasn't defined its own. -ifeq ("$(COMPONENT_OWNBUILDTARGET)", "") -build: $(COMPONENT_LIBRARY) - @mkdir -p $(COMPONENT_SRCDIRS) - -#Build the archive. We remove the archive first, otherwise ar will get confused if we update -#an archive when multiple filenames have the same name (src1/test.o and src2/test.o) -$(COMPONENT_LIBRARY): $(COMPONENT_OBJS) - $(summary) AR $@ - $(Q) rm -f $@ - $(Q) $(AR) cru $@ $(COMPONENT_OBJS) -endif - -CLEAN_FILES = $(COMPONENT_LIBRARY) $(COMPONENT_OBJS) $(COMPONENT_OBJS:.o=.d) $(COMPONENT_EXTRA_CLEAN) component_project_vars.mk - -ifeq ("$(COMPONENT_OWNCLEANTARGET)", "") -clean: - $(summary) RM $(CLEAN_FILES) - $(Q) rm -f $(CLEAN_FILES) -endif - -#Include all dependency files already generated --include $(COMPONENT_OBJS:.o=.d) - -#This pattern is generated for each COMPONENT_SRCDIR to compile the files in it. -define GenerateCompileTargets -# $(1) - directory containing source files, relative to $(COMPONENT_PATH) -$(1)/%.o: $$(COMPONENT_PATH)/$(1)/%.c | $(1) - $$(summary) CC $$@ - $$(Q) $$(CC) $$(CFLAGS) $(CPPFLAGS) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@ - -$(1)/%.o: $$(COMPONENT_PATH)/$(1)/%.cpp | $(1) - $$(summary) CXX $$@ - $$(Q) $$(CXX) $$(CXXFLAGS) $(CPPFLAGS) $$(addprefix -I,$$(COMPONENT_INCLUDES)) $$(addprefix -I,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@ - -$(1)/%.o: $$(COMPONENT_PATH)/$(1)/%.S | $(1) - $$(summary) AS $$@ - $$(Q) $$(CC) $$(CFLAGS) $(CPPFLAGS) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@ - -# CWD is build dir, create the build subdirectory if it doesn't exist -$(1): - @mkdir -p $(1) -endef - -#Generate all the compile target recipes -$(foreach srcdir,$(COMPONENT_SRCDIRS), $(eval $(call GenerateCompileTargets,$(srcdir)))) diff --git a/make/component_wrapper.mk b/make/component_wrapper.mk new file mode 100644 index 0000000000..68efe0d211 --- /dev/null +++ b/make/component_wrapper.mk @@ -0,0 +1,169 @@ +# Component wrapper makefile +# +# This makefile gets called recursively from the project make, once for each component. +# COMPONENT_MAKEFILE is set to point at the component.mk file for the component itself, +# which is included as part of this process (after default variables are defined). +# +# This makefile comprises multiple stages, marked in blocked comments below. +# +# CWD is the build directory of the component. + +ifeq ("$(PROJECT_PATH)","") +$(error Make was invoked from $(CURDIR). However please do not run make from the sdk or a component directory; invoke make from the project directory. See the ESP-IDF README for details.) +endif + + +################################################################################ +# 1) Set default variables for the component build (including configuration +# loaded from sdkconfig.) +################################################################################ + +# Find the path to the component +COMPONENT_PATH := $(abspath $(dir $(COMPONENT_MAKEFILE))) +export COMPONENT_PATH + +# COMPONENT_BUILD_DIR is otherwise known as CWD for the build +COMPONENT_BUILD_DIR := $(abspath .) + +# include elements common to both project & component makefiles +# (includes project configuration set via menuconfig) +include $(IDF_PATH)/make/common.mk + +# Some of the following defaults may be overriden by the component's component.mk makefile, +# during the next step: + +# Name of the component +COMPONENT_NAME := $(lastword $(subst /, ,$(realpath $(COMPONENT_PATH)))) + +# Absolute path of the .a file +COMPONENT_LIBRARY = lib$(COMPONENT_NAME).a + +# Source dirs a component has. Default to root directory of component. +COMPONENT_SRCDIRS = . + +# By default, include only the include/ dir. +COMPONENT_ADD_INCLUDEDIRS = include +COMPONENT_ADD_LDFLAGS = -l$(COMPONENT_NAME) + + +################################################################################ +# 2) Include the component.mk for the specific component (COMPONENT_MAKEFILE) to +# override variables & optionally define custom targets. +################################################################################ + +include $(COMPONENT_MAKEFILE) + + +################################################################################ +# 3) Set variables that depend on values that may changed by component.mk +################################################################################ + +# Object files which need to be linked into the library +# By default we take all .c, .cpp & .S files in COMPONENT_SRCDIRS. +ifeq ("$(COMPONENT_OBJS)", "") +# Find all source files in all COMPONENT_SRCDIRS +COMPONENT_OBJS := $(foreach compsrcdir,$(COMPONENT_SRCDIRS),$(patsubst %.c,%.o,$(wildcard $(COMPONENT_PATH)/$(compsrcdir)/*.c))) +COMPONENT_OBJS += $(foreach compsrcdir,$(COMPONENT_SRCDIRS),$(patsubst %.cpp,%.o,$(wildcard $(COMPONENT_PATH)/$(compsrcdir)/*.cpp))) +COMPONENT_OBJS += $(foreach compsrcdir,$(COMPONENT_SRCDIRS),$(patsubst %.S,%.o,$(wildcard $(COMPONENT_PATH)/$(compsrcdir)/*.S))) +# Make relative by removing COMPONENT_PATH from all found object paths +COMPONENT_OBJS := $(patsubst $(COMPONENT_PATH)/%,%,$(COMPONENT_OBJS)) +endif + +# If we're called to compile something, we'll get passed the COMPONENT_INCLUDES +# variable with all the include dirs from all the components in random order. This +# means we can accidentally grab a header from another component before grabbing our own. +# To make sure that does not happen, re-order the includes so ours come first. +OWN_INCLUDES:=$(abspath $(addprefix $(COMPONENT_PATH)/,$(COMPONENT_ADD_INCLUDEDIRS) $(COMPONENT_PRIV_INCLUDEDIRS))) +COMPONENT_INCLUDES := $(OWN_INCLUDES) $(filter-out $(OWN_INCLUDES),$(COMPONENT_INCLUDES)) + + +################################################################################ +# 4) Define a target to generate component_project_vars.mk Makefile which +# contains common per-component settings which are included directly in the +# top-level project make +################################################################################ + +# macro to generate variable-relative paths inside component_project_vars.mk, whenever possible +# ie put literal $(IDF_PATH), $(PROJECT_PATH) and $(BUILD_DIR_BASE) into the generated +# makefiles where possible. +# +# This means if directories move (breaking absolute paths), don't need to 'make clean' +define MakeVariablePath +$(subst $(IDF_PATH),$$(IDF_PATH),$(subst $(PROJECT_PATH),$$(PROJECT_PATH),$(subst $(BUILD_DIR_BASE),\$$(BUILD_DIR_BASE),$(1)))) +endef + +# component_project_vars.mk target for the component. This is used to +# take component.mk variables COMPONENT_ADD_INCLUDEDIRS, +# COMPONENT_ADD_LDFLAGS and COMPONENT_DEPENDS and inject those into +# the project make pass. +# +# The target here has no dependencies, as the parent target in +# project.mk evaluates dependencies before calling down to here. See +# GenerateComponentTargets macro in project.mk. +# +# If you are thinking of editing the output of this target for a +# component-specific feature, please don't! What you want is a +# Makefile.projbuild for your component (see docs/build-system.rst for +# more.) +component_project_vars.mk:: + $(details) "Building component project variables list $(abspath $@)" + @echo '# Automatically generated build file. Do not edit.' > $@ + @echo 'COMPONENT_INCLUDES += $(call MakeVariablePath,$(addprefix $(COMPONENT_PATH)/,$(COMPONENT_ADD_INCLUDEDIRS)))' >> $@ + @echo 'COMPONENT_LDFLAGS += $(call MakeVariablePath,$(COMPONENT_ADD_LDFLAGS))' >> $@ + @echo '$(COMPONENT_NAME)-build: $(addsuffix -build,$(COMPONENT_DEPENDS))' >> $@ + + +################################################################################ +# 5) If COMPONENT_OWNBUILDTARGET / COMPONENT_OWNCLEANTARGET is not set by component.mk, +# define default build, clean, etc. targets +################################################################################ + +# If COMPONENT_OWNBUILDTARGET is not set, define a phony build target and +# a COMPONENT_LIBRARY link target. +ifeq ("$(COMPONENT_OWNBUILDTARGET)", "") +.PHONY: build +build: $(COMPONENT_LIBRARY) + @mkdir -p $(COMPONENT_SRCDIRS) + +# Build the archive. We remove the archive first, otherwise ar will get confused if we update +# an archive when multiple filenames have the same name (src1/test.o and src2/test.o) +$(COMPONENT_LIBRARY): $(COMPONENT_OBJS) + $(summary) AR $@ + $(Q) rm -f $@ + $(Q) $(AR) cru $@ $(COMPONENT_OBJS) +endif + +# If COMPONENT_OWNCLEANTARGET is not set, define a phony clean target +ifeq ("$(COMPONENT_OWNCLEANTARGET)", "") +CLEAN_FILES = $(COMPONENT_LIBRARY) $(COMPONENT_OBJS) $(COMPONENT_OBJS:.o=.d) $(COMPONENT_EXTRA_CLEAN) component_project_vars.mk +.PHONY: clean +clean: + $(summary) RM $(CLEAN_FILES) + $(Q) rm -f $(CLEAN_FILES) +endif + +# Include all dependency files already generated +-include $(COMPONENT_OBJS:.o=.d) + +# This pattern is generated for each COMPONENT_SRCDIR to compile the files in it. +define GenerateCompileTargets +# $(1) - directory containing source files, relative to $(COMPONENT_PATH) +$(1)/%.o: $$(COMPONENT_PATH)/$(1)/%.c | $(1) + $$(summary) CC $$@ + $$(Q) $$(CC) $$(CFLAGS) $$(CPPFLAGS) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@ + +$(1)/%.o: $$(COMPONENT_PATH)/$(1)/%.cpp | $(1) + $$(summary) CXX $$@ + $$(Q) $$(CXX) $$(CXXFLAGS) $$(CPPFLAGS) $$(addprefix -I,$$(COMPONENT_INCLUDES)) $$(addprefix -I,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@ + +$(1)/%.o: $$(COMPONENT_PATH)/$(1)/%.S | $(1) + $$(summary) AS $$@ + $$(Q) $$(CC) $$(CPPFLAGS) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@ + +# CWD is build dir, create the build subdirectory if it doesn't exist +$(1): + @mkdir -p $(1) +endef + +# Generate all the compile target patterns +$(foreach srcdir,$(COMPONENT_SRCDIRS), $(eval $(call GenerateCompileTargets,$(srcdir)))) diff --git a/make/project.mk b/make/project.mk index 17d9e99c0c..f9cf20a329 100644 --- a/make/project.mk +++ b/make/project.mk @@ -48,80 +48,73 @@ PROJECT_PATH := $(abspath $(dir $(firstword $(MAKEFILE_LIST)))) export PROJECT_PATH endif -COMMON_MAKEFILES := $(abspath $(IDF_PATH)/make/project.mk $(IDF_PATH)/make/common.mk $(IDF_PATH)/make/component_common.mk) +# A list of the "common" makefiles, to use as a target dependency +COMMON_MAKEFILES := $(abspath $(IDF_PATH)/make/project.mk $(IDF_PATH)/make/common.mk $(IDF_PATH)/make/component_wrapper.mk) export COMMON_MAKEFILES -#The directory where we put all objects/libraries/binaries. The project Makefile can -#configure this if needed. +# The directory where we put all objects/libraries/binaries. The project Makefile can +# configure this if needed. BUILD_DIR_BASE ?= $(PROJECT_PATH)/build export BUILD_DIR_BASE -ifndef IS_BOOTLOADER_BUILD -# Include project config file, if it exists. -# (bootloader build doesn't need this, config is exported from top-level) -# -# (Note that we only rebuild auto.conf automatically for some targets, -# see project_config.mk for details.) -# -SDKCONFIG_MAKEFILE := $(BUILD_DIR_BASE)/include/config/auto.conf --include $(SDKCONFIG_MAKEFILE) -export $(filter CONFIG_%,$(.VARIABLES)) -endif - -#Component directories. These directories are searched for components. -#The project Makefile can override these component dirs, or define extra component directories. +# Component directories. These directories are searched for components. +# The project Makefile can override these component dirs, or define extra component directories. COMPONENT_DIRS ?= $(PROJECT_PATH)/components $(EXTRA_COMPONENT_DIRS) $(IDF_PATH)/components export COMPONENT_DIRS -#The project Makefile can define a list of components, but if it does not do this we just take -#all available components in the component dirs. +# Source directories of the project itself (a special, project-specific component.) Defaults to only "main". +SRCDIRS ?= main + +# The project Makefile can define a list of components, but if it does not do this we just take +# all available components in the component dirs. ifeq ("$(COMPONENTS)","") -#Find all component names. The component names are the same as the -#directories they're in, so /bla/components/mycomponent/ -> mycomponent. We later use -#the COMPONENT_DIRS bit to find back the component path. +# Find all component names. The component names are the same as the +# directories they're in, so /bla/components/mycomponent/ -> mycomponent. We then use +# COMPONENT_DIRS to build COMPONENT_PATHS with the full path to each component. COMPONENTS := $(foreach dir,$(COMPONENT_DIRS),$(wildcard $(dir)/*)) COMPONENTS := $(sort $(foreach comp,$(COMPONENTS),$(lastword $(subst /, ,$(comp))))) endif export COMPONENTS -#Sources default to only "main" -SRCDIRS ?= main - -#Here, we resolve and add all the components and source paths into absolute paths. -#If a component exists in multiple COMPONENT_DIRS, we take the first match. -#WARNING: These directories paths must be generated WITHOUT a trailing / so we -#can use $(notdir x) to get the component name. +# Resolve all of COMPONENTS into absolute paths in COMPONENT_PATHS. +# +# If a component name exists in multiple COMPONENT_DIRS, we take the first match. +# +# NOTE: These paths must be generated WITHOUT a trailing / so we +# can use $(notdir x) to get the component name. COMPONENT_PATHS := $(foreach comp,$(COMPONENTS),$(firstword $(foreach dir,$(COMPONENT_DIRS),$(wildcard $(dir)/$(comp))))) COMPONENT_PATHS += $(abspath $(SRCDIRS)) -#A component is buildable if it has a component.mk makefile; we assume that a -# 'make -C $(component dir) -f component.mk build' results in a lib$(componentname).a +# A component is buildable if it has a component.mk makefile in it COMPONENT_PATHS_BUILDABLE := $(foreach cp,$(COMPONENT_PATHS),$(if $(wildcard $(cp)/component.mk),$(cp))) -# Assemble global list of include dirs (COMPONENT_INCLUDES), and -# LDFLAGS args (COMPONENT_LDFLAGS) supplied by each component. +# Initialise a project-wide list of include dirs (COMPONENT_INCLUDES), +# and LDFLAGS args (COMPONENT_LDFLAGS) supplied by each component. +# +# These variables are built up via the component_project_vars.mk +# generated makefiles (one per component). COMPONENT_INCLUDES := COMPONENT_LDFLAGS := -# include paths for generated "component project variables" targets with -# COMPONENT_INCLUDES, COMPONENT_LDFLAGS & dependency targets +# COMPONENT_PROJECT_VARS is the list of component_project_vars.mk generated makefiles +# for each component. # -# See component_project_vars.mk target in component_common.mk +# Including $(COMPONENT_PROJECT_VARS) builds the COMPONENT_INCLUDES, +# COMPONENT_LDFLAGS variables and also targets for any inter-component +# dependencies. +# +# See the component_project_vars.mk target in component_wrapper.mk COMPONENT_PROJECT_VARS := $(addsuffix /component_project_vars.mk,$(notdir $(COMPONENT_PATHS_BUILDABLE))) COMPONENT_PROJECT_VARS := $(addprefix $(BUILD_DIR_BASE)/,$(COMPONENT_PROJECT_VARS)) include $(COMPONENT_PROJECT_VARS) -#Also add project include path, for top-level includes +# Also add top-level project include path, for top-level includes COMPONENT_INCLUDES += $(abspath $(BUILD_DIR_BASE)/include/) export COMPONENT_INCLUDES -export COMPONENT_LDFLAGS -#Make sure submakes can also use this. -export PROJECT_PATH - -#Include functionality common to both project & component --include $(IDF_PATH)/make/common.mk +# Set variables common to both project & component +include $(IDF_PATH)/make/common.mk # Set default LDFLAGS @@ -198,15 +191,15 @@ CXXFLAGS := $(strip \ export CFLAGS CPPFLAGS CXXFLAGS -#Set host compiler and binutils +# Set host compiler and binutils HOSTCC := $(CC) HOSTLD := $(LD) HOSTAR := $(AR) HOSTOBJCOPY := $(OBJCOPY) export HOSTCC HOSTLD HOSTAR HOSTOBJCOPY -#Set target compiler. Defaults to whatever the user has -#configured as prefix + yer olde gcc commands +# Set target compiler. Defaults to whatever the user has +# configured as prefix + ye olde gcc commands CC := $(call dequote,$(CONFIG_TOOLPREFIX))gcc CXX := $(call dequote,$(CONFIG_TOOLPREFIX))c++ LD := $(call dequote,$(CONFIG_TOOLPREFIX))ld @@ -230,10 +223,10 @@ COMPONENT_PATH := $(1) endef $(foreach componentpath,$(COMPONENT_PATHS),$(eval $(call includeProjBuildMakefile,$(componentpath)))) -ifndef IS_BOOTLOADER_BUILD # once we know component paths, we can include the config generation targets # # (bootloader build doesn't need this, config is exported from top-level) +ifndef IS_BOOTLOADER_BUILD include $(IDF_PATH)/make/project_config.mk endif @@ -265,12 +258,14 @@ $(BUILD_DIR_BASE): # # Is recursively expanded by the GenerateComponentTargets macro define ComponentMake -$(Q) +$(MAKE) -C $(BUILD_DIR_BASE)/$(2) -f $(1)/component.mk COMPONENT_PATH=$(1) COMPONENT_BUILD_DIR=$(BUILD_DIR_BASE)/$(2) +$(Q) +$(MAKE) -C $(BUILD_DIR_BASE)/$(2) -f $(IDF_PATH)/make/component_wrapper.mk COMPONENT_MAKEFILE=$(1)/component.mk endef -define GenerateComponentTargets +# Generate top-level component-specific targets for each component # $(1) - path to component dir # $(2) - name of component +# +define GenerateComponentTargets .PHONY: $(2)-build $(2)-clean $(2)-build: @@ -289,10 +284,19 @@ $(BUILD_DIR_BASE)/$(2): $(BUILD_DIR_BASE)/$(2)/lib$(2).a: $(2)-build $(details) "Target '$$^' responsible for '$$@'" # echo which build target built this file -# add a target to generate the component_project_vars.mk files -# that are used to inject variables into project make pass (see -# component_project_vars.mk target in component_common.mk). -$(BUILD_DIR_BASE)/$(2)/component_project_vars.mk: $(1)/component.mk $(COMMON_MAKEFILES) $(SDKCONFIG) | $(BUILD_DIR_BASE)/$(2) +# add a target to generate the component_project_vars.mk files that +# are used to inject variables into project make pass (see matching +# component_project_vars.mk target in component_wrapper.mk). +# +# If any component_project_vars.mk file is out of date, the make +# process will call this target to rebuild it and then restart. +# +# Note: $(SDKCONFIG) is a normal prereq as we need to rebuild these +# files whenever the config changes. $(SDKCONFIG_MAKEFILE) is an +# order-only prereq because if it hasn't been rebuilt, we need to +# build it first - but including it as a normal prereq can lead to +# infinite restarts as the conf process will keep updating it. +$(BUILD_DIR_BASE)/$(2)/component_project_vars.mk: $(1)/component.mk $(COMMON_MAKEFILES) $(SDKCONFIG) | $(BUILD_DIR_BASE)/$(2) $(SDKCONFIG_MAKEFILE) $(call ComponentMake,$(1),$(2)) component_project_vars.mk endef diff --git a/make/project_config.mk b/make/project_config.mk index 555086fb8d..09cec2e0be 100644 --- a/make/project_config.mk +++ b/make/project_config.mk @@ -42,7 +42,7 @@ defconfig: $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig $(BUILD_DIR_BASE) # Work out of whether we have to build the Kconfig makefile # (auto.conf), or if we're in a situation where we don't need it NON_CONFIG_TARGETS := clean %-clean help menuconfig defconfig -AUTO_CONF_REGEN_TARGET := $(BUILD_DIR_BASE)/include/config/auto.conf +AUTO_CONF_REGEN_TARGET := $(SDKCONFIG_MAKEFILE) # disable AUTO_CONF_REGEN_TARGET if all targets are non-config targets # (and not building default target) @@ -50,7 +50,7 @@ ifneq ("$(MAKECMDGOALS)","") ifeq ($(filter $(NON_CONFIG_TARGETS), $(MAKECMDGOALS)),$(MAKECMDGOALS)) AUTO_CONF_REGEN_TARGET := # dummy target -$(BUILD_DIR_BASE)/include/config/auto.conf: +$(SDKCONFIG_MAKEFILE): endif endif From f7cb6fc9690074674ad4a0e4d302131787b77253 Mon Sep 17 00:00:00 2001 From: Krzysztof Date: Wed, 9 Nov 2016 20:26:28 +0100 Subject: [PATCH 304/343] NVS Examples update Updated previusly submitted example, saved it as "07_nvs_rw_value" and added a new one. Overview of examples: * 07_nvs_rw_value - simple read and write a single value * 08_nvs_rw_blob - read and write a blob that is extened with new data on each restart of ESP32 Removed LICENSE files --- examples/07_nvs_read_write/README.md | 7 - .../07_nvs_read_write/main/nvs_read_write.c | 62 ------ .../Makefile | 2 +- examples/07_nvs_rw_value/README.md | 13 ++ .../main/component.mk | 0 examples/07_nvs_rw_value/main/nvs_rw_value.c | 77 ++++++++ examples/08_nvs_rw_blob/Makefile | 9 + examples/08_nvs_rw_blob/README.md | 14 ++ examples/08_nvs_rw_blob/main/component.mk | 10 + examples/08_nvs_rw_blob/main/nvs_rw_blob.c | 183 ++++++++++++++++++ 10 files changed, 307 insertions(+), 70 deletions(-) delete mode 100644 examples/07_nvs_read_write/README.md delete mode 100644 examples/07_nvs_read_write/main/nvs_read_write.c rename examples/{07_nvs_read_write => 07_nvs_rw_value}/Makefile (83%) create mode 100644 examples/07_nvs_rw_value/README.md rename examples/{07_nvs_read_write => 07_nvs_rw_value}/main/component.mk (100%) create mode 100644 examples/07_nvs_rw_value/main/nvs_rw_value.c create mode 100644 examples/08_nvs_rw_blob/Makefile create mode 100644 examples/08_nvs_rw_blob/README.md create mode 100644 examples/08_nvs_rw_blob/main/component.mk create mode 100644 examples/08_nvs_rw_blob/main/nvs_rw_blob.c diff --git a/examples/07_nvs_read_write/README.md b/examples/07_nvs_read_write/README.md deleted file mode 100644 index bac8ee8d54..0000000000 --- a/examples/07_nvs_read_write/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# Non-Volatile Storage (NVS) Read and Write Example - -Demonstrates how to read and write a value using NVS. The value tracks number of ESP32 module restarts. - -Example also shows how to use basic diagnostics if read / write operation was successful. - -See the README.md file in the upper level 'examples' directory for more information about examples. diff --git a/examples/07_nvs_read_write/main/nvs_read_write.c b/examples/07_nvs_read_write/main/nvs_read_write.c deleted file mode 100644 index 40d330f62f..0000000000 --- a/examples/07_nvs_read_write/main/nvs_read_write.c +++ /dev/null @@ -1,62 +0,0 @@ -/* Non-Volatile Storage (NVS) Read and Write Example - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ -#include -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "esp_system.h" -#include "nvs_flash.h" -#include "nvs.h" - -void app_main() -{ - nvs_flash_init(); - system_init(); - - nvs_handle handle_to_settings; - esp_err_t err; - int32_t restart_counter = 0; - - // Open the NVS - printf("Opening Non-Volatile Storage (NVS) ... "); - err = nvs_open("settings", NVS_READWRITE, &handle_to_settings); - printf((err != ESP_OK) ? "Failed!\n" : "OK\n"); - - // Read from the NVS - printf("Reading restart counter from NVS ... "); - err = nvs_get_i32(handle_to_settings, "restart_conter", &restart_counter); - switch (err) { - case ESP_OK: - printf("OK\n"); - printf("Restart counter = %d\n", restart_counter); - break; - case ESP_ERR_NVS_NOT_FOUND: - printf("The counter is not initialized yet!\n"); - break; - default : - printf("Error (%d) reading!\n", err); - } - - // Write to the NVS - printf("Updating restart counter in NVS ... "); - restart_counter++; - err = nvs_set_i32(handle_to_settings, "restart_conter", restart_counter); - printf((err != ESP_OK) ? "Failed!\n" : "OK\n"); - - // Close the NVS - nvs_close(handle_to_settings); - - // Restart module - for (int i = 10; i >= 0; i--) { - printf("Restarting in %d seconds...\n", i); - vTaskDelay(1000 / portTICK_RATE_MS); - } - printf("Restarting now.\n"); - fflush(stdout); - system_restart(); -} diff --git a/examples/07_nvs_read_write/Makefile b/examples/07_nvs_rw_value/Makefile similarity index 83% rename from examples/07_nvs_read_write/Makefile rename to examples/07_nvs_rw_value/Makefile index 3d6adb4d02..fdfc09c574 100644 --- a/examples/07_nvs_read_write/Makefile +++ b/examples/07_nvs_rw_value/Makefile @@ -3,7 +3,7 @@ # project subdirectory. # -PROJECT_NAME := nvs-read-write +PROJECT_NAME := nvs-rw-value include $(IDF_PATH)/make/project.mk diff --git a/examples/07_nvs_rw_value/README.md b/examples/07_nvs_rw_value/README.md new file mode 100644 index 0000000000..83dc29fd18 --- /dev/null +++ b/examples/07_nvs_rw_value/README.md @@ -0,0 +1,13 @@ +# Non-Volatile Storage (NVS) Read and Write Example + +Demonstrates how to read and write a single integer value using NVS. + +The value holds the number of ESP32 module restarts. Since it is written to NVS, the value is preserved between restarts. + +Example also shows how to check if read / write operation was successful, or certain value is not initialized in NVR. Diagnostic is provided in plain text to help track program flow and capture any issues on the way. + +Check another example *08_nvs_rw_blob*, that shows how to read and write a blob (binary large object). + +Detailed functional description of NVS and API is provided in [documentation](http://esp-idf.readthedocs.io/en/latest/api/nvs_flash.html). + +See the README.md file in the upper level 'examples' directory for more information about examples. diff --git a/examples/07_nvs_read_write/main/component.mk b/examples/07_nvs_rw_value/main/component.mk similarity index 100% rename from examples/07_nvs_read_write/main/component.mk rename to examples/07_nvs_rw_value/main/component.mk diff --git a/examples/07_nvs_rw_value/main/nvs_rw_value.c b/examples/07_nvs_rw_value/main/nvs_rw_value.c new file mode 100644 index 0000000000..df53d33b4a --- /dev/null +++ b/examples/07_nvs_rw_value/main/nvs_rw_value.c @@ -0,0 +1,77 @@ +/* Non-Volatile Storage (NVS) Read and Write a Value - Example + + For other examples please check: + https://github.com/espressif/esp-idf/tree/master/examples + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_system.h" +#include "nvs_flash.h" +#include "nvs.h" + +void app_main() +{ + nvs_flash_init(); + + nvs_handle my_handle; + esp_err_t err; + + printf("\n"); + + // Open + printf("Opening Non-Volatile Storage (NVS) ... "); + err = nvs_open("storage", NVS_READWRITE, &my_handle); + if (err != ESP_OK) { + printf("Error (%d) opening NVS!\n", err); + } else { + printf("Done\n"); + + // Read + printf("Reading restart counter from NVS ... "); + int32_t restart_counter = 0; // value will default to 0, if not set yet in NVS + err = nvs_get_i32(my_handle, "restart_conter", &restart_counter); + switch (err) { + case ESP_OK: + printf("Done\n"); + printf("Restart counter = %d\n", restart_counter); + break; + case ESP_ERR_NVS_NOT_FOUND: + printf("The value is not initialized yet!\n"); + break; + default : + printf("Error (%d) reading!\n", err); + } + + // Write + printf("Updating restart counter in NVS ... "); + restart_counter++; + err = nvs_set_i32(my_handle, "restart_conter", restart_counter); + printf((err != ESP_OK) ? "Failed!\n" : "Done\n"); + + // Commit + printf("Committing updates in NVS ... "); + err = nvs_commit(my_handle); + printf((err != ESP_OK) ? "Failed!\n" : "Done\n"); + + // Close + nvs_close(my_handle); + } + + printf("\n"); + + // Restart module + for (int i = 10; i >= 0; i--) { + printf("Restarting in %d seconds...\n", i); + vTaskDelay(1000 / portTICK_RATE_MS); + } + printf("Restarting now.\n"); + fflush(stdout); + system_restart(); +} diff --git a/examples/08_nvs_rw_blob/Makefile b/examples/08_nvs_rw_blob/Makefile new file mode 100644 index 0000000000..717744bbe8 --- /dev/null +++ b/examples/08_nvs_rw_blob/Makefile @@ -0,0 +1,9 @@ +# +# This is a project Makefile. It is assumed the directory this Makefile resides in is a +# project subdirectory. +# + +PROJECT_NAME := nvs-rw-blob + +include $(IDF_PATH)/make/project.mk + diff --git a/examples/08_nvs_rw_blob/README.md b/examples/08_nvs_rw_blob/README.md new file mode 100644 index 0000000000..81a0e36c71 --- /dev/null +++ b/examples/08_nvs_rw_blob/README.md @@ -0,0 +1,14 @@ +# Non-Volatile Storage (NVS) Read and Write Example + +Demonstrates how to read and write a single integer value and a blob (binary large object) using NVS to preserve them between ESP32 module restarts. + + * value - tracks number of ESP32 module soft and hard restarts. + * blob - contains a table with module run times. The table is read from NVS to dynamically allocated RAM. New run time is added to the table on each manually triggered soft restart and written back to NVS. Triggering is done by pulling down GPIO0. + +Example also shows how to implement diagnostics if read / write operation was successful. + +If not done already, consider checking simpler example *07_nvs_rw_value*, that has been used as a starting point for preparing this one. + +Detailed functional description of NVS and API is provided in [documentation](http://esp-idf.readthedocs.io/en/latest/api/nvs_flash.html). + +See the README.md file in the upper level 'examples' directory for more information about examples. diff --git a/examples/08_nvs_rw_blob/main/component.mk b/examples/08_nvs_rw_blob/main/component.mk new file mode 100644 index 0000000000..24356f23ed --- /dev/null +++ b/examples/08_nvs_rw_blob/main/component.mk @@ -0,0 +1,10 @@ +# +# Main Makefile. This is basically the same as a component makefile. +# +# This Makefile should, at the very least, just include $(SDK_PATH)/make/component_common.mk. By default, +# this will take the sources in the src/ directory, compile them and link them into +# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable, +# please read the ESP-IDF documents if you need to do this. +# + +include $(IDF_PATH)/make/component_common.mk diff --git a/examples/08_nvs_rw_blob/main/nvs_rw_blob.c b/examples/08_nvs_rw_blob/main/nvs_rw_blob.c new file mode 100644 index 0000000000..b4ff7e98ac --- /dev/null +++ b/examples/08_nvs_rw_blob/main/nvs_rw_blob.c @@ -0,0 +1,183 @@ +/* Non-Volatile Storage (NVS) Read and Write a Blob - Example + + For other examples please check: + https://github.com/espressif/esp-idf/tree/master/examples + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_system.h" +#include "nvs_flash.h" +#include "nvs.h" +#include "driver/gpio.h" + +#define STORAGE_NAMESPACE "storage" + +/* Save the number of module restarts in NVS + by first reading and then incrementing + the number that has been saved previously. + Return an error if anything goes wrong + during this process. + */ +esp_err_t save_restart_counter(void) +{ + nvs_handle my_handle; + esp_err_t err; + + // Open + err = nvs_open(STORAGE_NAMESPACE, NVS_READWRITE, &my_handle); + if (err != ESP_OK) return err; + + // Read + int32_t restart_counter = 0; // value will default to 0, if not set yet in NVS + err = nvs_get_i32(my_handle, "restart_conter", &restart_counter); + if (err != ESP_OK && err != ESP_ERR_NVS_NOT_FOUND) return err; + + // Write + restart_counter++; + err = nvs_set_i32(my_handle, "restart_conter", restart_counter); + if (err != ESP_OK) return err; + + // Commit + err = nvs_commit(my_handle); + if (err != ESP_OK) return err; + + // Close + nvs_close(my_handle); + return ESP_OK; +} + +/* Save new run time value in NVS + by first reading a table of previously saved values + and then adding the new value at the end of the table. + Return an error if anything goes wrong + during this process. + */ +esp_err_t save_run_time(void) +{ + nvs_handle my_handle; + esp_err_t err; + + // Open + err = nvs_open(STORAGE_NAMESPACE, NVS_READWRITE, &my_handle); + if (err != ESP_OK) return err; + + // Read the size of memory space required for blob + size_t required_size = 0; // value will default to 0, if not set yet in NVS + err = nvs_get_blob(my_handle, "run_time", NULL, &required_size); + if (err != ESP_OK && err != ESP_ERR_NVS_NOT_FOUND) return err; + + // Read previously saved blob if available + uint32_t* run_time; + if (required_size > 0) { + run_time = malloc(required_size); + // read previously saved blob + err = nvs_get_blob(my_handle, "run_time", run_time, &required_size); + if (err != ESP_OK) return err; + // add extra space for the new value + required_size += sizeof(uint32_t); + run_time = realloc(run_time, required_size); + } else { + // nothing saved jet - just allocate space for the first value to save + required_size = sizeof(uint32_t); + run_time = malloc(required_size); + } + + // Write value including previously saved blob if available + run_time[required_size / sizeof(uint32_t) - 1] = xTaskGetTickCount() * portTICK_PERIOD_MS; + err = nvs_set_blob(my_handle, "run_time", run_time, required_size); + if (err != ESP_OK) return err; + + free(run_time); + + // Commit + err = nvs_commit(my_handle); + if (err != ESP_OK) return err; + + // Close + nvs_close(my_handle); + return ESP_OK; +} + +/* Read from NVS and print restart counter + and the table with run times. + Return an error if anything goes wrong + during this process. + */ +esp_err_t print_what_saved(void) +{ + nvs_handle my_handle; + esp_err_t err; + + // Open + err = nvs_open(STORAGE_NAMESPACE, NVS_READWRITE, &my_handle); + if (err != ESP_OK) return err; + + // Read restart counter + int32_t restart_counter = 0; // value will default to 0, if not set yet in NVS + err = nvs_get_i32(my_handle, "restart_conter", &restart_counter); + if (err != ESP_OK && err != ESP_ERR_NVS_NOT_FOUND) return err; + printf("Restart counter = %d\n", restart_counter); + + // Read run time blob + size_t required_size = 0; // value will default to 0, if not set yet in NVS + // obtain required memory space to store blob being read from NVS + err = nvs_get_blob(my_handle, "run_time", NULL, &required_size); + if (err != ESP_OK && err != ESP_ERR_NVS_NOT_FOUND) return err; + printf("Run time:\n"); + if (required_size == 0) { + printf("Nothing saved yet!\n"); + } else { + uint32_t* run_time = malloc(required_size); + err = nvs_get_blob(my_handle, "run_time", run_time, &required_size); + if (err != ESP_OK) return err; + for (int i = 0; i < required_size / sizeof(uint32_t); i++) { + printf("%d: %d\n", i + 1, run_time[i]); + } + free(run_time); + } + + // Close + nvs_close(my_handle); + return ESP_OK; +} + + +void app_main() +{ + nvs_flash_init(); + + esp_err_t err; + + err = print_what_saved(); + if (err != ESP_OK) printf("Error (%d) reading data from NVS!\n", err); + + err = save_restart_counter(); + if (err != ESP_OK) printf("Error (%d) saving restart counter to NVS!\n", err); + + gpio_pad_select_gpio(GPIO_NUM_0); + gpio_set_direction(GPIO_NUM_0, GPIO_MODE_DEF_INPUT); + + /* Read the status of GPIO0. If GPIO0 is LOW for longer than 1000 ms, + then save module's run time and restart it + */ + while (1) { + if (gpio_get_level(GPIO_NUM_0) == 0) { + vTaskDelay(1000 / portTICK_RATE_MS); + if(gpio_get_level(GPIO_NUM_0) == 0) { + err = save_run_time(); + if (err != ESP_OK) printf("Error (%d) saving run time blob to NVS!\n", err); + printf("Restarting...\n"); + fflush(stdout); + system_restart(); + } + } + vTaskDelay(200 / portTICK_RATE_MS); + } +} From 3aca537157d7e8fc0d88be780260e4e1c134a897 Mon Sep 17 00:00:00 2001 From: Krzysztof Date: Thu, 10 Nov 2016 07:37:16 +0100 Subject: [PATCH 305/343] Optimsed code Following note in review by @igrr :+1: --- examples/08_nvs_rw_blob/main/nvs_rw_blob.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/examples/08_nvs_rw_blob/main/nvs_rw_blob.c b/examples/08_nvs_rw_blob/main/nvs_rw_blob.c index b4ff7e98ac..38066bf62f 100644 --- a/examples/08_nvs_rw_blob/main/nvs_rw_blob.c +++ b/examples/08_nvs_rw_blob/main/nvs_rw_blob.c @@ -74,22 +74,14 @@ esp_err_t save_run_time(void) if (err != ESP_OK && err != ESP_ERR_NVS_NOT_FOUND) return err; // Read previously saved blob if available - uint32_t* run_time; + uint32_t* run_time = malloc(required_size + sizeof(uint32_t)); if (required_size > 0) { - run_time = malloc(required_size); - // read previously saved blob err = nvs_get_blob(my_handle, "run_time", run_time, &required_size); if (err != ESP_OK) return err; - // add extra space for the new value - required_size += sizeof(uint32_t); - run_time = realloc(run_time, required_size); - } else { - // nothing saved jet - just allocate space for the first value to save - required_size = sizeof(uint32_t); - run_time = malloc(required_size); } // Write value including previously saved blob if available + required_size += sizeof(uint32_t); run_time[required_size / sizeof(uint32_t) - 1] = xTaskGetTickCount() * portTICK_PERIOD_MS; err = nvs_set_blob(my_handle, "run_time", run_time, required_size); if (err != ESP_OK) return err; From 25db1effd6f7673bac7f4eef290f6cd7a0556485 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 10 Nov 2016 15:52:47 +1100 Subject: [PATCH 306/343] docs: Rewrite build system docs to address new system, plus general editing Fixes TW#8017 --- docs/build_system.rst | 491 ++++++++++++++++++++++++++---------------- 1 file changed, 304 insertions(+), 187 deletions(-) diff --git a/docs/build_system.rst b/docs/build_system.rst index 34db487e0a..a9ebcfe004 100644 --- a/docs/build_system.rst +++ b/docs/build_system.rst @@ -8,262 +8,368 @@ Read this document if you want to know how to organise a new ESP-IDF project. We recommend using the esp-idf-template_ project as a starting point for your project. +Using the Build System +====================== + +The esp-idf README file contains a description of how to use the build system to build your project. + Overview ======== -An ESP-IDF project can be seen as an almagation of a number of components. -For example, for a webserver that shows the current humidity, we would -have: +An ESP-IDF project can be seen as an amalgamation of a number of components. +For example, for a webserver that shows the current humidity, there could be: - The ESP32 base libraries (libc, rom bindings etc) - The WiFi drivers - A TCP/IP stack - The FreeRTOS operating system - A webserver -- A driver for an humidity sensor +- A driver for the humidity sensor - Main code tying it all together -ESP-IDF makes these components explicit and configurable. To do that, when a project -is compiled, the build environment will look up all the components in the -ESP-IDF directories, the project directories and optionally custom other component -directories. It then allows the user to configure compile-time options using -a friendly text-based menu system to customize the ESP-IDF as well as other components -to the requirements of the project. After the components are customized, the -build process will compile everything into an output file, which can then be uploaded -into a board in a way that can also be defined by components. +ESP-IDF makes these components explicit and configurable. To do that, +when a project is compiled, the build environment will look up all the +components in the ESP-IDF directories, the project directories and +(optionally) in additional custom component directories. It then +allows the user to configure the ESP-IDF project using a a text-based +menu system to customize each component. After the components in the +project are configured, the build process will compile the project. -A project in this sense is defined as a directory under which all the files required -to build it live, excluding the ESP-IDF files and the toolchain. A simple project -tree might look like this:: +Concepts +-------- - - myProject/ - build/ +- A "project" is a directory that contains all the files and configuration to build a single "app" (executable), as well as additional supporting output such as a partition table, data/filesystem partitions, and a bootloader. + +- "Project configuration" is held in a single file called sdkconfig in the root directory of the project. This configuration file is modified via ``make menuconfig`` to customise the configuration of the project. A single project contains exactly one project configuration. + +- An "app" is an executable which is built by esp-idf. A single project will usually build two apps - a "project app" (the main executable, ie your custom firmware) and a "bootloader app" (the initial bootloader program which launches the project app). + +- "components" are modular pieces of standalone code which are compiled into static libraries (.a files) and linked into an app. Some are provided by esp-idf itself, others may be sourced from other places. + +Some things are not part of the project: + +- "ESP-IDF" is not part of the project. Instead it is standalone, and linked to the project via the ``IDF_PATH`` environment variable which holds the path of the ``esp-idf`` directory. This allows the IDF framework to be decoupled from your project. + +- The toolchain for compilation is not part of the project. The toolchain should be installed in the system command line PATH, or the path to the toolchain can be set as part of the compiler prefix in the project configuration. + + +Example Project +--------------- + +An example project directory tree might look like this:: + - myProject/ + - Makefile + - sdkconfig - components/ - component1/ - component.mk - Kconfig - src1.c - component2/ - component.mk - Kconfig - src1.c + - include/ + - component2.h - main/ - src1.c - src2.c - - Makefile + - component.mk + - build/ -As we can see, a project consists of a components/ subdirectory containing its -components as well as one or more directories containing the project-specific -sources; by default a single directory called 'main' is assumed. The project -directory will also have a Makefile where the projects name as well as optionally -other options are defined. After compilation, the project directory will contain -a 'build'-directory containing all of the objects, libraries and other generated -files as well as the final binary. +This example "myProject" contains the following elements: -Components also have a custom makefile - ``component.mk``. This contains various definititions -influencing the build process of the component as well as the project it's used -in. Components may also include a Kconfig file defining the compile-time options that are -settable by means of the menu system. +- A top-level project Makefile. This Makefile set the ``PROJECT_NAME`` variable and (optionally) defines + other project-wide make variables. It includes the core ``$(IDF_PATH)/make/project.mk`` makefile which + implements the rest of the ESP-IDF build system. -Project Makefile variables that can be set by the programmer:: +- "sdkconfig" project configuration file. This file is created/updated when "make menuconfig" runs, and holds configuration for all of the components in the project (including esp-idf itself). The "sdkconfig" file may or may not be added to the source control system of the project. - PROJECT_NAME: Mandatory. Name for the project - BUILD_DIR_BASE: Set the directory where all objects/libraries/binaries end up in. - Defaults to $(PROJECT_PATH)/build - COMPONENT_DIRS: Search path for components. Defaults to the component/ directories - in the ESP-IDF path and the project path. - COMPONENTS: A list of component names. Defaults to all the component found in the - COMPONENT_DIRS directory - EXTRA_COMPONENT_DIRS: Defaults to unset. Use this to add directories to the default - COMPONENT_DIRS. - SRCDIRS: Directories under the project dir containing project-specific sources. - Defaults to 'main'. These are treated as 'lite' components: they do not have - include directories that are passed to the compilation pass of all components and - they do not have a Kconfig option. +- Optional "components" directory contains components that are part of the project. A project does not have to contain custom components of this kind, but it can be useful for structuring reusable code or including third party components that aren't part of ESP-IDF. -Component-specific component.mk variables that can be set by the programmer:: +- "main" directory is a special "pseudo-component" that contains source code for the project itself. "main" is a default name, the Makefile variable ``SRCDIRS`` defaults to this but can be set to look for pseudo-components in other directories. - COMPONENT_ADD_INCLUDEDIRS: Relative path to include directories to be added to - the entire project. If an include directory is only needed to compile this - specific component, don't add it here. - COMPONENT_PRIV_INCLUDEDIRS: Relative path to include directories that are only used - when compiling this specific component. - COMPONENT_DEPENDS: Names of any components that need to be compiled before this component. - COMPONENT_ADD_LDFLAGS: LD flags to add for the entire project. Defaults to -l$(COMPONENT_NAME). - Add libraries etc in the current directory as $(abspath libwhatever.a) - COMPONENT_EXTRA_INCLUDES: Any extra include paths used when compiling the component's - source files. These will be prefixed with '-I' and passed to the compiler. - Similar to COMPONENT_PRIV_INCLUDEDIRS, but these paths are passed as-is instead of - expanded relative to the component directory. - COMPONENT_SRCDIRS: Relative directories to look in for sources. Defaults to '.', the current - directory (the root of the component) only. Use this to specify any subdirectories. Note - that specifying this overwrites the default action of compiling everything in the - components root dir; to keep this behaviour please also add '.' as a directory in this - list. - COMPONENT_OBJS: Object files to compile. Defaults to the .o variants of all .c and .S files - that are found in COMPONENT_SRCDIRS. - COMPONENT_EXTRA_CLEAN: Files that are generated using rules in the components Makefile - that also need to be cleaned - COMPONENT_BUILDRECIPE: Recipe to build the component. Optional. Defaults to building all - COMPONENT_OBJS and linking them into lib(componentname).a - COMPONENT_CLEANRECIPE: Recipe to clean the component. Optional. Defaults to removing - all built objects and libraries. - COMPONENT_BUILD_DIR: Equals the cwd of the component build, which is the build dir - of the component (where all the .o etc files should be created). +- "build" directory is where build output is created. After the make process is run, this directory will contain interim object files and libraries as well as final binary output files. This directory is usually not added to source control or distributed with the project source code. -These variables are already set early on in the Makefile and the values in it will -be usable in component or project Makefiles:: +Component directories contain a component makefile - ``component.mk``. This may contain variable definitions +to control the build process of the component, and its integration into the overall project. See `Component Makefiles` for more details. - CC, LD, AR, OBJCOPY: Xtensa gcc tools - HOSTCC, HOSTLD etc: Host gcc tools - LDFLAGS, CFLAGS: Set to usable values as defined in ESP-IDF Makefile - PROJECT_NAME: Name of the project, as set in project makefile - PROJECT_PATH: Path to the root of the project folder - COMPONENTS: Name of the components to be included - CONFIG_*: All values set by 'make menuconfig' have corresponding Makefile variables. +Each component may also include a ``Kconfig`` file defining the `component configuration` options that can be set via the project configuration. Some components may also include ``Kconfig.projbuild`` and ``Makefile.projbuild`` files, which are special files for `overriding parts of the project`. -Inside your component's component.mk makefile, you can override or add to these variables -as necessary. The changes are isolated from other components (see Makefile.projbuild below -if you want to share these changes with all other components.) +Project Makefiles +----------------- -For components, there also are these defines:: +Each project has a single Makefile that contains build settings for the entire project. By default, the project Makefile can be quite minimal. - COMPONENT_PATH: Absolute path to the root of the source tree of the component we're - compiling - COMPONENT_LIBRARY: The full path to the static library the components compilation pass - is supposed to generate +Minimal Example Makefile +^^^^^^^^^^^^^^^^^^^^^^^^ -Make Process ------------- +:: + PROJECT_NAME := myProject + + include $(IDF_PATH)/make/project.mk -The Make process is always invoked from the project directory by the -user; invoking it anywhere else gives an error. This is what happens if -we build a binary: -The Makefile first determines how it was included. It figures out -various paths as well as the components available to it. It will also -collect the ldflags and includes that the components specify they need. -It does this by running a dummy make on the components with a "get_variable" -target that will output these values. +Mandatory Project Variables +^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The Makefile will then create targets to build the lib*.a libraries of -all components and make the elf target depend on this. The main Makefile -invokes Make on the componen.mk of each components inside a sub-mke: this way -the components have full freedom to do whatever is necessary to build -the library without influencing other components. By default, the -component.mk includes the utility makefile $(IDF_PATH)/make/component_common.mk. -This provides default targets and configurations that will work -out-of-the-box for most projects. +- ``PROJECT_NAME``: Name of the project. Binary output files will use this name - ie myProject.bin, myProject.elf. -KConfig -------- +Optional Project Variables +^^^^^^^^^^^^^^^^^^^^^^^^^^ -Each component can also have a Kconfig file, alongside the component.mk, that contains -details to add to "menuconfig" for this component. +These variables all have default values that can be overridden for custom behaviour. Look in ``make/project.mk`` for all of the implementation details. + +- ``PROJECT_PATH``: Top-level project directory. Defaults to the directory containing the Makefile. Many other project variables are based on this variable. The project path cannot contain spaces. +- ``BUILD_DIR_BASE``: The build directory for all objects/libraries/binaries. Defaults to ``$(PROJECT_PATH)/build``. +- ``COMPONENT_DIRS``: Directories to search for components. Defaults to `$(IDF_PATH)/components`, `$(PROJECT_PATH)/components` and ``EXTRA_COMPONENT_DIRS``. Override this variable if you don't want to search for components in the esp-idf & project ``components`` directories. +- ``EXTRA_COMPONENT_DIRS``: Optional list of additional directories to search for components. Components themselves are in sub-directories of these directories, this is a top-level directory containing the component directories. +- ``COMPONENTS``: A list of component names to build into the project. Defaults to all components found in the COMPONENT_DIRS directories. +- ``SRCDIRS``: Directories under the main project directory which contain project-specific "pseudo-components". Defaults to 'main'. The difference between specifying a directory here and specifying it under ``EXTRA_COMPONENT_DIRS`` is that a directory in ``SRCDIRS`` is a component itself (contains a file "component.mk"), whereas a directory in ``EXTRA_COMPONENT_DIRS`` contains component directories which contain a file "component.mk". See the `Example Project` for a concrete case of this. + + +Component Makefiles +------------------- + +Each project contains one or more components, which can either be part of esp-idf or added from other component directories. + +A component is any sub-directory that contains a `component.mk` file.[#f1]_. + +Minimal Component Makefile +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The minimal ``component.mk`` file is an empty file(!). If the file is empty, the default component behaviour is set: +- All source files in the same directory as the makefile (*.c, *.cpp, *.S) will be compiled into the component library +- A sub-directory "include" will be added to the global include search path for all other components. +- The component library will be linked into the project app. + +See `example component makefiles` for more complete component makefile examples. + +Note that there is a different between an empty ``component.mk`` file (which invokes default component build behaviour) and no ``component.mk`` file (which means no default component build behaviour will occur.) It is possible for a component to have no `component.mk` file, if it only contains other files which influence the project configuration or build process. + +.. component variables: + +Preset Component Variables +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The following component-specific variables are available for use inside ``component.mk``, but should not be modified: + +- ``COMPONENT_PATH``: The component directory. Evaluates to the absolute path of the directory containing ``component.mk``. The component path cannot contain spaces. +- ``COMPONENT_NAME``: Name of the component. Defaults to the name of the component directory. +- ``COMPONENT_BUILD_DIR``: The component build directory. Evaluates to the absolute path of a directory inside `$(BUILD_DIR_BASE)` where this component's source files are to be built. This is also the Current Working Directory any time the component is being built, so relative paths in make targets, etc. will be relative to this directory. +- ``COMPONENT_LIBRARY``: Name of the static library file (relative to the component build directory) that will be built for this component. Defaults to ``$(COMPONENT_NAME).a``. + +The following variables are set at the project level, but exported for use in the component build: + +- ``PROJECT_NAME``: Name of the project, as set in project Makefile +- ``PROJECT_PATH``: Absolute path of the project directory containing the project Makefile. +- ``COMPONENTS``: Name of all components that are included in this build. +- ``CONFIG_*``: Each value in the project configuration has a corresponding variable available in make. All names begin with ``CONFIG_``. +- ``CC``, ``LD``, ``AR``, ``OBJCOPY``: Full paths to each tool from the gcc xtensa cross-toolchain. +- ``HOSTCC``, ``HOSTLD``, ``HOSTAR``: Full names of each tool from the host native toolchain. + +If you modify any of these variables inside ``component.mk`` then this will not prevent other components from building but it may make your component hard to build and/or debug. + +Optional Project-Wide Component Variables +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The following variables can be set inside ``component.mk`` to control build settings across the entire project: + +- ``COMPONENT_ADD_INCLUDEDIRS``: Paths, relative to the component + directory, which will be added to the include search path for + all components in the project. Defaults to ``include`` if not overridden. If an include directory is only needed to compile + this specific component, add it to ``COMPONENT_PRIV_INCLUDEDIRS`` instead. +- ``COMPONENT_ADD_LDFLAGS``: Add linker arguments to the LDFLAGS for + the app executable. Defaults to ``-l$(COMPONENT_NAME)``. If + adding pre-compiled libraries to this directory, add them as + absolute paths - ie $(COMPONENT_PATH)/libwhatever.a +- ``COMPONENT_DEPENDS``: Optional list of component names that should + be compiled before this component. This is not necessary for + link-time dependencies, because all component include directories + are available at all times. It is necessary if one component + generates an include file which you then want to include in another + component. Most components do not need to set this variable. + + +Optional Component-Specific Variables +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The following variables can be set inside ``component.mk`` to control the build of that component: + +- ``COMPONENT_PRIV_INCLUDEDIRS``: Directory paths, must be relative to + the component directory, which will be added to the include search + path for this component's source files only. +- ``COMPONENT_EXTRA_INCLUDES``: Any extra include paths used when + compiling the component's source files. These will be prefixed with + '-I' and passed as-is to the compiler. Similar to the + ``COMPONENT_PRIV_INCLUDEDIRS`` variable, except these paths are not + expanded relative to the component directory. +- ``COMPONENT_SRCDIRS``: Directory paths, must be relative to the + component directory, which will be searched for source files (*.cpp, + *.c, *.S). Defaults to '.', ie the component directory + itself. Override this to specify a different list of directories + which contain source files. +- ``COMPONENT_OBJS``: Object files to compile. Default value is a .o + file for each source file that is found in ``COMPONENT_SRCDIRS``. + Overriding this list allows you to exclude source files in + ``COMPONENT_SRCDIRS`` that would otherwise be compiled. See + `Specifying source files` +- ``COMPONENT_EXTRA_CLEAN``: Paths, relative to the component build + directory, of any files that are generated using custom make rules + in the component.mk file and which need to be removed as part of + ``make clean``. See `Source Code Generation` for an example. +- ``COMPONENT_OWNBUILDTARGET`` & `COMPONENT_OWNCLEANTARGET`: These + targets allow you to fully override the default build behaviour for + the component. See `Fully Overriding The Component Makefile` for + more details. +- ``CFLAGS``: Flags passed to the C compiler. A default set of + ``CFLAGS`` is defined based on project settings. Component-specific + additions can be made via ``CFLAGS +=``. It is also possible + (although not recommended) to override this variable completely for + a component. +- ``CPPFLAGS``: Flags passed to the C preprocessor (used for .c, .cpp + and .S files). A default set of ``CPPFLAGS`` is defined based on + project settings. Component-specific additions can be made via + ``CPPFLAGS +=``. It is also possible (although not recommended) to + override this variable completely for a component. +- ``CXXFLAGS``: Flags passed to the C++ compiler. A default set of + ``CXXFLAGS`` is defined based on project + settings. Component-specific additions can be made via ``CXXFLAGS + +=``. It is also possible (although not recommended) to override + this variable completely for a component. + +Component Configuration +----------------------- + +Each component can also have a Kconfig file, alongside ``component.mk``. This contains contains +configuration settings to add to the "make menuconfig" for this component. + +These settings are found under the "Component Settings" menu when menuconfig is run. + +To create a component KConfig file, it is easiest to start with one of the KConfig files distributed with esp-idf. + +For an example, see `Adding conditional configuration`. + +Build Process Internals +----------------------- + +Top Level: Project Makefile +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- "make" is always run from the project directory and the project makefile, typically named Makefile. +- The project makefile sets ``PROJECT_NAME`` and optionally customises other `optional project variables` +- The project makefile includes ``$(IDF_PATH)/make/project.mk`` which contains the project-level Make logic. +- ``project.mk`` fills in default project-level make variables and includes make variables from the project configuration. If the generated makefile containing project configuration is out of date, then it is regenerated (via targets in ``project_config.mk``) and then the make process restarts from the top. +- ``project.mk`` builds a list of components to build, based on the default component directories or a custom list of components set in `optional project variables`. +- Each component can set some `optional project-wide component variables`. These are included via generated makefiles named ``component_project_vars.mk`` - there is one per component. These generated makefiles are included into ``project.mk``. If any are missing or out of date, they are regenerated (via a recursive make call to the component makefile) and then the make process restarts from the top. +- `Makefile.projbuild` files from components are included into the make process, to add extra targets or configuration. +- By default, the project makefile also generates top-level build & clean targets for each component and sets up `app` and `clean` targets to invoke all of these sub-targets. +- In order to compile each component, a recursive make is performed for the component makefile. + +To better understand the project make process, have a read through the ``project.mk`` file itself. + +Second Level: Component Makefiles +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Each call to a component makefile goes via the ``$(IDF_PATH)/make/component_wrapper.mk`` wrapper makefile. +- The ``component_wrapper.mk`` is called with the current directory set to the component build directory, and the ``COMPONENT_MAKEFILE`` variable is set to the absolute path to ``component.mk``. +- ``component_wrapper.mk`` sets default values for all `component variables`, then includes the `component.mk` file which can override or modify these. +- If ``COMPONENT_OWNBUILDTARGET`` and ``COMPONENT_OWNCLEANTARGET`` are not defined, default build and clean targets are created for the component's source files and the prerequisite ``COMPONENT_LIBRARY`` static library file. +- The ``component_project_vars.mk`` file has its own target in ``component_wrapper.mk``, which is evaluated from ``project.mk`` if this file needs to be rebuilt due to changes in the component makefile or the project configuration. + +To better understand the component make process, have a read through the ``component_wrapper.mk`` file and some of the ``component.mk`` files included with esp-idf. + +Overriding Parts of the Project +------------------------------- Makefile.projbuild ------------------- +^^^^^^^^^^^^^^^^^^ -For components that have parts that need to be evaluated in the top-level -project context, you can create a file called Makefile.projbuild in the -component root directory. These files is included into the project's -top-level Makefile. +For components that have build requirements that must be evaluated in the top-level +project make pass, you can create a file called ``Makefile.projbuild`` in the +component directory. This makefile is included when ``project.mk`` is evaluated. For example, if your component needs to add to CFLAGS for the entire project (not just for its own source files) then you can set -``CFLAGS +=`` in Makefile.projbuild. Note that this isn't necessary for -adding include directories to the project, you can set -``COMPONENT_ADD_INCLUDEDIRS`` (see above) in the component.mk. +``CFLAGS +=`` in Makefile.projbuild. +``Makefile.projbuild`` files are used heavily inside esp-idf, for defining project-wide build features such as ``esptool.py`` command line arguments and the ``bootloader`` "special app". + +Note that ``Makefile.projbuild`` isn't necessary for the most common component uses - such as adding include directories to the project, or LDFLAGS to the final linking step. These values can be customised via the ``component.mk`` file itself. See `Optional Project-Wide Component Variables` for details. + +Take care when setting variables or targets in this file. As the values are included into the top-level project makefile pass, they can influence or break functionality across all components! KConfig.projbuild ------------------ +^^^^^^^^^^^^^^^^^ -There's an equivalent to Makefile.projbuild for KConfig: if you want to include -options at the top-level, not inside the 'components' submenu then create a Kconfig.projbuild and -it will be included in the main menu of menuconfig. +This is an equivalent to `Makefile.projbuild` for `component configuration` KConfig files. If you want to include +configuration options at the top-level of menuconfig, rather than inside the "Component Configuration" sub-menu, then these can be defined in the KConfig.projbuild file alongside the ``component.mk`` file. -Take good care when (re)defining stuff here: because it's included with all the other -.projbuild files, it's possible to overwrite variables or re-declare targets defined in -the ESP-IDF makefile/Kconfig and other .projbuild files. It's generally better to just -create a KConfig file, if you can. +Take care when adding configuration values in this file, as they will be included across the entire project configuration. Where possible, it's generally better to create a KConfig file for `component configuration`. -Writing Component Makefiles +Example Component Makefiles --------------------------- -A component consists of a directory which doubles as the name for the -component: a component named 'httpd' lives in a directory called 'httpd' -Because components usually live under the project directory (although -they can also reside in an other folder), the path to this may be -something like /home/myuser/projects/myprojects/components/httpd . +Because the build environment tries to set reasonable defaults that will work most +of the time, component.mk can be very small or even empty (see `Minimal Component Makefile`). However, overriding `component variables` is usually required for some functionality. -Components can have any name (unique to the project) but the name -cannot contain spaces (esp-idf does not support spaces in paths). - -One of the things that most components will have is a component.mk makefile, -containing instructions on how to build the component. Because the -build environment tries to set reasonable defaults that will work most -of the time, component.mk can be very small. - -Simplest component.mk -===================== - -At the minimum, component.mk will just include the ESP-IDF component "common" makefile, -which adds common component functionality:: - - include $(IDF_PATH)/make/component_common.mk - -This will take all the .c and .S files in the component root and compile -them into object files, finally linking them into a library. +Here are some more advanced examples of ``component.mk`` makefiles: Adding source directories -========================= +^^^^^^^^^^^^^^^^^^^^^^^^^ -By default, subdirectories are ignored. If your project has sources in subdirectories +By default, sub-directories are ignored. If your project has sources in sub-directories instead of in the root of the component then you can tell that to the build -system by setting COMPONENT_SRCDIRS:: +system by setting ``COMPONENT_SRCDIRS``:: COMPONENT_SRCDIRS := src1 src2 - include $(IDF_PATH)/make/component_common.mk -This will compile all source files in the src1/ and src2/ subdirectories +This will compile all source files in the src1/ and src2/ sub-directories instead. Specifying source files -======================= +^^^^^^^^^^^^^^^^^^^^^^^ The standard component.mk logic adds all .S and .c files in the source directories as sources to be compiled unconditionally. It is possible -to circumvent that logic and hardcode the objects to be compiled by -manually setting the COMPONENT_OBJS variable to the name of the +to circumvent that logic and hard-code the objects to be compiled by +manually setting the ``COMPONENT_OBJS`` variable to the name of the objects that need to be generated:: COMPONENT_OBJS := file1.o file2.o thing/filea.o thing/fileb.o anotherthing/main.o - include $(IDF_PATH)/make/component_common.mk + COMPONENT_SRCDIRS := . thing anotherthing +Note that ``COMPONENT_SRCDIRS`` must be set as well. Adding conditional configuration -================================ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The configuration system can be used to conditionally compile some files -dependending on the options selected in ``make menuconfig``: +depending on the options selected in ``make menuconfig``: -Kconfig:: +``Kconfig``:: config FOO_ENABLE_BAR - bool "Enable the BAR feature." - help - This enables the BAR feature of the FOO component. + bool "Enable the BAR feature." + help + This enables the BAR feature of the FOO component. -Makefile:: - COMPONENT_OBJS := foo_a.o foo_b.o $(if $(CONFIG_FOO_ENABLE_BAR),foo_bar.o foo_bar_interface.o) - include $(IDF_PATH)/make/component_common.mk +``component.mk``:: + COMPONENT_OBJS := foo_a.o foo_b.o + + ifdef CONFIG_FOO_BAR + COMPONENT_OBJS += foo_bar.o foo_bar_interface.o + endif + +See the `GNU Make Manual` for conditional syntax that can be used use in makefiles. Source Code Generation -====================== +^^^^^^^^^^^^^^^^^^^^^^ -Some components will have a situation where a source file isn't supplied -with the component itself but has to be generated from another file. Say -our component has a header file that consists of the converted binary -data of a BMP file, converted using a hypothetical tool called bmp2h. The -header file is then included in as C source file called graphics_lib.c:: +Some components will have a situation where a source file isn't +supplied with the component itself but has to be generated from +another file. Say our component has a header file that consists of the +converted binary data of a BMP file, converted using a hypothetical +tool called bmp2h. The header file is then included in as C source +file called graphics_lib.c:: COMPONENT_EXTRA_CLEAN := logo.h @@ -272,16 +378,25 @@ header file is then included in as C source file called graphics_lib.c:: logo.h: $(COMPONENT_PATH)/logo.bmp bmp2h -i $^ -o $@ - include $(IDF_PATH)/make/component_common.mk In this example, graphics_lib.o and logo.h will be generated in the -current directory (the build directory) while logo.bmp comes with the -component and resides under the component path. Because logo.h is a -generated file, it needs to be cleaned when make clean is called which -why it is added to the COMPONENT_EXTRA_CLEAN variable. +component build directory, whereas logo.bmp resides in the component +source directory. + +Because logo.h is a generated file, it needs to be cleaned when make +clean is called which why it is added to the COMPONENT_EXTRA_CLEAN +variable. + +Adding logo.h to the ``graphics_lib.o`` dependencies causes it to be +generated before ``graphics_lib.c`` is compiled. + +If a a source file in another component included ``logo.h``, then this +component's name would have to be added to the other component's +``COMPONENT_DEPENDS`` list to ensure that the components were built +in-order. Cosmetic Improvements -===================== +^^^^^^^^^^^^^^^^^^^^^ The above example will work just fine, but there's one last cosmetic improvement that can be done. The make system tries to make the make @@ -295,10 +410,9 @@ make process:: graphics_lib.o: logo.h logo.h: $(COMPONENT_PATH)/logo.bmp - $(summary) BMP2H $@ - $(Q) bmp2h -i $^ -o $@ + $(summary) BMP2H $@ + $(Q) bmp2h -i $^ -o $@ - include $(IDF_PATH)/make/component_common.mk Fully Overriding The Component Makefile --------------------------------------- @@ -307,12 +421,15 @@ Obviously, there are cases where all these recipes are insufficient for a certain component, for example when the component is basically a wrapper around another third-party component not originally intended to be compiled under this build system. In that case, it's possible to forego -the build system entirely by setting COMPONENT_OWNBUILDTARGET and -possibly COMPONENT_OWNCLEANTARGET and defining your own build- and clean +the esp-idf build system entirely by setting COMPONENT_OWNBUILDTARGET and +possibly COMPONENT_OWNCLEANTARGET and defining your own targets named ``build`` and ``clean`` in ``component.mk`` target. The build target can do anything as long as it creates -$(COMPONENT_LIBRARY) for the main file to link into the project binary, -and even that is not necessary: if the COMPONENT_ADD_LDFLAGS variable -is set, the component can instruct the linker to do anything else as well. +$(COMPONENT_LIBRARY) for the project make process to link into the app binary. + +(Actually, even this is not strictly necessary - if the COMPONENT_ADD_LDFLAGS variable +is set then the component can instruct the linker to link other binaries instead.) .. _esp-idf-template: https://github.com/espressif/esp-idf-template +.. _GNU Make Manual: https://www.gnu.org/software/make/manual/make.html +.. _[_f1]: Actually, some components in esp-idf are "pure configuration" components that don't have a component.mk file, only a Makefile.projbuild and/or Kconfig.projbuild file. However, these components are unusual and most components have a component.mk file. From 07f36a9437fa2fa3f8de7bd2dba0759504f9ad86 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 10 Nov 2016 16:19:59 +1100 Subject: [PATCH 307/343] Build system: Use ifndef X in makefiles instead of ifeq("$(X)","") --- make/component_wrapper.mk | 8 ++++---- make/project.mk | 9 ++++----- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/make/component_wrapper.mk b/make/component_wrapper.mk index 68efe0d211..fe081e32fd 100644 --- a/make/component_wrapper.mk +++ b/make/component_wrapper.mk @@ -8,7 +8,7 @@ # # CWD is the build directory of the component. -ifeq ("$(PROJECT_PATH)","") +ifndef PROJECT_PATH $(error Make was invoked from $(CURDIR). However please do not run make from the sdk or a component directory; invoke make from the project directory. See the ESP-IDF README for details.) endif @@ -60,7 +60,7 @@ include $(COMPONENT_MAKEFILE) # Object files which need to be linked into the library # By default we take all .c, .cpp & .S files in COMPONENT_SRCDIRS. -ifeq ("$(COMPONENT_OBJS)", "") +ifndef COMPONENT_OBJS # Find all source files in all COMPONENT_SRCDIRS COMPONENT_OBJS := $(foreach compsrcdir,$(COMPONENT_SRCDIRS),$(patsubst %.c,%.o,$(wildcard $(COMPONENT_PATH)/$(compsrcdir)/*.c))) COMPONENT_OBJS += $(foreach compsrcdir,$(COMPONENT_SRCDIRS),$(patsubst %.cpp,%.o,$(wildcard $(COMPONENT_PATH)/$(compsrcdir)/*.cpp))) @@ -120,7 +120,7 @@ component_project_vars.mk:: # If COMPONENT_OWNBUILDTARGET is not set, define a phony build target and # a COMPONENT_LIBRARY link target. -ifeq ("$(COMPONENT_OWNBUILDTARGET)", "") +ifndef COMPONENT_OWNBUILDTARGET .PHONY: build build: $(COMPONENT_LIBRARY) @mkdir -p $(COMPONENT_SRCDIRS) @@ -134,7 +134,7 @@ $(COMPONENT_LIBRARY): $(COMPONENT_OBJS) endif # If COMPONENT_OWNCLEANTARGET is not set, define a phony clean target -ifeq ("$(COMPONENT_OWNCLEANTARGET)", "") +ifndef COMPONENT_OWNCLEANTARGET CLEAN_FILES = $(COMPONENT_LIBRARY) $(COMPONENT_OBJS) $(COMPONENT_OBJS:.o=.d) $(COMPONENT_EXTRA_CLEAN) component_project_vars.mk .PHONY: clean clean: diff --git a/make/project.mk b/make/project.mk index f9cf20a329..4554d1d329 100644 --- a/make/project.mk +++ b/make/project.mk @@ -40,10 +40,9 @@ help: MAKEFLAGS_OLD := $(MAKEFLAGS) MAKEFLAGS +=-rR -# Figure out PROJECT_PATH if not set -ifeq ("$(PROJECT_PATH)","") -#The path to the project: we assume the Makefile including this file resides -#in the root of that directory. +# Default path to the project: we assume the Makefile including this file +# is in the project directory +ifndef PROJECT_PATH PROJECT_PATH := $(abspath $(dir $(firstword $(MAKEFILE_LIST)))) export PROJECT_PATH endif @@ -67,7 +66,7 @@ SRCDIRS ?= main # The project Makefile can define a list of components, but if it does not do this we just take # all available components in the component dirs. -ifeq ("$(COMPONENTS)","") +ifndef COMPONENTS # Find all component names. The component names are the same as the # directories they're in, so /bla/components/mycomponent/ -> mycomponent. We then use # COMPONENT_DIRS to build COMPONENT_PATHS with the full path to each component. From 4f4c9030fd284e79eed46aa403fb9ec5efba84a8 Mon Sep 17 00:00:00 2001 From: Wangjialin Date: Thu, 10 Nov 2016 17:01:39 +0800 Subject: [PATCH 308/343] Fix uart tx bug, data pass(with flow control) through test ok. --- components/driver/uart.c | 2 +- components/esp32/include/esp_err.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/components/driver/uart.c b/components/driver/uart.c index b961fbed71..d9e3fd64ca 100644 --- a/components/driver/uart.c +++ b/components/driver/uart.c @@ -729,7 +729,7 @@ static int uart_tx_all(uart_port_t uart_num, const char* src, size_t size, bool } else { evt.type = UART_DATA; } - xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void*) &evt, sizeof(uart_event_t), portMAX_DELAY); + xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void*) &evt, sizeof(uart_tx_data_t), portMAX_DELAY); while(size > 0) { int send_size = size > max_size / 2 ? max_size / 2 : size; xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void*) (src + offset), send_size, portMAX_DELAY); diff --git a/components/esp32/include/esp_err.h b/components/esp32/include/esp_err.h index f8271ba259..a1f4b8f359 100644 --- a/components/esp32/include/esp_err.h +++ b/components/esp32/include/esp_err.h @@ -34,6 +34,8 @@ typedef int32_t esp_err_t; #define ESP_ERR_INVALID_SIZE 0x104 #define ESP_ERR_NOT_FOUND 0x105 #define ESP_ERR_NOT_SUPPORTED 0x106 +#define ESP_ERR_TIMEOUT 0x107 + #define ESP_ERR_WIFI_BASE 0x3000 /*!< Starting number of WiFi error codes */ From 86d8f63005d42bb9c46330c67b35ba8efc3a04ec Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Thu, 10 Nov 2016 17:59:46 +0800 Subject: [PATCH 309/343] Per-CPU interrupt handlers and args --- components/esp32/crosscore_int.c | 7 +---- .../include/freertos/FreeRTOSConfig.h | 6 ----- components/freertos/readme_smp.txt | 5 ---- components/freertos/xtensa_intr.c | 11 ++++++-- components/freertos/xtensa_intr_asm.S | 23 ++++++++++++++-- components/freertos/xtensa_vectors.S | 26 +++++++++++++++++++ 6 files changed, 57 insertions(+), 21 deletions(-) diff --git a/components/esp32/crosscore_int.c b/components/esp32/crosscore_int.c index 60a45da402..60f972a2a2 100644 --- a/components/esp32/crosscore_int.c +++ b/components/esp32/crosscore_int.c @@ -45,14 +45,9 @@ the ISR will cause it to switch _away_ from it. portYIELD_FROM_ISR will probably */ static void esp_crosscore_isr(void *arg) { uint32_t myReasonVal; -#if 0 //A pointer to the correct reason array item is passed to this ISR. volatile uint32_t *myReason=arg; -#else - //The previous line does not work yet, the interrupt code needs work to understand two separate interrupt and argument - //tables... this is a valid but slightly less optimal replacement. - volatile uint32_t *myReason=&reason[xPortGetCoreID()]; -#endif + //Clear the interrupt first. if (xPortGetCoreID()==0) { WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_0_REG, 0); diff --git a/components/freertos/include/freertos/FreeRTOSConfig.h b/components/freertos/include/freertos/FreeRTOSConfig.h index 224857c86c..47566ab3b3 100644 --- a/components/freertos/include/freertos/FreeRTOSConfig.h +++ b/components/freertos/include/freertos/FreeRTOSConfig.h @@ -265,12 +265,6 @@ #define INCLUDE_eTaskGetState 1 #define configUSE_QUEUE_SETS 1 -#if (!defined XT_INTEXC_HOOKS) -#define configXT_INTEXC_HOOKS 1 /* Exception hooks used by certain tests */ -#if configUSE_TRACE_FACILITY_2 -#define configASSERT_2 1 /* Specific to Xtensa port */ -#endif -#endif #define configXT_BOARD 1 /* Board mode */ #define configXT_SIMULATOR 0 diff --git a/components/freertos/readme_smp.txt b/components/freertos/readme_smp.txt index 38f332416a..fdd9b146b1 100644 --- a/components/freertos/readme_smp.txt +++ b/components/freertos/readme_smp.txt @@ -19,11 +19,6 @@ it would on a single-core system: the other core still will keep on executing all it's own. Use a mux, queue or semaphore to protect your structures instead. -- While each core has individual interrupts, the handlers are shared. This -means that when you set a handler for an interrupt, it will get triggered if -the interrupt is triggered on both CPU0 as well as on CPU1. This is something -we may change in future FreeRTOS-esp32 releases. - - This FreeRTOS version has the task local storage backported from the 8.2.x versions. It, however, has an addition: you can also set a callback when you set the pointer. This callback will be called by the idle task, with the diff --git a/components/freertos/xtensa_intr.c b/components/freertos/xtensa_intr.c index f5ca7d151f..e9c0b79b96 100644 --- a/components/freertos/xtensa_intr.c +++ b/components/freertos/xtensa_intr.c @@ -30,7 +30,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include +#include "freertos/FreeRTOS.h" #include "freertos/xtensa_api.h" +#include "freertos/portable.h" #include "rom/ets_sys.h" @@ -39,7 +41,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /* Handler table is in xtensa_intr_asm.S */ // Todo: Make multicore - JD -extern xt_exc_handler _xt_exception_table[XCHAL_EXCCAUSE_NUM]; +extern xt_exc_handler _xt_exception_table[XCHAL_EXCCAUSE_NUM*portNUM_PROCESSORS]; /* @@ -66,6 +68,8 @@ xt_exc_handler xt_set_exception_handler(int n, xt_exc_handler f) if( n < 0 || n >= XCHAL_EXCCAUSE_NUM ) return 0; /* invalid exception number */ + /* Convert exception number to _xt_exception_table name */ + n = n * portNUM_PROCESSORS + xPortGetCoreID(); old = _xt_exception_table[n]; if (f) { @@ -89,7 +93,7 @@ typedef struct xt_handler_table_entry { void * arg; } xt_handler_table_entry; -extern xt_handler_table_entry _xt_interrupt_table[XCHAL_NUM_INTERRUPTS]; +extern xt_handler_table_entry _xt_interrupt_table[XCHAL_NUM_INTERRUPTS*portNUM_PROCESSORS]; /* @@ -118,6 +122,9 @@ xt_handler xt_set_interrupt_handler(int n, xt_handler f, void * arg) if( Xthal_intlevel[n] > XCHAL_EXCM_LEVEL ) return 0; /* priority level too high to safely handle in C */ + /* Convert exception number to _xt_exception_table name */ + n = n * portNUM_PROCESSORS + xPortGetCoreID(); + entry = _xt_interrupt_table + n; old = entry->handler; diff --git a/components/freertos/xtensa_intr_asm.S b/components/freertos/xtensa_intr_asm.S index 5f9890dfe4..8c7ae63fdb 100644 --- a/components/freertos/xtensa_intr_asm.S +++ b/components/freertos/xtensa_intr_asm.S @@ -30,6 +30,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include "xtensa_context.h" +#include "FreeRTOSConfig.h" #if XCHAL_HAVE_INTERRUPTS @@ -59,6 +60,15 @@ _xt_vpri_mask: .word 0xFFFFFFFF /* Virtual priority mask */ Table of C-callable interrupt handlers for each interrupt. Note that not all slots can be filled, because interrupts at level > EXCM_LEVEL will not be dispatched to a C handler by default. + + Stored as: + int 0 cpu 0 + int 0 cpu 1 + ... + int 0 cpu n + int 1 cpu 0 + int 1 cpu 1 + etc ------------------------------------------------------------------------------- */ @@ -69,7 +79,7 @@ _xt_vpri_mask: .word 0xFFFFFFFF /* Virtual priority mask */ _xt_interrupt_table: .set i, 0 - .rept XCHAL_NUM_INTERRUPTS + .rept XCHAL_NUM_INTERRUPTS*portNUM_PROCESSORS .word xt_unhandled_interrupt /* handler address */ .word i /* handler arg (default: intnum) */ .set i, i+1 @@ -85,6 +95,15 @@ _xt_interrupt_table: Table of C-callable exception handlers for each exception. Note that not all slots will be active, because some exceptions (e.g. coprocessor exceptions) are always handled by the OS and cannot be hooked by user handlers. + + Stored as: + exc 0 cpu 0 + exc 0 cpu 1 + ... + exc 0 cpu n + exc 1 cpu 0 + exc 1 cpu 1 + etc ------------------------------------------------------------------------------- */ @@ -93,7 +112,7 @@ _xt_interrupt_table: .align 4 _xt_exception_table: - .rept XCHAL_EXCCAUSE_NUM + .rept XCHAL_EXCCAUSE_NUM * portNUM_PROCESSORS .word xt_unhandled_exception /* handler address */ .endr diff --git a/components/freertos/xtensa_vectors.S b/components/freertos/xtensa_vectors.S index 7cf70f0032..2a373810fd 100644 --- a/components/freertos/xtensa_vectors.S +++ b/components/freertos/xtensa_vectors.S @@ -113,6 +113,27 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define XIE_ARG 4 #define XIE_SIZE 8 + +/* + Macro get_percpu_entry_for - convert a per-core ID into a multicore entry. + Basically does reg=reg*portNUM_PROCESSORS+current_core_id + Multiple versions here for multiple +*/ + .macro get_percpu_entry_for reg scratch +#if (portNUM_PROCESSORS == 1) + /* No need to do anything */ +#elif (portNUM_PROCESSORS == 2) + /* Optimized 2-core code. */ + getcoreid \scratch + addx2 \reg,\reg,\scratch +#else + /* Generalized n-core code. Untested! */ + movi \scratch,portNUM_PROCESSORS + mull \scratch,\reg,\scratch + getcoreid \reg + add \reg,\scratch,\reg +#endif + .endm /* -------------------------------------------------------------------------------- Macro extract_msb - return the input with only the highest bit set. @@ -229,6 +250,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. find_ms_setbit a3, a4, a3, 0 /* a3 = interrupt number */ + get_percpu_entry_for a3, a12 movi a4, _xt_interrupt_table addx8 a3, a3, a4 /* a3 = address of interrupt table entry */ l32i a4, a3, XIE_HANDLER /* a4 = handler address */ @@ -395,6 +417,9 @@ panic_print_hex_ok: with index 0 containing the entry for user exceptions. Initialized with all 0s, meaning no handler is installed at each level. See comment in xtensa_rtos.h for more details. + + *WARNING* This array is for all CPUs, that is, installing a hook for + one CPU will install it for all others as well! -------------------------------------------------------------------------------- */ @@ -688,6 +713,7 @@ _xt_user_exc: rsr a2, EXCCAUSE /* recover exc cause */ movi a3, _xt_exception_table + get_percpu_entry_for a3, a4 addx4 a4, a2, a3 /* a4 = address of exception table entry */ l32i a4, a4, 0 /* a4 = handler address */ #ifdef __XTENSA_CALL0_ABI__ From 07c30f22b58f4511912a2e809bba3474769632bd Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Thu, 10 Nov 2016 18:04:23 +0800 Subject: [PATCH 310/343] Add core info to xt interrupt api --- components/freertos/include/freertos/xtensa_api.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/components/freertos/include/freertos/xtensa_api.h b/components/freertos/include/freertos/xtensa_api.h index 04ad7d62d8..87922691dd 100644 --- a/components/freertos/include/freertos/xtensa_api.h +++ b/components/freertos/include/freertos/xtensa_api.h @@ -42,7 +42,8 @@ typedef void (*xt_exc_handler)(XtExcFrame *); /* ------------------------------------------------------------------------------- - Call this function to set a handler for the specified exception. + Call this function to set a handler for the specified exception. The handler + will be installed on the core that calls this function. n - Exception number (type) f - Handler function address, NULL to uninstall handler. @@ -61,7 +62,8 @@ extern xt_exc_handler xt_set_exception_handler(int n, xt_exc_handler f); /* ------------------------------------------------------------------------------- - Call this function to set a handler for the specified interrupt. + Call this function to set a handler for the specified interrupt. The handler + will be installed on the core that calls this function. n - Interrupt number. f - Handler function address, NULL to uninstall handler. @@ -73,7 +75,8 @@ extern xt_handler xt_set_interrupt_handler(int n, xt_handler f, void * arg); /* ------------------------------------------------------------------------------- - Call this function to enable the specified interrupts. + Call this function to enable the specified interrupts on the core that runs + this code. mask - Bit mask of interrupts to be enabled. ------------------------------------------------------------------------------- @@ -83,7 +86,8 @@ extern void xt_ints_on(unsigned int mask); /* ------------------------------------------------------------------------------- - Call this function to disable the specified interrupts. + Call this function to disable the specified interrupts on the core that runs + this code. mask - Bit mask of interrupts to be disabled. ------------------------------------------------------------------------------- From 2f6d71ff8ce28fda15898c5fe1b5669ee8dba505 Mon Sep 17 00:00:00 2001 From: Liu Zhi Fu Date: Thu, 10 Nov 2016 21:12:22 +0800 Subject: [PATCH 311/343] esp32: merge amsdu esp32 now can support AMSDU --- components/esp32/lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp32/lib b/components/esp32/lib index 76f9109806..84af0ed366 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit 76f91098061b0052fe1bb67e85001014f39b84a0 +Subproject commit 84af0ed366e1ba38984f7df517a77f8ec4fa27ed From c6073cb5de044d9fe5662dd3eee50ec4f37181ce Mon Sep 17 00:00:00 2001 From: Krzysztof Date: Thu, 10 Nov 2016 22:44:09 +0100 Subject: [PATCH 312/343] Conform Style Guide --- docs/conf.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 494ab3cf7f..551cd86dd0 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -22,9 +22,6 @@ import os # -- Run DoxyGen to prepare XML for Sphinx--------------------------------- # ref. https://github.com/rtfd/readthedocs.org/issues/388 -# -# added by krzychb, 24-Oct-2016 -# from subprocess import call, Popen, PIPE import shlex @@ -298,8 +295,6 @@ texinfo_documents = [ # -- Use sphinx_rtd_theme for local builds -------------------------------- # ref. https://github.com/snide/sphinx_rtd_theme#using-this-theme-locally-then-building-on-read-the-docs # -# added by krzychb, 24-Oct-2016 -# # on_rtd is whether we are on readthedocs.org on_rtd = os.environ.get('READTHEDOCS', None) == 'True' From 48a976ddbf3706c67eb15729777fba96c831a526 Mon Sep 17 00:00:00 2001 From: Krzysztof Date: Thu, 10 Nov 2016 22:44:59 +0100 Subject: [PATCH 313/343] Fixed link so it can render by Sphinx --- docs/style-guide.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/style-guide.rst b/docs/style-guide.rst index 4fa8321762..9bf00f1f7d 100644 --- a/docs/style-guide.rst +++ b/docs/style-guide.rst @@ -172,7 +172,7 @@ To re-format a file, run:: Documenting code ---------------- -Please see the guide here: `Documenting Code `_. +Please see the guide here: :doc:`documenting-code`. Structure and naming -------------------- From 9858fde4a23ffd56454641741185979555bb1372 Mon Sep 17 00:00:00 2001 From: Krzysztof Date: Thu, 10 Nov 2016 22:47:29 +0100 Subject: [PATCH 314/343] New items to documentation TOC - Style Guide - UART API --- docs/index.rst | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index 42be69ee0c..3f32806e5c 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -92,9 +92,10 @@ Contents: Wi-Fi Bluetooth - GPIO - LED Control - + api/gpio + api/uart + api/ledc + Logging Non-Volatile Storage Virtual Filesystem @@ -114,6 +115,7 @@ Contents: :maxdepth: 1 contributing + Style Guide documenting-code contributor-agreement From ce0382f0c03f7ffbe5d75d4a2b6a3ede30406cef Mon Sep 17 00:00:00 2001 From: Krzysztof Date: Thu, 10 Nov 2016 22:50:55 +0100 Subject: [PATCH 315/343] Revised api files - Included UART API - Addedd "Header Files" - Improved template - deleted redundat nvs.rst --- docs/api/bt.rst | 5 +++ docs/api/esp_wifi.rst | 7 ++- docs/api/gpio.rst | 7 ++- docs/api/ledc.rst | 5 +++ docs/api/log.rst | 14 ++++++ docs/api/nvs.rst | 68 ----------------------------- docs/api/nvs_flash.rst | 6 +++ docs/api/template.rst | 39 ++++++++++++----- docs/api/uart.rst | 98 ++++++++++++++++++++++++++++++++++++++++++ docs/api/vfs.rst | 6 +++ 10 files changed, 174 insertions(+), 81 deletions(-) delete mode 100644 docs/api/nvs.rst create mode 100644 docs/api/uart.rst diff --git a/docs/api/bt.rst b/docs/api/bt.rst index 7cbbb9158b..0ab17b2aa5 100644 --- a/docs/api/bt.rst +++ b/docs/api/bt.rst @@ -18,6 +18,11 @@ API Reference .. _Instructions: template.html +Header Files +^^^^^^^^^^^^ + + * `bt/include/bt.h `_ + Type Definitions ^^^^^^^^^^^^^^^^ diff --git a/docs/api/esp_wifi.rst b/docs/api/esp_wifi.rst index e417e18ca0..c13d3d751a 100644 --- a/docs/api/esp_wifi.rst +++ b/docs/api/esp_wifi.rst @@ -18,6 +18,11 @@ API Reference .. _Instructions: template.html +Header Files +^^^^^^^^^^^^ + + * `esp32/include/esp_wifi.h `_ + Macros ------ @@ -28,7 +33,6 @@ Type Definitions ---------------- .. doxygentypedef:: wifi_promiscuous_cb_t -.. doxygentypedef:: wifi_rxcb_t .. doxygentypedef:: esp_vendor_ie_cb_t Functions @@ -68,7 +72,6 @@ Functions .. doxygenfunction:: esp_wifi_get_config .. doxygenfunction:: esp_wifi_ap_get_sta_list .. doxygenfunction:: esp_wifi_set_storage -.. doxygenfunction:: esp_wifi_reg_rxcb .. doxygenfunction:: esp_wifi_set_auto_connect .. doxygenfunction:: esp_wifi_get_auto_connect .. doxygenfunction:: esp_wifi_set_vendor_ie diff --git a/docs/api/gpio.rst b/docs/api/gpio.rst index 72ba3e82fb..0cd4eca365 100644 --- a/docs/api/gpio.rst +++ b/docs/api/gpio.rst @@ -18,8 +18,13 @@ API Reference .. _Instructions: template.html +Header Files +^^^^^^^^^^^^ + + * `driver/include/driver/driver/gpio.h `_ + Macros ------- +^^^^^^ .. doxygendefine:: GPIO_SEL_0 .. doxygendefine:: GPIO_SEL_1 diff --git a/docs/api/ledc.rst b/docs/api/ledc.rst index 32b639f3f9..f379e9d008 100644 --- a/docs/api/ledc.rst +++ b/docs/api/ledc.rst @@ -18,6 +18,11 @@ API Reference .. _Instructions: template.html +Header Files +^^^^^^^^^^^^ + + * `driver/include/driver/ledc.h `_ + Data Structures ^^^^^^^^^^^^^^^ diff --git a/docs/api/log.rst b/docs/api/log.rst index 49f97108aa..d2f2fcd073 100644 --- a/docs/api/log.rst +++ b/docs/api/log.rst @@ -1,8 +1,22 @@ .. include:: ../../components/log/README.rst +Application Example +------------------- + +`Instructions`_ + API Reference ------------- +`Instructions`_ + +.. _Instructions: template.html + +Header Files +^^^^^^^^^^^^ + + * `log/include/esp_log.h `_ + Macros ^^^^^^ diff --git a/docs/api/nvs.rst b/docs/api/nvs.rst deleted file mode 100644 index fc2bba5a16..0000000000 --- a/docs/api/nvs.rst +++ /dev/null @@ -1,68 +0,0 @@ -.. include:: ../../components/nvs_flash/README.rst - -API Reference -------------- - -Enumerations -^^^^^^^^^^^^ - -.. doxygenenum:: nvs_open_mode - -Functions -^^^^^^^^^ - -.. doxygenfunction:: nvs_flash_init -.. doxygenfunction:: nvs_flash_init_custom - -.. doxygenfunction:: nvs_open - -*Note: the following nvs_set_X function are "the same" except the data type accepted* - -.. doxygenfunction:: nvs_set_i8 -.. doxygenfunction:: nvs_set_u8 -.. doxygenfunction:: nvs_set_i16 -.. doxygenfunction:: nvs_set_u16 -.. doxygenfunction:: nvs_set_i32 -.. doxygenfunction:: nvs_set_u32 -.. doxygenfunction:: nvs_set_i64 -.. doxygenfunction:: nvs_set_u64 -.. doxygenfunction:: nvs_set_str -.. doxygenfunction:: nvs_set_blob - -*Note: the following nvs_get_X functions are "the same" except the data type returned* - -.. doxygenfunction:: nvs_get_i8 -.. doxygenfunction:: nvs_get_u8 -.. doxygenfunction:: nvs_get_i16 -.. doxygenfunction:: nvs_get_u16 -.. doxygenfunction:: nvs_get_i32 -.. doxygenfunction:: nvs_get_u32 -.. doxygenfunction:: nvs_get_i64 -.. doxygenfunction:: nvs_get_u64 -.. doxygenfunction:: nvs_get_str -.. doxygenfunction:: nvs_get_blob - -.. doxygenfunction:: nvs_erase_key -.. doxygenfunction:: nvs_erase_all -.. doxygenfunction:: nvs_commit -.. doxygenfunction:: nvs_close - -Error codes -^^^^^^^^^^^ - -.. doxygendefine:: ESP_ERR_NVS_BASE -.. doxygendefine:: ESP_ERR_NVS_NOT_INITIALIZED -.. doxygendefine:: ESP_ERR_NVS_NOT_FOUND -.. doxygendefine:: ESP_ERR_NVS_TYPE_MISMATCH -.. doxygendefine:: ESP_ERR_NVS_READ_ONLY -.. doxygendefine:: ESP_ERR_NVS_NOT_ENOUGH_SPACE -.. doxygendefine:: ESP_ERR_NVS_INVALID_NAME -.. doxygendefine:: ESP_ERR_NVS_INVALID_HANDLE -.. doxygendefine:: ESP_ERR_NVS_REMOVE_FAILED -.. doxygendefine:: ESP_ERR_NVS_KEY_TOO_LONG -.. doxygendefine:: ESP_ERR_NVS_PAGE_FULL -.. doxygendefine:: ESP_ERR_NVS_INVALID_STATE -.. doxygendefine:: ESP_ERR_NVS_INVALID_LENGTH - - - diff --git a/docs/api/nvs_flash.rst b/docs/api/nvs_flash.rst index 16c74fa530..0768fa5597 100644 --- a/docs/api/nvs_flash.rst +++ b/docs/api/nvs_flash.rst @@ -8,6 +8,12 @@ Application Example API Reference ------------- +Header Files +^^^^^^^^^^^^ + + * `nvs_flash/include/nvs_flash.h `_ + * `nvs_flash/include/nvs.h `_ + Macros ^^^^^^ diff --git a/docs/api/template.rst b/docs/api/template.rst index 3c8bcdb62c..6feb7ba271 100644 --- a/docs/api/template.rst +++ b/docs/api/template.rst @@ -51,10 +51,11 @@ API Reference *INSTRUCTIONS* - 1. Provide list of API members divided into sections. - 2. Use corresponding ``.. doxygen..`` directives, so member documentation is auto updated. + 1. Specify the names of header files used to generate this reference. Each name should be linked to the source on `espressif/esp-idf `_ repository. + 2. Provide list of API members divided into sections. + 3. Use corresponding ``.. doxygen..`` directives, so member documentation is auto updated. - * Data Structures -``.. doxygenstruct::`` + * Data Structures -``.. doxygenstruct::`` together with ``:members:`` * Macros - ``.. doxygendefine::`` * Type Definitions - ``.. doxygentypedef::`` * Enumerations - ``.. doxygenenum::`` @@ -62,30 +63,48 @@ API Reference See `Breathe documentation `_ for additional information. - 3. Once done remove superfluous headers. - 4. When changes are committed and documentation is build, check how this section rendered. :doc:`Correct annotations <../documenting-code>` in respective header files, if required. + 4. Once done remove superfluous headers. + 5. When changes are committed and documentation is build, check how this section rendered. :doc:`Correct annotations <../documenting-code>` in respective header files, if required. + +Header Files +^^^^^^^^^^^^ + + * `path/header-file.h` Data Structures ^^^^^^^^^^^^^^^ -``.. doxygenstruct:: name_of_structure`` +:: + + .. doxygenstruct:: name_of_structure + :members: Macros ^^^^^^ -``.. doxygendefine:: name_of_macro`` +:: + + .. doxygendefine:: name_of_macro Type Definitions ^^^^^^^^^^^^^^^^ -``.. doxygentypedef:: name_of_type`` +:: + + .. doxygentypedef:: name_of_type Enumerations ^^^^^^^^^^^^ -``.. doxygenenum:: name_of_enumeration`` +:: + + .. doxygenenum:: name_of_enumeration Functions ^^^^^^^^^ -``.. doxygenfunction:: name_of_function`` +:: + + .. doxygenfunction:: name_of_function + + diff --git a/docs/api/uart.rst b/docs/api/uart.rst new file mode 100644 index 0000000000..609816fd46 --- /dev/null +++ b/docs/api/uart.rst @@ -0,0 +1,98 @@ +UART +==== + +Overview +-------- + +`Instructions`_ + +Application Example +------------------- + +`Instructions`_ + +API Reference +------------- + +`Instructions`_ + +.. _Instructions: template.html + +Header Files +^^^^^^^^^^^^ + + * `driver/include/driver/uart.h `_ + +Data Structures +^^^^^^^^^^^^^^^ + +.. doxygenstruct:: uart_config_t + :members: + +.. doxygenstruct:: uart_intr_config_t + :members: + +.. doxygenstruct:: uart_event_t + :members: + +Macros +^^^^^^ + +.. doxygendefine:: UART_FIFO_LEN +.. doxygendefine:: UART_INTR_MASK +.. doxygendefine:: UART_LINE_INV_MASK +.. doxygendefine:: UART_BITRATE_MAX +.. doxygendefine:: UART_PIN_NO_CHANGE +.. doxygendefine:: UART_INVERSE_DISABLE +.. doxygendefine:: UART_INVERSE_RXD +.. doxygendefine:: UART_INVERSE_CTS +.. doxygendefine:: UART_INVERSE_TXD +.. doxygendefine:: UART_INVERSE_RTS + +Enumerations +^^^^^^^^^^^^ + +.. doxygenenum:: uart_word_length_t +.. doxygenenum:: uart_stop_bits_t +.. doxygenenum:: uart_port_t +.. doxygenenum:: uart_parity_t +.. doxygenenum:: uart_hw_flowcontrol_t +.. doxygenenum:: uart_event_type_t + +Functions +^^^^^^^^^ + +.. doxygenfunction:: uart_set_word_length +.. doxygenfunction:: uart_get_word_length +.. doxygenfunction:: uart_set_stop_bits +.. doxygenfunction:: uart_get_stop_bits +.. doxygenfunction:: uart_set_parity +.. doxygenfunction:: uart_get_parity +.. doxygenfunction:: uart_set_baudrate +.. doxygenfunction:: uart_get_baudrate +.. doxygenfunction:: uart_set_line_inverse +.. doxygenfunction:: uart_set_hw_flow_ctrl +.. doxygenfunction:: uart_get_hw_flow_ctrl +.. doxygenfunction:: uart_clear_intr_status +.. doxygenfunction:: uart_enable_intr_mask +.. doxygenfunction:: uart_disable_intr_mask +.. doxygenfunction:: uart_enable_rx_intr +.. doxygenfunction:: uart_disable_rx_intr +.. doxygenfunction:: uart_disable_tx_intr +.. doxygenfunction:: uart_enable_tx_intr +.. doxygenfunction:: uart_isr_register +.. doxygenfunction:: uart_set_pin +.. doxygenfunction:: uart_set_rts +.. doxygenfunction:: uart_set_dtr +.. doxygenfunction:: uart_param_config +.. doxygenfunction:: uart_intr_config +.. doxygenfunction:: uart_driver_install +.. doxygenfunction:: uart_driver_delete +.. doxygenfunction:: uart_wait_tx_done +.. doxygenfunction:: uart_tx_chars +.. doxygenfunction:: uart_write_bytes +.. doxygenfunction:: uart_write_bytes_with_break +.. doxygenfunction:: uart_read_bytes +.. doxygenfunction:: uart_flush + + diff --git a/docs/api/vfs.rst b/docs/api/vfs.rst index 122a8671ea..df6cd03f67 100644 --- a/docs/api/vfs.rst +++ b/docs/api/vfs.rst @@ -8,6 +8,12 @@ Application Example API Reference ------------- +Header Files +^^^^^^^^^^^^ + + * `vfs/include/esp_vfs.h `_ + * `vfs/include/esp_vfs_dev.h `_ + Macros ^^^^^^ From 341593f7d204898fbc9686a3edc05972765386ee Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Fri, 11 Nov 2016 12:29:38 +1100 Subject: [PATCH 316/343] build system: Remove need for $(Q) macro in recipes, use --silent in MAKEFLAGS instead --- components/bootloader/Makefile.projbuild | 6 ++-- components/esptool_py/Makefile.projbuild | 6 ++-- components/partition_table/Makefile.projbuild | 8 ++--- docs/build_system.rst | 30 ++++++++----------- make/common.mk | 9 +++--- make/component_wrapper.mk | 12 ++++---- make/project.mk | 6 ++-- make/project_config.mk | 14 ++++----- tools/kconfig/Makefile | 26 ++++++++-------- 9 files changed, 56 insertions(+), 61 deletions(-) diff --git a/components/bootloader/Makefile.projbuild b/components/bootloader/Makefile.projbuild index c03288d107..90d9784427 100644 --- a/components/bootloader/Makefile.projbuild +++ b/components/bootloader/Makefile.projbuild @@ -21,10 +21,10 @@ BOOTLOADER_MAKE=+$(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src \ .PHONY: bootloader-clean bootloader-flash bootloader $(BOOTLOADER_BIN) $(BOOTLOADER_BIN): $(SDKCONFIG_MAKEFILE) - $(Q) $(BOOTLOADER_MAKE) $@ + $(BOOTLOADER_MAKE) $@ bootloader-clean: - $(Q) $(BOOTLOADER_MAKE) app-clean + $(BOOTLOADER_MAKE) app-clean clean: bootloader-clean @@ -41,7 +41,7 @@ bootloader-flash: $(BOOTLOADER_BIN) $(ESPTOOLPY_WRITE_FLASH) 0x1000 $^ $(BOOTLOADER_BUILD_DIR): - $(Q) mkdir -p $@ + mkdir -p $@ else CFLAGS += -D BOOTLOADER_BUILD=1 -I $(IDF_PATH)/components/esp32/include diff --git a/components/esptool_py/Makefile.projbuild b/components/esptool_py/Makefile.projbuild index 69c01e1e7f..27a2132845 100644 --- a/components/esptool_py/Makefile.projbuild +++ b/components/esptool_py/Makefile.projbuild @@ -24,14 +24,14 @@ ESPTOOLPY_WRITE_FLASH=$(ESPTOOLPY_SERIAL) write_flash $(if $(CONFIG_ESPTOOLPY_CO ESPTOOL_ALL_FLASH_ARGS += $(CONFIG_APP_OFFSET) $(APP_BIN) $(APP_BIN): $(APP_ELF) $(ESPTOOLPY_SRC) - $(Q) $(ESPTOOLPY) elf2image $(ESPTOOL_FLASH_OPTIONS) -o $@ $< + $(ESPTOOLPY) elf2image $(ESPTOOL_FLASH_OPTIONS) -o $@ $< flash: all_binaries $(ESPTOOLPY_SRC) @echo "Flashing binaries to serial port $(ESPPORT) (app at offset $(CONFIG_APP_OFFSET))..." - $(Q) $(ESPTOOLPY_WRITE_FLASH) $(ESPTOOL_ALL_FLASH_ARGS) + $(ESPTOOLPY_WRITE_FLASH) $(ESPTOOL_ALL_FLASH_ARGS) app-flash: $(APP_BIN) $(ESPTOOLPY_SRC) @echo "Flashing app to serial port $(ESPPORT), offset $(CONFIG_APP_OFFSET)..." - $(Q) $(ESPTOOLPY_WRITE_FLASH) $(CONFIG_APP_OFFSET) $(APP_BIN) + $(ESPTOOLPY_WRITE_FLASH) $(CONFIG_APP_OFFSET) $(APP_BIN) $(eval $(call SubmoduleCheck,$(ESPTOOLPY_SRC),$(COMPONENT_PATH)/esptool)) diff --git a/components/partition_table/Makefile.projbuild b/components/partition_table/Makefile.projbuild index 98631cc854..0799c91d4f 100644 --- a/components/partition_table/Makefile.projbuild +++ b/components/partition_table/Makefile.projbuild @@ -20,7 +20,7 @@ PARTITION_TABLE_BIN := $(BUILD_DIR_BASE)/$(notdir $(PARTITION_TABLE_CSV_PATH:.cs $(PARTITION_TABLE_BIN): $(PARTITION_TABLE_CSV_PATH) @echo "Building partitions from $(PARTITION_TABLE_CSV_PATH)..." - $(Q) $(GEN_ESP32PART) $< $@ + $(GEN_ESP32PART) $< $@ all_binaries: $(PARTITION_TABLE_BIN) @@ -30,16 +30,16 @@ ESPTOOL_ALL_FLASH_ARGS += 0x4000 $(PARTITION_TABLE_BIN) partition_table: $(PARTITION_TABLE_BIN) @echo "Partition table binary generated. Contents:" @echo $(SEPARATOR) - $(Q) $(GEN_ESP32PART) $< + $(GEN_ESP32PART) $< @echo $(SEPARATOR) @echo "Partition flashing command:" @echo "$(PARTITION_TABLE_FLASH_CMD)" partition_table-flash: $(PARTITION_TABLE_BIN) @echo "Flashing partition table..." - $(Q) $(PARTITION_TABLE_FLASH_CMD) + $(PARTITION_TABLE_FLASH_CMD) partition_table-clean: - $(Q) rm -f $(PARTITION_TABLE_BIN) + rm -f $(PARTITION_TABLE_BIN) clean: partition_table-clean diff --git a/docs/build_system.rst b/docs/build_system.rst index a9ebcfe004..50514083ef 100644 --- a/docs/build_system.rst +++ b/docs/build_system.rst @@ -275,6 +275,18 @@ Second Level: Component Makefiles To better understand the component make process, have a read through the ``component_wrapper.mk`` file and some of the ``component.mk`` files included with esp-idf. +Debugging The Make Process +-------------------------- + +Some tips for debugging the esp-idf build system: + +- Appending ``V=1`` to the make arguments (or setting it as an environment variable) will cause make to echo all commands executed, and also each directory as it is entered for a sub-make. +- Running ``make -w`` will cause make to echo each directory as it is entered for a sub-make - same as ``V=1`` but without also echoing all commands. +- Running ``make --trace`` (possibly in addition to one of the above arguments) will print out every target as it is built, and the dependency which caused it to be built. +- Running ``make -p`` prints a (very verbose) summary of every generated target in each makefile. + +For more debugging tips and general make information, see the `GNU Make Manual`. + Overriding Parts of the Project ------------------------------- @@ -395,24 +407,6 @@ component's name would have to be added to the other component's ``COMPONENT_DEPENDS`` list to ensure that the components were built in-order. -Cosmetic Improvements -^^^^^^^^^^^^^^^^^^^^^ - -The above example will work just fine, but there's one last cosmetic -improvement that can be done. The make system tries to make the make -process somewhat easier on the eyes by hiding the commands (unless you -run make with the V=1 switch) and this does not do that yet. Here's an -improved version that will output in the same style as the rest of the -make process:: - - COMPONENT_EXTRA_CLEAN := test_tjpgd_logo.h - - graphics_lib.o: logo.h - - logo.h: $(COMPONENT_PATH)/logo.bmp - $(summary) BMP2H $@ - $(Q) bmp2h -i $^ -o $@ - Fully Overriding The Component Makefile --------------------------------------- diff --git a/make/common.mk b/make/common.mk index 779811f1ad..c465fd4b22 100644 --- a/make/common.mk +++ b/make/common.mk @@ -16,13 +16,14 @@ export SDKCONFIG_MAKEFILE # sub-makes (like bootloader) will reuse this path # if V is unset or not 1, $(summary) echoes a summary and $(details) does nothing V ?= $(VERBOSE) ifeq ("$(V)","1") -Q := summary := @true details := @echo else -Q := @ summary := @echo details := @true + +# disable echoing of commands, directory names +MAKEFLAGS += --silent endif # Pseudo-target to check a git submodule has been properly initialised @@ -36,8 +37,8 @@ endif define SubmoduleCheck $(1): @echo "WARNING: Missing submodule $(2) for $$@..." - $(Q) [ -d ${IDF_PATH}/.git ] || ( echo "ERROR: esp-idf must be cloned from git to work."; exit 1) - $(Q) [ -x $(which git) ] || ( echo "ERROR: Need to run 'git submodule --init' in esp-idf root directory."; exit 1) + [ -d ${IDF_PATH}/.git ] || ( echo "ERROR: esp-idf must be cloned from git to work."; exit 1) + [ -x $(which git) ] || ( echo "ERROR: Need to run 'git submodule --init' in esp-idf root directory."; exit 1) @echo "Attempting 'git submodule update --init' in esp-idf root directory..." cd ${IDF_PATH} && git submodule update --init $(2) diff --git a/make/component_wrapper.mk b/make/component_wrapper.mk index fe081e32fd..84bd52da5a 100644 --- a/make/component_wrapper.mk +++ b/make/component_wrapper.mk @@ -129,8 +129,8 @@ build: $(COMPONENT_LIBRARY) # an archive when multiple filenames have the same name (src1/test.o and src2/test.o) $(COMPONENT_LIBRARY): $(COMPONENT_OBJS) $(summary) AR $@ - $(Q) rm -f $@ - $(Q) $(AR) cru $@ $(COMPONENT_OBJS) + rm -f $@ + $(AR) cru $@ $(COMPONENT_OBJS) endif # If COMPONENT_OWNCLEANTARGET is not set, define a phony clean target @@ -139,7 +139,7 @@ CLEAN_FILES = $(COMPONENT_LIBRARY) $(COMPONENT_OBJS) $(COMPONENT_OBJS:.o=.d) $(C .PHONY: clean clean: $(summary) RM $(CLEAN_FILES) - $(Q) rm -f $(CLEAN_FILES) + rm -f $(CLEAN_FILES) endif # Include all dependency files already generated @@ -150,15 +150,15 @@ define GenerateCompileTargets # $(1) - directory containing source files, relative to $(COMPONENT_PATH) $(1)/%.o: $$(COMPONENT_PATH)/$(1)/%.c | $(1) $$(summary) CC $$@ - $$(Q) $$(CC) $$(CFLAGS) $$(CPPFLAGS) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@ + $$(CC) $$(CFLAGS) $$(CPPFLAGS) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@ $(1)/%.o: $$(COMPONENT_PATH)/$(1)/%.cpp | $(1) $$(summary) CXX $$@ - $$(Q) $$(CXX) $$(CXXFLAGS) $$(CPPFLAGS) $$(addprefix -I,$$(COMPONENT_INCLUDES)) $$(addprefix -I,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@ + $$(CXX) $$(CXXFLAGS) $$(CPPFLAGS) $$(addprefix -I,$$(COMPONENT_INCLUDES)) $$(addprefix -I,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@ $(1)/%.o: $$(COMPONENT_PATH)/$(1)/%.S | $(1) $$(summary) AS $$@ - $$(Q) $$(CC) $$(CPPFLAGS) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@ + $$(CC) $$(CPPFLAGS) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@ # CWD is build dir, create the build subdirectory if it doesn't exist $(1): diff --git a/make/project.mk b/make/project.mk index 4554d1d329..a273da1c25 100644 --- a/make/project.mk +++ b/make/project.mk @@ -238,7 +238,7 @@ COMPONENT_LIBRARIES = $(filter $(notdir $(COMPONENT_PATHS_BUILDABLE)),$(APP_LIBR # the rules to build these are emitted as part of GenerateComponentTarget below $(APP_ELF): $(foreach libcomp,$(COMPONENT_LIBRARIES),$(BUILD_DIR_BASE)/$(libcomp)/lib$(libcomp).a) $(summary) LD $(notdir $@) - $(Q) $(CC) $(LDFLAGS) -o $@ -Wl,-Map=$(APP_MAP) + $(CC) $(LDFLAGS) -o $@ -Wl,-Map=$(APP_MAP) # Generation of $(APP_BIN) from $(APP_ELF) is added by the esptool # component's Makefile.projbuild @@ -257,7 +257,7 @@ $(BUILD_DIR_BASE): # # Is recursively expanded by the GenerateComponentTargets macro define ComponentMake -$(Q) +$(MAKE) -C $(BUILD_DIR_BASE)/$(2) -f $(IDF_PATH)/make/component_wrapper.mk COMPONENT_MAKEFILE=$(1)/component.mk ++$(MAKE) -C $(BUILD_DIR_BASE)/$(2) -f $(IDF_PATH)/make/component_wrapper.mk COMPONENT_MAKEFILE=$(1)/component.mk endef # Generate top-level component-specific targets for each component @@ -303,7 +303,7 @@ $(foreach component,$(COMPONENT_PATHS_BUILDABLE),$(eval $(call GenerateComponent app-clean: $(addsuffix -clean,$(notdir $(COMPONENT_PATHS_BUILDABLE))) $(summary) RM $(APP_ELF) - $(Q) rm -f $(APP_ELF) $(APP_BIN) $(APP_MAP) + rm -f $(APP_ELF) $(APP_BIN) $(APP_MAP) clean: app-clean diff --git a/make/project_config.mk b/make/project_config.mk index 09cec2e0be..aac231f99f 100644 --- a/make/project_config.mk +++ b/make/project_config.mk @@ -23,7 +23,7 @@ KCONFIG_TOOL_ENV=KCONFIG_AUTOHEADER=$(abspath $(BUILD_DIR_BASE)/include/sdkconfi menuconfig: $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig $(summary) MENUCONFIG - $(Q) $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig + $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig ifeq ("$(wildcard $(SDKCONFIG))","") ifeq ("$(filter defconfig,$(MAKECMDGOALS))","") @@ -36,8 +36,8 @@ endif defconfig: $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig $(BUILD_DIR_BASE) $(summary) DEFCONFIG - $(Q) mkdir -p $(BUILD_DIR_BASE)/include/config - $(Q) $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/conf --olddefconfig $(IDF_PATH)/Kconfig + mkdir -p $(BUILD_DIR_BASE)/include/config + $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/conf --olddefconfig $(IDF_PATH)/Kconfig # Work out of whether we have to build the Kconfig makefile # (auto.conf), or if we're in a situation where we don't need it @@ -56,9 +56,9 @@ endif $(AUTO_CONF_REGEN_TARGET) $(BUILD_DIR_BASE)/include/sdkconfig.h: $(SDKCONFIG) $(KCONFIG_TOOL_DIR)/conf $(COMPONENT_KCONFIGS) $(COMPONENT_KCONFIGS_PROJBUILD) $(summary) GENCONFIG - $(Q) mkdir -p $(BUILD_DIR_BASE)/include/config - $(Q) cd $(BUILD_DIR_BASE); $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/conf --silentoldconfig $(IDF_PATH)/Kconfig - $(Q) touch $(AUTO_CONF_REGEN_TARGET) $(BUILD_DIR_BASE)/include/sdkconfig.h + mkdir -p $(BUILD_DIR_BASE)/include/config + cd $(BUILD_DIR_BASE); $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/conf --silentoldconfig $(IDF_PATH)/Kconfig + touch $(AUTO_CONF_REGEN_TARGET) $(BUILD_DIR_BASE)/include/sdkconfig.h # touch to ensure both output files are newer - as 'conf' can also update sdkconfig (a dependency). Without this, # sometimes you can get an infinite make loop on Windows where sdkconfig always gets regenerated newer # than the target(!) @@ -68,4 +68,4 @@ clean: config-clean config-clean: $(summary RM CONFIG) $(MAKE) -C $(KCONFIG_TOOL_DIR) clean - $(Q) rm -rf $(BUILD_DIR_BASE)/include/config $(BUILD_DIR_BASE)/include/sdkconfig.h + rm -rf $(BUILD_DIR_BASE)/include/config $(BUILD_DIR_BASE)/include/sdkconfig.h diff --git a/tools/kconfig/Makefile b/tools/kconfig/Makefile index fee5a69316..9680b74109 100644 --- a/tools/kconfig/Makefile +++ b/tools/kconfig/Makefile @@ -41,13 +41,13 @@ nconfig: nconf $< $(silent) $(Kconfig) silentoldconfig: conf - $(Q)mkdir -p include/config include/generated + mkdir -p include/config include/generated $< $(silent) --$@ $(Kconfig) localyesconfig localmodconfig: streamline_config.pl conf - $(Q)mkdir -p include/config include/generated - $(Q)perl $< --$@ . $(Kconfig) > .tmp.config - $(Q)if [ -f .config ]; then \ + mkdir -p include/config include/generated + perl $< --$@ . $(Kconfig) > .tmp.config + if [ -f .config ]; then \ cmp -s .tmp.config .config || \ (mv -f .config .config.old.1; \ mv -f .tmp.config .config; \ @@ -57,7 +57,7 @@ localyesconfig localmodconfig: streamline_config.pl conf mv -f .tmp.config .config; \ conf $(silent) --silentoldconfig $(Kconfig); \ fi - $(Q)rm -f .tmp.config + rm -f .tmp.config # These targets map 1:1 to the commandline options of 'conf' @@ -84,22 +84,22 @@ ifeq ($(KBUILD_DEFCONFIG),) else ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG)),) @$(kecho) "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'" - $(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig) + $< $(silent) --defconfig=arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig) else @$(kecho) "*** Default configuration is based on target '$(KBUILD_DEFCONFIG)'" - $(Q) $(MAKE) -f $(srctree)/Makefile $(KBUILD_DEFCONFIG) + $(MAKE) -f $(srctree)/Makefile $(KBUILD_DEFCONFIG) endif endif %_defconfig: conf - $(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig) + $< $(silent) --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig) configfiles=$(wildcard $(srctree)/kernel/configs/$@ $(srctree)/arch/$(SRCARCH)/configs/$@) %.config: conf $(if $(call configfiles),, $(error No configuration exists for this target on this architecture)) - $(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m .config $(configfiles) - +$(Q)yes "" | $(MAKE) -f $(srctree)/Makefile oldconfig + $(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m .config $(configfiles) + +yes "" | $(MAKE) -f $(srctree)/Makefile oldconfig PHONY += kvmconfig kvmconfig: kvm_guest.config @@ -111,7 +111,7 @@ xenconfig: xen.config PHONY += tinyconfig tinyconfig: - $(Q)$(MAKE) -f $(srctree)/Makefile allnoconfig tiny.config + $(MAKE) -f $(srctree)/Makefile allnoconfig tiny.config # Help text used by make help help: @@ -181,7 +181,7 @@ clean-files += $(conf-objs) $(mconf-objs) conf mconf $(lxdialog) PHONY += dochecklxdialog $(addprefix ,$(lxdialog)): dochecklxdialog dochecklxdialog: - $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(CC) $(CFLAGS) $(LOADLIBES_mconf) + $(CONFIG_SHELL) $(check-lxdialog) -check $(CC) $(CFLAGS) $(LOADLIBES_mconf) always := dochecklxdialog @@ -285,7 +285,7 @@ quiet_cmd_moc = MOC $@ # Extract gconf menu items for i18n support gconf.glade.h: gconf.glade - $(Q)intltool-extract --type=gettext/glade --srcdir=$(srctree) \ + intltool-extract --type=gettext/glade --srcdir=$(srctree) \ gconf.glade From 7b77daaea41274a221930f01d8bc1226ef46a336 Mon Sep 17 00:00:00 2001 From: Xia Xiao Tian Date: Fri, 11 Nov 2016 10:51:33 +0800 Subject: [PATCH 317/343] wps: add blocking param for API esp_wifi_wps_start() --- components/esp32/include/esp_wps.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/components/esp32/include/esp_wps.h b/components/esp32/include/esp_wps.h index 0a413a1978..f95eaa5e2a 100644 --- a/components/esp32/include/esp_wps.h +++ b/components/esp32/include/esp_wps.h @@ -83,7 +83,9 @@ esp_err_t esp_wifi_wps_disable(void); * * @attention WPS can only be used when ESP32 station is enabled. * - * @param null + * @param timeout_ms : maximum blocking time before API return. + * - 0 : non-blocking + * - 1~120000 : blocking time (not supported in IDF v1.0) * * @return * - ESP_OK : succeed @@ -92,7 +94,7 @@ esp_err_t esp_wifi_wps_disable(void); * - ESP_ERR_WIFI_WPS_SM : wps state machine is not initialized * - ESP_ERR_WIFI_FAIL : wps initialization fails */ -esp_err_t esp_wifi_wps_start(void); +esp_err_t esp_wifi_wps_start(int timeout_ms); /** * @} From 9aa9086c8b72852a58ded9bb1769640c5eaffee1 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 11 Nov 2016 12:16:54 +0800 Subject: [PATCH 318/343] examples: minor tweaks to comments --- examples/07_nvs_rw_value/README.md | 4 ++-- examples/07_nvs_rw_value/main/component.mk | 8 -------- examples/07_nvs_rw_value/main/nvs_rw_value.c | 5 ++++- examples/08_nvs_rw_blob/main/component.mk | 8 -------- examples/08_nvs_rw_blob/main/nvs_rw_blob.c | 5 ++++- 5 files changed, 10 insertions(+), 20 deletions(-) diff --git a/examples/07_nvs_rw_value/README.md b/examples/07_nvs_rw_value/README.md index 83dc29fd18..09cd364e8d 100644 --- a/examples/07_nvs_rw_value/README.md +++ b/examples/07_nvs_rw_value/README.md @@ -4,9 +4,9 @@ Demonstrates how to read and write a single integer value using NVS. The value holds the number of ESP32 module restarts. Since it is written to NVS, the value is preserved between restarts. -Example also shows how to check if read / write operation was successful, or certain value is not initialized in NVR. Diagnostic is provided in plain text to help track program flow and capture any issues on the way. +Example also shows how to check if read / write operation was successful, or certain value is not initialized in NVS. Diagnostic is provided in plain text to help track program flow and capture any issues on the way. -Check another example *08_nvs_rw_blob*, that shows how to read and write a blob (binary large object). +Check another example *08_nvs_rw_blob*, that shows how to read and write variable length binary data (blob). Detailed functional description of NVS and API is provided in [documentation](http://esp-idf.readthedocs.io/en/latest/api/nvs_flash.html). diff --git a/examples/07_nvs_rw_value/main/component.mk b/examples/07_nvs_rw_value/main/component.mk index 24356f23ed..d33485c26c 100644 --- a/examples/07_nvs_rw_value/main/component.mk +++ b/examples/07_nvs_rw_value/main/component.mk @@ -1,10 +1,2 @@ -# -# Main Makefile. This is basically the same as a component makefile. -# -# This Makefile should, at the very least, just include $(SDK_PATH)/make/component_common.mk. By default, -# this will take the sources in the src/ directory, compile them and link them into -# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable, -# please read the ESP-IDF documents if you need to do this. -# include $(IDF_PATH)/make/component_common.mk diff --git a/examples/07_nvs_rw_value/main/nvs_rw_value.c b/examples/07_nvs_rw_value/main/nvs_rw_value.c index df53d33b4a..978c48edb8 100644 --- a/examples/07_nvs_rw_value/main/nvs_rw_value.c +++ b/examples/07_nvs_rw_value/main/nvs_rw_value.c @@ -55,7 +55,10 @@ void app_main() err = nvs_set_i32(my_handle, "restart_conter", restart_counter); printf((err != ESP_OK) ? "Failed!\n" : "Done\n"); - // Commit + // Commit written value. + // After setting any values, nvs_commit() must be called to ensure changes are written + // to flash storage. Implementations may write to storage at other times, + // but this is not guaranteed. printf("Committing updates in NVS ... "); err = nvs_commit(my_handle); printf((err != ESP_OK) ? "Failed!\n" : "Done\n"); diff --git a/examples/08_nvs_rw_blob/main/component.mk b/examples/08_nvs_rw_blob/main/component.mk index 24356f23ed..d33485c26c 100644 --- a/examples/08_nvs_rw_blob/main/component.mk +++ b/examples/08_nvs_rw_blob/main/component.mk @@ -1,10 +1,2 @@ -# -# Main Makefile. This is basically the same as a component makefile. -# -# This Makefile should, at the very least, just include $(SDK_PATH)/make/component_common.mk. By default, -# this will take the sources in the src/ directory, compile them and link them into -# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable, -# please read the ESP-IDF documents if you need to do this. -# include $(IDF_PATH)/make/component_common.mk diff --git a/examples/08_nvs_rw_blob/main/nvs_rw_blob.c b/examples/08_nvs_rw_blob/main/nvs_rw_blob.c index 38066bf62f..3fbdfcacd6 100644 --- a/examples/08_nvs_rw_blob/main/nvs_rw_blob.c +++ b/examples/08_nvs_rw_blob/main/nvs_rw_blob.c @@ -44,7 +44,10 @@ esp_err_t save_restart_counter(void) err = nvs_set_i32(my_handle, "restart_conter", restart_counter); if (err != ESP_OK) return err; - // Commit + // Commit written value. + // After setting any values, nvs_commit() must be called to ensure changes are written + // to flash storage. Implementations may write to storage at other times, + // but this is not guaranteed. err = nvs_commit(my_handle); if (err != ESP_OK) return err; From fdf3db19590cd722c8d0be11b3649cc2b1ff8c29 Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Fri, 11 Nov 2016 12:26:42 +0800 Subject: [PATCH 319/343] Comment fix --- components/freertos/xtensa_vectors.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/freertos/xtensa_vectors.S b/components/freertos/xtensa_vectors.S index 2a373810fd..f180705e70 100644 --- a/components/freertos/xtensa_vectors.S +++ b/components/freertos/xtensa_vectors.S @@ -117,7 +117,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /* Macro get_percpu_entry_for - convert a per-core ID into a multicore entry. Basically does reg=reg*portNUM_PROCESSORS+current_core_id - Multiple versions here for multiple + Multiple versions here to optimize for specific portNUM_PROCESSORS values. */ .macro get_percpu_entry_for reg scratch #if (portNUM_PROCESSORS == 1) From 57009aaa7f9138958678d08bc9ecc2f037f4e9da Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Fri, 11 Nov 2016 19:20:54 +0800 Subject: [PATCH 320/343] Add a more scalable mechanism for the FreeRTOS tick- and idle hooks; idle handler now uses WAITI to reduce power --- components/esp32/freertos_hooks.c | 81 +++++++++++++++++++ components/esp32/include/esp_freertos_hooks.h | 58 +++++++++++++ components/esp32/int_wdt.c | 64 ++++++++------- components/esp32/task_wdt.c | 24 ++++-- components/freertos/Kconfig | 29 +++++++ .../include/freertos/FreeRTOSConfig.h | 4 +- components/freertos/tasks.c | 20 +++-- 7 files changed, 234 insertions(+), 46 deletions(-) create mode 100644 components/esp32/freertos_hooks.c create mode 100644 components/esp32/include/esp_freertos_hooks.h diff --git a/components/esp32/freertos_hooks.c b/components/esp32/freertos_hooks.c new file mode 100644 index 0000000000..50ebd3d054 --- /dev/null +++ b/components/esp32/freertos_hooks.c @@ -0,0 +1,81 @@ +#include +#include +#include +#include "esp_attr.h" +#include "esp_freertos_hooks.h" + +//We use just a static array here because it's not expected many components will need +//an idle or tick hook. +#define MAX_HOOKS 8 + +static esp_freertos_idle_cb_t idle_cb[MAX_HOOKS]={0}; +static esp_freertos_tick_cb_t tick_cb[MAX_HOOKS]={0}; + +void IRAM_ATTR esp_vApplicationTickHook() +{ + int n; + for (n=0; n +#include "esp_err.h" + + +/* + Definitions for the tickhook and idlehook callbacks +*/ +typedef bool (*esp_freertos_idle_cb_t)(); +typedef void (*esp_freertos_tick_cb_t)(); + +/** + * @brief Register a callback to be called on the freertos idle hook + * The callback should return true if it's okay for the core to + * sleep until an interrupt (or FreeRTOS tick) happens and false + * if it should be called again as fast as possible. + * + * @param esp_freertos_idle_cb_t new_idle_cb : Callback to be called + * + * @return ESP_OK : Callback registered + * @return ESP_ERR_NO_MEM : No more space to register hook + */ +esp_err_t esp_register_freertos_idle_hook(esp_freertos_idle_cb_t new_idle_cb); + +/** + * @brief Register a callback to be called on the freertos tick hook + * + * @param esp_freertos_tick_cb_t new_tick_cb : Callback to be called + * + * @return ESP_OK : Callback registered + * @return ESP_ERR_NO_MEM : No more space to register hook + */ +esp_err_t esp_register_freertos_tick_hook(esp_freertos_tick_cb_t tick_cb); + + +/** + * @brief Unregister an idle callback registered earlier + * + * @param esp_freertos_idle_cb_t new_idle_cb : Callback to be unregistered + * + * @return void + */ +void esp_deregister_freertos_idle_hook(esp_freertos_idle_cb_t old_idle_cb); + + +/** + * @brief Unregister a tick callback registered earlier + * + * @param esp_freertos_idle_cb_t new_idle_cb : Callback to be unregistered + * + * @return void + */ +void esp_deregister_freertos_tick_hook(esp_freertos_tick_cb_t old_tick_cb); + + +#endif \ No newline at end of file diff --git a/components/esp32/int_wdt.c b/components/esp32/int_wdt.c index 11de8f20d2..fe3ddab370 100644 --- a/components/esp32/int_wdt.c +++ b/components/esp32/int_wdt.c @@ -25,6 +25,7 @@ #include "esp_err.h" #include "esp_intr.h" #include "esp_attr.h" +#include "esp_freertos_hooks.h" #include "soc/timer_group_struct.h" #include "soc/timer_group_reg.h" @@ -36,6 +37,38 @@ #define WDT_INT_NUM 24 +//Take care: the tick hook can also be called before esp_int_wdt_init() is called. +#if CONFIG_INT_WDT_CHECK_CPU1 +//Not static; the ISR assembly checks this. +bool int_wdt_app_cpu_ticked=false; + +static void IRAM_ATTR tick_hook(void) { + if (xPortGetCoreID()!=0) { + int_wdt_app_cpu_ticked=true; + } else { + //Only feed wdt if app cpu also ticked. + if (int_wdt_app_cpu_ticked) { + TIMERG1.wdt_wprotect=TIMG_WDT_WKEY_VALUE; + TIMERG1.wdt_config2=CONFIG_INT_WDT_TIMEOUT_MS*2; //Set timeout before interrupt + TIMERG1.wdt_config3=CONFIG_INT_WDT_TIMEOUT_MS*4; //Set timeout before reset + TIMERG1.wdt_feed=1; + TIMERG1.wdt_wprotect=0; + int_wdt_app_cpu_ticked=false; + } + } +} +#else +static void IRAM_ATTR tick_hook(void) { + if (xPortGetCoreID()!=0) return; + TIMERG1.wdt_wprotect=TIMG_WDT_WKEY_VALUE; + TIMERG1.wdt_config2=CONFIG_INT_WDT_TIMEOUT_MS*2; //Set timeout before interrupt + TIMERG1.wdt_config3=CONFIG_INT_WDT_TIMEOUT_MS*4; //Set timeout before reset + TIMERG1.wdt_feed=1; + TIMERG1.wdt_wprotect=0; +} +#endif + + void esp_int_wdt_init() { TIMERG1.wdt_wprotect=TIMG_WDT_WKEY_VALUE; TIMERG1.wdt_config0.sys_reset_length=7; //3.2uS @@ -53,6 +86,7 @@ void esp_int_wdt_init() { TIMERG1.wdt_wprotect=0; TIMERG1.int_clr_timers.wdt=1; TIMERG1.int_ena.wdt=1; + esp_register_freertos_tick_hook(tick_hook); ESP_INTR_DISABLE(WDT_INT_NUM); intr_matrix_set(xPortGetCoreID(), ETS_TG1_WDT_LEVEL_INTR_SOURCE, WDT_INT_NUM); //We do not register a handler for the interrupt because it is interrupt level 4 which @@ -62,35 +96,5 @@ void esp_int_wdt_init() { } -//Take care: the tick hook can also be called before esp_int_wdt_init() is called. -#if CONFIG_INT_WDT_CHECK_CPU1 -//Not static; the ISR assembly checks this. -bool int_wdt_app_cpu_ticked=false; - -void IRAM_ATTR vApplicationTickHook(void) { - if (xPortGetCoreID()!=0) { - int_wdt_app_cpu_ticked=true; - } else { - //Only feed wdt if app cpu also ticked. - if (int_wdt_app_cpu_ticked) { - TIMERG1.wdt_wprotect=TIMG_WDT_WKEY_VALUE; - TIMERG1.wdt_config2=CONFIG_INT_WDT_TIMEOUT_MS*2; //Set timeout before interrupt - TIMERG1.wdt_config3=CONFIG_INT_WDT_TIMEOUT_MS*4; //Set timeout before reset - TIMERG1.wdt_feed=1; - TIMERG1.wdt_wprotect=0; - int_wdt_app_cpu_ticked=false; - } - } -} -#else -void IRAM_ATTR vApplicationTickHook(void) { - if (xPortGetCoreID()!=0) return; - TIMERG1.wdt_wprotect=TIMG_WDT_WKEY_VALUE; - TIMERG1.wdt_config2=CONFIG_INT_WDT_TIMEOUT_MS*2; //Set timeout before interrupt - TIMERG1.wdt_config3=CONFIG_INT_WDT_TIMEOUT_MS*4; //Set timeout before reset - TIMERG1.wdt_feed=1; - TIMERG1.wdt_wprotect=0; -} -#endif #endif \ No newline at end of file diff --git a/components/esp32/task_wdt.c b/components/esp32/task_wdt.c index bec1cadaa7..f8cfdef26e 100644 --- a/components/esp32/task_wdt.c +++ b/components/esp32/task_wdt.c @@ -26,6 +26,7 @@ #include "esp_err.h" #include "esp_intr.h" #include "esp_attr.h" +#include "esp_freertos_hooks.h" #include "soc/timer_group_struct.h" #include "soc/timer_group_reg.h" #include "esp_log.h" @@ -140,6 +141,18 @@ void esp_task_wdt_delete() { } } + +#if CONFIG_TASK_WDT_CHECK_IDLE_TASK +static bool idle_hook(void) { +#if !CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1 + if (xPortGetCoreID()!=0) return; +#endif + esp_task_wdt_feed(); + return true; +} +#endif + + void esp_task_wdt_init() { TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE; TIMERG0.wdt_config0.sys_reset_length=7; //3.2uS @@ -153,6 +166,9 @@ void esp_task_wdt_init() { TIMERG0.wdt_config0.en=1; TIMERG0.wdt_feed=1; TIMERG0.wdt_wprotect=0; +#if CONFIG_TASK_WDT_CHECK_IDLE_TASK + esp_register_freertos_idle_hook(idle_hook); +#endif ESP_INTR_DISABLE(ETS_T0_WDT_INUM); intr_matrix_set(xPortGetCoreID(), ETS_TG0_WDT_LEVEL_INTR_SOURCE, ETS_T0_WDT_INUM); xt_set_interrupt_handler(ETS_T0_WDT_INUM, task_wdt_isr, NULL); @@ -161,13 +177,5 @@ void esp_task_wdt_init() { ESP_INTR_ENABLE(ETS_T0_WDT_INUM); } -#if CONFIG_TASK_WDT_CHECK_IDLE_TASK -void vApplicationIdleHook(void) { -#if !CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1 - if (xPortGetCoreID()!=0) return; -#endif - esp_task_wdt_feed(); -} -#endif #endif \ No newline at end of file diff --git a/components/freertos/Kconfig b/components/freertos/Kconfig index 91e824b2dc..b9db00e50b 100644 --- a/components/freertos/Kconfig +++ b/components/freertos/Kconfig @@ -141,6 +141,35 @@ config FREERTOS_ISR_STACKSIZE The interrupt handlers have their own stack. The size of the stack can be defined here. Each processor has its own stack, so the total size occupied will be twice this. +config FREERTOS_LEGACY_HOOKS + bool "Use FreeRTOS legacy hooks" + default n + help + FreeRTOS offers a number of hooks/callback functions that are called when a timer + tick happens, the idle thread runs etc. esp-idf replaces these by runtime registerable + hooks using the esp_register_freertos_xxx_hook system, but for legacy reasons the old + hooks can also still be enabled. Please enable this only if you have code that for some + reason can't be migrated to the esp_register_freertos_xxx_hook system. + +if FREERTOS_LEGACY_HOOKS + +config FREERTOS_LEGACY_IDLE_HOOK + bool "Enable legacy idle hook" + default n + help + If enabled, FreeRTOS will call a function called vApplicationIdleHook when the idle thread + on a CPU is running. Please make sure your code defines such a function. + +config FREERTOS_LEGACY_TICK_HOOK + bool "Enable legacy tick hook" + default n + help + If enabled, FreeRTOS will call a function called vApplicationTickHook when a FreeRTOS + tick is executed. Please make sure your code defines such a function. + +endif #FREERTOS_LEGACY_HOOKS + + menuconfig FREERTOS_DEBUG_INTERNALS bool "Debug FreeRTOS internals" default n diff --git a/components/freertos/include/freertos/FreeRTOSConfig.h b/components/freertos/include/freertos/FreeRTOSConfig.h index 47566ab3b3..13ce73e0a8 100644 --- a/components/freertos/include/freertos/FreeRTOSConfig.h +++ b/components/freertos/include/freertos/FreeRTOSConfig.h @@ -152,9 +152,9 @@ *----------------------------------------------------------*/ #define configUSE_PREEMPTION 1 -#define configUSE_IDLE_HOOK ( CONFIG_TASK_WDT_CHECK_IDLE_TASK ) +#define configUSE_IDLE_HOOK ( CONFIG_FREERTOS_LEGACY_IDLE_HOOK ) -#define configUSE_TICK_HOOK ( CONFIG_INT_WDT ) +#define configUSE_TICK_HOOK ( CONFIG_FREERTOS_LEGACY_TICK_HOOK ) #define configTICK_RATE_HZ ( CONFIG_FREERTOS_HZ ) diff --git a/components/freertos/tasks.c b/components/freertos/tasks.c index b79d3a98ba..88aa8d3ef5 100644 --- a/components/freertos/tasks.c +++ b/components/freertos/tasks.c @@ -476,6 +476,7 @@ to its original value when it is released. */ #if configUSE_TICK_HOOK > 0 extern void vApplicationTickHook( void ); #endif +extern void esp_vApplicationTickHook( void ); #if portFIRST_TASK_HOOK extern void vPortFirstTaskHook(TaskFunction_t taskfn); @@ -2360,22 +2361,21 @@ BaseType_t xSwitchRequired = pdFALSE; We can't really calculate what we need, that's done on core 0... just assume we need a switch. ToDo: Make this more intelligent? -- JD */ - //We do need the tick hook to satisfy the int watchdog. - #if ( configUSE_TICK_HOOK == 1 ) { /* Guard against the tick hook being called when the pended tick count is being unwound (when the scheduler is being unlocked). */ if( ( uxSchedulerSuspended[ xPortGetCoreID() ] != ( UBaseType_t ) pdFALSE ) || uxPendedTicks == ( UBaseType_t ) 0U ) { + #if ( configUSE_TICK_HOOK == 1 ) vApplicationTickHook(); + #endif /* configUSE_TICK_HOOK */ + esp_vApplicationTickHook(); } else { mtCOVERAGE_TEST_MARKER(); } } - #endif /* configUSE_TICK_HOOK */ - return pdTRUE; } @@ -2506,20 +2506,21 @@ BaseType_t xSwitchRequired = pdFALSE; } #endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) ) */ - #if ( configUSE_TICK_HOOK == 1 ) { /* Guard against the tick hook being called when the pended tick count is being unwound (when the scheduler is being unlocked). */ if( uxPendedTicks == ( UBaseType_t ) 0U ) { + #if ( configUSE_TICK_HOOK == 1 ) vApplicationTickHook(); + #endif /* configUSE_TICK_HOOK */ + esp_vApplicationTickHook(); } else { mtCOVERAGE_TEST_MARKER(); } } - #endif /* configUSE_TICK_HOOK */ taskEXIT_CRITICAL_ISR(&xTaskQueueMutex); } else @@ -2533,6 +2534,7 @@ BaseType_t xSwitchRequired = pdFALSE; vApplicationTickHook(); } #endif + esp_vApplicationTickHook(); } #if ( configUSE_PREEMPTION == 1 ) @@ -3270,6 +3272,12 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters ) vApplicationIdleHook(); } #endif /* configUSE_IDLE_HOOK */ + { + /* Call the esp-idf hook system */ + extern void esp_vApplicationIdleHook( void ); + esp_vApplicationIdleHook(); + } + /* This conditional compilation should use inequality to 0, not equality to 1. This is to ensure portSUPPRESS_TICKS_AND_SLEEP() is called when From cc510c1d95086b6a94ea92c260eceb40f75e3577 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Mon, 14 Nov 2016 10:51:53 +1100 Subject: [PATCH 321/343] build system: Remove make 3.81 "component_project_vars.mk: No such file or directory" messages Also add an explicit make version check & warning. --- make/project.mk | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/make/project.mk b/make/project.mk index a273da1c25..a10f6cd24a 100644 --- a/make/project.mk +++ b/make/project.mk @@ -36,6 +36,13 @@ help: @echo "See also 'make bootloader', 'make bootloader-flash', 'make bootloader-clean', " @echo "'make partition_table', etc, etc." +# dependency checks +ifndef MAKE_RESTARTS +ifeq ("$(filter 4.% 3.81 3.82,$(MAKE_VERSION))","") +$(warning "esp-idf build system only supports GNU Make versions 3.81 or newer. You may see unexpected results with other Makes.") +endif +endif + # disable built-in make rules, makes debugging saner MAKEFLAGS_OLD := $(MAKEFLAGS) MAKEFLAGS +=-rR @@ -105,7 +112,8 @@ COMPONENT_LDFLAGS := # See the component_project_vars.mk target in component_wrapper.mk COMPONENT_PROJECT_VARS := $(addsuffix /component_project_vars.mk,$(notdir $(COMPONENT_PATHS_BUILDABLE))) COMPONENT_PROJECT_VARS := $(addprefix $(BUILD_DIR_BASE)/,$(COMPONENT_PROJECT_VARS)) -include $(COMPONENT_PROJECT_VARS) +# this line is -include instead of include to prevent a spurious error message on make 3.81 +-include $(COMPONENT_PROJECT_VARS) # Also add top-level project include path, for top-level includes COMPONENT_INCLUDES += $(abspath $(BUILD_DIR_BASE)/include/) From f9e9e6b9389e009d45a9c3271180666007eb27f4 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Mon, 14 Nov 2016 10:57:45 +1100 Subject: [PATCH 322/343] Build system: Change deprecation message to include component path, easier to fix --- make/component_common.mk | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/make/component_common.mk b/make/component_common.mk index 32af3c7c06..187e1ed63a 100644 --- a/make/component_common.mk +++ b/make/component_common.mk @@ -1,3 +1 @@ -$(warning Deprecated feature: It is no longer necessary to include component_common.mk.) -$(warning The line "include $$(IDF_PATH)/make/component_common.mk" can be removed from component.mk files.) - +$(warning Deprecated feature: No longer necessary to include component_common.mk from $(COMPONENT_PATH)/component.mk) From b5de58139919e1143f289efc426569bb2d111106 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 3 Nov 2016 17:33:30 +1100 Subject: [PATCH 323/343] Secure boot: initial image signature support --- .gitmodules | 3 + components/bootloader/Kconfig.projbuild | 16 +++ components/bootloader/Makefile.projbuild | 24 +++-- components/bootloader/src/Makefile | 2 +- .../bootloader/src/main/bootloader_start.c | 25 +++++ .../bootloader_support/Makefile.projbuild | 3 + components/bootloader_support/component.mk | 25 +++++ .../include/esp_secure_boot.h | 10 +- .../src/secure_boot_signatures.c | 99 +++++++++++++++++++ components/esptool_py/Makefile.projbuild | 6 ++ components/esptool_py/esptool | 2 +- components/micro-ecc/component.mk | 8 ++ components/micro-ecc/micro-ecc | 1 + components/partition_table/Makefile.projbuild | 3 + docs/security/secure-boot.rst | 87 +++++++++------- make/common.mk | 20 +++- make/component_common.mk | 6 +- make/project.mk | 1 + 18 files changed, 291 insertions(+), 50 deletions(-) create mode 100644 components/bootloader_support/Makefile.projbuild create mode 100644 components/bootloader_support/src/secure_boot_signatures.c create mode 100644 components/micro-ecc/component.mk create mode 160000 components/micro-ecc/micro-ecc diff --git a/.gitmodules b/.gitmodules index df40848261..c26f92e80c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,3 +7,6 @@ [submodule "components/bt/lib"] path = components/bt/lib url = https://github.com/espressif/esp32-bt-lib.git +[submodule "components/micro-ecc/micro-ecc"] + path = components/micro-ecc/micro-ecc + url = https://github.com/kmackay/micro-ecc.git diff --git a/components/bootloader/Kconfig.projbuild b/components/bootloader/Kconfig.projbuild index 55c2eebd14..b568f61a04 100644 --- a/components/bootloader/Kconfig.projbuild +++ b/components/bootloader/Kconfig.projbuild @@ -77,6 +77,22 @@ config SECURE_BOOTLOADER_KEY_FILE See docs/security/secure-boot.rst for details. +config SECURE_BOOT_SIGNING_KEY + string "Secure boot signing key" + depends on SECURE_BOOTLOADER_ENABLED + default secure_boot_signing_key.pem + help + Path to the key file used to sign partition tables and app images for secure boot. + + Key file is an ECDSA private key (NIST256p curve) in PEM format. + + Path is evaluated relative to the project directory. + + You can generate a new signing key by running the following command: + espsecure.py generate_signing_key secure_boot_signing_key.pem + + See docs/security/secure-boot.rst for details. + config SECURE_BOOTLOADER_ENABLED bool default SECURE_BOOTLOADER_ONE_TIME_FLASH || SECURE_BOOTLOADER_REFLASHABLE diff --git a/components/bootloader/Makefile.projbuild b/components/bootloader/Makefile.projbuild index 3799e913c8..831d988584 100644 --- a/components/bootloader/Makefile.projbuild +++ b/components/bootloader/Makefile.projbuild @@ -15,13 +15,17 @@ BOOTLOADER_BUILD_DIR=$(abspath $(BUILD_DIR_BASE)/bootloader) BOOTLOADER_BIN=$(BOOTLOADER_BUILD_DIR)/bootloader.bin BOOTLOADER_SDKCONFIG=$(BOOTLOADER_BUILD_DIR)/sdkconfig -SECURE_BOOT_KEYFILE=$(abspath $(call dequote,$(CONFIG_SECURE_BOOTLOADER_KEY_FILE))) +# both signing key paths are resolved relative to the project directory +SECURE_BOOTLOADER_KEY=$(abspath $(call dequote,$(CONFIG_SECURE_BOOTLOADER_KEY_FILE))) +SECURE_BOOT_SIGNING_KEY=$(abspath $(call dequote,$(CONFIG_SECURE_BOOT_SIGNING_KEY))) +export SECURE_BOOT_SIGNING_KEY # used by bootloader_support component # Custom recursive make for bootloader sub-project BOOTLOADER_MAKE=+$(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src \ V=$(V) SDKCONFIG=$(BOOTLOADER_SDKCONFIG) \ BUILD_DIR_BASE=$(BOOTLOADER_BUILD_DIR) IS_BOOTLOADER_BUILD=1 + .PHONY: bootloader-clean bootloader-flash bootloader $(BOOTLOADER_BIN) $(BOOTLOADER_BIN): | $(BOOTLOADER_BUILD_DIR)/sdkconfig @@ -59,16 +63,15 @@ bootloader: $(BOOTLOADER_BIN) @echo "* IMPORTANT: After first boot, BOOTLOADER CANNOT BE RE-FLASHED on same device" else ifdef CONFIG_SECURE_BOOTLOADER_REFLASHABLE -# Reflashable secure bootloader (recommended for testing only) -# generates a digest binary (bootloader + digest) and prints -# instructions for reflashing. User must run commands manually. +# Reflashable secure bootloader +# generates a digest binary (bootloader + digest) BOOTLOADER_DIGEST_BIN=$(BOOTLOADER_BUILD_DIR)/bootloader-reflash-digest.bin bootloader: $(BOOTLOADER_DIGEST_BIN) @echo $(SEPARATOR) @echo "Bootloader built and secure digest generated. First time flash command is:" - @echo "$(ESPEFUSEPY) burn_key secure_boot $(SECURE_BOOT_KEYFILE)" + @echo "$(ESPEFUSEPY) burn_key secure_boot $(SECURE_BOOTLOADER_KEY)" @echo "$(ESPTOOLPY_WRITE_FLASH) 0x1000 $(BOOTLOADER_BIN)" @echo $(SEPARATOR) @echo "To reflash the bootloader after initial flash:" @@ -77,15 +80,16 @@ bootloader: $(BOOTLOADER_DIGEST_BIN) @echo "* After first boot, only re-flashes of this kind (with same key) will be accepted." @echo "* Not recommended to re-use the same secure boot keyfile on multiple production devices." -$(BOOTLOADER_DIGEST_BIN): $(BOOTLOADER_BIN) $(SECURE_BOOT_KEYFILE) - @echo "DIGEST $< + $(SECURE_BOOT_KEYFILE) -> $@" - $(Q) $(ESPSECUREPY) digest_secure_bootloader -k $(SECURE_BOOT_KEYFILE) -o $@ $< +$(BOOTLOADER_DIGEST_BIN): $(BOOTLOADER_BIN) $(SECURE_BOOTLOADER_KEY) + @echo "DIGEST $(notdir $@)" + $(Q) $(ESPSECUREPY) digest_secure_bootloader -k $(SECURE_BOOTLOADER_KEY) -o $@ $< -$(SECURE_BOOT_KEYFILE): +$(SECURE_BOOTLOADER_KEY): @echo $(SEPARATOR) - @echo "Need to generate secure boot digest key first. Run following command:" + @echo "Need to generate secure boot signing key. Run following command:" @echo "$(ESPSECUREPY) generate_key $@" @echo "Keep key file safe after generating." + @echo "(See secure boot documentation for caveats & alternatives.)") @exit 1 else diff --git a/components/bootloader/src/Makefile b/components/bootloader/src/Makefile index 278e0e9afb..1cfc80c5fe 100644 --- a/components/bootloader/src/Makefile +++ b/components/bootloader/src/Makefile @@ -4,7 +4,7 @@ # PROJECT_NAME := bootloader -COMPONENTS := esptool_py bootloader bootloader_support log spi_flash +COMPONENTS := esptool_py bootloader bootloader_support log spi_flash micro-ecc # The bootloader pseudo-component is also included in this build, for its Kconfig.projbuild to be included. # diff --git a/components/bootloader/src/main/bootloader_start.c b/components/bootloader/src/main/bootloader_start.c index 59b180fd84..3ebb8cf520 100644 --- a/components/bootloader/src/main/bootloader_start.c +++ b/components/bootloader/src/main/bootloader_start.c @@ -110,6 +110,7 @@ void IRAM_ATTR call_start_cpu0() */ bool load_partition_table(bootloader_state_t* bs, uint32_t addr) { + esp_err_t err; const esp_partition_info_t *partitions; const int PARTITION_TABLE_SIZE = 0x1000; const int MAX_PARTITIONS = PARTITION_TABLE_SIZE / sizeof(esp_partition_info_t); @@ -118,6 +119,14 @@ bool load_partition_table(bootloader_state_t* bs, uint32_t addr) ESP_LOGI(TAG, "Partition Table:"); ESP_LOGI(TAG, "## Label Usage Type ST Offset Length"); + if(esp_secure_boot_enabled()) { + err = esp_secure_boot_verify_signature(addr, 0x1000); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to verify partition table signature."); + return false; + } + } + partitions = bootloader_mmap(addr, 0x1000); if (!partitions) { ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", addr, 0x1000); @@ -334,7 +343,23 @@ void bootloader_main() static void unpack_load_app(const esp_partition_pos_t* partition) { + esp_err_t err; esp_image_header_t image_header; + uint32_t image_length; + + if (esp_secure_boot_enabled()) { + /* TODO: verify the app image as part of OTA boot decision, so can have fallbacks */ + err = esp_image_basic_verify(partition->offset, &image_length); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to verify app image @ 0x%x (%d)", partition->offset, err); + return; + } + err = esp_secure_boot_verify_signature(partition->offset, image_length); + if (err != ESP_OK) { + ESP_LOGE(TAG, "App image @ 0x%x failed signature verification (%d)", partition->offset, err); + return; + } + } if (esp_image_load_header(partition->offset, &image_header) != ESP_OK) { ESP_LOGE(TAG, "Failed to load app image header @ 0x%x", partition->offset); diff --git a/components/bootloader_support/Makefile.projbuild b/components/bootloader_support/Makefile.projbuild new file mode 100644 index 0000000000..f93967a719 --- /dev/null +++ b/components/bootloader_support/Makefile.projbuild @@ -0,0 +1,3 @@ +# projbuild file for bootloader support +# (included in bootloader & main app) + diff --git a/components/bootloader_support/component.mk b/components/bootloader_support/component.mk index 2988fe287e..7f546dcba9 100755 --- a/components/bootloader_support/component.mk +++ b/components/bootloader_support/component.mk @@ -1,11 +1,36 @@ COMPONENT_ADD_INCLUDEDIRS := include COMPONENT_PRIV_INCLUDEDIRS := include_priv +# include configuration macros early +include $(IDF_PATH)/make/common.mk + ifdef IS_BOOTLOADER_BUILD # share "private" headers with the bootloader component +# eventual goal: all functionality that needs this lives in bootloader_support COMPONENT_ADD_INCLUDEDIRS += include_priv endif COMPONENT_SRCDIRS := src +# +# Secure boot signing key support +# +ifdef CONFIG_SECURE_BOOTLOADER_ENABLED + +SECURE_BOOT_VERIFICATION_KEY := $(abspath signature_verification_key.bin) + +COMPONENT_EMBED_FILES := $(SECURE_BOOT_VERIFICATION_KEY) + +$(SECURE_BOOT_SIGNING_KEY): + @echo "Need to generate secure boot signing key." + @echo "One way is to run this command:" + @echo "$(ESPSECUREPY) generate_signing_key $@" + @echo "Keep key file safe after generating." + @echo "(See secure boot documentation for risks & alternatives.)" + @exit 1 + +$(SECURE_BOOT_VERIFICATION_KEY): $(SECURE_BOOT_SIGNING_KEY) + $(ESPSECUREPY) extract_public_key --keyfile $< $@ +endif + include $(IDF_PATH)/make/component_common.mk diff --git a/components/bootloader_support/include/esp_secure_boot.h b/components/bootloader_support/include/esp_secure_boot.h index 4bf2dc8b23..c1c0171512 100644 --- a/components/bootloader_support/include/esp_secure_boot.h +++ b/components/bootloader_support/include/esp_secure_boot.h @@ -60,6 +60,14 @@ static inline bool esp_secure_boot_enabled(void) { */ esp_err_t esp_secure_boot_permanently_enable(void); - +/** @brief Verify the signature appended to some binary data in flash. + * + * @param src_addr Starting offset of the data in flash. + * @param length Length of data in bytes. Signature is appended -after- length bytes. + * + * @return ESP_OK if signature is valid, ESP_ERR_INVALID_STATE if + * signature fails, ESP_FAIL for other failures (ie can't read flash). + */ +esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length); #endif diff --git a/components/bootloader_support/src/secure_boot_signatures.c b/components/bootloader_support/src/secure_boot_signatures.c new file mode 100644 index 0000000000..5f02de38b0 --- /dev/null +++ b/components/bootloader_support/src/secure_boot_signatures.c @@ -0,0 +1,99 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include "sdkconfig.h" + +#include "bootloader_flash.h" +#include "esp_log.h" +#include "esp_image_format.h" +#include "esp_secure_boot.h" + +#include "uECC.h" + +#ifdef BOOTLOADER_BUILD +#include "rom/sha.h" +typedef SHA_CTX sha_context; +#else +#include "hwcrypto/sha.h" +typedef esp_sha_context sha_context; +#endif + +typedef struct { + uint32_t version; + uint8_t signature[64]; +} signature_block_t; + +static const char* TAG = "secure_boot"; + +extern const uint8_t signature_verification_key_start[] asm("_binary_signature_verification_key_bin_start"); +extern const uint8_t signature_verification_key_end[] asm("_binary_signature_verification_key_bin_end"); + +#define SIGNATURE_VERIFICATION_KEYLEN 64 + +esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length) +{ + sha_context sha; + uint8_t digest[64]; + ptrdiff_t keylen; + const uint8_t *data; + const signature_block_t *sigblock; + bool is_valid; + + ESP_LOGD(TAG, "verifying signature src_addr 0x%x length 0x%x", src_addr, length); + + data = bootloader_mmap(src_addr, length + sizeof(signature_block_t)); + if(data == NULL) { + ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", src_addr, length+sizeof(signature_block_t)); + return ESP_FAIL; + } + + sigblock = (const signature_block_t *)(data + length); + + if (sigblock->version != 0) { + ESP_LOGE(TAG, "src 0x%x has invalid signature version field 0x%08x", src_addr, sigblock->version); + goto unmap_and_fail; + } + +#ifdef BOOTLOADER_BUILD + /* Use ROM SHA functions directly */ + ets_sha_enable(); + ets_sha_init(&sha); + ets_sha_update(&sha, SHA2_512, data, length); + ets_sha_finish(&sha, SHA2_512, digest); + ets_sha_disable(); +#else + /* Use thread-safe esp-idf SHA layer */ + esp_sha512_init(&sha); + esp_sha512_start(&sha, false); + esp_sha512_update(&sha, data, length); + esp_sha512_finish(&sha, digest); + esp_sha512_free(&sha); +#endif + + keylen = signature_verification_key_end - signature_verification_key_start; + if(keylen != SIGNATURE_VERIFICATION_KEYLEN) { + ESP_LOGE(TAG, "Embedded public verification key has wrong length %d", keylen); + goto unmap_and_fail; + } + + is_valid = uECC_verify(signature_verification_key_start, + digest, sizeof(digest), sigblock->signature, + uECC_secp256r1()); + + bootloader_unmap(data); + return is_valid ? ESP_OK : ESP_ERR_IMAGE_INVALID; + + unmap_and_fail: + bootloader_unmap(data); + return ESP_FAIL; +} diff --git a/components/esptool_py/Makefile.projbuild b/components/esptool_py/Makefile.projbuild index dfb9dfc4c2..5807512b86 100644 --- a/components/esptool_py/Makefile.projbuild +++ b/components/esptool_py/Makefile.projbuild @@ -18,6 +18,7 @@ ESPTOOLPY_SERIAL := $(ESPTOOLPY) --port $(ESPPORT) --baud $(ESPBAUD) # Supporting esptool command line tools ESPEFUSEPY := $(PYTHON) $(COMPONENT_PATH)/esptool/espefuse.py ESPSECUREPY := $(PYTHON) $(COMPONENT_PATH)/esptool/espsecure.py +export ESPSECUREPY # is used in bootloader_support component ESPTOOL_FLASH_OPTIONS := --flash_mode $(ESPFLASHMODE) --flash_freq $(ESPFLASHFREQ) --flash_size $(ESPFLASHSIZE) @@ -33,6 +34,11 @@ ESPTOOL_ALL_FLASH_ARGS += $(CONFIG_APP_OFFSET) $(APP_BIN) $(APP_BIN): $(APP_ELF) $(ESPTOOLPY_SRC) $(Q) $(ESPTOOLPY) elf2image $(ESPTOOL_FLASH_OPTIONS) $(ESPTOOL_ELF2IMAGE_OPTIONS) -o $@ $< +ifdef CONFIG_SECURE_BOOTLOADER_ENABLED +ifndef IS_BOOTLOADER_BUILD + $(Q) $(ESPSECUREPY) sign_data --keyfile $(SECURE_BOOT_SIGNING_KEY) $@ # signed in-place +endif +endif flash: all_binaries $(ESPTOOLPY_SRC) @echo "Flashing binaries to serial port $(ESPPORT) (app at offset $(CONFIG_APP_OFFSET))..." diff --git a/components/esptool_py/esptool b/components/esptool_py/esptool index 95dae1651e..68ed7c7a4e 160000 --- a/components/esptool_py/esptool +++ b/components/esptool_py/esptool @@ -1 +1 @@ -Subproject commit 95dae1651e5aea1adb2b6018b23f65a305f67387 +Subproject commit 68ed7c7a4e4409899f10dddda1e02b20e5cb32f0 diff --git a/components/micro-ecc/component.mk b/components/micro-ecc/component.mk new file mode 100644 index 0000000000..df29f400d4 --- /dev/null +++ b/components/micro-ecc/component.mk @@ -0,0 +1,8 @@ +# only compile the micro-ecc/uECC.c source file +# (SRCDIRS is needed so build system can find the source file) +COMPONENT_SRCDIRS := micro-ecc +COMPONENT_OBJS := micro-ecc/uECC.o + +COMPONENT_ADD_INCLUDEDIRS := micro-ecc + +include $(IDF_PATH)/make/component_common.mk diff --git a/components/micro-ecc/micro-ecc b/components/micro-ecc/micro-ecc new file mode 160000 index 0000000000..14222e062d --- /dev/null +++ b/components/micro-ecc/micro-ecc @@ -0,0 +1 @@ +Subproject commit 14222e062d77f45321676e813d9525f32a88e8fa diff --git a/components/partition_table/Makefile.projbuild b/components/partition_table/Makefile.projbuild index 98631cc854..e6f3bce8f9 100644 --- a/components/partition_table/Makefile.projbuild +++ b/components/partition_table/Makefile.projbuild @@ -21,6 +21,9 @@ PARTITION_TABLE_BIN := $(BUILD_DIR_BASE)/$(notdir $(PARTITION_TABLE_CSV_PATH:.cs $(PARTITION_TABLE_BIN): $(PARTITION_TABLE_CSV_PATH) @echo "Building partitions from $(PARTITION_TABLE_CSV_PATH)..." $(Q) $(GEN_ESP32PART) $< $@ +ifdef CONFIG_SECURE_BOOTLOADER_ENABLED + $(Q) $(ESPSECUREPY) sign_data --keyfile $(SECURE_BOOT_SIGNING_KEY) $@ # signed in-place +endif all_binaries: $(PARTITION_TABLE_BIN) diff --git a/docs/security/secure-boot.rst b/docs/security/secure-boot.rst index 5e33367b49..169f2d56bc 100644 --- a/docs/security/secure-boot.rst +++ b/docs/security/secure-boot.rst @@ -8,9 +8,9 @@ Secure Boot is separate from the Encrypted Flash feature, and you can use secure Background ---------- -- Most data is stored in flash. Flash access does not need to protected for secure boot to function, because critical data is stored in Efuses internal to the chip. +- Most data is stored in flash. Flash access does not need to be protected from physical access in order for secure boot to function, because critical data is stored in Efuses internal to the chip. -- Efuses are used to store the secure bootloader key (in efuse block 2), and also a single Efuse (ABS_DONE_0) is burned (written to 1) to permanently enable secure boot on the chip. For more details about efuse, see the (forthcoming) chapter in the Technical Reference Manual. +- Efuses are used to store the secure bootloader key (in efuse block 2), and also a single Efuse bit (ABS_DONE_0) is burned (written to 1) to permanently enable secure boot on the chip. For more details about efuse, see the (forthcoming) chapter in the Technical Reference Manual. - To understand the secure boot process, first familiarise yourself with the standard `esp-idf boot process`. @@ -21,57 +21,62 @@ This is a high level overview of the secure boot process. Step by step instructi 1. The options to enable secure boot are provided in the ``make menuconfig`` hierarchy, under "Bootloader Config". -2. Bootloader Config includes the path to a ECDSA public key. This "image public key" is compiled into the software bootloader. +2. Bootloader Config includes the path to a secure boot signing key. This is a ECDSA public/private key pair in a PEM format file. -2. The software bootloader image is built by esp-idf with the public key embedded, and with a secure boot flag set in its header. This software bootloader image is flashed at offset 0x1000. +2. The software bootloader image is built by esp-idf with the public key (signature verification) portion of the secure boot signing key compiled in, and with a secure boot flag set in its header. This software bootloader image is flashed at offset 0x1000. 3. On first boot, the software bootloader tests the secure boot flag. If it is set, the following process is followed to enable secure boot: - - Hardware secure boot support generates a device secure bootloader key (stored read/write protected in efuse), and a secure digest. The digest is derived from the key, an IV, and the bootloader image contents. + - Hardware secure boot support generates a device secure bootloader key (generated via hardware RNG, then stored read/write protected in efuse), and a secure digest. The digest is derived from the key, an IV, and the bootloader image contents. - The secure digest is flashed at offset 0x0 in the flash. - - Bootloader permanently enables secure boot by burning the ABS_DONE_0 efuse. The software bootloader then becomes protected (the chip will only boot this bootloader image.) + - Bootloader permanently enables secure boot by burning the ABS_DONE_0 efuse. The software bootloader then becomes protected (the chip will only boot a bootloader image if the digest matches.) - Bootloader also disables JTAG via efuse. -4. On subsequent boots the ROM bootloader sees that the secure boot efuse is burned, reads the saved digest at 0x0 and uses hardware secure boot support to compare it with a newly calculated digest. If the digest does not match then booting will not continue. +4. On subsequent boots the ROM bootloader sees that the secure boot efuse is burned, reads the saved digest at 0x0 and uses hardware secure boot support to compare it with a newly calculated digest. If the digest does not match then booting will not continue. The digest and comparison are performed entirely by hardware, for technical details see `Hardware Secure Boot Support`. -5. When running in secure boot mode, the software bootloader uses the image public key (embedded in the bootloader itself) to verify all subsequent partition tables and app images before they are booted. +5. When running in secure boot mode, the software bootloader uses the secure boot signing key's public key (embedded in the bootloader itself, and therefore validated as part of the bootloader digest) to verify all subsequent partition tables and app images before they are booted. Keys ---- The following keys are used by the secure boot process: -- "secure bootloader key" is a 256-bit AES key that is stored in Efuse block 2. The bootloader can generate this key itself from hardware, the user does not need to supply it. The Efuse holding this key must be read & write protected (preventing software access) before secure boot is enabled. +- "secure bootloader key" is a 256-bit AES key that is stored in Efuse block 2. The bootloader can generate this key itself from a hardware random number generation, the user does not need to supply it (it is optionally possible to supply this key, see `Re-Flashable Software Bootloader`). The Efuse holding this key is read & write protected (preventing software access) before secure boot is enabled. -- "image public key" is a ECDSA public key (curve TBD) in format TBD. This public key is flashed into the software bootloader and used to verify the remaining parts of the flash (partition table, app image) before booting continues. The public key can be freely distributed, it does not need to be kept secret. +- "secure boot signing key" is a standard ECDSA public/private key pair (NIST256p aka prime256v1 curve) in PEM format. + + - The public key from this key pair (for signature verificaton but not signature creation) is compiled into the software bootloader and used to verify the second stage of booting (partition table, app image) before booting continues. The public key can be freely distributed, it does not need to be kept secret. + + - The private key from this key pair *must be securely kept private*, as anyone who has this key can authenticate to a bootloader with secure boot using the matching public key. -- "image private key" is a ECDSA private key, a matching pair with "image public key". This private key is used to sign partition tables and app images for the secure boot process. **This private key must be securely kept private** as anyone who has this key can authenticate to the secure boot process. It is acceptable to use the same private key across multiple production devices. How To Enable Secure Boot ------------------------- -1. Run ``make menuconfig``, navigate to "Bootloader Config" -> "Secure Boot" and select the option "One-time Flash". (For the alternative "Reflashable" choice, see `Re-Flashable Software Bootloader`.) +1. Run ``make menuconfig``, navigate to "Bootloader Config" -> "Secure Boot" and select the option "One-time Flash". (To understand the alternative "Reflashable" choice, see `Re-Flashable Software Bootloader`.) -2. Select names for public & private image key files "Image Public Key File" and "Image Private Key File". These options will appear after secure boot is enabled. The files can be anywhere on your system. Relative paths are evaluated from the project directory. The files don't need to exist yet. +2. Select a name for the secure boot signing key. This option will appear after secure boot is enabled. The file can be anywhere on your system. A relative path will be evaluated from the project directory. The file does not need to exist yet. 3. Set other config options (as desired). Pay particular attention to the "Bootloader Config" options, as you can only flash the bootloader once. Then exit menuconfig and save your configuration -4. Run ``make generate_image_keypair`` to generate an image public key and a matching image private key. +4. The first time you run ``make``, if the signing key is not found then an error message will be printed with a command to generate a signing key via ``espsecure.py generate_signing_key``. - **IMPORTANT** The key pair is generated using the best random number source available via the OS and its Python installation (`/dev/urandom` on OSX/Linux and `CryptGenRandom()` on Windows). If this random number source is weak, then the private key will be weak. + **IMPORTANT** A signing key genereated this way will use the best random number source available to the OS and its Python installation (`/dev/urandom` on OSX/Linux and `CryptGenRandom()` on Windows). If this random number source is weak, then the private key will be weak. + + **IMPORTANT** For production environments, we recommend generating the keypair using openssl or another industry standard encryption program. See `Generating Secure Boot Signing Key` for more details. 5. Run ``make bootloader`` to build a secure boot enabled bootloader. The output of `make` will include a prompt for a flashing command, using `esptool.py write_flash`. -6. When you're ready to flash the bootloader, run the specified command (you have to enter it yourself, this step is not automated) and then wait for flashing to complete. **Remember this is a one time flash, you can't change the bootloader after this!**. +6. When you're ready to flash the bootloader, run the specified command (you have to enter it yourself, this step is not performed by make) and then wait for flashing to complete. **Remember this is a one time flash, you can't change the bootloader after this!**. -7. Run `make flash` to build and flash the partition table and the just-built app image. The app image will be signed using the private key you generated in step 4. +7. Run `make flash` to build and flash the partition table and the just-built app image. The app image will be signed using the signing key you generated in step 4. *NOTE*: `make flash` doesn't flash the bootloader if secure boot is enabled. 8. Reset the ESP32 and it will boot the software bootloader you flashed. The software bootloader will enable secure boot on the chip, and then it verifies the app image signature and boots the app. You should watch the serial console output from the ESP32 to verify that secure boot is enabled and no errors have occured due to the build configuration. -**IMPORTANT** Secure boot won't ever be enabled until after a valid partition table and app image have been flashed. This is to prevent accidents before the system is fully configured. +*NOTE* Secure boot won't be enabled until after a valid partition table and app image have been flashed. This is to prevent accidents before the system is fully configured. -9. On subsequent boots, the secure boot hardware will verify the software bootloader (using the secure bootloader key) and then the software bootloader will verify the partition table and app image (using the image public key). +9. On subsequent boots, the secure boot hardware will verify the software bootloader (using the secure bootloader key) and then the software bootloader will verify the partition table and app image (using the signing key). Re-Flashable Software Bootloader -------------------------------- @@ -80,19 +85,34 @@ The "Secure Boot: One-Time Flash" is the recommended software bootloader configu However, an alternative mode "Secure Boot: Reflashable" is also available. This mode allows you to supply a 256-bit key file that is used for the secure bootloader key. As you have the key file, you can generate new bootloader images and secure boot digests for them. -*NOTE*: Although it's possible, we strongly recommend not generating one secure boot key and flashing it to every device in a production environment. +In the esp-idf build process, this 256-bit key file is derived from the app signing key generated during the generate_signing_key step above. The private key's SHA-256 value is used to generate an 256-bit value which is then burned to efuse and used to protect the bootloader. This is a convenience so you only need to generate/protect a single private key. + +*NOTE*: Although it's possible, we strongly recommend not generating one secure boot key and flashing it to every device in a production environment. The "One-Time Flash" option is recommended for production environments. + +To enable a reflashable bootloader: 1. In the ``make menuconfig`` step, select "Bootloader Config" -> "Secure Boot" -> "Reflashable". -2. Select a name for the "Secure bootloader key file". The file can be anywhere on your system, and does not have to exist yet. A path is evaluated relative to the project directory. The file doesn't have to exist yet. +2. Follow the steps shown above to choose a signing key file, and generate the key file. -3. The first time you run ``make bootloader``, the system will prompt you with a ``espsecure.py generate_key`` command that can be used to generate the secure bootloader key. +3. Run ``make bootloader``. A 256-bit key file will be created, derived from the private key you generated for signing. Two sets of flashing steps will be printed - the first set of steps includes an ``espefuse.py burn_key`` command which is used to write the derived key to efuse. (Flashing this key is a one-time-only process.) The second set of steps can be used to reflash the bootloader with a pre-generated digest (generated during the build process, using the derived key). - **IMPORTANT** The new key is generated using the best random number source available via the OS and its Python installation (`/dev/urandom` on OSX/Linux and `CryptGenRandom()` on Windows). If this random number source is weak, then the secure bootloader key will be weak. +4. Resume from `Step 6` of the one-time process, to flash the bootloader and enable secure boot. Watch the console log output closely to ensure there were no errors in the secure boot configuration. -4. Run ``make bootloader`` again. Two sets of flashing steps will be printed - the first set of steps includes an ``espefuse.py burn_key`` command which is used to write the secure bootloader key to efuse. (Flashing this key is a one-time-only process.) The second set of steps can be used to reflash the bootloader with a pre-generated digest (generated during the build process, using the secure bootloader key file). +Generating Secure Boot Signing Key +---------------------------------- -5. Resume from `Step 6` of the one-time process, to flash the bootloader and enable secure boot. Watch the console log output closely to ensure there were no errors in the secure boot configuration. +The build system will prompt you with a command to generate a new signing key via ``espsecure.py generate_signing_key``. This uses the python-ecdsa library, which in turn uses Python's os.urandom() as a random number source. + +The strength of the signing key is proportional to (a) the random number source of the system, and (b) the correctness of the algorithm used. For production devices, we recommend generating signing keys from a system with a quality entropy source, and using the best available EC key generation utilities. + +For example, to generate a signing key using the openssl command line: + +``` +openssl ecparam -name prime256v1 -genkey -noout -out my_secure_boot_signing_key.pem +``` + +Remember that the strength of the secure boot system depends on keeping the signing key private. Technical Details @@ -107,9 +127,9 @@ The Secure Boot support hardware can perform three basic operations: 1. Generate a random sequence of bytes from a hardware random number generator. -2. Generate a digest from data (usually the bootloader image from flash) using a key stored in Efuse block 2. The key in Efuse can (& should) be read/write protected, which prevents software access. For full details of this algorithm see `Secure Bootloader Digest Algorithm`. The digest can only be read from hardware if Efuse ABS_DONE_0 is *not* burned (ie still 0), to prevent new digests from being calculated on the device after secure boot is enabled. +2. Generate a digest from data (usually the bootloader image from flash) using a key stored in Efuse block 2. The key in Efuse can (& should) be read/write protected, which prevents software access. For full details of this algorithm see `Secure Bootloader Digest Algorithm`. The digest can only be read back by software if Efuse ABS_DONE_0 is *not* burned (ie still 0). -3. Verify a digest from data (usually the bootloader image from flash), and compare it to a pre-existing digest (usually read from flash offset 0x0). The hardware returns a true/false comparison without making the digest available to software. +3. Verify a digest from data (usually the bootloader image from flash), and compare it to a pre-existing digest (usually read from flash offset 0x0). The hardware returns a true/false comparison without making the digest available to software. This function is available even when Efuse ABS_DONE_0 is burned. Secure Bootloader Digest Algorithm ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -122,9 +142,9 @@ Items marked with (^) are to fulfill hardware restrictions, as opposed to crypto 1. Prefix the image with a 128 byte randomly generated IV. 2. If the image is not modulo 128, pad the image to a 128 byte boundary with 0xFF. (^) -3. For each 16 byte block of the input image: - - Reverse the byte order of the block (^) - - Use the AES256 algorithm in ECB mode to encrypt the block. +3. For each 16 byte plaintext block of the input image: + - Reverse the byte order of the plaintext block (^) + - Apply AES256 in ECB mode to the plaintext block. - Reverse the byte order of the 16 bytes of ciphertext output. (^) - Append to the overall ciphertext output. 4. Byte-swap each 4 byte word of the ciphertext (^) @@ -137,9 +157,10 @@ Image Signing Algorithm Deterministic ECDSA as specified by `RFC6979`. -Curve is TBD. -Key format is TBD. -Output format is TBD. +- Curve is NIST256p (openssl calls this curve "prime256v1", it is also sometimes called secp256r1). +- Key format used for storage is PEM. + - In the bootloader, the public key (for signature verification) is flashed as 64 raw bytes. +- Image signature is 68 bytes - a 4 byte version word (currently zero), followed by a 64 bytes of signature data. These 68 bytes are appended to an app image or partition table data. .. _esp-idf boot process: ../boot-process.rst diff --git a/make/common.mk b/make/common.mk index 2b7376a4db..0c523c8775 100644 --- a/make/common.mk +++ b/make/common.mk @@ -53,8 +53,26 @@ endef # convenience variable for printing an 80 asterisk wide separator line SEPARATOR:="*******************************************************************************" -# macro to remove quotes from an argument, ie $(call dequote (CONFIG_BLAH)) +# macro to remove quotes from an argument, ie $(call dequote,$(CONFIG_BLAH)) define dequote $(subst ",,$(1)) endef # " comment kept here to keep syntax highlighting happy + + +# macro to keep an absolute path as-is, but resolve a relative path +# against a particular parent directory +# +# $(1) path to resolve +# $(2) directory to resolve non-absolute path against +# +# Path and directory don't have to exist (definition of a "relative +# path" is one that doesn't start with /) +# +# $(2) can contain a trailing forward slash or not, result will not +# double any path slashes. +# +# example $(call resolvepath,$(CONFIG_PATH),$(CONFIG_DIR)) +define resolvepath +$(if $(filter /%,$(1)),$(1),$(subst //,/,$(2)/$(1))) +endef diff --git a/make/component_common.mk b/make/component_common.mk index 58711b7c6e..70a6f60f07 100644 --- a/make/component_common.mk +++ b/make/component_common.mk @@ -134,10 +134,10 @@ OBJCOPY_EMBED_ARGS := --input binary --output elf32-xtensa-le --binary-architect # because objcopy generates the symbol name from the full command line # path to the input file. define GenerateEmbedTarget -$(1).$(2).o: $$(COMPONENT_PATH)/$(1) | $$(dir $(1)) +$(1).$(2).o: $(call resolvepath,$(1),$(COMPONENT_PATH)) | $$(dir $(1)) $$(summary) EMBED $$@ - $$(Q) cp $$< $$(notdir $$<) - $$(Q) $(if $(subst bin,,$(2)),echo -ne '\0' >> $$(notdir $$<) ) + $$(Q) $(if $(filter-out $$(notdir $$(abspath $$<)),$$(abspath $$(notdir $$<))), cp $$< $$(notdir $$<) ) # copy input file to build dir, unless already in build dir + $$(Q) $(if $(subst bin,,$(2)),echo -ne '\0' >> $$(notdir $$<) ) # trailing NUL byte on text output $$(Q) $$(OBJCOPY) $(OBJCOPY_EMBED_ARGS) $$(notdir $$<) $$@ $$(Q) rm $$(notdir $$<) endef diff --git a/make/project.mk b/make/project.mk index 7e8dc46d54..5a12732a4e 100644 --- a/make/project.mk +++ b/make/project.mk @@ -151,6 +151,7 @@ LDFLAGS ?= -nostdlib \ -L$(IDF_PATH)/ld \ $(addprefix -L$(BUILD_DIR_BASE)/,$(COMPONENTS) $(SRCDIRS)) \ -u call_user_start_cpu0 \ + $(EXTRA_LDFLAGS) \ -Wl,--gc-sections \ -Wl,-static \ -Wl,--start-group \ From 64f3893cb9c7a4c792f4ecbb7c4375f25bf768f7 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Fri, 4 Nov 2016 16:05:00 +1100 Subject: [PATCH 324/343] secure boot: Derive secure bootloader key from private key Means only one key needs to be managed. --- components/bootloader/Kconfig.projbuild | 23 +++-------------- components/bootloader/Makefile.projbuild | 25 ++++++++----------- .../bootloader_support/Makefile.projbuild | 3 --- components/bootloader_support/component.mk | 8 ++++-- components/esptool_py/esptool | 2 +- make/project.mk | 5 +++- make/project_config.mk | 1 - 7 files changed, 25 insertions(+), 42 deletions(-) delete mode 100644 components/bootloader_support/Makefile.projbuild diff --git a/components/bootloader/Kconfig.projbuild b/components/bootloader/Kconfig.projbuild index b568f61a04..536b971268 100644 --- a/components/bootloader/Kconfig.projbuild +++ b/components/bootloader/Kconfig.projbuild @@ -54,29 +54,14 @@ config SECURE_BOOTLOADER_ONE_TIME_FLASH config SECURE_BOOTLOADER_REFLASHABLE bool "Reflashable" help - Generate the bootloader digest key on the computer instead of inside - the chip. Allows the secure bootloader to be re-flashed by using the - same key. + Generate a reusable secure bootloader key, derived (via SHA-256) from the secure boot signing key. - This option is less secure than one-time flash, because a leak of the digest key allows reflashing of any device that uses it. + This allows the secure bootloader to be re-flashed by anyone with access to the secure boot signing key. + + This option is less secure than one-time flash, because a leak of the digest key from one device allows reflashing of any device that uses it. endchoice -config SECURE_BOOTLOADER_KEY_FILE - string "Secure bootloader key file" - depends on SECURE_BOOTLOADER_REFLASHABLE - default secure_boot_key.bin - help - Path to the key file for a reflashable secure bootloader digest. - File must contain 32 randomly generated bytes. - - Path is evaluated relative to the project directory. - - You can generate a new key by running the following command: - espsecure.py generate_key secure_boot_key.bin - - See docs/security/secure-boot.rst for details. - config SECURE_BOOT_SIGNING_KEY string "Secure boot signing key" depends on SECURE_BOOTLOADER_ENABLED diff --git a/components/bootloader/Makefile.projbuild b/components/bootloader/Makefile.projbuild index 831d988584..1b1c07bea3 100644 --- a/components/bootloader/Makefile.projbuild +++ b/components/bootloader/Makefile.projbuild @@ -15,8 +15,7 @@ BOOTLOADER_BUILD_DIR=$(abspath $(BUILD_DIR_BASE)/bootloader) BOOTLOADER_BIN=$(BOOTLOADER_BUILD_DIR)/bootloader.bin BOOTLOADER_SDKCONFIG=$(BOOTLOADER_BUILD_DIR)/sdkconfig -# both signing key paths are resolved relative to the project directory -SECURE_BOOTLOADER_KEY=$(abspath $(call dequote,$(CONFIG_SECURE_BOOTLOADER_KEY_FILE))) +# signing key path is resolved relative to the project directory SECURE_BOOT_SIGNING_KEY=$(abspath $(call dequote,$(CONFIG_SECURE_BOOT_SIGNING_KEY))) export SECURE_BOOT_SIGNING_KEY # used by bootloader_support component @@ -31,10 +30,6 @@ BOOTLOADER_MAKE=+$(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src \ $(BOOTLOADER_BIN): | $(BOOTLOADER_BUILD_DIR)/sdkconfig $(Q) $(BOOTLOADER_MAKE) $@ -bootloader-clean: - $(Q) $(BOOTLOADER_MAKE) app-clean config-clean - $(Q) rm -f $(BOOTLOADER_SDKCONFIG) $(BOOTLOADER_SDKCONFIG).old - clean: bootloader-clean ifdef CONFIG_SECURE_BOOTLOADER_DISABLED @@ -66,7 +61,11 @@ else ifdef CONFIG_SECURE_BOOTLOADER_REFLASHABLE # Reflashable secure bootloader # generates a digest binary (bootloader + digest) -BOOTLOADER_DIGEST_BIN=$(BOOTLOADER_BUILD_DIR)/bootloader-reflash-digest.bin +BOOTLOADER_DIGEST_BIN := $(BOOTLOADER_BUILD_DIR)/bootloader-reflash-digest.bin +SECURE_BOOTLOADER_KEY := $(BOOTLOADER_BUILD_DIR)/secure-bootloader-key.bin + +$(SECURE_BOOTLOADER_KEY): $(SECURE_BOOT_SIGNING_KEY) + $(Q) $(ESPSECUREPY) digest_private_key -k $< $@ bootloader: $(BOOTLOADER_DIGEST_BIN) @echo $(SEPARATOR) @@ -84,20 +83,16 @@ $(BOOTLOADER_DIGEST_BIN): $(BOOTLOADER_BIN) $(SECURE_BOOTLOADER_KEY) @echo "DIGEST $(notdir $@)" $(Q) $(ESPSECUREPY) digest_secure_bootloader -k $(SECURE_BOOTLOADER_KEY) -o $@ $< -$(SECURE_BOOTLOADER_KEY): - @echo $(SEPARATOR) - @echo "Need to generate secure boot signing key. Run following command:" - @echo "$(ESPSECUREPY) generate_key $@" - @echo "Keep key file safe after generating." - @echo "(See secure boot documentation for caveats & alternatives.)") - @exit 1 - else bootloader: @echo "Invalid bootloader target: bad sdkconfig?" @exit 1 endif +bootloader-clean: + $(Q) $(BOOTLOADER_MAKE) app-clean config-clean + $(Q) rm -f $(BOOTLOADER_SDKCONFIG) $(BOOTLOADER_SDKCONFIG).old $(SECURE_BOOTLOADER_KEY) $(BOOTLOADER_DIGEST_BIN) + all_binaries: $(BOOTLOADER_BIN) # synchronise the project level config to the bootloader's diff --git a/components/bootloader_support/Makefile.projbuild b/components/bootloader_support/Makefile.projbuild deleted file mode 100644 index f93967a719..0000000000 --- a/components/bootloader_support/Makefile.projbuild +++ /dev/null @@ -1,3 +0,0 @@ -# projbuild file for bootloader support -# (included in bootloader & main app) - diff --git a/components/bootloader_support/component.mk b/components/bootloader_support/component.mk index 7f546dcba9..e68949d82a 100755 --- a/components/bootloader_support/component.mk +++ b/components/bootloader_support/component.mk @@ -17,10 +17,9 @@ COMPONENT_SRCDIRS := src # ifdef CONFIG_SECURE_BOOTLOADER_ENABLED +# this path is created relative to the component build directory SECURE_BOOT_VERIFICATION_KEY := $(abspath signature_verification_key.bin) -COMPONENT_EMBED_FILES := $(SECURE_BOOT_VERIFICATION_KEY) - $(SECURE_BOOT_SIGNING_KEY): @echo "Need to generate secure boot signing key." @echo "One way is to run this command:" @@ -31,6 +30,11 @@ $(SECURE_BOOT_SIGNING_KEY): $(SECURE_BOOT_VERIFICATION_KEY): $(SECURE_BOOT_SIGNING_KEY) $(ESPSECUREPY) extract_public_key --keyfile $< $@ + +COMPONENT_EXTRA_CLEAN += $(SECURE_BOOT_VERIFICATION_KEY) + +COMPONENT_EMBED_FILES := $(SECURE_BOOT_VERIFICATION_KEY) + endif include $(IDF_PATH)/make/component_common.mk diff --git a/components/esptool_py/esptool b/components/esptool_py/esptool index 68ed7c7a4e..98e5dbfa78 160000 --- a/components/esptool_py/esptool +++ b/components/esptool_py/esptool @@ -1 +1 @@ -Subproject commit 68ed7c7a4e4409899f10dddda1e02b20e5cb32f0 +Subproject commit 98e5dbfa78fa53cebcb4c56530e683f889bf21c3 diff --git a/make/project.mk b/make/project.mk index 5a12732a4e..e0d578c104 100644 --- a/make/project.mk +++ b/make/project.mk @@ -306,6 +306,9 @@ app-clean: $(addsuffix -clean,$(notdir $(COMPONENT_PATHS_BUILDABLE))) $(summary) RM $(APP_ELF) $(Q) rm -f $(APP_ELF) $(APP_BIN) $(APP_MAP) -clean: app-clean +# NB: this ordering is deliberate (app-clean before config-clean), +# so config remains valid during all component clean targets +config-clean: app-clean +clean: config-clean diff --git a/make/project_config.mk b/make/project_config.mk index 7ca83ce5af..56a05090bc 100644 --- a/make/project_config.mk +++ b/make/project_config.mk @@ -59,7 +59,6 @@ $(AUTO_CONF_REGEN_TARGET) $(BUILD_DIR_BASE)/include/sdkconfig.h: $(SDKCONFIG) $( # sometimes you can get an infinite make loop on Windows where sdkconfig always gets regenerated newer # than the target(!) -clean: config-clean .PHONY: config-clean config-clean: $(summary RM CONFIG) From 7402a1b9738a7542e6e37de8768c9580a196aee0 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Mon, 7 Nov 2016 14:35:23 +1100 Subject: [PATCH 325/343] partition_table: Move from 0x4000 to 0x8000 Also fix a bug with correctly padding bootloader image when length is already a multiple of 16. --- components/bootloader_support/src/bootloader_flash.c | 4 ++-- components/bootloader_support/src/esp_image_format.c | 8 +++++++- components/esp32/include/esp_flash_data_types.h | 2 +- components/partition_table/Makefile.projbuild | 6 ++++-- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/components/bootloader_support/src/bootloader_flash.c b/components/bootloader_support/src/bootloader_flash.c index a50cd157e9..fcaf24ad2c 100644 --- a/components/bootloader_support/src/bootloader_flash.c +++ b/components/bootloader_support/src/bootloader_flash.c @@ -94,11 +94,11 @@ void bootloader_unmap(const void *mapping) esp_err_t bootloader_flash_read(size_t src_addr, void *dest, size_t size) { if(src_addr & 3) { - ESP_LOGE(TAG, "bootloader_flash_read src_addr not 4-byte aligned"); + ESP_LOGE(TAG, "bootloader_flash_read src_addr 0x%x not 4-byte aligned", src_addr); return ESP_FAIL; } if((intptr_t)dest & 3) { - ESP_LOGE(TAG, "bootloader_flash_read dest not 4-byte aligned"); + ESP_LOGE(TAG, "bootloader_flash_read dest 0x%x not 4-byte aligned", (intptr_t)dest); return ESP_FAIL; } diff --git a/components/bootloader_support/src/esp_image_format.c b/components/bootloader_support/src/esp_image_format.c index ad3cd33f13..3e7dcafa9e 100644 --- a/components/bootloader_support/src/esp_image_format.c +++ b/components/bootloader_support/src/esp_image_format.c @@ -62,6 +62,7 @@ esp_err_t esp_image_load_segment_header(uint8_t index, uint32_t src_addr, const } for(int i = 0; i <= index && err == ESP_OK; i++) { + ESP_LOGV(TAG, "loading segment header %d at offset 0x%x", i, next_addr); err = bootloader_flash_read(next_addr, segment_header, sizeof(esp_image_segment_header_t)); if (err == ESP_OK) { if ((segment_header->data_len & 3) != 0 @@ -69,6 +70,7 @@ esp_err_t esp_image_load_segment_header(uint8_t index, uint32_t src_addr, const ESP_LOGE(TAG, "invalid segment length 0x%x", segment_header->data_len); err = ESP_ERR_IMAGE_INVALID; } + ESP_LOGV(TAG, "segment data length 0x%x", segment_header->data_len); next_addr += sizeof(esp_image_segment_header_t); *segment_data_offset = next_addr; next_addr += segment_header->data_len; @@ -140,7 +142,11 @@ esp_err_t esp_image_basic_verify(uint32_t src_addr, uint32_t *p_length) } /* image padded to next full 16 byte block, with checksum byte at very end */ - length += 15 - (length % 16); + ESP_LOGV(TAG, "unpadded image length 0x%x", length); + length += 16; /* always pad by at least 1 byte */ + length = length - (length % 16); + ESP_LOGV(TAG, "padded image length 0x%x", length); + ESP_LOGD(TAG, "reading checksum block at 0x%x", src_addr + length - 16); bootloader_flash_read(src_addr + length - 16, buf, 16); if (checksum != buf[15]) { ESP_LOGE(TAG, "checksum failed. Calculated 0x%x read 0x%x", diff --git a/components/esp32/include/esp_flash_data_types.h b/components/esp32/include/esp_flash_data_types.h index ce4acb7bc9..783f2c59bb 100644 --- a/components/esp32/include/esp_flash_data_types.h +++ b/components/esp32/include/esp_flash_data_types.h @@ -21,7 +21,7 @@ extern "C" { #endif -#define ESP_PARTITION_TABLE_ADDR 0x4000 +#define ESP_PARTITION_TABLE_ADDR 0x8000 #define ESP_PARTITION_MAGIC 0x50AA /* OTA selection structure (two copies in the OTA data partition.) diff --git a/components/partition_table/Makefile.projbuild b/components/partition_table/Makefile.projbuild index e6f3bce8f9..4273f53c3a 100644 --- a/components/partition_table/Makefile.projbuild +++ b/components/partition_table/Makefile.projbuild @@ -11,6 +11,8 @@ # NB: gen_esp32part.py lives in the sdk/bin/ dir not component dir GEN_ESP32PART := $(PYTHON) $(COMPONENT_PATH)/gen_esp32part.py -q +PARTITION_TABLE_OFFSET := 0x8000 + # Path to partition CSV file is relative to project path for custom # partition CSV files, but relative to component dir otherwise.$ PARTITION_TABLE_ROOT := $(call dequote,$(if $(CONFIG_PARTITION_TABLE_CUSTOM),$(PROJECT_PATH),$(COMPONENT_PATH))) @@ -27,8 +29,8 @@ endif all_binaries: $(PARTITION_TABLE_BIN) -PARTITION_TABLE_FLASH_CMD = $(ESPTOOLPY_SERIAL) write_flash 0x4000 $(PARTITION_TABLE_BIN) -ESPTOOL_ALL_FLASH_ARGS += 0x4000 $(PARTITION_TABLE_BIN) +PARTITION_TABLE_FLASH_CMD = $(ESPTOOLPY_SERIAL) write_flash $(PARTITION_TABLE_OFFSET) $(PARTITION_TABLE_BIN) +ESPTOOL_ALL_FLASH_ARGS += $(PARTITION_TABLE_OFFSET) $(PARTITION_TABLE_BIN) partition_table: $(PARTITION_TABLE_BIN) @echo "Partition table binary generated. Contents:" From ff1b2c603911f58f3602fe8d9f7cf6c1cddff63b Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Mon, 7 Nov 2016 15:32:21 +1100 Subject: [PATCH 326/343] partition_table: Pad generated table to 0xC00 length, for easier signing --- components/partition_table/gen_esp32part.py | 8 +++++++- .../partition_table/tests/gen_esp32part_tests.py | 15 ++++++++++----- docs/partition-tables.rst | 5 +++++ 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/components/partition_table/gen_esp32part.py b/components/partition_table/gen_esp32part.py index 8b5df2b3b5..b399f31b78 100755 --- a/components/partition_table/gen_esp32part.py +++ b/components/partition_table/gen_esp32part.py @@ -9,6 +9,8 @@ import struct import argparse import sys +MAX_PARTITION_LENGTH = 0xC00 # 3K for partition data (96 entries) leaves 1K in a 4K sector for signature + __version__ = '1.0' quiet = False @@ -92,7 +94,11 @@ class PartitionTable(list): return result def to_binary(self): - return "".join(e.to_binary() for e in self) + result = "".join(e.to_binary() for e in self) + if len(result )>= MAX_PARTITION_LENGTH: + raise InputError("Binary partition table length (%d) longer than max" % len(result)) + result += "\xFF" * (MAX_PARTITION_LENGTH - len(result)) # pad the sector, for signing + return result def to_csv(self, simple_formatting=False): rows = [ "# Espressif ESP32 Partition Table", diff --git a/components/partition_table/tests/gen_esp32part_tests.py b/components/partition_table/tests/gen_esp32part_tests.py index 413f1aac91..d12539ea87 100755 --- a/components/partition_table/tests/gen_esp32part_tests.py +++ b/components/partition_table/tests/gen_esp32part_tests.py @@ -37,6 +37,10 @@ LONGER_BINARY_TABLE += "\xAA\x50\x10\x00" + \ "second" + ("\0"*10) + \ "\x00\x00\x00\x00" +def _strip_trailing_ffs(binary_table): + while binary_table.endswith("\xFF"): + binary_table = binary_table[0:len(binary_table)-1] + return binary_table class CSVParserTests(unittest.TestCase): @@ -156,7 +160,7 @@ class BinaryOutputTests(unittest.TestCase): first, 0x30, 0xEE, 0x100400, 0x300000 """ t = PartitionTable.from_csv(csv) - tb = t.to_binary() + tb = _strip_trailing_ffs(t.to_binary()) self.assertEqual(len(tb), 32) self.assertEqual('\xAA\x50', tb[0:2]) # magic self.assertEqual('\x30\xee', tb[2:4]) # type, subtype @@ -170,7 +174,7 @@ first, 0x30, 0xEE, 0x100400, 0x300000 second,0x31, 0xEF, , 0x100000 """ t = PartitionTable.from_csv(csv) - tb = t.to_binary() + tb = _strip_trailing_ffs(t.to_binary()) self.assertEqual(len(tb), 64) self.assertEqual('\xAA\x50', tb[0:2]) self.assertEqual('\xAA\x50', tb[32:34]) @@ -215,7 +219,7 @@ class BinaryParserTests(unittest.TestCase): self.assertEqual(t[2].type, 0x10) self.assertEqual(t[2].name, "second") - round_trip = t.to_binary() + round_trip = _strip_trailing_ffs(t.to_binary()) self.assertEqual(round_trip, LONGER_BINARY_TABLE) def test_bad_magic(self): @@ -267,7 +271,7 @@ class CSVOutputTests(unittest.TestCase): self.assertEqual(row[0], "factory") self.assertEqual(row[1], "app") self.assertEqual(row[2], "2") - self.assertEqual(row[3], "64K") + self.assertEqual(row[3], "0x10000") self.assertEqual(row[4], "1M") # round trip back to a PartitionTable and check is identical @@ -291,7 +295,7 @@ class CommandLineTests(unittest.TestCase): # reopen the CSV and check the generated binary is identical with open(csvpath, 'r') as f: from_csv = PartitionTable.from_csv(f.read()) - self.assertEqual(from_csv.to_binary(), LONGER_BINARY_TABLE) + self.assertEqual(_strip_trailing_ffs(from_csv.to_binary()), LONGER_BINARY_TABLE) # run gen_esp32part.py to conver the CSV to binary again subprocess.check_call([sys.executable, "../gen_esp32part.py", @@ -299,6 +303,7 @@ class CommandLineTests(unittest.TestCase): # assert that file reads back as identical with open(binpath, 'rb') as f: binary_readback = f.read() + binary_readback = _strip_trailing_ffs(binary_readback) self.assertEqual(binary_readback, LONGER_BINARY_TABLE) finally: diff --git a/docs/partition-tables.rst b/docs/partition-tables.rst index 88597532d2..5f5911bd52 100644 --- a/docs/partition-tables.rst +++ b/docs/partition-tables.rst @@ -6,6 +6,8 @@ Overview A single ESP32's flash can contain multiple apps, as well as many different kinds of data (calibration data, filesystems, parameter storage, etc). For this reason a partition table is flashed to offset 0x4000 in the flash. +Partition table length is 0xC00 bytes (maximum 95 partition table entries). If the partition table is signed due to `secure boot`, the signature is appended after the table data. + Each entry in the partition table has a name (label), type (app, data, or something else), subtype and the offset in flash where the partition is loaded. The simplest way to use the partition table is to `make menuconfig` and choose one of the simple predefined partition tables: @@ -130,3 +132,6 @@ Flashing the partition table * ``make flash``: Will flash everything including the partition table. A manual flashing command is also printed as part of ``make partition_table``. + + +.. _secure boot: security/secure-boot.rst From fe66dd85f09881c4ab8c48e37cda715f065fccfe Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Mon, 7 Nov 2016 15:45:26 +1100 Subject: [PATCH 327/343] secure boot: Enable based on sdkconfig, remove "secure boot flag" from binary image --- components/bootloader/Kconfig.projbuild | 35 ++++++++++++++++++- .../bootloader/src/main/bootloader_start.c | 24 +++++++------ .../include/esp_image_format.h | 3 +- .../include/esp_secure_boot.h | 2 +- .../bootloader_support/src/secure_boot.c | 26 ++++++++++++-- 5 files changed, 73 insertions(+), 17 deletions(-) diff --git a/components/bootloader/Kconfig.projbuild b/components/bootloader/Kconfig.projbuild index 536b971268..949638594d 100644 --- a/components/bootloader/Kconfig.projbuild +++ b/components/bootloader/Kconfig.projbuild @@ -28,6 +28,12 @@ config LOG_BOOTLOADER_LEVEL default 4 if LOG_BOOTLOADER_LEVEL_DEBUG default 5 if LOG_BOOTLOADER_LEVEL_VERBOSE +endmenu + + + +menu "Secure boot configuration" + choice SECURE_BOOTLOADER bool "Secure bootloader" default SECURE_BOOTLOADER_DISABLED @@ -78,8 +84,35 @@ config SECURE_BOOT_SIGNING_KEY See docs/security/secure-boot.rst for details. +config SECURE_BOOT_DISABLE_JTAG + bool "First boot: Permanently disable JTAG" + depends on SECURE_BOOTLOADER_ENABLED + default Y + help + Bootloader permanently disable JTAG (across entire chip) when enabling secure boot. This happens on first boot of the bootloader. + + It is recommended this option remains set for production environments. + +config SECURE_BOOT_DISABLE_UART_BOOTLOADER + bool "First boot: Permanently disable UART bootloader" + depends on SECURE_BOOTLOADER_ENABLED + default Y + help + Bootloader permanently disables UART and other bootloader modes when enabling secure boot. This happens on first boot. + + It is recommended this option remains set for production environments. + +config SECURE_BOOT_TEST_MODE + bool "Test mode: don't actually enable secure boot" + depends on SECURE_BOOTLOADER_ENABLED + default N + help + If this option is set, all permanent secure boot changes (via Efuse) are disabled. + + This option is for testing purposes only - it effectively completely disables secure boot protection. + config SECURE_BOOTLOADER_ENABLED bool default SECURE_BOOTLOADER_ONE_TIME_FLASH || SECURE_BOOTLOADER_REFLASHABLE -endmenu +endmenu \ No newline at end of file diff --git a/components/bootloader/src/main/bootloader_start.c b/components/bootloader/src/main/bootloader_start.c index 3ebb8cf520..6c23257be5 100644 --- a/components/bootloader/src/main/bootloader_start.c +++ b/components/bootloader/src/main/bootloader_start.c @@ -316,17 +316,17 @@ void bootloader_main() ESP_LOGI(TAG, "Loading app partition at offset %08x", load_part_pos); - if(fhdr.secure_boot_flag == 0x01) { - /* Generate secure digest from this bootloader to protect future - modifications */ - err = esp_secure_boot_permanently_enable(); - if (err != ESP_OK){ - ESP_LOGE(TAG, "Bootloader digest generation failed (%d). SECURE BOOT IS NOT ENABLED.", err); - /* Allow booting to continue, as the failure is probably - due to user-configured EFUSEs for testing... - */ - } +#ifdef CONFIG_SECURE_BOOTLOADER_ENABLED + /* Generate secure digest from this bootloader to protect future + modifications */ + err = esp_secure_boot_permanently_enable(); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Bootloader digest generation failed (%d). SECURE BOOT IS NOT ENABLED.", err); + /* Allow booting to continue, as the failure is probably + due to user-configured EFUSEs for testing... + */ } +#endif if(fhdr.encrypt_flag == 0x01) { /* encrypt flash */ @@ -354,12 +354,16 @@ static void unpack_load_app(const esp_partition_pos_t* partition) ESP_LOGE(TAG, "Failed to verify app image @ 0x%x (%d)", partition->offset, err); return; } +#ifdef CONFIG_SECURE_BOOTLOADER_ENABLED + ESP_LOGI(TAG, "Verifying app signature @ 0x%x (length 0x%x)", partition->offset, image_length); err = esp_secure_boot_verify_signature(partition->offset, image_length); if (err != ESP_OK) { ESP_LOGE(TAG, "App image @ 0x%x failed signature verification (%d)", partition->offset, err); return; } + ESP_LOGD(TAG, "App signature is valid"); } +#endif if (esp_image_load_header(partition->offset, &image_header) != ESP_OK) { ESP_LOGE(TAG, "Failed to load app image header @ 0x%x", partition->offset); diff --git a/components/bootloader_support/include/esp_image_format.h b/components/bootloader_support/include/esp_image_format.h index a8b1739d73..326ff130d5 100644 --- a/components/bootloader_support/include/esp_image_format.h +++ b/components/bootloader_support/include/esp_image_format.h @@ -64,8 +64,7 @@ typedef struct { uint8_t spi_size: 4; /* flash chip size (esp_image_flash_size_t as uint8_t) */ uint32_t entry_addr; uint8_t encrypt_flag; /* encrypt flag */ - uint8_t secure_boot_flag; /* secure boot flag */ - uint8_t extra_header[14]; /* ESP32 additional header, unused by second bootloader */ + uint8_t extra_header[15]; /* ESP32 additional header, unused by second bootloader */ } esp_image_header_t; /* Header of binary image segment */ diff --git a/components/bootloader_support/include/esp_secure_boot.h b/components/bootloader_support/include/esp_secure_boot.h index c1c0171512..eaa1048628 100644 --- a/components/bootloader_support/include/esp_secure_boot.h +++ b/components/bootloader_support/include/esp_secure_boot.h @@ -32,7 +32,7 @@ * @return true if secure boot is enabled. */ static inline bool esp_secure_boot_enabled(void) { - return REG_GET_FIELD(EFUSE_BLK0_RDATA6_REG, EFUSE_RD_ABS_DONE_0); + return REG_READ(EFUSE_BLK0_RDATA6_REG) & EFUSE_RD_ABS_DONE_0; } diff --git a/components/bootloader_support/src/secure_boot.c b/components/bootloader_support/src/secure_boot.c index c17aebfbea..2cfe505492 100644 --- a/components/bootloader_support/src/secure_boot.c +++ b/components/bootloader_support/src/secure_boot.c @@ -110,12 +110,16 @@ static bool secure_boot_generate(uint32_t image_len){ /* Burn values written to the efuse write registers */ static inline void burn_efuses() { +#ifdef CONFIG_SECURE_BOOT_TEST_MODE + ESP_LOGE(TAG, "SECURE BOOT TEST MODE. Not really burning any efuses!"); +#else REG_WRITE(EFUSE_CONF_REG, 0x5A5A); /* efuse_pgm_op_ena, force no rd/wr disable */ REG_WRITE(EFUSE_CMD_REG, 0x02); /* efuse_pgm_cmd */ while (REG_READ(EFUSE_CMD_REG)); /* wait for efuse_pagm_cmd=0 */ REG_WRITE(EFUSE_CONF_REG, 0x5AA5); /* efuse_read_op_ena, release force */ REG_WRITE(EFUSE_CMD_REG, 0x01); /* efuse_read_cmd */ while (REG_READ(EFUSE_CMD_REG)); /* wait for efuse_read_cmd=0 */ +#endif } esp_err_t esp_secure_boot_permanently_enable(void) { @@ -185,10 +189,22 @@ esp_err_t esp_secure_boot_permanently_enable(void) { return ESP_ERR_INVALID_STATE; } - ESP_LOGI(TAG, "blowing secure boot efuse & disabling JTAG..."); + ESP_LOGI(TAG, "blowing secure boot efuse..."); ESP_LOGD(TAG, "before updating, EFUSE_BLK0_RDATA6 %x", REG_READ(EFUSE_BLK0_RDATA6_REG)); - REG_WRITE(EFUSE_BLK0_WDATA6_REG, - EFUSE_RD_ABS_DONE_0 | EFUSE_RD_DISABLE_JTAG); + + uint32_t new_wdata6 = EFUSE_RD_ABS_DONE_0; + + #ifdef CONFIG_SECURE_BOOT_DISABLE_JTAG + ESP_LOGI(TAG, "disabling JTAG..."); + new_wdata6 |= EFUSE_RD_DISABLE_JTAG; + #endif + + #ifdef CONFIG_SECURE_BOOT_DISABLE_UART_BOOTLOADER + ESP_LOGI(TAG, "disabling UART bootloader..."); + new_wdata6 |= EFUSE_RD_CONSOLE_DEBUG_DISABLE_S; + #endif + + REG_WRITE(EFUSE_BLK0_WDATA6_REG, new_wdata6); burn_efuses(); uint32_t after = REG_READ(EFUSE_BLK0_RDATA6_REG); ESP_LOGD(TAG, "after updating, EFUSE_BLK0_RDATA6 %x", after); @@ -196,7 +212,11 @@ esp_err_t esp_secure_boot_permanently_enable(void) { ESP_LOGI(TAG, "secure boot is now enabled for bootloader image"); return ESP_OK; } else { +#ifdef CONFIG_SECURE_BOOT_TEST_MODE + ESP_LOGE(TAG, "secure boot not enabled due to test mode"); +#else ESP_LOGE(TAG, "secure boot not enabled for bootloader image, EFUSE_RD_ABS_DONE_0 is probably write protected!"); +#endif return ESP_ERR_INVALID_STATE; } } From e459f803da9cc3bd6640c9d56215ebeb63c27946 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Mon, 7 Nov 2016 15:45:57 +1100 Subject: [PATCH 328/343] secure boot: Functional partition table & app signature verification --- .../bootloader/src/main/bootloader_start.c | 54 ++++++++++--------- .../include/esp_image_format.h | 2 +- .../include/esp_secure_boot.h | 4 +- .../include_priv/bootloader_flash.h | 8 +-- .../bootloader_support/src/bootloader_flash.c | 6 +-- .../bootloader_support/src/esp_image_format.c | 4 +- .../bootloader_support/src/secure_boot.c | 2 +- .../src/secure_boot_signatures.c | 30 +++++++---- components/esptool_py/Makefile.projbuild | 17 +++--- components/esptool_py/esptool | 2 +- components/partition_table/Makefile.projbuild | 15 ++++-- components/partition_table/gen_esp32part.py | 9 ++-- docs/security/secure-boot.rst | 39 ++++++++------ make/common.mk | 3 +- 14 files changed, 116 insertions(+), 79 deletions(-) diff --git a/components/bootloader/src/main/bootloader_start.c b/components/bootloader/src/main/bootloader_start.c index 6c23257be5..36d3ff0d29 100644 --- a/components/bootloader/src/main/bootloader_start.c +++ b/components/bootloader/src/main/bootloader_start.c @@ -104,35 +104,38 @@ void IRAM_ATTR call_start_cpu0() * OTA info sector, factory app sector, and test app sector. * * @inputs: bs bootloader state structure used to save the data - * addr address of partition table in flash * @return: return true, if the partition table is loaded (and MD5 checksum is valid) * */ -bool load_partition_table(bootloader_state_t* bs, uint32_t addr) +bool load_partition_table(bootloader_state_t* bs) { esp_err_t err; const esp_partition_info_t *partitions; - const int PARTITION_TABLE_SIZE = 0x1000; - const int MAX_PARTITIONS = PARTITION_TABLE_SIZE / sizeof(esp_partition_info_t); + const int ESP_PARTITION_TABLE_DATA_LEN = 0xC00; /* length of actual data (signature is appended to this) */ + const int MAX_PARTITIONS = ESP_PARTITION_TABLE_DATA_LEN / sizeof(esp_partition_info_t); char *partition_usage; ESP_LOGI(TAG, "Partition Table:"); ESP_LOGI(TAG, "## Label Usage Type ST Offset Length"); +#ifdef CONFIG_SECURE_BOOTLOADER_ENABLED if(esp_secure_boot_enabled()) { - err = esp_secure_boot_verify_signature(addr, 0x1000); + ESP_LOGI(TAG, "Verifying partition table signature..."); + err = esp_secure_boot_verify_signature(ESP_PARTITION_TABLE_ADDR, ESP_PARTITION_TABLE_DATA_LEN); if (err != ESP_OK) { ESP_LOGE(TAG, "Failed to verify partition table signature."); return false; } + ESP_LOGD(TAG, "Partition table signature verified"); } +#endif - partitions = bootloader_mmap(addr, 0x1000); + partitions = bootloader_mmap(ESP_PARTITION_TABLE_ADDR, ESP_PARTITION_TABLE_DATA_LEN); if (!partitions) { - ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", addr, 0x1000); + ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", ESP_PARTITION_TABLE_ADDR, ESP_PARTITION_TABLE_DATA_LEN); return false; } - ESP_LOGD(TAG, "mapped partition table 0x%x at 0x%x", addr, (intptr_t)partitions); + ESP_LOGD(TAG, "mapped partition table 0x%x at 0x%x", ESP_PARTITION_TABLE_ADDR, (intptr_t)partitions); for(int i = 0; i < MAX_PARTITIONS; i++) { const esp_partition_info_t *partition = &partitions[i]; @@ -197,7 +200,7 @@ bool load_partition_table(bootloader_state_t* bs, uint32_t addr) partition->pos.offset, partition->pos.size); } - bootloader_unmap(partitions); + bootloader_munmap(partitions); ESP_LOGI(TAG,"End of partition table"); return true; @@ -248,7 +251,7 @@ void bootloader_main() update_flash_config(&fhdr); - if (!load_partition_table(&bs, ESP_PARTITION_TABLE_ADDR)) { + if (!load_partition_table(&bs)) { ESP_LOGE(TAG, "load partition table error!"); return; } @@ -268,7 +271,7 @@ void bootloader_main() } sa = ota_select_map[0]; sb = ota_select_map[1]; - bootloader_unmap(ota_select_map); + bootloader_munmap(ota_select_map); if(sa.ota_seq == 0xFFFFFFFF && sb.ota_seq == 0xFFFFFFFF) { // init status flash @@ -336,7 +339,7 @@ void bootloader_main() } } - // copy sections to RAM, set up caches, and start application + // copy loaded segments to RAM, set up caches for mapped segments, and start application unpack_load_app(&load_part_pos); } @@ -347,14 +350,15 @@ static void unpack_load_app(const esp_partition_pos_t* partition) esp_image_header_t image_header; uint32_t image_length; - if (esp_secure_boot_enabled()) { - /* TODO: verify the app image as part of OTA boot decision, so can have fallbacks */ - err = esp_image_basic_verify(partition->offset, &image_length); - if (err != ESP_OK) { - ESP_LOGE(TAG, "Failed to verify app image @ 0x%x (%d)", partition->offset, err); - return; - } + /* TODO: verify the app image as part of OTA boot decision, so can have fallbacks */ + err = esp_image_basic_verify(partition->offset, &image_length); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to verify app image @ 0x%x (%d)", partition->offset, err); + return; + } + #ifdef CONFIG_SECURE_BOOTLOADER_ENABLED + if (esp_secure_boot_enabled()) { ESP_LOGI(TAG, "Verifying app signature @ 0x%x (length 0x%x)", partition->offset, image_length); err = esp_secure_boot_verify_signature(partition->offset, image_length); if (err != ESP_OK) { @@ -377,7 +381,7 @@ static void unpack_load_app(const esp_partition_pos_t* partition) uint32_t irom_load_addr = 0; uint32_t irom_size = 0; - /* Reload the RTC memory sections whenever a non-deepsleep reset + /* Reload the RTC memory segments whenever a non-deepsleep reset is occurring */ bool load_rtc_memory = rtc_get_reset_reason(0) != DEEPSLEEP_RESET; @@ -409,7 +413,7 @@ static void unpack_load_app(const esp_partition_pos_t* partition) } if (address >= DROM_LOW && address < DROM_HIGH) { - ESP_LOGD(TAG, "found drom section, map from %08x to %08x", data_offs, + ESP_LOGD(TAG, "found drom segment, map from %08x to %08x", data_offs, segment_header.load_addr); drom_addr = data_offs; drom_load_addr = segment_header.load_addr; @@ -419,7 +423,7 @@ static void unpack_load_app(const esp_partition_pos_t* partition) } if (address >= IROM_LOW && address < IROM_HIGH) { - ESP_LOGD(TAG, "found irom section, map from %08x to %08x", data_offs, + ESP_LOGD(TAG, "found irom segment, map from %08x to %08x", data_offs, segment_header.load_addr); irom_addr = data_offs; irom_load_addr = segment_header.load_addr; @@ -429,12 +433,12 @@ static void unpack_load_app(const esp_partition_pos_t* partition) } if (!load_rtc_memory && address >= RTC_IRAM_LOW && address < RTC_IRAM_HIGH) { - ESP_LOGD(TAG, "Skipping RTC code section at %08x\n", data_offs); + ESP_LOGD(TAG, "Skipping RTC code segment at %08x\n", data_offs); load = false; } if (!load_rtc_memory && address >= RTC_DATA_LOW && address < RTC_DATA_HIGH) { - ESP_LOGD(TAG, "Skipping RTC data section at %08x\n", data_offs); + ESP_LOGD(TAG, "Skipping RTC data segment at %08x\n", data_offs); load = false; } @@ -449,7 +453,7 @@ static void unpack_load_app(const esp_partition_pos_t* partition) return; } memcpy((void *)segment_header.load_addr, data, segment_header.data_len); - bootloader_unmap(data); + bootloader_munmap(data); } } diff --git a/components/bootloader_support/include/esp_image_format.h b/components/bootloader_support/include/esp_image_format.h index 326ff130d5..a32a50a4a5 100644 --- a/components/bootloader_support/include/esp_image_format.h +++ b/components/bootloader_support/include/esp_image_format.h @@ -107,7 +107,7 @@ esp_err_t esp_image_load_segment_header(uint8_t index, uint32_t src_addr, const * * Image validation checks: * - Magic byte - * - No single section longer than 16MB + * - No single segment longer than 16MB * - Total image no longer than 16MB * - 8 bit image checksum is valid * diff --git a/components/bootloader_support/include/esp_secure_boot.h b/components/bootloader_support/include/esp_secure_boot.h index eaa1048628..f9fc57708d 100644 --- a/components/bootloader_support/include/esp_secure_boot.h +++ b/components/bootloader_support/include/esp_secure_boot.h @@ -60,7 +60,9 @@ static inline bool esp_secure_boot_enabled(void) { */ esp_err_t esp_secure_boot_permanently_enable(void); -/** @brief Verify the signature appended to some binary data in flash. +/** @brief Verify the secure boot signature (determinstic ECDSA w/ SHA256) appended to some binary data in flash. + * + * Public key is compiled into the calling program. See docs/security/secure-boot.rst for details. * * @param src_addr Starting offset of the data in flash. * @param length Length of data in bytes. Signature is appended -after- length bytes. diff --git a/components/bootloader_support/include_priv/bootloader_flash.h b/components/bootloader_support/include_priv/bootloader_flash.h index d70ec22d56..769c47b904 100644 --- a/components/bootloader_support/include_priv/bootloader_flash.h +++ b/components/bootloader_support/include_priv/bootloader_flash.h @@ -29,11 +29,11 @@ /** * @brief Map a region of flash to data memory * - * @important In bootloader code, only one region can be bootloader_mmaped at once. The previous region must be bootloader_unmapped before another region is mapped. + * @important In bootloader code, only one region can be bootloader_mmaped at once. The previous region must be bootloader_munmapped before another region is mapped. * * @important In app code, these functions are not thread safe. * - * Call bootloader_unmap once for each successful call to bootloader_mmap. + * Call bootloader_munmap once for each successful call to bootloader_mmap. * * In esp-idf app, this function maps directly to spi_flash_mmap. * @@ -49,9 +49,9 @@ const void *bootloader_mmap(uint32_t src_addr, uint32_t size); /** * @brief Unmap a previously mapped region of flash * - * Call bootloader_unmap once for each successful call to bootloader_mmap. + * Call bootloader_munmap once for each successful call to bootloader_mmap. */ -void bootloader_unmap(const void *mapping); +void bootloader_munmap(const void *mapping); /** * @brief Read data from Flash. diff --git a/components/bootloader_support/src/bootloader_flash.c b/components/bootloader_support/src/bootloader_flash.c index fcaf24ad2c..3fd107dea8 100644 --- a/components/bootloader_support/src/bootloader_flash.c +++ b/components/bootloader_support/src/bootloader_flash.c @@ -38,7 +38,7 @@ const void *bootloader_mmap(uint32_t src_addr, uint32_t size) return result; } -void bootloader_unmap(const void *mapping) +void bootloader_munmap(const void *mapping) { if(mapping && map) { spi_flash_munmap(map); @@ -68,7 +68,7 @@ const void *bootloader_mmap(uint32_t src_addr, uint32_t size) } uint32_t src_addr_aligned = src_addr & 0xffff0000; - uint32_t count = (size + 0xffff) / 0x10000; + uint32_t count = (size + (src_addr - src_addr_aligned) + 0xffff) / 0x10000; Cache_Read_Disable(0); Cache_Flush(0); ESP_LOGD(TAG, "mmu set paddr=%08x count=%d", src_addr_aligned, count ); @@ -80,7 +80,7 @@ const void *bootloader_mmap(uint32_t src_addr, uint32_t size) return (void *)(0x3f400000 + (src_addr - src_addr_aligned)); } -void bootloader_unmap(const void *mapping) +void bootloader_munmap(const void *mapping) { if (mapped) { /* Full MMU reset */ diff --git a/components/bootloader_support/src/esp_image_format.c b/components/bootloader_support/src/esp_image_format.c index 3e7dcafa9e..42a3e4ffe2 100644 --- a/components/bootloader_support/src/esp_image_format.c +++ b/components/bootloader_support/src/esp_image_format.c @@ -70,8 +70,8 @@ esp_err_t esp_image_load_segment_header(uint8_t index, uint32_t src_addr, const ESP_LOGE(TAG, "invalid segment length 0x%x", segment_header->data_len); err = ESP_ERR_IMAGE_INVALID; } - ESP_LOGV(TAG, "segment data length 0x%x", segment_header->data_len); next_addr += sizeof(esp_image_segment_header_t); + ESP_LOGV(TAG, "segment data length 0x%x data starts 0x%x", segment_header->data_len, next_addr); *segment_data_offset = next_addr; next_addr += segment_header->data_len; } @@ -124,7 +124,7 @@ esp_err_t esp_image_basic_verify(uint32_t src_addr, uint32_t *p_length) for(int i = 0; i < segment_header.data_len; i++) { checksum ^= segment_data[i]; } - bootloader_unmap(segment_data); + bootloader_munmap(segment_data); } /* End of image, verify checksum */ diff --git a/components/bootloader_support/src/secure_boot.c b/components/bootloader_support/src/secure_boot.c index 2cfe505492..d908d39c38 100644 --- a/components/bootloader_support/src/secure_boot.c +++ b/components/bootloader_support/src/secure_boot.c @@ -90,7 +90,7 @@ static bool secure_boot_generate(uint32_t image_len){ for (int i = 0; i < image_len; i+= HASH_BLOCK_SIZE) { ets_secure_boot_hash(image + i/sizeof(void *)); } - bootloader_unmap(image); + bootloader_munmap(image); ets_secure_boot_obtain(); ets_secure_boot_rd_abstract(buf); diff --git a/components/bootloader_support/src/secure_boot_signatures.c b/components/bootloader_support/src/secure_boot_signatures.c index 5f02de38b0..5106eb396f 100644 --- a/components/bootloader_support/src/secure_boot_signatures.c +++ b/components/bootloader_support/src/secure_boot_signatures.c @@ -43,9 +43,10 @@ extern const uint8_t signature_verification_key_end[] asm("_binary_signature_ver esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length) { sha_context sha; - uint8_t digest[64]; + uint8_t digest[32]; ptrdiff_t keylen; - const uint8_t *data; + const uint8_t *data, *digest_data; + uint32_t digest_len, chunk_len; const signature_block_t *sigblock; bool is_valid; @@ -68,16 +69,23 @@ esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length) /* Use ROM SHA functions directly */ ets_sha_enable(); ets_sha_init(&sha); - ets_sha_update(&sha, SHA2_512, data, length); - ets_sha_finish(&sha, SHA2_512, digest); + digest_len = length * 8; + digest_data = data; + while (digest_len > 0) { + uint32_t chunk_len = (digest_len > 64) ? 64 : digest_len; + ets_sha_update(&sha, SHA2_256, digest_data, chunk_len); + digest_len -= chunk_len; + digest_data += chunk_len / 8; + } + ets_sha_finish(&sha, SHA2_256, digest); ets_sha_disable(); #else /* Use thread-safe esp-idf SHA layer */ - esp_sha512_init(&sha); - esp_sha512_start(&sha, false); - esp_sha512_update(&sha, data, length); - esp_sha512_finish(&sha, digest); - esp_sha512_free(&sha); + esp_sha256_init(&sha); + esp_sha256_start(&sha, false); + esp_sha256_update(&sha, data, length); + esp_sha256_finish(&sha, digest); + esp_sha256_free(&sha); #endif keylen = signature_verification_key_end - signature_verification_key_start; @@ -90,10 +98,10 @@ esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length) digest, sizeof(digest), sigblock->signature, uECC_secp256r1()); - bootloader_unmap(data); + bootloader_munmap(data); return is_valid ? ESP_OK : ESP_ERR_IMAGE_INVALID; unmap_and_fail: - bootloader_unmap(data); + bootloader_munmap(data); return ESP_FAIL; } diff --git a/components/esptool_py/Makefile.projbuild b/components/esptool_py/Makefile.projbuild index 5807512b86..bfbece45e6 100644 --- a/components/esptool_py/Makefile.projbuild +++ b/components/esptool_py/Makefile.projbuild @@ -24,21 +24,24 @@ ESPTOOL_FLASH_OPTIONS := --flash_mode $(ESPFLASHMODE) --flash_freq $(ESPFLASHFRE ESPTOOL_ELF2IMAGE_OPTIONS := -ifdef CONFIG_SECURE_BOOTLOADER_ENABLED -ESPTOOL_ELF2IMAGE_OPTIONS += "--set-secure-boot-flag" -endif - ESPTOOLPY_WRITE_FLASH=$(ESPTOOLPY_SERIAL) write_flash $(if $(CONFIG_ESPTOOLPY_COMPRESSED),-z) $(ESPTOOL_FLASH_OPTIONS) ESPTOOL_ALL_FLASH_ARGS += $(CONFIG_APP_OFFSET) $(APP_BIN) -$(APP_BIN): $(APP_ELF) $(ESPTOOLPY_SRC) - $(Q) $(ESPTOOLPY) elf2image $(ESPTOOL_FLASH_OPTIONS) $(ESPTOOL_ELF2IMAGE_OPTIONS) -o $@ $< ifdef CONFIG_SECURE_BOOTLOADER_ENABLED ifndef IS_BOOTLOADER_BUILD - $(Q) $(ESPSECUREPY) sign_data --keyfile $(SECURE_BOOT_SIGNING_KEY) $@ # signed in-place +# for secure boot, add a signing step to get from unsiged app to signed app +APP_BIN_UNSIGNED := $(APP_BIN:.bin=-unsigned.bin) + +$(APP_BIN): $(APP_BIN_UNSIGNED) + $(Q) $(ESPSECUREPY) sign_data --keyfile $(SECURE_BOOT_SIGNING_KEY) -o $@ $^ # signed in-place endif endif +# non-secure boot (or bootloader), both these files are the same +APP_BIN_UNSIGNED ?= $(APP_BIN) + +$(APP_BIN_UNSIGNED): $(APP_ELF) $(ESPTOOLPY_SRC) + $(Q) $(ESPTOOLPY) elf2image $(ESPTOOL_FLASH_OPTIONS) $(ESPTOOL_ELF2IMAGE_OPTIONS) -o $@ $< flash: all_binaries $(ESPTOOLPY_SRC) @echo "Flashing binaries to serial port $(ESPPORT) (app at offset $(CONFIG_APP_OFFSET))..." diff --git a/components/esptool_py/esptool b/components/esptool_py/esptool index 98e5dbfa78..d8b1ffdd50 160000 --- a/components/esptool_py/esptool +++ b/components/esptool_py/esptool @@ -1 +1 @@ -Subproject commit 98e5dbfa78fa53cebcb4c56530e683f889bf21c3 +Subproject commit d8b1ffdd500bd80a35fb66b64e2733195b39e519 diff --git a/components/partition_table/Makefile.projbuild b/components/partition_table/Makefile.projbuild index 4273f53c3a..f8b822ef2c 100644 --- a/components/partition_table/Makefile.projbuild +++ b/components/partition_table/Makefile.projbuild @@ -20,12 +20,19 @@ PARTITION_TABLE_CSV_PATH := $(call dequote,$(abspath $(PARTITION_TABLE_ROOT)/$(s PARTITION_TABLE_BIN := $(BUILD_DIR_BASE)/$(notdir $(PARTITION_TABLE_CSV_PATH:.csv=.bin)) -$(PARTITION_TABLE_BIN): $(PARTITION_TABLE_CSV_PATH) +ifdef CONFIG_SECURE_BOOTLOADER_ENABLED +PARTITION_TABLE_BIN_UNSIGNED := $(PARTITION_TABLE_BIN:.bin=-unsigned.bin) +# add an extra signing step for secure partition table +$(PARTITION_TABLE_BIN): $(PARTITION_TABLE_BIN_UNSIGNED) + $(Q) $(ESPSECUREPY) sign_data --keyfile $(SECURE_BOOT_SIGNING_KEY) -o $@ $< +else +# secure bootloader disabled, both files are the same +PARTITION_TABLE_BIN_UNSIGNED := $(PARTITION_TABLE_BIN) +endif + +$(PARTITION_TABLE_BIN_UNSIGNED): $(PARTITION_TABLE_CSV_PATH) $(SDKCONFIG_MAKEFILE) @echo "Building partitions from $(PARTITION_TABLE_CSV_PATH)..." $(Q) $(GEN_ESP32PART) $< $@ -ifdef CONFIG_SECURE_BOOTLOADER_ENABLED - $(Q) $(ESPSECUREPY) sign_data --keyfile $(SECURE_BOOT_SIGNING_KEY) $@ # signed in-place -endif all_binaries: $(PARTITION_TABLE_BIN) diff --git a/components/partition_table/gen_esp32part.py b/components/partition_table/gen_esp32part.py index b399f31b78..cb6a5f24a1 100755 --- a/components/partition_table/gen_esp32part.py +++ b/components/partition_table/gen_esp32part.py @@ -86,11 +86,14 @@ class PartitionTable(list): @classmethod def from_binary(cls, b): - if len(b) % 32 != 0: - raise InputError("Partition table length must be a multiple of 32 bytes. Got %d bytes." % len(b)) result = cls() for o in range(0,len(b),32): - result.append(PartitionDefinition.from_binary(b[o:o+32])) + data = b[o:o+32] + if len(data) != 32: + raise InputError("Ran out of partition table data before reaching end marker") + if data == '\xFF'*32: + break # end of partition table + result.append(PartitionDefinition.from_binary(data)) return result def to_binary(self): diff --git a/docs/security/secure-boot.rst b/docs/security/secure-boot.rst index 169f2d56bc..9a22aeca97 100644 --- a/docs/security/secure-boot.rst +++ b/docs/security/secure-boot.rst @@ -19,28 +19,28 @@ Secure Boot Process Overview This is a high level overview of the secure boot process. Step by step instructions are supplied under `How To Enable Secure Boot`. Further in-depth details are supplied under `Technical Details`: -1. The options to enable secure boot are provided in the ``make menuconfig`` hierarchy, under "Bootloader Config". +1. The options to enable secure boot are provided in the ``make menuconfig`` hierarchy, under "Secure Boot Configuration". 2. Bootloader Config includes the path to a secure boot signing key. This is a ECDSA public/private key pair in a PEM format file. -2. The software bootloader image is built by esp-idf with the public key (signature verification) portion of the secure boot signing key compiled in, and with a secure boot flag set in its header. This software bootloader image is flashed at offset 0x1000. +2. The software bootloader image is built by esp-idf with secure boot support enabled and the public key (signature verification) portion of the secure boot signing key compiled in. This software bootloader image is flashed at offset 0x1000. -3. On first boot, the software bootloader tests the secure boot flag. If it is set, the following process is followed to enable secure boot: +3. On first boot, the software bootloader follows the following process to enable secure boot: - Hardware secure boot support generates a device secure bootloader key (generated via hardware RNG, then stored read/write protected in efuse), and a secure digest. The digest is derived from the key, an IV, and the bootloader image contents. - The secure digest is flashed at offset 0x0 in the flash. - Bootloader permanently enables secure boot by burning the ABS_DONE_0 efuse. The software bootloader then becomes protected (the chip will only boot a bootloader image if the digest matches.) - - Bootloader also disables JTAG via efuse. + - Depending on menuconfig choices, the bootloader may also disable JTAG and the UART bootloader function, both via efuse. (This is recommended.) 4. On subsequent boots the ROM bootloader sees that the secure boot efuse is burned, reads the saved digest at 0x0 and uses hardware secure boot support to compare it with a newly calculated digest. If the digest does not match then booting will not continue. The digest and comparison are performed entirely by hardware, for technical details see `Hardware Secure Boot Support`. -5. When running in secure boot mode, the software bootloader uses the secure boot signing key's public key (embedded in the bootloader itself, and therefore validated as part of the bootloader digest) to verify all subsequent partition tables and app images before they are booted. +5. When running in secure boot mode, the software bootloader uses the secure boot signing key (the public key of which is embedded in the bootloader itself, and therefore validated as part of the bootloader) to verify all subsequent partition tables and app images before they are booted. Keys ---- The following keys are used by the secure boot process: -- "secure bootloader key" is a 256-bit AES key that is stored in Efuse block 2. The bootloader can generate this key itself from a hardware random number generation, the user does not need to supply it (it is optionally possible to supply this key, see `Re-Flashable Software Bootloader`). The Efuse holding this key is read & write protected (preventing software access) before secure boot is enabled. +- "secure bootloader key" is a 256-bit AES key that is stored in Efuse block 2. The bootloader can generate this key itself from the internal hardware random number generator, the user does not need to supply it (it is optionally possible to supply this key, see `Re-Flashable Software Bootloader`). The Efuse holding this key is read & write protected (preventing software access) before secure boot is enabled. - "secure boot signing key" is a standard ECDSA public/private key pair (NIST256p aka prime256v1 curve) in PEM format. @@ -52,15 +52,15 @@ The following keys are used by the secure boot process: How To Enable Secure Boot ------------------------- -1. Run ``make menuconfig``, navigate to "Bootloader Config" -> "Secure Boot" and select the option "One-time Flash". (To understand the alternative "Reflashable" choice, see `Re-Flashable Software Bootloader`.) +1. Run ``make menuconfig``, navigate to "Secure Boot Configuration" and select the option "One-time Flash". (To understand the alternative "Reflashable" choice, see `Re-Flashable Software Bootloader`.) 2. Select a name for the secure boot signing key. This option will appear after secure boot is enabled. The file can be anywhere on your system. A relative path will be evaluated from the project directory. The file does not need to exist yet. -3. Set other config options (as desired). Pay particular attention to the "Bootloader Config" options, as you can only flash the bootloader once. Then exit menuconfig and save your configuration +3. Set other menuconfig options (as desired). Pay particular attention to the "Bootloader Config" options, as you can only flash the bootloader once. Then exit menuconfig and save your configuration 4. The first time you run ``make``, if the signing key is not found then an error message will be printed with a command to generate a signing key via ``espsecure.py generate_signing_key``. - **IMPORTANT** A signing key genereated this way will use the best random number source available to the OS and its Python installation (`/dev/urandom` on OSX/Linux and `CryptGenRandom()` on Windows). If this random number source is weak, then the private key will be weak. + **IMPORTANT** A signing key generated this way will use the best random number source available to the OS and its Python installation (`/dev/urandom` on OSX/Linux and `CryptGenRandom()` on Windows). If this random number source is weak, then the private key will be weak. **IMPORTANT** For production environments, we recommend generating the keypair using openssl or another industry standard encryption program. See `Generating Secure Boot Signing Key` for more details. @@ -76,16 +76,16 @@ How To Enable Secure Boot *NOTE* Secure boot won't be enabled until after a valid partition table and app image have been flashed. This is to prevent accidents before the system is fully configured. -9. On subsequent boots, the secure boot hardware will verify the software bootloader (using the secure bootloader key) and then the software bootloader will verify the partition table and app image (using the signing key). +9. On subsequent boots, the secure boot hardware will verify the software bootloader (using the secure bootloader key) and then the software bootloader will verify the partition table and app image (using the public key portion of the secure boot signing key). Re-Flashable Software Bootloader -------------------------------- -The "Secure Boot: One-Time Flash" is the recommended software bootloader configuration for production devices. In this mode, each device gets a unique key that is never stored outside the device. +Configuration "Secure Boot: One-Time Flash" is the recommended configuration for production devices. In this mode, each device gets a unique key that is never stored outside the device. However, an alternative mode "Secure Boot: Reflashable" is also available. This mode allows you to supply a 256-bit key file that is used for the secure bootloader key. As you have the key file, you can generate new bootloader images and secure boot digests for them. -In the esp-idf build process, this 256-bit key file is derived from the app signing key generated during the generate_signing_key step above. The private key's SHA-256 value is used to generate an 256-bit value which is then burned to efuse and used to protect the bootloader. This is a convenience so you only need to generate/protect a single private key. +In the esp-idf build process, this 256-bit key file is derived from the app signing key generated during the generate_signing_key step above. The private key's SHA-256 digest is used as the 256-bit secure bootloader key. This is a convenience so you only need to generate/protect a single private key. *NOTE*: Although it's possible, we strongly recommend not generating one secure boot key and flashing it to every device in a production environment. The "One-Time Flash" option is recommended for production environments. @@ -95,7 +95,7 @@ To enable a reflashable bootloader: 2. Follow the steps shown above to choose a signing key file, and generate the key file. -3. Run ``make bootloader``. A 256-bit key file will be created, derived from the private key you generated for signing. Two sets of flashing steps will be printed - the first set of steps includes an ``espefuse.py burn_key`` command which is used to write the derived key to efuse. (Flashing this key is a one-time-only process.) The second set of steps can be used to reflash the bootloader with a pre-generated digest (generated during the build process, using the derived key). +3. Run ``make bootloader``. A 256-bit key file will be created, derived from the private key that is used for signing. Two sets of flashing steps will be printed - the first set of steps includes an ``espefuse.py burn_key`` command which is used to write the bootloader key to efuse. (Flashing this key is a one-time-only process.) The second set of steps can be used to reflash the bootloader with a pre-calculated digest (generated during the build process). 4. Resume from `Step 6` of the one-time process, to flash the bootloader and enable secure boot. Watch the console log output closely to ensure there were no errors in the secure boot configuration. @@ -114,6 +114,13 @@ openssl ecparam -name prime256v1 -genkey -noout -out my_secure_boot_signing_key. Remember that the strength of the secure boot system depends on keeping the signing key private. +Secure Boot Best Practices +-------------------------- + +* Generate the signing key on a system with a quality source of entropy. +* Keep the signing key private at all times. A leak of this key will compromise the secure boot system. +* Do not allow any third party to observe any aspects of the key generation or signing process using espsecure.py. Both processes are vulnerable to timing or other side-channel attacks. +* Enable all secure boot options. These include flash encryption, disabling of JTAG, and disabling alternative boot modes. Technical Details ----------------- @@ -143,9 +150,9 @@ Items marked with (^) are to fulfill hardware restrictions, as opposed to crypto 1. Prefix the image with a 128 byte randomly generated IV. 2. If the image is not modulo 128, pad the image to a 128 byte boundary with 0xFF. (^) 3. For each 16 byte plaintext block of the input image: - - Reverse the byte order of the plaintext block (^) + - Reverse the byte order of the plaintext input block (^) - Apply AES256 in ECB mode to the plaintext block. - - Reverse the byte order of the 16 bytes of ciphertext output. (^) + - Reverse the byte order of the ciphertext output block. (^) - Append to the overall ciphertext output. 4. Byte-swap each 4 byte word of the ciphertext (^) 5. Calculate SHA-512 of the ciphertext. @@ -158,10 +165,12 @@ Image Signing Algorithm Deterministic ECDSA as specified by `RFC6979`. - Curve is NIST256p (openssl calls this curve "prime256v1", it is also sometimes called secp256r1). +- Hash function is SHA256. - Key format used for storage is PEM. - In the bootloader, the public key (for signature verification) is flashed as 64 raw bytes. - Image signature is 68 bytes - a 4 byte version word (currently zero), followed by a 64 bytes of signature data. These 68 bytes are appended to an app image or partition table data. + .. _esp-idf boot process: ../boot-process.rst .. _RFC6979: https://tools.ietf.org/html/rfc6979 diff --git a/make/common.mk b/make/common.mk index 0c523c8775..bec8151b55 100644 --- a/make/common.mk +++ b/make/common.mk @@ -6,7 +6,8 @@ # # (Note that we only rebuild auto.conf automatically for some targets, # see project_config.mk for details.) --include $(BUILD_DIR_BASE)/include/config/auto.conf +SDKCONFIG_MAKEFILE := $(BUILD_DIR_BASE)/include/config/auto.conf +-include $(SDKCONFIG_MAKEFILE) #Handling of V=1/VERBOSE=1 flag # From 5a5e19cd8b5b1ea09adce8ae73e62e400b09b65a Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 9 Nov 2016 11:55:09 +1100 Subject: [PATCH 329/343] Bump esptool revision (espefuse.py fixes) --- components/esptool_py/esptool | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esptool_py/esptool b/components/esptool_py/esptool index d8b1ffdd50..b1e00025fa 160000 --- a/components/esptool_py/esptool +++ b/components/esptool_py/esptool @@ -1 +1 @@ -Subproject commit d8b1ffdd500bd80a35fb66b64e2733195b39e519 +Subproject commit b1e00025fa6cbc63062b205259ee70d91bfe4989 From bcdebda8e47961751d35031272350f6a33a004b4 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Fri, 11 Nov 2016 14:44:10 +1100 Subject: [PATCH 330/343] Build system: Don't shell-quote SEPARATOR variable or it evaluates as a bunch of wildcards! --- components/bootloader/Makefile.projbuild | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bootloader/Makefile.projbuild b/components/bootloader/Makefile.projbuild index 1b1c07bea3..3ed5e18783 100644 --- a/components/bootloader/Makefile.projbuild +++ b/components/bootloader/Makefile.projbuild @@ -37,7 +37,7 @@ ifdef CONFIG_SECURE_BOOTLOADER_DISABLED # with 'make flash' and no warnings are printed. bootloader: $(BOOTLOADER_BIN) - @echo "$(SEPARATOR)" + @echo $(SEPARATOR) @echo "Bootloader built. Default flash command is:" @echo "$(ESPTOOLPY_WRITE_FLASH) 0x1000 $(BOOTLOADER_BIN)" From 8691b54758102275b7e635bdaa52c2fafe8b4334 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Fri, 11 Nov 2016 15:14:13 +1100 Subject: [PATCH 331/343] secure boot: Rename efuse option for UART bootloader to option for ROM interpreter --- components/bootloader/Kconfig.projbuild | 38 +++++++++---------- .../src/secure_boot_signatures.c | 2 +- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/components/bootloader/Kconfig.projbuild b/components/bootloader/Kconfig.projbuild index 949638594d..50165d0e58 100644 --- a/components/bootloader/Kconfig.projbuild +++ b/components/bootloader/Kconfig.projbuild @@ -85,31 +85,31 @@ config SECURE_BOOT_SIGNING_KEY See docs/security/secure-boot.rst for details. config SECURE_BOOT_DISABLE_JTAG - bool "First boot: Permanently disable JTAG" - depends on SECURE_BOOTLOADER_ENABLED - default Y - help - Bootloader permanently disable JTAG (across entire chip) when enabling secure boot. This happens on first boot of the bootloader. + bool "First boot: Permanently disable JTAG" + depends on SECURE_BOOTLOADER_ENABLED + default Y + help + Bootloader permanently disable JTAG (across entire chip) when enabling secure boot. This happens on first boot of the bootloader. - It is recommended this option remains set for production environments. + It is recommended this option remains set for production environments. -config SECURE_BOOT_DISABLE_UART_BOOTLOADER - bool "First boot: Permanently disable UART bootloader" - depends on SECURE_BOOTLOADER_ENABLED - default Y - help - Bootloader permanently disables UART and other bootloader modes when enabling secure boot. This happens on first boot. +config SECURE_BOOT_DISABLE_ROM_BASIC + bool "First boot: Permanently disable ROM BASIC fallback" + depends on SECURE_BOOTLOADER_ENABLED + default Y + help + Bootloader permanently disables ROM BASIC (on UART console) as a fallback if the bootloader image becomes invalid. This happens on first boot. - It is recommended this option remains set for production environments. + It is recommended this option remains set in production environments. config SECURE_BOOT_TEST_MODE - bool "Test mode: don't actually enable secure boot" - depends on SECURE_BOOTLOADER_ENABLED - default N - help - If this option is set, all permanent secure boot changes (via Efuse) are disabled. + bool "Test mode: don't actually enable secure boot" + depends on SECURE_BOOTLOADER_ENABLED + default N + help + If this option is set, all permanent secure boot changes (via Efuse) are disabled. - This option is for testing purposes only - it effectively completely disables secure boot protection. + This option is for testing purposes only - it effectively completely disables secure boot protection. config SECURE_BOOTLOADER_ENABLED bool diff --git a/components/bootloader_support/src/secure_boot_signatures.c b/components/bootloader_support/src/secure_boot_signatures.c index 5106eb396f..6d47651b2f 100644 --- a/components/bootloader_support/src/secure_boot_signatures.c +++ b/components/bootloader_support/src/secure_boot_signatures.c @@ -46,7 +46,7 @@ esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length) uint8_t digest[32]; ptrdiff_t keylen; const uint8_t *data, *digest_data; - uint32_t digest_len, chunk_len; + uint32_t digest_len; const signature_block_t *sigblock; bool is_valid; From 045a53a7e5aeb1263ee24671473e3a705d9df6e3 Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Mon, 14 Nov 2016 10:20:49 +0800 Subject: [PATCH 332/343] Fix wdt idle hook --- components/esp32/task_wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp32/task_wdt.c b/components/esp32/task_wdt.c index f8cfdef26e..549b7f58b2 100644 --- a/components/esp32/task_wdt.c +++ b/components/esp32/task_wdt.c @@ -145,7 +145,7 @@ void esp_task_wdt_delete() { #if CONFIG_TASK_WDT_CHECK_IDLE_TASK static bool idle_hook(void) { #if !CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1 - if (xPortGetCoreID()!=0) return; + if (xPortGetCoreID()!=0) return true; #endif esp_task_wdt_feed(); return true; From 572f62928b9dd6a5036b98893a6a2059c34d9e87 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Fri, 11 Nov 2016 15:40:29 +1100 Subject: [PATCH 333/343] Secure boot: Documentation tweaks --- docs/index.rst | 1 + docs/security/secure-boot.rst | 30 ++++++++++++++++-------------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index c973950615..30cfa177c3 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -34,6 +34,7 @@ Contents: partition-tables build_system openocd + Secure Boot .. toctree:: :caption: API Reference diff --git a/docs/security/secure-boot.rst b/docs/security/secure-boot.rst index 9a22aeca97..c08b17cb47 100644 --- a/docs/security/secure-boot.rst +++ b/docs/security/secure-boot.rst @@ -3,17 +3,20 @@ Secure Boot Secure Boot is a feature for ensuring only your code can run on the chip. Data loaded from flash is verified on each reset. -Secure Boot is separate from the Encrypted Flash feature, and you can use secure boot without encrypting the flash contents. However for maximum protection we recommend using both features together. +Secure Boot is separate from the Encrypted Flash feature, and you can use secure boot without encrypting the flash contents. However we recommend using both features together for a secure environment. + Background ---------- -- Most data is stored in flash. Flash access does not need to be protected from physical access in order for secure boot to function, because critical data is stored in Efuses internal to the chip. +- Most data is stored in flash. Flash access does not need to be protected from physical access in order for secure boot to function, because critical data is stored (non-software-accessible) in Efuses internal to the chip. - Efuses are used to store the secure bootloader key (in efuse block 2), and also a single Efuse bit (ABS_DONE_0) is burned (written to 1) to permanently enable secure boot on the chip. For more details about efuse, see the (forthcoming) chapter in the Technical Reference Manual. - To understand the secure boot process, first familiarise yourself with the standard `esp-idf boot process`. +- Both stages of the boot process (initial software bootloader load, and subsequent partition & app loading) are verified by the secure boot process, in a "chain of trust" relationship. + Secure Boot Process Overview ---------------------------- @@ -21,19 +24,19 @@ This is a high level overview of the secure boot process. Step by step instructi 1. The options to enable secure boot are provided in the ``make menuconfig`` hierarchy, under "Secure Boot Configuration". -2. Bootloader Config includes the path to a secure boot signing key. This is a ECDSA public/private key pair in a PEM format file. +2. Secure Boot Configuration includes "Secure boot signing key", which is a file path. This file is a ECDSA public/private key pair in a PEM format file. 2. The software bootloader image is built by esp-idf with secure boot support enabled and the public key (signature verification) portion of the secure boot signing key compiled in. This software bootloader image is flashed at offset 0x1000. 3. On first boot, the software bootloader follows the following process to enable secure boot: - Hardware secure boot support generates a device secure bootloader key (generated via hardware RNG, then stored read/write protected in efuse), and a secure digest. The digest is derived from the key, an IV, and the bootloader image contents. - The secure digest is flashed at offset 0x0 in the flash. + - Depending on Secure Boot Configuration, efuses are burned to disable JTAG and the ROM BASIC interpreter (it is strongly recommended these options are turned on.) - Bootloader permanently enables secure boot by burning the ABS_DONE_0 efuse. The software bootloader then becomes protected (the chip will only boot a bootloader image if the digest matches.) - - Depending on menuconfig choices, the bootloader may also disable JTAG and the UART bootloader function, both via efuse. (This is recommended.) -4. On subsequent boots the ROM bootloader sees that the secure boot efuse is burned, reads the saved digest at 0x0 and uses hardware secure boot support to compare it with a newly calculated digest. If the digest does not match then booting will not continue. The digest and comparison are performed entirely by hardware, for technical details see `Hardware Secure Boot Support`. +4. On subsequent boots the ROM bootloader sees that the secure boot efuse is burned, reads the saved digest at 0x0 and uses hardware secure boot support to compare it with a newly calculated digest. If the digest does not match then booting will not continue. The digest and comparison are performed entirely by hardware, and the calculated digest is not readable by software. For technical details see `Hardware Secure Boot Support`. -5. When running in secure boot mode, the software bootloader uses the secure boot signing key (the public key of which is embedded in the bootloader itself, and therefore validated as part of the bootloader) to verify all subsequent partition tables and app images before they are booted. +5. When running in secure boot mode, the software bootloader uses the secure boot signing key (the public key of which is embedded in the bootloader itself, and therefore validated as part of the bootloader) to verify the signature appended to all subsequent partition tables and app images before they are booted. Keys ---- @@ -42,11 +45,11 @@ The following keys are used by the secure boot process: - "secure bootloader key" is a 256-bit AES key that is stored in Efuse block 2. The bootloader can generate this key itself from the internal hardware random number generator, the user does not need to supply it (it is optionally possible to supply this key, see `Re-Flashable Software Bootloader`). The Efuse holding this key is read & write protected (preventing software access) before secure boot is enabled. -- "secure boot signing key" is a standard ECDSA public/private key pair (NIST256p aka prime256v1 curve) in PEM format. +- "secure boot signing key" is a standard ECDSA public/private key pair (see `Image Signing Algorithm`) in PEM format. - The public key from this key pair (for signature verificaton but not signature creation) is compiled into the software bootloader and used to verify the second stage of booting (partition table, app image) before booting continues. The public key can be freely distributed, it does not need to be kept secret. - - The private key from this key pair *must be securely kept private*, as anyone who has this key can authenticate to a bootloader with secure boot using the matching public key. + - The private key from this key pair *must be securely kept private*, as anyone who has this key can authenticate to any bootloader that is configured with secure boot and the matching public key. How To Enable Secure Boot @@ -76,7 +79,7 @@ How To Enable Secure Boot *NOTE* Secure boot won't be enabled until after a valid partition table and app image have been flashed. This is to prevent accidents before the system is fully configured. -9. On subsequent boots, the secure boot hardware will verify the software bootloader (using the secure bootloader key) and then the software bootloader will verify the partition table and app image (using the public key portion of the secure boot signing key). +9. On subsequent boots, the secure boot hardware will verify the software bootloader has not changed (using the secure bootloader key) and then the software bootloader will verify the signed partition table and app image (using the public key portion of the secure boot signing key). Re-Flashable Software Bootloader -------------------------------- @@ -120,7 +123,7 @@ Secure Boot Best Practices * Generate the signing key on a system with a quality source of entropy. * Keep the signing key private at all times. A leak of this key will compromise the secure boot system. * Do not allow any third party to observe any aspects of the key generation or signing process using espsecure.py. Both processes are vulnerable to timing or other side-channel attacks. -* Enable all secure boot options. These include flash encryption, disabling of JTAG, and disabling alternative boot modes. +* Enable all secure boot options in the Secure Boot Configuration. These include flash encryption, disabling of JTAG, disabling BASIC ROM interpeter, and disabling the UART bootloader encrypted flash access. Technical Details ----------------- @@ -136,19 +139,19 @@ The Secure Boot support hardware can perform three basic operations: 2. Generate a digest from data (usually the bootloader image from flash) using a key stored in Efuse block 2. The key in Efuse can (& should) be read/write protected, which prevents software access. For full details of this algorithm see `Secure Bootloader Digest Algorithm`. The digest can only be read back by software if Efuse ABS_DONE_0 is *not* burned (ie still 0). -3. Verify a digest from data (usually the bootloader image from flash), and compare it to a pre-existing digest (usually read from flash offset 0x0). The hardware returns a true/false comparison without making the digest available to software. This function is available even when Efuse ABS_DONE_0 is burned. +3. Generate a digest from data (usually the bootloader image from flash) using the same algorithm as step 2 and compare it to a pre-calculated digest supplied in a buffer (usually read from flash offset 0x0). The hardware returns a true/false comparison without making the digest available to software. This function is available even when Efuse ABS_DONE_0 is burned. Secure Bootloader Digest Algorithm ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Starting with an "image" of binary data as input, this algorithm generates a digest as output. +Starting with an "image" of binary data as input, this algorithm generates a digest as output. The digest is sometimes referred to as an "abstract" in hardware documentation. For a Python version of this algorithm, see the `espsecure.py` tool in the components/esptool_py directory. Items marked with (^) are to fulfill hardware restrictions, as opposed to cryptographic restrictions. 1. Prefix the image with a 128 byte randomly generated IV. -2. If the image is not modulo 128, pad the image to a 128 byte boundary with 0xFF. (^) +2. If the image length is not modulo 128, pad the image to a 128 byte boundary with 0xFF. (^) 3. For each 16 byte plaintext block of the input image: - Reverse the byte order of the plaintext input block (^) - Apply AES256 in ECB mode to the plaintext block. @@ -171,6 +174,5 @@ Deterministic ECDSA as specified by `RFC6979`. - Image signature is 68 bytes - a 4 byte version word (currently zero), followed by a 64 bytes of signature data. These 68 bytes are appended to an app image or partition table data. - .. _esp-idf boot process: ../boot-process.rst .. _RFC6979: https://tools.ietf.org/html/rfc6979 From 0b4fe9dd6dc62571abcc66c0235582f00d94d2e5 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Fri, 11 Nov 2016 15:40:58 +1100 Subject: [PATCH 334/343] secure boot: Add warnings this feature is not finished yet --- components/bootloader/Makefile.projbuild | 21 +++++++++++++++++++++ docs/security/secure-boot.rst | 1 + 2 files changed, 22 insertions(+) diff --git a/components/bootloader/Makefile.projbuild b/components/bootloader/Makefile.projbuild index 3ed5e18783..551bceb981 100644 --- a/components/bootloader/Makefile.projbuild +++ b/components/bootloader/Makefile.projbuild @@ -47,6 +47,16 @@ bootloader-flash: $(BOOTLOADER_BIN) $(BOOTLOADER_MAKE) flash else ifdef CONFIG_SECURE_BOOTLOADER_ONE_TIME_FLASH + +#### TEMPORARILY DISABLE THIS OPTION +ifneq ("$(IDF_INSECURE_SECURE_BOOT)","1") +bootloader: + @echo "Secure boot features are not yet mature, so the current secure bootloader will not properly secure the device" + @echo "If you flash this bootloader, you will be left with an non-updateable bootloader that is missing features." + @echo "If you really want to do this, set the environment variable IDF_INSECURE_SECURE_BOOT=1 and rerun make." + exit 1 +else + # One time flashing requires user to run esptool.py command themselves, # and warning is printed about inability to reflash. @@ -57,10 +67,20 @@ bootloader: $(BOOTLOADER_BIN) @echo $(SEPARATOR) @echo "* IMPORTANT: After first boot, BOOTLOADER CANNOT BE RE-FLASHED on same device" +endif # IDF_INSECURE_SECURE_BOOT else ifdef CONFIG_SECURE_BOOTLOADER_REFLASHABLE # Reflashable secure bootloader # generates a digest binary (bootloader + digest) +#### TEMPORARILY DISABLE THIS OPTION +ifneq ("$(IDF_INSECURE_SECURE_BOOT)","1") +bootloader: + @echo "Secure boot features are not yet mature, so the current secure bootloader will not properly secure the device." + @echo "If using this feature, expect to reflash the bootloader at least one more time." + @echo "If you really want to do this, set the environment variable IDF_INSECURE_SECURE_BOOT=1 and rerun make." + exit 1 +else + BOOTLOADER_DIGEST_BIN := $(BOOTLOADER_BUILD_DIR)/bootloader-reflash-digest.bin SECURE_BOOTLOADER_KEY := $(BOOTLOADER_BUILD_DIR)/secure-bootloader-key.bin @@ -83,6 +103,7 @@ $(BOOTLOADER_DIGEST_BIN): $(BOOTLOADER_BIN) $(SECURE_BOOTLOADER_KEY) @echo "DIGEST $(notdir $@)" $(Q) $(ESPSECUREPY) digest_secure_bootloader -k $(SECURE_BOOTLOADER_KEY) -o $@ $< +endif # IDF_INSECURE_SECURE_BOOT else bootloader: @echo "Invalid bootloader target: bad sdkconfig?" diff --git a/docs/security/secure-boot.rst b/docs/security/secure-boot.rst index c08b17cb47..bdc1b71699 100644 --- a/docs/security/secure-boot.rst +++ b/docs/security/secure-boot.rst @@ -5,6 +5,7 @@ Secure Boot is a feature for ensuring only your code can run on the chip. Data l Secure Boot is separate from the Encrypted Flash feature, and you can use secure boot without encrypting the flash contents. However we recommend using both features together for a secure environment. +**IMPORTANT: As Encrypted Flash feature and related security features are not yet released, Secure Boot should not be considered sufficient for a secure device and we strongly recommend not enabling the one-time secure bootloader feature until it is mature.** Background ---------- From 09c7ccfa2cd2c21f14c0c599e25e3bb473dd64eb Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Fri, 11 Nov 2016 15:47:38 +1100 Subject: [PATCH 335/343] bootloader: Fix unused variable errors when secure boot is disabled --- components/bootloader/src/main/bootloader_start.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/components/bootloader/src/main/bootloader_start.c b/components/bootloader/src/main/bootloader_start.c index 36d3ff0d29..a811294a8f 100644 --- a/components/bootloader/src/main/bootloader_start.c +++ b/components/bootloader/src/main/bootloader_start.c @@ -109,7 +109,6 @@ void IRAM_ATTR call_start_cpu0() */ bool load_partition_table(bootloader_state_t* bs) { - esp_err_t err; const esp_partition_info_t *partitions; const int ESP_PARTITION_TABLE_DATA_LEN = 0xC00; /* length of actual data (signature is appended to this) */ const int MAX_PARTITIONS = ESP_PARTITION_TABLE_DATA_LEN / sizeof(esp_partition_info_t); @@ -121,7 +120,7 @@ bool load_partition_table(bootloader_state_t* bs) #ifdef CONFIG_SECURE_BOOTLOADER_ENABLED if(esp_secure_boot_enabled()) { ESP_LOGI(TAG, "Verifying partition table signature..."); - err = esp_secure_boot_verify_signature(ESP_PARTITION_TABLE_ADDR, ESP_PARTITION_TABLE_DATA_LEN); + esp_err_t err = esp_secure_boot_verify_signature(ESP_PARTITION_TABLE_ADDR, ESP_PARTITION_TABLE_DATA_LEN); if (err != ESP_OK) { ESP_LOGE(TAG, "Failed to verify partition table signature."); return false; @@ -227,7 +226,6 @@ void bootloader_main() { ESP_LOGI(TAG, "Espressif ESP32 2nd stage bootloader v. %s", BOOT_VERSION); - esp_err_t err; esp_image_header_t fhdr; bootloader_state_t bs; SpiFlashOpResult spiRet1,spiRet2; @@ -322,7 +320,7 @@ void bootloader_main() #ifdef CONFIG_SECURE_BOOTLOADER_ENABLED /* Generate secure digest from this bootloader to protect future modifications */ - err = esp_secure_boot_permanently_enable(); + esp_err_t err = esp_secure_boot_permanently_enable(); if (err != ESP_OK) { ESP_LOGE(TAG, "Bootloader digest generation failed (%d). SECURE BOOT IS NOT ENABLED.", err); /* Allow booting to continue, as the failure is probably From c04f05ee84754a378d0d25eddf2d00d8a2e52226 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Mon, 14 Nov 2016 15:29:27 +1100 Subject: [PATCH 336/343] build examples: Only build verbose on failure, save on log output --- make/build_examples.sh | 19 +++++++++---------- make/component_wrapper.mk | 20 +++++++++++++------- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/make/build_examples.sh b/make/build_examples.sh index 53cba23b1e..a522666a98 100755 --- a/make/build_examples.sh +++ b/make/build_examples.sh @@ -15,16 +15,15 @@ RESULT=0 set -e for example in ${IDF_PATH}/examples/*; do - [ -f ${example}/Makefile ] || continue - echo "Building ${example} as ${EXAMPLE_NUM}..." - mkdir ${EXAMPLE_NUM} - cp -r ${example} ${EXAMPLE_NUM} - pushd ${EXAMPLE_NUM}/`basename ${example}` - # can't do "make defconfig all" as this will trip menuconfig - # sometimes - make defconfig V=1 && make V=1 || RESULT=$? - popd - EXAMPLE_NUM=$(( $EXAMPLE_NUM + 1 )) + [ -f ${example}/Makefile ] || continue + echo "Building ${example} as ${EXAMPLE_NUM}..." + mkdir ${EXAMPLE_NUM} + cp -r ${example} ${EXAMPLE_NUM} + pushd ${EXAMPLE_NUM}/`basename ${example}` + # build non-verbose first, only build verbose if there's an error + make defconfig all || (RESULT=$?; make V=1) + popd + EXAMPLE_NUM=$(( $EXAMPLE_NUM + 1 )) done exit $RESULT diff --git a/make/component_wrapper.mk b/make/component_wrapper.mk index e1283bda8f..55a135158a 100644 --- a/make/component_wrapper.mk +++ b/make/component_wrapper.mk @@ -41,8 +41,9 @@ COMPONENT_LIBRARY = lib$(COMPONENT_NAME).a # Source dirs a component has. Default to root directory of component. COMPONENT_SRCDIRS = . -#Names of binary files to embed as symbols in the component library +#Names of binary & text files to embed as raw content in the component library COMPONENT_EMBED_FILES ?= +COMPONENT_EMBED_TXTFILES ?= # By default, include only the include/ dir. COMPONENT_ADD_INCLUDEDIRS = include @@ -72,6 +73,11 @@ COMPONENT_OBJS += $(foreach compsrcdir,$(COMPONENT_SRCDIRS),$(patsubst %.S,%.o,$ COMPONENT_OBJS := $(patsubst $(COMPONENT_PATH)/%,%,$(COMPONENT_OBJS)) endif +# Object files with embedded binaries to add to the component library +# Correspond to the files named in COMPONENT_EMBED_FILES & COMPONENT_EMBED_TXTFILES +COMPONENT_EMBED_OBJS ?= $(addsuffix .bin.o,$(COMPONENT_EMBED_FILES)) $(addsuffix .txt.o,$(COMPONENT_EMBED_TXTFILES)) + + # If we're called to compile something, we'll get passed the COMPONENT_INCLUDES # variable with all the include dirs from all the components in random order. This # means we can accidentally grab a header from another component before grabbing our own. @@ -133,7 +139,7 @@ build: $(COMPONENT_LIBRARY) $(COMPONENT_LIBRARY): $(COMPONENT_OBJS) $(COMPONENT_EMBED_OBJS) $(summary) AR $@ rm -f $@ - $(AR) cru $@ $(COMPONENT_OBJS) + $(AR) cru $@ $^ endif # If COMPONENT_OWNCLEANTARGET is not set, define a phony clean target @@ -187,11 +193,11 @@ OBJCOPY_EMBED_ARGS := --input binary --output elf32-xtensa-le --binary-architect # path to the input file. define GenerateEmbedTarget $(1).$(2).o: $(call resolvepath,$(1),$(COMPONENT_PATH)) | $$(dir $(1)) - $$(summary) EMBED $$@ - $$(Q) $(if $(filter-out $$(notdir $$(abspath $$<)),$$(abspath $$(notdir $$<))), cp $$< $$(notdir $$<) ) # copy input file to build dir, unless already in build dir - $$(Q) $(if $(subst bin,,$(2)),echo -ne '\0' >> $$(notdir $$<) ) # trailing NUL byte on text output - $$(Q) $$(OBJCOPY) $(OBJCOPY_EMBED_ARGS) $$(notdir $$<) $$@ - $$(Q) rm $$(notdir $$<) + $(summary) EMBED $$@ + $$(if $$(filter-out $$(notdir $$(abspath $$<)),$$(abspath $$(notdir $$<))), cp $$< $$(notdir $$<) ) # copy input file to build dir, unless already in build dir + $$(if $$(subst bin,,$(2)),echo -ne '\0' >> $$(notdir $$<) ) # trailing NUL byte on text output + $(OBJCOPY) $(OBJCOPY_EMBED_ARGS) $$(notdir $$<) $$@ + rm $$(notdir $$<) endef # generate targets to embed binary & text files From f7af4ddc89d553c04bddb5e070dc0c26e5b1d0c2 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Mon, 14 Nov 2016 15:54:33 +1100 Subject: [PATCH 337/343] Examples: Remove deprecated system_init() call --- examples/01_hello_world/main/hello_world_main.c | 1 - examples/02_blink/main/blink.c | 1 - examples/03_http_request/main/http_request_main.c | 1 - examples/04_https_request/main/https_request_main.c | 1 - examples/06_sntp/main/sntp_main.c | 1 - 5 files changed, 5 deletions(-) diff --git a/examples/01_hello_world/main/hello_world_main.c b/examples/01_hello_world/main/hello_world_main.c index ad2c0acbbd..1ff190acef 100644 --- a/examples/01_hello_world/main/hello_world_main.c +++ b/examples/01_hello_world/main/hello_world_main.c @@ -27,6 +27,5 @@ void hello_task(void *pvParameter) void app_main() { nvs_flash_init(); - system_init(); xTaskCreate(&hello_task, "hello_task", 2048, NULL, 5, NULL); } diff --git a/examples/02_blink/main/blink.c b/examples/02_blink/main/blink.c index 6de0e1fa36..1e49e51b2f 100644 --- a/examples/02_blink/main/blink.c +++ b/examples/02_blink/main/blink.c @@ -43,6 +43,5 @@ void blink_task(void *pvParameter) void app_main() { nvs_flash_init(); - system_init(); xTaskCreate(&blink_task, "blink_task", 512, NULL, 5, NULL); } diff --git a/examples/03_http_request/main/http_request_main.c b/examples/03_http_request/main/http_request_main.c index 32f75c0da2..2c203f8394 100644 --- a/examples/03_http_request/main/http_request_main.c +++ b/examples/03_http_request/main/http_request_main.c @@ -175,7 +175,6 @@ static void http_get_task(void *pvParameters) void app_main() { nvs_flash_init(); - system_init(); initialise_wifi(); xTaskCreate(&http_get_task, "http_get_task", 2048, NULL, 5, NULL); } diff --git a/examples/04_https_request/main/https_request_main.c b/examples/04_https_request/main/https_request_main.c index 7f302409d8..2ad56681d0 100644 --- a/examples/04_https_request/main/https_request_main.c +++ b/examples/04_https_request/main/https_request_main.c @@ -369,7 +369,6 @@ static void https_get_task(void *pvParameters) void app_main() { nvs_flash_init(); - system_init(); initialise_wifi(); xTaskCreate(&https_get_task, "https_get_task", 8192, NULL, 5, NULL); } diff --git a/examples/06_sntp/main/sntp_main.c b/examples/06_sntp/main/sntp_main.c index 7f516625e3..83f33b9656 100644 --- a/examples/06_sntp/main/sntp_main.c +++ b/examples/06_sntp/main/sntp_main.c @@ -94,7 +94,6 @@ void app_main() static void obtain_time(void) { nvs_flash_init(); - system_init(); initialise_wifi(); xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); From 751736f902f9790f69e8f1cb43348ef35d8f077b Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Mon, 14 Nov 2016 15:55:26 +1100 Subject: [PATCH 338/343] ble_adv example: Remove int return value from app_main() --- examples/05_ble_adv/main/app_bt.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/05_ble_adv/main/app_bt.c b/examples/05_ble_adv/main/app_bt.c index 7f5dda5ec5..bfdd0b8c68 100755 --- a/examples/05_ble_adv/main/app_bt.c +++ b/examples/05_ble_adv/main/app_bt.c @@ -197,10 +197,9 @@ void bleAdvtTask(void *pvParameters) } } -int app_main() +void app_main() { bt_controller_init(); xTaskCreatePinnedToCore(&bleAdvtTask, "bleAdvtTask", 2048, NULL, 5, NULL, 0); - return 0; } From 9a7db9ca85f9471de4d8019aead68a1176cf62d3 Mon Sep 17 00:00:00 2001 From: Xia Xiao Tian Date: Mon, 14 Nov 2016 14:34:09 +0800 Subject: [PATCH 339/343] add comments for system_event_sta_wps_er_pin_t --- components/esp32/include/esp_event.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp32/include/esp_event.h b/components/esp32/include/esp_event.h index 3b2b54acca..55575b13a8 100644 --- a/components/esp32/include/esp_event.h +++ b/components/esp32/include/esp_event.h @@ -102,7 +102,7 @@ typedef union { system_event_sta_scan_done_t scan_done; /**< ESP32 station scan (APs) done */ system_event_sta_authmode_change_t auth_change; /**< the auth mode of AP ESP32 station connected to changed */ system_event_sta_got_ip_t got_ip; /**< ESP32 station got IP */ - system_event_sta_wps_er_pin_t sta_er_pin; + system_event_sta_wps_er_pin_t sta_er_pin; /**< ESP32 station WPS enrollee mode PIN code received */ system_event_ap_staconnected_t sta_connected; /**< a station connected to ESP32 soft-AP */ system_event_ap_stadisconnected_t sta_disconnected; /**< a station disconnected to ESP32 soft-AP */ system_event_ap_probe_req_rx_t ap_probereqrecved; /**< ESP32 soft-AP receive probe request packet */ From 64a2f0ee0bf31f7921069f601515f9bc638ccfff Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Tue, 15 Nov 2016 10:29:52 +0800 Subject: [PATCH 340/343] Amend gpio driver to work around SoC bug with some pullups/pulldowns in the GPIO peripheral; mark existing function that does not always work as deprecated --- components/driver/gpio.c | 92 ++++++++++++++++++++--- components/driver/include/driver/gpio.h | 84 +++++++++++++++++++-- components/esp32/gdbstub.c | 3 +- components/esp32/include/soc/io_mux_reg.h | 39 +++++++++- 4 files changed, 194 insertions(+), 24 deletions(-) diff --git a/components/driver/gpio.c b/components/driver/gpio.c index b445d3df03..ddbcb352c0 100644 --- a/components/driver/gpio.c +++ b/components/driver/gpio.c @@ -69,6 +69,74 @@ const uint32_t GPIO_PIN_MUX_REG[GPIO_PIN_COUNT] = { GPIO_PIN_REG_39 }; +const gpio_pu_pd_desc_t gpio_pu_pd_desc[GPIO_PIN_COUNT]={ + {RTC_IO_TOUCH_PAD1_REG, RTC_IO_TOUCH_PAD1_RUE_M, RTC_IO_TOUCH_PAD1_RDE_M}, + {PERIPHS_IO_MUX_U0TXD_U, FUN_PU, FUN_PD}, + {RTC_IO_TOUCH_PAD2_REG, RTC_IO_TOUCH_PAD2_RUE_M, RTC_IO_TOUCH_PAD2_RDE_M}, + {PERIPHS_IO_MUX_U0RXD_U, FUN_PU, FUN_PD}, + {RTC_IO_TOUCH_PAD0_REG, RTC_IO_TOUCH_PAD0_RUE_M, RTC_IO_TOUCH_PAD0_RDE_M}, + {PERIPHS_IO_MUX_GPIO5_U, FUN_PU, FUN_PD}, + {PERIPHS_IO_MUX_SD_CLK_U, FUN_PU, FUN_PD}, + {PERIPHS_IO_MUX_SD_DATA0_U, FUN_PU, FUN_PD}, + {PERIPHS_IO_MUX_SD_DATA1_U, FUN_PU, FUN_PD}, + {PERIPHS_IO_MUX_SD_DATA2_U, FUN_PU, FUN_PD}, + {PERIPHS_IO_MUX_SD_DATA3_U, FUN_PU, FUN_PD}, + {PERIPHS_IO_MUX_SD_CMD_U, FUN_PU, FUN_PD}, + {RTC_IO_TOUCH_PAD5_REG, RTC_IO_TOUCH_PAD5_RUE_M, RTC_IO_TOUCH_PAD5_RDE_M}, + {RTC_IO_TOUCH_PAD4_REG, RTC_IO_TOUCH_PAD4_RUE_M, RTC_IO_TOUCH_PAD4_RDE_M}, + {RTC_IO_TOUCH_PAD6_REG, RTC_IO_TOUCH_PAD6_RUE_M, RTC_IO_TOUCH_PAD6_RDE_M}, + {RTC_IO_TOUCH_PAD3_REG, RTC_IO_TOUCH_PAD3_RUE_M, RTC_IO_TOUCH_PAD3_RDE_M}, + {PERIPHS_IO_MUX_GPIO16_U, FUN_PU, FUN_PD}, + {PERIPHS_IO_MUX_GPIO17_U, FUN_PU, FUN_PD}, + {PERIPHS_IO_MUX_GPIO18_U, FUN_PU, FUN_PD}, + {PERIPHS_IO_MUX_GPIO19_U, FUN_PU, FUN_PD}, + {0,0,0}, + {PERIPHS_IO_MUX_GPIO21_U, FUN_PU, FUN_PD}, + {PERIPHS_IO_MUX_GPIO22_U, FUN_PU, FUN_PD}, + {PERIPHS_IO_MUX_GPIO23_U, FUN_PU, FUN_PD}, + {0,0,0}, + {RTC_IO_PAD_DAC1_REG, RTC_IO_PDAC1_RUE_M, RTC_IO_PDAC1_RDE_M}, + {RTC_IO_PAD_DAC2_REG, RTC_IO_PDAC2_RUE_M, RTC_IO_PDAC2_RDE_M}, + {RTC_IO_TOUCH_PAD7_REG, RTC_IO_TOUCH_PAD7_RUE_M, RTC_IO_TOUCH_PAD7_RDE_M}, + {0,0,0}, + {0,0,0}, + {0,0,0}, + {0,0,0}, + {RTC_IO_XTAL_32K_PAD_REG, RTC_IO_X32P_RUE_M, RTC_IO_X32P_RDE_M}, + {RTC_IO_XTAL_32K_PAD_REG, RTC_IO_X32N_RUE_M, RTC_IO_X32N_RDE_M}, + {PERIPHS_IO_MUX_GPIO34_U, FUN_PU, FUN_PD}, + {PERIPHS_IO_MUX_GPIO35_U, FUN_PU, FUN_PD}, + {PERIPHS_IO_MUX_GPIO36_U, FUN_PU, FUN_PD}, + {PERIPHS_IO_MUX_GPIO37_U, FUN_PU, FUN_PD}, + {PERIPHS_IO_MUX_GPIO38_U, FUN_PU, FUN_PD}, + {PERIPHS_IO_MUX_GPIO39_U, FUN_PU, FUN_PD} +}; + + +esp_err_t gpio_pullup_en(gpio_num_t gpio_num) { + GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); + REG_SET_BIT(gpio_pu_pd_desc[gpio_num].reg, gpio_pu_pd_desc[gpio_num].pu); + return ESP_OK; +} + +esp_err_t gpio_pullup_dis(gpio_num_t gpio_num) { + GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); + REG_CLR_BIT(gpio_pu_pd_desc[gpio_num].reg, gpio_pu_pd_desc[gpio_num].pu); + return ESP_OK; +} + +esp_err_t gpio_pulldown_en(gpio_num_t gpio_num) { + GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); + REG_SET_BIT(gpio_pu_pd_desc[gpio_num].reg, gpio_pu_pd_desc[gpio_num].pd); + return ESP_OK; +} + +esp_err_t gpio_pulldown_dis(gpio_num_t gpio_num) { + GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); + REG_CLR_BIT(gpio_pu_pd_desc[gpio_num].reg, gpio_pu_pd_desc[gpio_num].pd); + return ESP_OK; +} + esp_err_t gpio_set_intr_type(gpio_num_t gpio_num, gpio_int_type_t intr_type) { GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); @@ -152,20 +220,20 @@ esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull) esp_err_t ret = ESP_OK; switch(pull) { case GPIO_PULLUP_ONLY: - PIN_PULLUP_EN(GPIO_PIN_MUX_REG[gpio_num]); - PIN_PULLDWN_DIS(GPIO_PIN_MUX_REG[gpio_num]); + REG_SET_BIT(gpio_pu_pd_desc[gpio_num].reg, gpio_pu_pd_desc[gpio_num].pu); + REG_CLR_BIT(gpio_pu_pd_desc[gpio_num].reg, gpio_pu_pd_desc[gpio_num].pd); break; case GPIO_PULLDOWN_ONLY: - PIN_PULLUP_DIS(GPIO_PIN_MUX_REG[gpio_num]); - PIN_PULLDWN_EN(GPIO_PIN_MUX_REG[gpio_num]); + REG_CLR_BIT(gpio_pu_pd_desc[gpio_num].reg, gpio_pu_pd_desc[gpio_num].pu); + REG_SET_BIT(gpio_pu_pd_desc[gpio_num].reg, gpio_pu_pd_desc[gpio_num].pd); break; case GPIO_PULLUP_PULLDOWN: - PIN_PULLUP_EN(GPIO_PIN_MUX_REG[gpio_num]); - PIN_PULLDWN_EN(GPIO_PIN_MUX_REG[gpio_num]); + REG_SET_BIT(gpio_pu_pd_desc[gpio_num].reg, gpio_pu_pd_desc[gpio_num].pu); + REG_SET_BIT(gpio_pu_pd_desc[gpio_num].reg, gpio_pu_pd_desc[gpio_num].pd); break; case GPIO_FLOATING: - PIN_PULLUP_DIS(GPIO_PIN_MUX_REG[gpio_num]); - PIN_PULLDWN_DIS(GPIO_PIN_MUX_REG[gpio_num]); + REG_CLR_BIT(gpio_pu_pd_desc[gpio_num].reg, gpio_pu_pd_desc[gpio_num].pu); + REG_CLR_BIT(gpio_pu_pd_desc[gpio_num].reg, gpio_pu_pd_desc[gpio_num].pd); break; default: ESP_LOGE(GPIO_TAG, "Unknown pull up/down mode,gpio_num=%u,pull=%u",gpio_num,pull); @@ -253,15 +321,15 @@ esp_err_t gpio_config(gpio_config_t *pGPIOConfig) } if(pGPIOConfig->pull_up_en) { pu_en = 1; - PIN_PULLUP_EN(io_reg); + REG_SET_BIT(gpio_pu_pd_desc[io_num].reg, gpio_pu_pd_desc[io_num].pd); } else { - PIN_PULLUP_DIS(io_reg); + REG_CLR_BIT(gpio_pu_pd_desc[io_num].reg, gpio_pu_pd_desc[io_num].pd); } if(pGPIOConfig->pull_down_en) { pd_en = 1; - PIN_PULLDWN_EN(io_reg); + REG_SET_BIT(gpio_pu_pd_desc[io_num].reg, gpio_pu_pd_desc[io_num].pd); } else { - PIN_PULLDWN_DIS(io_reg); + REG_CLR_BIT(gpio_pu_pd_desc[io_num].reg, gpio_pu_pd_desc[io_num].pd); } ESP_LOGI(GPIO_TAG, "GPIO[%d]| InputEn: %d| OutputEn: %d| OpenDrain: %d| Pullup: %d| Pulldown: %d| Intr:%d ", io_num, input_en, output_en, od_en, pu_en, pd_en, pGPIOConfig->intr_type); gpio_set_intr_type(io_num, pGPIOConfig->intr_type); diff --git a/components/driver/include/driver/gpio.h b/components/driver/include/driver/gpio.h index 73efeaa342..5dad11f2ff 100644 --- a/components/driver/include/driver/gpio.h +++ b/components/driver/include/driver/gpio.h @@ -117,6 +117,29 @@ extern const uint32_t GPIO_PIN_MUX_REG[GPIO_PIN_COUNT]; #define GPIO_IS_VALID_GPIO(gpio_num) ((gpio_num < GPIO_PIN_COUNT && GPIO_PIN_MUX_REG[gpio_num] != 0)) //to decide whether it is a valid GPIO number #define GPIO_IS_VALID_OUTPUT_GPIO(gpio_num) ((GPIO_IS_VALID_GPIO(gpio_num)) && (gpio_num < 34)) //to decide whether it can be a valid GPIO number of output mode +typedef struct { + uint32_t reg; /*!< Register to modify to enable or disable pullups or pulldowns */ + uint32_t pu; /*!< Bit to set or clear in the above register to enable or disable the pullup, respectively */ + uint32_t pd; /*!< Bit to set or clear in the above register to enable or disable the pulldown, respectively */ +} gpio_pu_pd_desc_t; + + +/** + * Per-GPIO pullup/pulldown information + * On the ESP32, some GPIOs need their pullups and pulldowns enabled and disabled in the RTC + * peripheral instead of in the GPIO peripheral. This array documents for every GPIO what bit + * to set or clear. + * + * This array is non-static, so if you need a very quick way of toggling the pull-up/downs, you can just + * do e.g. REG_SET_BIT(gpio_pu_pd_desc[gpio_num].reg, gpio_pu_pd_desc[gpio_num].pu); inline. + * + * ToDo: Functions using the contents of this array will do a read/modify/write on GPIO as well as RTC + * registers. We may need to look into muxes/locks for other code that accesses these RTC registers when we + * write drivers for the RTC stuff. + */ +extern const gpio_pu_pd_desc_t gpio_pu_pd_desc[GPIO_PIN_COUNT]; + + typedef enum { GPIO_NUM_0 = 0, /*!< GPIO0, input and output */ GPIO_NUM_1 = 1, /*!< GPIO1, input and output */ @@ -220,7 +243,7 @@ esp_err_t gpio_config(gpio_config_t *pGPIOConfig); /** * @brief GPIO set interrupt trigger type * - * @param gpio_num GPIO number. If you want to set output level of GPIO16, gpio_num should be GPIO_NUM_16 (16); + * @param gpio_num GPIO number. If you want to set the trigger type of e.g. of GPIO16, gpio_num should be GPIO_NUM_16 (16); * @param intr_type Interrupt type, select from gpio_int_type_t * * @return @@ -233,7 +256,7 @@ esp_err_t gpio_set_intr_type(gpio_num_t gpio_num, gpio_int_type_t intr_type); /** * @brief Enable GPIO module interrupt signal * - * @param gpio_num GPIO number. If you want to set output level of GPIO16, gpio_num should be GPIO_NUM_16 (16); + * @param gpio_num GPIO number. If you want to enable an interrupt on e.g. GPIO16, gpio_num should be GPIO_NUM_16 (16); * * @return * - ESP_OK Success @@ -245,7 +268,7 @@ esp_err_t gpio_intr_enable(gpio_num_t gpio_num); /** * @brief Disable GPIO module interrupt signal * - * @param gpio_num GPIO number. If you want to set output level of GPIO16, gpio_num should be GPIO_NUM_16 (16); + * @param gpio_num GPIO number. If you want to disable the interrupt of e.g. GPIO16, gpio_num should be GPIO_NUM_16 (16); * * @return * - ESP_OK success @@ -257,7 +280,7 @@ esp_err_t gpio_intr_disable(gpio_num_t gpio_num); /** * @brief GPIO set output level * - * @param gpio_num GPIO number. If you want to set output level of GPIO16, gpio_num should be GPIO_NUM_16 (16); + * @param gpio_num GPIO number. If you want to set the output level of e.g. GPIO16, gpio_num should be GPIO_NUM_16 (16); * @param level Output level. 0: low ; 1: high * * @return @@ -270,7 +293,7 @@ esp_err_t gpio_set_level(gpio_num_t gpio_num, uint32_t level); /** * @brief GPIO get input level * - * @param gpio_num GPIO number. If you want to get level of pin GPIO16, gpio_num should be GPIO_NUM_16 (16); + * @param gpio_num GPIO number. If you want to get the logic level of e.g. pin GPIO16, gpio_num should be GPIO_NUM_16 (16); * * @return * - 0 the GPIO input level is 0 @@ -284,7 +307,7 @@ int gpio_get_level(gpio_num_t gpio_num); * * Configure GPIO direction,such as output_only,input_only,output_and_input * - * @param gpio_num Configure GPIO pins number, it should be GPIO number. If you want to set direction of GPIO16, gpio_num should be GPIO_NUM_16 (16); + * @param gpio_num Configure GPIO pins number, it should be GPIO number. If you want to set direction of e.g. GPIO16, gpio_num should be GPIO_NUM_16 (16); * @param mode GPIO direction * * @return @@ -299,7 +322,7 @@ esp_err_t gpio_set_direction(gpio_num_t gpio_num, gpio_mode_t mode); * * User this Function,configure GPIO pull mode,such as pull-up,pull-down * - * @param gpio_num GPIO number. If you want to set pull up or down mode for GPIO16,gpio_num should be GPIO_NUM_16 (16); + * @param gpio_num GPIO number. If you want to set pull up or down mode for e.g. GPIO16, gpio_num should be GPIO_NUM_16 (16); * @param pull GPIO pull up/down mode. * * @return @@ -354,6 +377,53 @@ esp_err_t gpio_wakeup_disable(gpio_num_t gpio_num); */ esp_err_t gpio_isr_register(uint32_t gpio_intr_num, void (*fn)(void*), void * arg); + + +/** + * @brief Enable pull-up on GPIO. + * + * @param gpio_num GPIO number + * + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG Parameter error + */ +esp_err_t gpio_pullup_en(gpio_num_t gpio_num); + +/** + * @brief Disable pull-up on GPIO. + * + * @param gpio_num GPIO number + * + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG Parameter error + */ +esp_err_t gpio_pullup_dis(gpio_num_t gpio_num); + +/** + * @brief Enable pull-down on GPIO. + * + * @param gpio_num GPIO number + * + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG Parameter error + */ +esp_err_t gpio_pulldown_en(gpio_num_t gpio_num); + +/** + * @brief Disable pull-down on GPIO. + * + * @param gpio_num GPIO number + * + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG Parameter error + */ +esp_err_t gpio_pulldown_dis(gpio_num_t gpio_num); + + /** * *************** ATTENTION ********************/ /** diff --git a/components/esp32/gdbstub.c b/components/esp32/gdbstub.c index a43793f835..819944a902 100644 --- a/components/esp32/gdbstub.c +++ b/components/esp32/gdbstub.c @@ -25,6 +25,7 @@ #include "soc/io_mux_reg.h" #include "esp_gdbstub.h" +#include "driver/gpio.h" //Length of buffer used to reserve GDB commands. Has to be at least able to fit the G command, which //implies a minimum size of about 320 bytes. @@ -354,7 +355,7 @@ static int gdbReadCommand() { void esp_gdbstub_panic_handler(XtExcFrame *frame) { dumpHwToRegfile(frame); //Make sure txd/rxd are enabled - PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U); + gpio_pullup_dis(1); PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_U0RXD); PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD_U0TXD); diff --git a/components/esp32/include/soc/io_mux_reg.h b/components/esp32/include/soc/io_mux_reg.h index 208a60703a..de8fe7ec99 100644 --- a/components/esp32/include/soc/io_mux_reg.h +++ b/components/esp32/include/soc/io_mux_reg.h @@ -34,10 +34,41 @@ #define PIN_INPUT_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,FUN_IE) #define PIN_INPUT_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,FUN_IE) #define PIN_SET_DRV(PIN_NAME, drv) REG_SET_FIELD(PIN_NAME, FUN_DRV, (drv)); -#define PIN_PULLUP_DIS(PIN_NAME) REG_CLR_BIT(PIN_NAME, FUN_PU) -#define PIN_PULLUP_EN(PIN_NAME) REG_SET_BIT(PIN_NAME, FUN_PU) -#define PIN_PULLDWN_DIS(PIN_NAME) REG_CLR_BIT(PIN_NAME, FUN_PD) -#define PIN_PULLDWN_EN(PIN_NAME) REG_SET_BIT(PIN_NAME, FUN_PD) + +/* + * @attention + * The PIN_PULL[UP|DWN]_[EN|DIS]() functions used to exist as macros in previous SDK versions. + * Unfortunately, however, they do not work for some GPIOs on the ESP32 chip, which needs pullups + * and -downs turned on and off through RTC registers. The functions still exist for compatibility + * with older code, but are marked as deprecated in order to generate a warning. + * Please replace them in this fashion: (make sure to include driver/gpio.h as well) + * PIN_PULLUP_EN(GPIO_PIN_MUX_REG[x]) -> gpio_pullup_en(x) + * PIN_PULLUP_DIS(GPIO_PIN_MUX_REG[x]) -> gpio_pullup_dis(x) + * PIN_PULLDWN_EN(GPIO_PIN_MUX_REG[x]) -> gpio_pulldown_en(x) + * PIN_PULLDWN_DIS(GPIO_PIN_MUX_REG[x]) -> gpio_pulldown_dis(x) + * +*/ +static inline void __attribute__ ((deprecated)) PIN_PULLUP_DIS(uint32_t PIN_NAME) +{ + REG_CLR_BIT(PIN_NAME, FUN_PU); +} + +static inline void __attribute__ ((deprecated)) PIN_PULLUP_EN(uint32_t PIN_NAME) +{ + REG_SET_BIT(PIN_NAME, FUN_PU); +} + +static inline void __attribute__ ((deprecated)) PIN_PULLDWN_DIS(uint32_t PIN_NAME) +{ + REG_CLR_BIT(PIN_NAME, FUN_PD); +} + +static inline void __attribute__ ((deprecated)) PIN_PULLDWN_EN(uint32_t PIN_NAME) +{ + REG_SET_BIT(PIN_NAME, FUN_PD); +} + + #define PIN_FUNC_SELECT(PIN_NAME, FUNC) REG_SET_FIELD(PIN_NAME, MCU_SEL, FUNC) #define PIN_FUNC_GPIO 2 From adb4be859cb74cefbe81527a23effaeb05abe355 Mon Sep 17 00:00:00 2001 From: Xia Xiao Tian Date: Tue, 15 Nov 2016 11:19:15 +0800 Subject: [PATCH 341/343] wps: update wifi lib -- add wps lib --- components/esp32/lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp32/lib b/components/esp32/lib index 84af0ed366..01f5c068e1 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit 84af0ed366e1ba38984f7df517a77f8ec4fa27ed +Subproject commit 01f5c068e1ac3968add98439ee2f1748b9e391fa From fa1d5bfbc78797ac261ab5d63662cdbf1b68f254 Mon Sep 17 00:00:00 2001 From: liuhan Date: Thu, 3 Nov 2016 13:30:32 +0800 Subject: [PATCH 342/343] tcpip_adapter: add set hostname interface --- .../tcpip_adapter/include/tcpip_adapter.h | 13 +++++++++ components/tcpip_adapter/tcpip_adapter_lwip.c | 28 +++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/components/tcpip_adapter/include/tcpip_adapter.h b/components/tcpip_adapter/include/tcpip_adapter.h index e847016884..45d6ade305 100644 --- a/components/tcpip_adapter/include/tcpip_adapter.h +++ b/components/tcpip_adapter/include/tcpip_adapter.h @@ -372,6 +372,19 @@ wifi_interface_t tcpip_adapter_get_wifi_if(void *dev); */ esp_err_t tcpip_adapter_get_sta_list(wifi_sta_list_t *wifi_sta_list, tcpip_adapter_sta_list_t *tcpip_sta_list); +#define TCPIP_HOSTNAME_MAX_SIZE 31 +/** + * @brief Set the hostname to the interface + * + * @param[in] tcpip_if: the interface which we will set the hostname + * @param[in] hostname: the host name for set the interfce + * + * @return ESP_OK:success + * ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY:interface status error + * ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS:parameter error + */ +esp_err_t tcpip_adapter_set_hostname(tcpip_adapter_if_t tcpip_if, const char *hostname); + #ifdef __cplusplus } #endif diff --git a/components/tcpip_adapter/tcpip_adapter_lwip.c b/components/tcpip_adapter/tcpip_adapter_lwip.c index 9b6e9d94fa..3edc90509e 100644 --- a/components/tcpip_adapter/tcpip_adapter_lwip.c +++ b/components/tcpip_adapter/tcpip_adapter_lwip.c @@ -607,4 +607,32 @@ esp_err_t tcpip_adapter_get_sta_list(wifi_sta_list_t *wifi_sta_list, tcpip_adapt return ESP_OK; } +esp_err_t tcpip_adapter_set_hostname(tcpip_adapter_if_t tcpip_if, const char *hostname) +{ + struct netif *p_netif; + static char hostinfo[TCPIP_HOSTNAME_MAX_SIZE + 1]; + + if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || hostname == NULL) { + return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; + } + + if (strlen(hostname) >= TCPIP_HOSTNAME_MAX_SIZE) { + return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; + } + + p_netif = esp_netif[tcpip_if]; + if (p_netif != NULL) { + if (netif_is_up(p_netif)) { + return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY; + } else { + memset(hostinfo, 0, sizeof(hostinfo)); + memcpy(hostinfo, hostname, strlen(hostname)); + p_netif->hostname = hostinfo; + return ESP_OK; + } + } else { + return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; + } +} + #endif From 9a2887c458c20b05ffad8f7ef8dbd54a20b97920 Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Tue, 15 Nov 2016 12:10:02 +0800 Subject: [PATCH 343/343] Add comments/headers according to merge request comments --- components/esp32/freertos_hooks.c | 15 ++++++++++ components/esp32/include/esp_freertos_hooks.h | 29 +++++++++++++++++-- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/components/esp32/freertos_hooks.c b/components/esp32/freertos_hooks.c index 50ebd3d054..d59a20363d 100644 --- a/components/esp32/freertos_hooks.c +++ b/components/esp32/freertos_hooks.c @@ -1,3 +1,18 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + #include #include #include diff --git a/components/esp32/include/esp_freertos_hooks.h b/components/esp32/include/esp_freertos_hooks.h index 1bb5ab194a..45a1649723 100644 --- a/components/esp32/include/esp_freertos_hooks.h +++ b/components/esp32/include/esp_freertos_hooks.h @@ -1,9 +1,27 @@ -#ifndef ESP_FREERTOS_HOOKS_H -#define ESP_FREERTOS_HOOKS_H +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef __ESP_FREERTOS_HOOKS_H__ +#define __ESP_FREERTOS_HOOKS_H__ #include #include "esp_err.h" +#ifdef __cplusplus +extern "C" +{ +#endif /* Definitions for the tickhook and idlehook callbacks @@ -17,6 +35,9 @@ typedef void (*esp_freertos_tick_cb_t)(); * sleep until an interrupt (or FreeRTOS tick) happens and false * if it should be called again as fast as possible. * + * @warning Idle callbacks MUST NOT, UNDER ANY CIRCUMSTANCES, CALL + * A FUNCTION THAT MIGHT BLOCK. + * * @param esp_freertos_idle_cb_t new_idle_cb : Callback to be called * * @return ESP_OK : Callback registered @@ -54,5 +75,9 @@ void esp_deregister_freertos_idle_hook(esp_freertos_idle_cb_t old_idle_cb); */ void esp_deregister_freertos_tick_hook(esp_freertos_tick_cb_t old_tick_cb); +#ifdef __cplusplus +} +#endif + #endif \ No newline at end of file