improv_console.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. #include "platform_console.h"
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include "esp_log.h"
  6. #include "esp_console.h"
  7. #include "esp_vfs_dev.h"
  8. #include "driver/uart.h"
  9. #include "linenoise/linenoise.h"
  10. #include "argtable3/argtable3.h"
  11. #include "nvs.h"
  12. #include "nvs_flash.h"
  13. #include "pthread.h"
  14. #include "platform_esp32.h"
  15. #include "cmd_decl.h"
  16. #include "trace.h"
  17. #include "platform_config.h"
  18. #include "telnet.h"
  19. #include "tools.h"
  20. #include "improv.h"
  21. #include "messaging.h"
  22. #include "config.h"
  23. #include "improv_console.h"
  24. #include "network_status.h"
  25. static const char * TAG ="improv_console";
  26. const time_t improv_timeout_ms = 50;
  27. TickType_t improv_timeout_tick = pdMS_TO_TICKS(improv_timeout_ms);
  28. ImprovState_t improv_state = IMPROV_STATE_READY_AUTHORIZED;
  29. const size_t improv_buffer_size = 121;
  30. size_t improv_buffer_len = 0;
  31. uint8_t * improv_buffer_data = NULL;
  32. TickType_t improv_delay = portMAX_DELAY;
  33. void cb_improv_got_ip(nm_state_t new_state, int sub_state){
  34. if(improv_state == IMPROV_STATE_PROVISIONING){
  35. char * url = network_status_alloc_get_system_url();
  36. ESP_LOGI(TAG,"Signaling improv state connected state with url: %s",STR_OR_BLANK(url));
  37. improv_send_device_url(IMPROV_CMD_WIFI_SETTINGS,url);
  38. FREE_AND_NULL(url);
  39. }
  40. }
  41. void cb_improv_disconnected(nm_state_t new_state, int sub_state){
  42. if(improv_state == IMPROV_STATE_PROVISIONING){
  43. ESP_LOGI(TAG,"Signalling improv connect failure ");
  44. improv_state = IMPROV_STATE_READY_AUTHORIZED;
  45. improv_send_error(IMPROV_ERROR_UNABLE_TO_CONNECT);
  46. }
  47. }
  48. bool on_improv_command(ImprovCommandStruct_t *command){
  49. esp_err_t err = ESP_OK;
  50. wifi_connect_state_t wifi_state = network_wifi_get_connect_state();
  51. const esp_app_desc_t* desc = esp_ota_get_app_description();
  52. improv_buffer_len = 0;
  53. char * url=NULL;
  54. char * host_name = NULL;
  55. ESP_LOGI(TAG, "Processing improv command %s",improv_get_command_desc(command->command));
  56. if(!command){
  57. return false;
  58. }
  59. switch (command->command)
  60. {
  61. case IMPROV_CMD_WIFI_SETTINGS:
  62. // attempt to connect to the provided SSID+password
  63. improv_state = IMPROV_STATE_PROVISIONING;
  64. ESP_LOGI(TAG,"Improv connect to %s",command->ssid );
  65. network_async_connect(command->ssid, command->password);
  66. FREE_AND_NULL(command->ssid);
  67. FREE_AND_NULL(command->password);
  68. break;
  69. case IMPROV_CMD_GET_CURRENT_STATE:
  70. if(wifi_state !=NETWORK_WIFI_STATE_CONNECTING){
  71. network_async_scan();
  72. }
  73. switch (wifi_state)
  74. {
  75. case NETWORK_WIFI_STATE_CONNECTING:
  76. ESP_LOGI(TAG,"Signaling improv state " );
  77. return improv_send_current_state(improv_state);
  78. break;
  79. case NETWORK_WIFI_STATE_INVALID_CONFIG:
  80. improv_state = IMPROV_STATE_READY_AUTHORIZED;
  81. ESP_LOGW(TAG,"Signaling improv state IMPROV_ERROR_UNABLE_TO_CONNECT" );
  82. return improv_send_error(IMPROV_ERROR_UNABLE_TO_CONNECT);
  83. break;
  84. case NETWORK_WIFI_STATE_FAILED:
  85. ESP_LOGW(TAG,"Signaling improv state IMPROV_ERROR_NOT_AUTHORIZED" );
  86. network_async_scan();
  87. improv_state = IMPROV_STATE_READY_AUTHORIZED;
  88. return improv_send_error(IMPROV_ERROR_NOT_AUTHORIZED);
  89. break;
  90. case NETWORK_WIFI_STATE_CONNECTED:
  91. network_async_scan();
  92. url = network_status_alloc_get_system_url();
  93. ESP_LOGI(TAG,"Signaling improv state connected state with url: %s",STR_OR_BLANK(url));
  94. improv_state = IMPROV_STATE_PROVISIONED;
  95. improv_send_current_state(improv_state);
  96. // also send url
  97. improv_send_device_url(IMPROV_CMD_GET_CURRENT_STATE,url);
  98. FREE_AND_NULL(url);
  99. break;
  100. default:
  101. ESP_LOGI(TAG,"Signaling improv state " );
  102. return improv_send_current_state(improv_state);
  103. break;
  104. }
  105. break;
  106. case IMPROV_CMD_GET_DEVICE_INFO:
  107. ESP_LOGI(TAG,"Signaling improv with device info. Firmware Name: %s, Version: %s ",desc->project_name,desc->version );
  108. host_name = config_alloc_get_str("host_name",NULL,"Squeezelite");
  109. improv_send_device_info(desc->project_name,desc->version,"ESP32",host_name);
  110. FREE_AND_NULL(host_name);
  111. break;
  112. case IMPROV_CMD_GET_WIFI_NETWORKS:
  113. ESP_LOGI(TAG,"Signaling improv with list of wifi networks " );
  114. improv_wifi_list_send();
  115. break;
  116. default:
  117. ESP_LOGE(TAG,"Signaling improv with invalid RPC call received" );
  118. improv_send_error(IMPROV_ERROR_INVALID_RPC);
  119. break;
  120. }
  121. return false;
  122. }
  123. void on_improv_error(ImprovError_t error){
  124. improv_send_error(error);
  125. ESP_LOGE(TAG,"Error processing improv-wifi packet : %s", improv_get_error_desc(error));
  126. }
  127. #if BUFFER_DEBUG
  128. void dump_buffer(const char * prefix, const char * buff, size_t len){
  129. printf("\n%s (%d): ",prefix, len);
  130. for(int i=0;i<len;i++){
  131. printf(" %c ",isprint(buff[i])?buff[i]:'.');
  132. }
  133. printf("\n%s (%d): ",prefix, len);
  134. for(int i=0;i<len;i++){
  135. printf("0x%03x ",buff[i]);
  136. }
  137. printf("\n");
  138. }
  139. #else
  140. #define dump_buffer(prefix,buff,size)
  141. #endif
  142. bool improv_send_callback(uint8_t * buffer, size_t length){
  143. dump_buffer("send", (const char *) buffer, length);
  144. uart_write_bytes(CONFIG_ESP_CONSOLE_UART_NUM,buffer,length );
  145. return true;
  146. }
  147. void improv_console_init(){
  148. ESP_LOGI(TAG,"Initializing improv callbacks");
  149. network_register_state_callback(NETWORK_WIFI_ACTIVE_STATE,WIFI_CONNECTED_STATE, "improv_got_ip", &cb_improv_got_ip);
  150. network_register_state_callback(NETWORK_WIFI_ACTIVE_STATE,WIFI_CONNECTING_NEW_FAILED_STATE, "improv_disconnect", &cb_improv_disconnected);
  151. network_register_state_callback(NETWORK_WIFI_CONFIGURING_ACTIVE_STATE,WIFI_CONFIGURING_CONNECT_FAILED_STATE, "improv_disconnect", &cb_improv_disconnected);
  152. }