int Img_CallbackThread::RegisterObserver(c_ProcessingObserver* pObserver, void * /*pContext*/) //************************************************************************************************************* { // Before executing the event, check that the Img_EnsWrapper is (still) unregistered from the observer // Note: OMX components must be locked to ensure that there is no modification of Img_EnsWrapper data by // concurrent OMX components. // printf("\n************** Img_CallbackThread::RegisterObserver\n"); OTB_ASSERT(pObserver != NULL); // Check if we can accept the request // Note: component is locked if (m_NbRegistered >= Max_NumberObserverRegistred) { // Max number of registered client reached OTB_ASSERT(0); return eError_ToManyRegistredComponent; } // Check if observer is already registered if (IsRegistredObserver(pObserver)) { // Observer already registered OTB_ASSERT(0); return eError_ComponentAlreadyRegistred; } // Set observer notif function e_ProcObsError eObsErr = pObserver->SetNotifFunction(Img_CallbackThread::staticObserverNotifFunction, (void *) this); if (eObsErr != PROCOBS_ERROR_NONE) { // ENS Wrapper failed to register OTB_ASSERT(eObsErr == PROCOBS_ERROR_NONE); return eError_CannotRegisterNotifyFunction; } // Successfully registered: store the new entry m_Array_RegisteredObserver[m_NbRegistered] = pObserver; m_NbRegistered++; return eError_None; }
int ImgMasterCallbackThread::staticRegisterObserver(c_ProcessingObserver* pObserver, void * pContext) //************************************************************************************************************* { // Register the observer and create the singleton instance if required //printf("\n\n\n\n\n************** ImgMasterCallbackThread::staticRegisterObserver\n\n\n\n\n\n"); //printf("staticRegisterObserver\n"); MutexedCode ProtectedCode(m_Mutex); OTB_ASSERT(pObserver != NULL); ImgMasterCallbackThread *pImgCallbackThread = __GetInstance(); if (pImgCallbackThread == NULL) { // Cannot get the instance OTB_ASSERT(pImgCallbackThread != NULL); return (eError_CannotGetInstance); } int result = ((Img_CallbackThread *) pImgCallbackThread)->RegisterObserver(pObserver, pContext); if (result != eError_None) { // Registry of observer failed OTB_ASSERT(result == eError_None); } else { // Start if not done if (pImgCallbackThread->IsThreadStarted() != true) result = pImgCallbackThread->Start(); } return (result); }
int ImgMasterCallbackThread::staticUnregisterObserver(c_ProcessingObserver* pObserver, void * pContext) //************************************************************************************************************* { OTB_ASSERT(pObserver != NULL); MutexedCode ProtectedCode(m_Mutex); ImgMasterCallbackThread *pImgCallbackThread = __GetInstance(); if (pImgCallbackThread == NULL) { OTB_ASSERT(pImgCallbackThread != NULL); return (eError_CannotGetInstance); } int result = ((Img_CallbackThread *) pImgCallbackThread)->UnregisterObserver(pObserver, pContext); if (result != eError_None) { OTB_ASSERT(result == eError_None); } if (pImgCallbackThread->GetNbRegistredObserver() == 0) { // No more observer, stop the thead and delete object pImgCallbackThread->Stop(); // delete pImgCallbackThread; //Deinstantiate the object m_pSingleton = NULL; // The smart pointer will distroy the pointer } return (result); }
int Img_CallbackThread::UnregisterObserver(c_ProcessingObserver* pObserver, void * /*pContext*/) //******************************************************************************** { // printf("\n ************** Img_CallbackThread::UnregisterObserver\n"); OTB_ASSERT(pObserver != NULL); // Check if we can accept the request // Note: component is locked size_t index; if (IsRegistredObserver(pObserver, &index) == false) { // The requester is not registered return eError_ComponentNotRegistred; } // Unset notif function from observer e_ProcObsError eObsErr = pObserver->UnsetNotifFunction(); OTB_ASSERT(eObsErr == PROCOBS_ERROR_NONE); // In case of error, we continue anyway so that the ENS wrapper is really // unregistered from the observer // Swap last entry with current (now free) one so that the array has no holes m_Array_RegisteredObserver[index] = m_Array_RegisteredObserver[m_NbRegistered - 1]; m_Array_RegisteredObserver[m_NbRegistered - 1] = NULL; m_NbRegistered--; return eObsErr == PROCOBS_ERROR_NONE ? eError_None : eError_CannotUnregisterNotifyFunction; }
bool ICACHE_FLASH_ATTR otb_conf_update_loc(int loc, char *val) { int len; bool rc = FALSE; otb_conf_struct *conf; DEBUG("CONF: otb_conf_update entry"); conf = &otb_conf_private; OTB_ASSERT((loc >= 1) && (loc <= 3)); len = os_strlen(val); if (len > (OTB_CONF_LOCATION_MAX_LEN)) { otb_cmd_rsp_append("location string too long", val); goto EXIT_LABEL; } switch (loc) { case 1: os_strncpy(conf->loc.loc1, val, OTB_CONF_LOCATION_MAX_LEN); break; case 2: os_strncpy(conf->loc.loc2, val, OTB_CONF_LOCATION_MAX_LEN); break; case 3: os_strncpy(conf->loc.loc3, val, OTB_CONF_LOCATION_MAX_LEN); break; default: OTB_ASSERT(FALSE); goto EXIT_LABEL; break; } rc = otb_conf_update(conf); if (!rc) { ERROR("CONF: Failed to update config"); otb_cmd_rsp_append("internal error"); } EXIT_LABEL: DEBUG("CONF: otb_conf_update exit"); return rc; }
bool ICACHE_FLASH_ATTR otb_ds18b20_conf_delete(unsigned char *next_cmd, void *arg, unsigned char *prev_cmd) { bool rc = FALSE; int cmd; char *match; char *addr; otb_conf_ds18b20 *ds18b20; DEBUG("DS18B20: otb_ds18b20_conf_delete entry"); cmd = (int)arg; if (cmd == OTB_CMD_DS18B20_ALL) { os_memset(otb_conf->ds18b20, 0, sizeof(struct otbDs18b20DeviceAddress) * OTB_DS18B20_MAX_DS18B20S); otb_conf->ds18b20s = 0; rc = TRUE; goto EXIT_LABEL; } else if (cmd == OTB_CMD_DS18B20_ADDR) { // We've tested the address is configured already, so a bit of asserting addr = prev_cmd; match = otb_ds18b20_get_sensor_name(addr, &ds18b20); OTB_ASSERT(match != NULL); os_memset(ds18b20, 0, sizeof(otb_conf_ds18b20)); otb_conf->ds18b20s--; rc = TRUE; } else { OTB_ASSERT(FALSE); } EXIT_LABEL: // If successful store off new config if (rc) { rc = otb_conf_update(otb_conf); if (!rc) { otb_cmd_rsp_append("failed to store new config"); } } DEBUG("DS18B20: otb_ds18b20_conf_delete exit"); return rc; }
void ICACHE_FLASH_ATTR otb_conf_init(void) { DEBUG("CONF: otb_conf_init entry"); OTB_ASSERT(OTB_DS18B20_MAX_ADDRESS_STRING_LENGTH == OTB_CONF_DS18B20_MAX_ID_LEN); OTB_ASSERT(OTB_CONF_MAX_CONF_SIZE >= sizeof(otb_conf_struct)); os_memset((void *)&otb_conf_private, 0, sizeof(otb_conf)); otb_conf = &otb_conf_private; DEBUG("CONF: otb_conf_init entry"); return; }
t_ThreadReturnType Img_CallbackThread::staticObserversThread(void* param) //************************************************************************************************************* { // static Entry point for new thread Img_CallbackThread *pImgThread = (Img_CallbackThread *) param; if (pImgThread) { OTB_ASSERT(pImgThread->IsThreadStarted()== false); pImgThread->ObserversThread(param); // call the thread main routine RETURN_THREAD(0); } else { OTB_ASSERT(0); // Cannot create the thread RETURN_THREAD((t_ThreadReturnType)-1); } }
uint16_t ICACHE_FLASH_ATTR otb_conf_calc_checksum(otb_conf_struct *conf) { uint16_t calc_sum = 0; uint8_t *conf_data; uint16_t ii; DEBUG("CONF: otb_conf_calc_checksum entry"); // Check 16-bit ii is sufficient OTB_ASSERT(sizeof(otb_conf_struct) <= 2^16); conf_data = (uint8_t *)conf; // Very simple checksum algorithm for (ii = 0; ii < sizeof(otb_conf_struct); ii++) { calc_sum += conf_data[ii]; } // Now take off the checksum field - this is not part of the checksum check calc_sum -= conf_data[OTB_CONF_CHECKSUM_BYTE1-1]; calc_sum -= conf_data[OTB_CONF_CHECKSUM_BYTE2-1]; DEBUG("CONF: otb_conf_calc_checksum exit"); return calc_sum; }
void Img_CallbackThread::ObserverNotifFunction(void *pContext, c_ProcessingObserver *pObserver) //************************************************************************************************************* { // Memorize the observer request // printf("\n ************** Img_CallbackThread::ObserverNotifFunction\n"); OTB_ASSERT(pObserver != NULL); (void) pContext; Observer_Message* pMessage = NULL; m_QueueMessages.PopFree(pMessage); OTB_ASSERT(pMessage != NULL); if (pMessage != NULL) { pMessage->eType = OBSERVER_NOTIF_MSG; pMessage->pObserver = pObserver; m_QueueMessages.PushUsed(pMessage); } }
bool ICACHE_FLASH_ATTR otb_conf_set_keep_ap_active(unsigned char *next_cmd, void *arg, unsigned char *prev_cmd) { bool rc = FALSE; bool active; DEBUG("CONF: otb_conf_set_keep_ap_active entry"); active = (bool)arg; OTB_ASSERT((active == FALSE) || (active == TRUE)); if (active) { if (otb_wifi_ap_enable()) { rc = TRUE; } } else { if (otb_wifi_ap_disable()) { rc = TRUE; } } DEBUG("CONF: otb_conf_set_keep_ap_active exit"); return rc; }
t_ThreadReturnType Img_CallbackThread::ObserversThread(void* /* No param */) //************************************************************************************************************* { // Thread that manage imaging's component callbacks m_bIsThreadStarted = true; while (1) { // Wait message notification m_Semaphore_WaitingFoMessage.Wait(); if ( (m_QueueMessages.GetUsedCount()==0) && (m_bAskThreadToStop==true)) { break; } // Unqueue message to be processed Observer_Message* pMessage = NULL; m_QueueMessages.PopUsed(pMessage); OTB_ASSERT(pMessage != NULL); if (pMessage->eType == OBSERVER_EXIT_MSG) {// old method should be remvoed break; } if (m_bAskThreadToStop==true) { OTB_ASSERT(pMessage != NULL); } // Before executing the event, check that the ENS Wrapper is (still) unregistered from the observer // Note: OMX components must be locked to ensure that there is no modification of Img_EnsWrapper data by concurrent OMX components. bool bFound = IsRegistredObserver(pMessage->pObserver); if (bFound == true) { // If observer is registered execute it //GetComponentManager().GlobalLock(ExtendedMutex::eLock_Child, (const int)g_Handle_ImgCallbackThread, __FUNCTION__); pMessage->pObserver->Execute();// Execute event //GetComponentManager().GlobalUnlock((const int)g_Handle_ImgCallbackThread, __FUNCTION__); } m_QueueMessages.PushFree(pMessage); } //DBGT_EPILOG("ObserversThread - exit\n"); m_bIsThreadStarted = false; m_Semaphore_WaitingForExit.Notify(); RETURN_THREAD(S_OK); }
/* static */ImgMasterCallbackThread *ImgMasterCallbackThread::__GetInstance() //************************************************************************************************************* { // protected NON Mutexed code. Create an instance if required if (m_pSingleton) return (m_pSingleton); //else m_pSingleton = new ImgMasterCallbackThread; OTB_ASSERT(m_pSingleton); return (m_pSingleton); }
void Img_CallbackThread::staticObserverNotifFunction(void *pContext, c_ProcessingObserver *pObserver) //************************************************************************************************************* { // static function used by c_observer Img_CallbackThread *pImgWrapper = (Img_CallbackThread *) pContext; if (pImgWrapper) { pImgWrapper->ObserverNotifFunction(pContext, pObserver); // Call the instance } else { OTB_ASSERT(0); } }
void ICACHE_FLASH_ATTR otb_conf_init_config(otb_conf_struct *conf) { DEBUG("CONF: otb_conf_init_config entry"); os_memset(conf, 0, sizeof(otb_conf_struct)); conf->magic = OTB_CONF_MAGIC; conf->version = OTB_CONF_VERSION_CURRENT; conf->mqtt.port = OTB_MQTT_DEFAULT_PORT; // Do this last! conf->checksum = otb_conf_calc_checksum(conf); OTB_ASSERT(otb_conf_verify_checksum(conf)); DEBUG("CONF: otb_conf_init_config exit"); return; }
int Img_CallbackThread::Stop() //************************************************************************************************************* { if (m_NbRegistered != 0) return (eError_None); m_bAskThreadToStop=true; m_Semaphore_WaitingFoMessage.Notify(); // Wait for observer processing thread to exit m_Semaphore_WaitingForExit.Wait(); OTB_ASSERT(IsThreadStarted()== false); // Destroy semaphores m_Semaphore_WaitingFoMessage.Destroy(); m_Semaphore_WaitingForExit .Destroy(); m_QueueMessages.Clean(); return (eError_None); }
int Img_CallbackThread::Start(int priority, size_t stack) //************************************************************************************************************* { // start the callback thread if not already done if (IsThreadStarted() == true) return (eError_None); // Create semaphores m_Semaphore_WaitingFoMessage.Create(0); m_Semaphore_WaitingForExit.Create(0); m_bAskThreadToStop = false; OTB_ASSERT(m_bIsThreadStarted == false); m_QueueMessages.Init(&Observer_EmptyMsg); // Start the thread managing the observers requests steCreateThread(staticObserversThread, this, stack, priority, "IMG-OBSERVER-CB-THREAD"); return(S_OK); }
bool ICACHE_FLASH_ATTR otb_conf_verify(otb_conf_struct *conf) { bool rc = FALSE; int ii; char pad[3] = {0, 0, 0}; bool modified = FALSE; int valid_adss = 0; DEBUG("CONF: otb_conf_verify entry"); // Test magic value if (otb_conf->magic != OTB_CONF_MAGIC) { ERROR("CONF: Bad magic value - invalid config file"); rc = FALSE; goto EXIT_LABEL; } // Test version valid if (otb_conf->version > OTB_CONF_VERSION_CURRENT) { ERROR("CONF: Bad magic value - invalid config file"); rc = FALSE; goto EXIT_LABEL; } // Test checksum rc = otb_conf_verify_checksum(conf); if (!rc) { ERROR("CONF: Bad checksum - invalid config file"); goto EXIT_LABEL; } if (otb_conf->version >= 1) { if ((os_strnlen(conf->ssid, OTB_CONF_WIFI_SSID_MAX_LEN) >= OTB_CONF_WIFI_SSID_MAX_LEN) || (os_strnlen(conf->password, OTB_CONF_WIFI_PASSWORD_MAX_LEN) >= OTB_CONF_WIFI_PASSWORD_MAX_LEN)) { // Reset _both_ ssid and password if either got corrupted WARN("CONF: SSID or Password wasn't null terminated"); os_memset(conf->ssid, 0, OTB_CONF_WIFI_SSID_MAX_LEN); os_memset(conf->password, 0, OTB_CONF_WIFI_PASSWORD_MAX_LEN); modified = TRUE; } if (os_memcmp(conf->pad1, pad, sizeof(*(conf->pad1)))) { WARN("CONF: Pad 1 wasn't 0"); os_memset(conf->pad1, 0, 3); modified = TRUE; } // DS18B20 config checking if ((conf->ds18b20s < 0) || (conf->ds18b20s > OTB_DS18B20_MAX_DS18B20S)) { WARN("CONF: Invalid number of DS18B20s"); conf->ds18b20s = 0; os_memset(conf->ds18b20, 0, OTB_DS18B20_MAX_DS18B20S * sizeof(otb_conf_ds18b20)); } for (ii = 0; ii < OTB_DS18B20_MAX_DS18B20S; ii++) { // Check DS18B20 id is right length (or 0), and location is null terminated if (((os_strnlen(conf->ds18b20[ii].id, OTB_CONF_DS18B20_MAX_ID_LEN) != OTB_CONF_DS18B20_MAX_ID_LEN-1) && (conf->ds18b20[ii].id[0] != 0)) || (os_strnlen(conf->ds18b20[ii].loc, OTB_CONF_DS18B20_LOCATION_MAX_LEN) >= OTB_CONF_DS18B20_LOCATION_MAX_LEN)) { WARN("CONF: DS18B20 index %d id or location invalid", ii); os_memset(conf->ds18b20[ii].id, 0, OTB_CONF_DS18B20_MAX_ID_LEN); os_memset(conf->ds18b20[ii].loc, 0, OTB_CONF_DS18B20_LOCATION_MAX_LEN); modified = TRUE; } } if ((os_strnlen(conf->loc.loc1, OTB_CONF_LOCATION_MAX_LEN) >= OTB_CONF_LOCATION_MAX_LEN) || (os_strnlen(conf->loc.loc2, OTB_CONF_LOCATION_MAX_LEN) >= OTB_CONF_LOCATION_MAX_LEN) || (os_strnlen(conf->loc.loc3, OTB_CONF_LOCATION_MAX_LEN) >= OTB_CONF_LOCATION_MAX_LEN)) { WARN("CONF: Location invalid"); os_memset(conf->loc.loc1, 0, OTB_CONF_LOCATION_MAX_LEN); os_memset(conf->loc.loc2, 0, OTB_CONF_LOCATION_MAX_LEN); os_memset(conf->loc.loc3, 0, OTB_CONF_LOCATION_MAX_LEN); modified = TRUE; } // ADS config checking if ((conf->adss < 0) || (conf->adss > OTB_CONF_ADS_MAX_ADSS)) { WARN("CONF: Invalid number of ADSs"); otb_conf_ads_init(conf); modified = TRUE; } for (ii = 0; ii < OTB_CONF_ADS_MAX_ADSS; ii++) { if (conf->ads[ii].addr != 0x00) { valid_adss++; } } if (valid_adss != otb_conf->adss) { WARN("CONF: Wrong overall ADS number set - clearing"); otb_conf_ads_init(conf); modified = TRUE; } for (ii = 0; ii < OTB_CONF_ADS_MAX_ADSS; ii++) { // Check ADS id is right length (or 0), and location is null terminated if ((os_strnlen(conf->ads[ii].loc, OTB_CONF_ADS_LOCATION_MAX_LEN) >= OTB_CONF_ADS_LOCATION_MAX_LEN) || ((conf->ads[ii].addr != 0x00) && (conf->ads[ii].addr != 0x48) && (conf->ads[ii].addr != 0x49) && (conf->ads[ii].addr != 0x4a) && (conf->ads[ii].addr != 0x4b)) || (conf->ads[ii].index != ii) || (conf->ads[ii].pad1[0] != 0) || ((conf->ads[ii].mux < 0) || (conf->ads[ii].mux > 7)) || ((conf->ads[ii].gain < 0) || (conf->ads[ii].gain > 7)) || ((conf->ads[ii].rate < 0) || (conf->ads[ii].rate > 7)) || ((conf->ads[ii].cont < 0) || (conf->ads[ii].cont > 1)) || ((conf->ads[ii].rms < 0) || (conf->ads[ii].rms > 1)) || ((conf->ads[ii].period < 0) || (conf->ads[ii].period >= 0xffff)) || ((conf->ads[ii].samples < 0) || (conf->ads[ii].samples >= 1024))) { WARN("CONF: ADS index %d something invalid", ii); INFO("CONF: ADS %d index: %d", ii, conf->ads[ii].index); INFO("CONF: ADS %d address: 0x%02x", ii, conf->ads[ii].addr); INFO("CONF: ADS %d location: %s", ii, conf->ads[ii].loc); INFO("CONF: ADS %d pad1: 0x%x", ii, conf->ads[ii].pad1[0]); INFO("CONF: ADS %d mux: 0x%x", ii, conf->ads[ii].mux); INFO("CONF: ADS %d gain: 0x%x", ii, conf->ads[ii].gain); INFO("CONF: ADS %d rate: 0x%x", ii, conf->ads[ii].rate); INFO("CONF: ADS %d cont: 0x%x", ii, conf->ads[ii].cont); INFO("CONF: ADS %d rms: 0x%x", ii, conf->ads[ii].rms); INFO("CONF: ADS %d period: %ds", ii, conf->ads[ii].period); INFO("CONF: ADS %d samples: %d", ii, conf->ads[ii].samples); otb_conf_ads_init_one(&(conf->ads[ii]), ii); modified = TRUE; } } for (ii = 0; ii < 17; ii++) { if ((conf->gpio_boot_state[ii] < 0) || (conf->gpio_boot_state[ii] > 1)) { WARN("CONF: gpio_boot_state %d invalid 0x2.2x", ii, conf->gpio_boot_state[ii]); conf->gpio_boot_state[ii] = 0; modified = TRUE; } } for (ii = 0; ii < 3; ii++) { if (conf->pad3[ii] != 0) { WARN("CONF: pad3 %d invalid 0x%2.2x", ii, conf->pad3[0]); conf->pad3[ii] = 0; modified = TRUE; } } } if (otb_conf->version > 1) { // When increment version number need to add code here to handle checking new // fields, and also upgrading back level versions ERROR("CONF: No versioning code provided for config version: %d", otb_conf->version); OTB_ASSERT(FALSE); } if (modified) { // Need to update rather than save so new checksum is calculated rc = otb_conf_update(conf); if (!rc) { ERROR("CONF: Failed to save corrected config"); goto EXIT_LABEL; } } // If we get this far everything was fine, or we fixed it rc = TRUE; EXIT_LABEL: DEBUG("CONF: otb_conf_verify exit"); return(rc); }
void ICACHE_FLASH_ATTR otb_conf_mqtt_conf(char *cmd1, char *cmd2, char *cmd3, char *cmd4, char *cmd5) { uint8 ii; uint8 field = OTB_MQTT_CONFIG_INVALID_; bool rc = FALSE; char *value; int loc_num; char response[8]; char *ok_error; DEBUG("CONF: otb_conf_mqtt entry"); // Note that cmd1 and cmd2 are colon terminated // Supported commands: // cmd1 = get/set // cmd2 = field // cmd3 = value (set only) if ((cmd1 == NULL) || (cmd2 == NULL)) { INFO("CONF: Invalid config command"); otb_mqtt_send_status(OTB_MQTT_SYSTEM_CONFIG, OTB_MQTT_STATUS_ERROR, "Invalid command", ""); goto EXIT_LABEL; } if (otb_mqtt_match(cmd1, OTB_MQTT_CMD_SET)) { for (ii = OTB_MQTT_CONFIG_FIRST_; ii <= OTB_MQTT_CONFIG_LAST_; ii++) { if (otb_mqtt_match(cmd2, otb_mqtt_config_fields[ii])) { field = ii; break; } } switch (field) { #if 0 case OTB_MQTT_CONFIG_LOC1_: case OTB_MQTT_CONFIG_LOC2_: case OTB_MQTT_CONFIG_LOC3_: otb_conf_update_loc(cmd2, cmd3); break; case OTB_MQTT_CONFIG_DS18B20_: otb_ds18b20_conf_set(cmd3, cmd4); break; case OTB_MQTT_CONFIG_ADS_: otb_i2c_ads_conf_set(cmd3, cmd4, cmd5); break; #endif default: INFO("CONF: Invalid config field"); otb_mqtt_send_status(OTB_MQTT_SYSTEM_CONFIG, OTB_MQTT_CMD_SET, OTB_MQTT_STATUS_ERROR, "Invalid field"); goto EXIT_LABEL; break; } } else if (otb_mqtt_match(cmd1, OTB_MQTT_CMD_GET)) { for (ii = OTB_MQTT_CONFIG_FIRST_; ii <= OTB_MQTT_CONFIG_LAST_; ii++) { if (otb_mqtt_match(cmd2, otb_mqtt_config_fields[ii])) { field = ii; break; } } switch (field) { case OTB_MQTT_CONFIG_KEEP_AP_ACTIVE_: value = otb_conf->keep_ap_active ? OTB_MQTT_TRUE : OTB_MQTT_FALSE; otb_mqtt_send_status(OTB_MQTT_SYSTEM_CONFIG, OTB_MQTT_CMD_GET, OTB_MQTT_STATUS_OK, value); break; case OTB_MQTT_CONFIG_LOC1_: case OTB_MQTT_CONFIG_LOC2_: case OTB_MQTT_CONFIG_LOC3_: rc = FALSE; ok_error = OTB_MQTT_STATUS_ERROR; loc_num = atoi(cmd2+3); value = "Invalid location"; if ((loc_num >= 1) && (loc_num <= 3)) { ok_error = OTB_MQTT_STATUS_OK; switch (loc_num) { case 1: value = otb_conf->loc.loc1; rc = TRUE; break; case 2: value = otb_conf->loc.loc2; rc = TRUE; break; case 3: value = otb_conf->loc.loc3; rc = TRUE; break; default: OTB_ASSERT(FALSE); rc = FALSE; ok_error = OTB_MQTT_STATUS_OK; value = "Internal error"; break; } } otb_mqtt_send_status(OTB_MQTT_SYSTEM_CONFIG, OTB_MQTT_CMD_GET, ok_error, value); goto EXIT_LABEL; break; case OTB_MQTT_CONFIG_DS18B20_: otb_ds18b20_conf_get(cmd3, cmd4); break; case OTB_MQTT_CONFIG_ADS_: otb_i2c_ads_conf_get(cmd3, cmd4, cmd5); break; case OTB_MQTT_CONFIG_DS18B20S_: os_snprintf(response, 8, "%d", otb_conf->ds18b20s); otb_mqtt_send_status(OTB_MQTT_SYSTEM_CONFIG, OTB_MQTT_CMD_GET, OTB_MQTT_STATUS_OK, response); break; case OTB_MQTT_CONFIG_ALL_: { unsigned char *conf_struct = (unsigned char *)otb_conf; unsigned char scratch[129]; unsigned char kk = 0; os_snprintf(scratch, 128, "len:%d", sizeof(otb_conf_struct)); otb_mqtt_send_status(OTB_MQTT_SYSTEM_CONFIG, OTB_MQTT_CMD_GET, OTB_MQTT_STATUS_OK, scratch); for (int jj = 0; jj < sizeof(otb_conf_struct); jj++) { os_snprintf(scratch+(kk*2), (128-(kk*2)), "%02x", conf_struct[jj]); if (kk >= 63) { // Send message of 64 bytes (128 byte string null terminated) scratch[128] = 0; otb_mqtt_send_status(OTB_MQTT_SYSTEM_CONFIG, OTB_MQTT_CMD_GET, OTB_MQTT_STATUS_OK, scratch); kk = 0; } else { kk++; } } if (kk != 0) { // Send message of k bytes scratch[kk*2] = 0; otb_mqtt_send_status(OTB_MQTT_SYSTEM_CONFIG, OTB_MQTT_CMD_GET, OTB_MQTT_STATUS_OK, scratch); } } break; default: INFO("CONF: Invalid config field"); otb_mqtt_send_status(OTB_MQTT_SYSTEM_CONFIG, OTB_MQTT_CMD_GET, OTB_MQTT_STATUS_ERROR, "Invalid field"); goto EXIT_LABEL; break; } } else { INFO("CONF: Unknown config command"); otb_mqtt_send_status(OTB_MQTT_SYSTEM_CONFIG, OTB_MQTT_STATUS_ERROR, "Invalid command", ""); goto EXIT_LABEL; } EXIT_LABEL: if (!rc) { // Nothing to do - we send an error above } DEBUG("CONF: otb_conf_mqtt exit"); return; }