extern bool ini_conf_save(p_conf conf) { dictionary *dict; FILE *fp; char buf[PATH_MAX]; int i; if (conf == NULL) { return false; } conf->confver = XREADER_VERSION_NUM; dict = dictionary_new(0); if (dict == NULL) return false; fp = fopen(conf_filename, "w"); if (fp == NULL) { return false; } if (iniparser_setstring(dict, "Global", NULL) != 0) goto error; if (iniparser_setstring(dict, "UI", NULL) != 0) goto error; if (iniparser_setstring(dict, "Text", NULL) != 0) goto error; if (iniparser_setstring(dict, "Image", NULL) != 0) goto error; if (iniparser_setstring(dict, "Music", NULL) != 0) goto error; iniparser_setstring(dict, "Global:path", conf->path); iniparser_setstring(dict, "UI:forecolor", hexToString(buf, sizeof(buf), conf->forecolor)); iniparser_setstring(dict, "Image:giftranscolor", hexToString(buf, sizeof(buf), conf->giftranscolor)); iniparser_setstring(dict, "UI:bgcolor", hexToString(buf, sizeof(buf), conf->bgcolor)); iniparser_setstring(dict, "UI:have_bg", booleanToString(buf, sizeof(buf), conf->have_bg)); iniparser_setstring(dict, "UI:titlecolor", hexToString(buf, sizeof(buf), conf->titlecolor)); iniparser_setstring(dict, "UI:menutextcolor", hexToString(buf, sizeof(buf), conf->menutextcolor)); iniparser_setstring(dict, "UI:menubcolor", hexToString(buf, sizeof(buf), conf->menubcolor)); iniparser_setstring(dict, "UI:selicolor", hexToString(buf, sizeof(buf), conf->selicolor)); iniparser_setstring(dict, "UI:selbcolor", hexToString(buf, sizeof(buf), conf->selbcolor)); iniparser_setstring(dict, "UI:msgbcolor", hexToString(buf, sizeof(buf), conf->msgbcolor)); iniparser_setstring(dict, "UI:usedyncolor", booleanToString(buf, sizeof(buf), conf->usedyncolor)); iniparser_setstring(dict, "Text:rowspace", dwordToString(buf, sizeof(buf), conf->rowspace)); iniparser_setstring(dict, "Text:infobar", infobarToString(buf, sizeof(buf), conf->infobar)); iniparser_setstring(dict, "Text:infobar_style", intToString(buf, sizeof(buf), conf->infobar_style)); iniparser_setstring(dict, "Text:rlastrow", booleanToString(buf, sizeof(buf), conf->rlastrow)); iniparser_setstring(dict, "Text:autobm", booleanToString(buf, sizeof(buf), conf->autobm)); iniparser_setstring(dict, "Text:vertread", vertreadToString(buf, sizeof(buf), conf->vertread)); iniparser_setstring(dict, "Text:encode", encodeToString(buf, sizeof(buf), conf->encode)); iniparser_setstring(dict, "Image:fit", fitToString(buf, sizeof(buf), conf->fit)); iniparser_setstring(dict, "Image:imginfobar", booleanToString(buf, sizeof(buf), conf->imginfobar)); iniparser_setstring(dict, "Text:scrollbar", booleanToString(buf, sizeof(buf), conf->scrollbar)); iniparser_setstring(dict, "Image:scale", dwordToString(buf, sizeof(buf), conf->scale)); iniparser_setstring(dict, "Image:rotate", rotateToString(buf, sizeof(buf), conf->rotate)); for (i = 0; i < 20; ++i) { char key[20]; SPRINTF_S(key, "Text:txtkey1_%02d", i); iniparser_setstring(dict, key, hexToString(buf, sizeof(buf), conf->txtkey[i])); SPRINTF_S(key, "Image:imgkey1_%02d", i); iniparser_setstring(dict, key, hexToString(buf, sizeof(buf), conf->imgkey[i])); } iniparser_setstring(dict, "Global:shortpath", conf->shortpath); iniparser_setstring(dict, "Global:confver", hexToString(buf, sizeof(buf), conf->confver)); iniparser_setstring(dict, "Image:bicubic", booleanToString(buf, sizeof(buf), conf->bicubic)); iniparser_setstring(dict, "Text:wordspace", dwordToString(buf, sizeof(buf), conf->wordspace)); iniparser_setstring(dict, "Text:borderspace", dwordToString(buf, sizeof(buf), conf->borderspace)); iniparser_setstring(dict, "Global:lastfile", conf->lastfile); iniparser_setstring(dict, "Music:mp3encode", encodeToString(buf, sizeof(buf), conf->mp3encode)); iniparser_setstring(dict, "Music:lyricencode", encodeToString(buf, sizeof(buf), conf->lyricencode)); iniparser_setstring(dict, "Music:mp3cycle", cycleToString(buf, sizeof(buf), conf->mp3cycle)); iniparser_setstring(dict, "Global:isreading", booleanToString(buf, sizeof(buf), conf->isreading)); iniparser_setstring(dict, "UI:bgarch", conf->bgarch); iniparser_setstring(dict, "UI:bgfile", conf->bgfile); iniparser_setstring(dict, "UI:bgwhere", intToString(buf, sizeof(buf), conf->bgwhere)); iniparser_setstring(dict, "Image:slideinterval", dwordToString(buf, sizeof(buf), conf->slideinterval)); iniparser_setstring(dict, "Music:hprmctrl", booleanToString(buf, sizeof(buf), conf->hprmctrl)); iniparser_setstring(dict, "UI:grayscale", intToString(buf, sizeof(buf), conf->grayscale)); iniparser_setstring(dict, "Global:showhidden", booleanToString(buf, sizeof(buf), conf->showhidden)); iniparser_setstring(dict, "Global:showunknown", booleanToString(buf, sizeof(buf), conf->showunknown)); iniparser_setstring(dict, "Global:showfinfo", booleanToString(buf, sizeof(buf), conf->showfinfo)); iniparser_setstring(dict, "Global:allowdelete", booleanToString(buf, sizeof(buf), conf->allowdelete)); iniparser_setstring(dict, "Global:arrange", arrangeToString(buf, sizeof(buf), conf->arrange)); iniparser_setstring(dict, "Global:enableusb", booleanToString(buf, sizeof(buf), conf->enableusb)); iniparser_setstring(dict, "Image:viewpos", viewposToString(buf, sizeof(buf), conf->viewpos)); iniparser_setstring(dict, "Image:imgmvspd", dwordToString(buf, sizeof(buf), conf->imgmvspd)); iniparser_setstring(dict, "Image:imgpaging", imgpagingToString(buf, sizeof(buf), conf->imgpaging)); iniparser_setstring(dict, "Image:imgpaging_spd", dwordToString(buf, sizeof(buf), conf->imgpaging_spd)); iniparser_setstring(dict, "Image:imgpaging_interval", dwordToString(buf, sizeof(buf), conf->imgpaging_interval)); iniparser_setstring(dict, "Image:imgpaging_duration", dwordToString(buf, sizeof(buf), conf->imgpaging_duration)); for (i = 0; i < 20; ++i) { char key[20]; SPRINTF_S(key, "Global:flkey1_%02d", i); iniparser_setstring(dict, key, hexToString(buf, sizeof(buf), conf->flkey[i])); } iniparser_setstring(dict, "UI:fontsize", intToString(buf, sizeof(buf), conf->fontsize)); iniparser_setstring(dict, "Text:reordertxt", booleanToString(buf, sizeof(buf), conf->reordertxt)); iniparser_setstring(dict, "Text:pagetonext", booleanToString(buf, sizeof(buf), conf->pagetonext)); iniparser_setstring(dict, "Text:autopage", intToString(buf, sizeof(buf), conf->autopage)); iniparser_setstring(dict, "Text:prev_autopage", intToString(buf, sizeof(buf), conf->prev_autopage)); iniparser_setstring(dict, "Text:autopagetype", intToString(buf, sizeof(buf), conf->autopagetype)); iniparser_setstring(dict, "Text:autolinedelay", intToString(buf, sizeof(buf), conf->autolinedelay)); iniparser_setstring(dict, "Image:thumb", thumbToString(buf, sizeof(buf), conf->thumb)); iniparser_setstring(dict, "Text:bookfontsize", intToString(buf, sizeof(buf), conf->bookfontsize)); iniparser_setstring(dict, "Text:enable_analog", booleanToString(buf, sizeof(buf), conf->enable_analog)); iniparser_setstring(dict, "Image:img_enable_analog", booleanToString(buf, sizeof(buf), conf->img_enable_analog)); for (i = 0; i < 20; ++i) { char key[20]; SPRINTF_S(key, "Text:txtkey2_%02d", i); iniparser_setstring(dict, key, hexToString(buf, sizeof(buf), conf->txtkey2[i])); SPRINTF_S(key, "Image:imgkey2_%02d", i); iniparser_setstring(dict, key, hexToString(buf, sizeof(buf), conf->imgkey2[i])); SPRINTF_S(key, "Global:flkey2_%02d", i); iniparser_setstring(dict, key, hexToString(buf, sizeof(buf), conf->flkey2[i])); } iniparser_setstring(dict, "Image:imgpagereserve", dwordToString(buf, sizeof(buf), conf->imgpagereserve)); iniparser_setstring(dict, "Music:lyricex", dwordToString(buf, sizeof(buf), conf->lyricex)); iniparser_setstring(dict, "Music:autoplay", booleanToString(buf, sizeof(buf), conf->autoplay)); iniparser_setstring(dict, "Text:usettf", booleanToString(buf, sizeof(buf), conf->usettf)); iniparser_setstring(dict, "Text:cttfarch", conf->cttfarch); iniparser_setstring(dict, "Text:cttfpath", conf->cttfpath); iniparser_setstring(dict, "Text:ettfarch", conf->ettfarch); iniparser_setstring(dict, "Text:ettfpath", conf->ettfpath); for (i = 0; i < 3; ++i) { char key[20]; SPRINTF_S(key, "Global:freqs_%d", i); iniparser_setstring(dict, key, intToString(buf, sizeof(buf), conf->freqs[i])); } iniparser_setstring(dict, "Image:imgbrightness", intToString(buf, sizeof(buf), conf->imgbrightness)); iniparser_setstring(dict, "Global:dis_scrsave", booleanToString(buf, sizeof(buf), conf->dis_scrsave)); iniparser_setstring(dict, "Global:autosleep", intToString(buf, sizeof(buf), conf->autosleep)); iniparser_setstring(dict, "Image:load_exif", booleanToString(buf, sizeof(buf), conf->load_exif)); iniparser_setstring(dict, "Global:launchtype", intToString(buf, sizeof(buf), conf->launchtype)); iniparser_setstring(dict, "Text:infobar_use_ttf_mode", booleanToString(buf, sizeof(buf), conf->infobar_use_ttf_mode)); iniparser_setstring(dict, "Text:infobar_fontsize", dwordToString(buf, sizeof(buf), conf->infobar_fontsize)); iniparser_setstring(dict, "Image:no_repeat", booleanToString(buf, sizeof(buf), conf->img_no_repeat)); iniparser_setstring(dict, "Global:hide_flash", booleanToString(buf, sizeof(buf), conf->hide_flash)); iniparser_setstring(dict, "Text:tabstop", dwordToString(buf, sizeof(buf), conf->tabstop)); iniparser_setstring(dict, "Music:apetagorder", booleanToString(buf, sizeof(buf), conf->apetagorder)); iniparser_setstring(dict, "UI:language", conf->language); iniparser_setstring(dict, "UI:filelistwidth", intToString(buf, sizeof(buf), conf->filelistwidth)); iniparser_setstring(dict, "Text:ttf_load_to_memory", booleanToString(buf, sizeof(buf), conf->ttf_load_to_memory)); iniparser_setstring(dict, "Global:save_password", booleanToString(buf, sizeof(buf), conf->save_password)); iniparser_setstring(dict, "Text:scrollbar_width", intToString(buf, sizeof(buf), conf->scrollbar_width)); iniparser_setstring(dict, "Text:hide_last_row", booleanToString(buf, sizeof(buf), conf->hide_last_row)); iniparser_setstring(dict, "Text:infobar_show_timer", booleanToString(buf, sizeof(buf), conf->infobar_show_timer)); iniparser_setstring(dict, "Text:englishtruncate", booleanToString(buf, sizeof(buf), conf->englishtruncate)); iniparser_setstring(dict, "Image:image_scroll_chgn_speed", booleanToString(buf, sizeof(buf), conf->image_scroll_chgn_speed)); iniparser_setstring(dict, "Text:ttf_haste_up", booleanToString(buf, sizeof(buf), conf->ttf_haste_up)); iniparser_setstring(dict, "Text:linenum_style", booleanToString(buf, sizeof(buf), conf->linenum_style)); iniparser_setstring(dict, "Text:infobar_align", alignToString(buf, sizeof(buf), conf->infobar_align)); iniparser_setstring(dict, "Music:musicdrv_opts", conf->musicdrv_opts); iniparser_setstring(dict, "Image:magnetic_scrolling", booleanToString(buf, sizeof(buf), conf->magnetic_scrolling)); iniparser_setstring(dict, "Image:use_image_queue", booleanToString(buf, sizeof(buf), conf->use_image_queue)); iniparser_setstring(dict, "Image:max_cache_img", dwordToString(buf, sizeof(buf), conf->max_cache_img)); iniparser_setstring(dict, "Music:show_encoder_msg", booleanToString(buf, sizeof(buf), conf->show_encoder_msg)); iniparser_dump_ini(dict, fp); fclose(fp); dictionary_del(dict); return true; error: if (fp != NULL) fclose(fp); return false; }
/** * \brief Runs a control event managing the configuration file. * This functions handles reading the configuration information * sent by the drone on the TCP 'control' socket on port 5559. * Called by the 'ardrone_control' thread loop in 'ardrone_control.c'. */ C_RESULT ardrone_control_configuration_run( uint32_t ardrone_state, ardrone_control_configuration_event_t* event ) { int32_t buffer_size; char *start_buffer, *buffer; char *value, *param, *c; bool_t ini_buffer_end, ini_buffer_more; C_RESULT res = C_OK; int bytes_to_read; /* Multiconfiguration support */ static char *custom_configuration_list_buffer = NULL; static int custom_configuration_list_buffer_size = 0; static int custom_configuration_list_data_size = 0; #define CUSTOM_CFG_BLOCK_SIZE 1024 int i; switch( event->config_state ) { case CONFIG_REQUEST_INI: if( ardrone_state & ARDRONE_COMMAND_MASK ) { /* If the ACK bit is set, we must ask the drone to clear it before asking the configuration. */ DEBUG_CONFIG_RECEIVE("%s %s %i - Requesting ack. bit reset.\n",__FILE__,__FUNCTION__,__LINE__); ardrone_at_update_control_mode(ACK_CONTROL_MODE, 0); } else { DEBUG_CONFIG_RECEIVE("%s %s %i - Requesting the configuration.\n",__FILE__,__FUNCTION__,__LINE__); ini_buffer_index = 0; ardrone_at_configuration_get_ctrl_mode(); set_state(event, CONFIG_RECEIVE_INI); } break; /* multi-configuration support */ case CUSTOM_CONFIG_REQUEST: DEBUG_CONFIG_RECEIVE("%s %s %i\n",__FILE__,__FUNCTION__,__LINE__); if( ardrone_state & ARDRONE_COMMAND_MASK ) { DEBUG_CONFIG_RECEIVE("%s %s %i - Requesting ack. bit reset.\n",__FILE__,__FUNCTION__,__LINE__); ardrone_at_update_control_mode(ACK_CONTROL_MODE, 0); } else { DEBUG_CONFIG_RECEIVE("%s %s %i - Requesting the custom config.\n",__FILE__,__FUNCTION__,__LINE__); custom_configuration_list_buffer = NULL; custom_configuration_list_buffer_size = 0; custom_configuration_list_data_size = 0; ardrone_at_custom_configuration_get_ctrl_mode(); set_state(event, CUSTOM_CONFIG_RECEIVE); } break; case CONFIG_RECEIVE_INI: DEBUG_CONFIG_RECEIVE("%s %s %i - Trying to read the control socket.\n",__FILE__,__FUNCTION__,__LINE__); // Read data coming from ARDrone buffer_size = ARDRONE_CONTROL_CONFIGURATION_INI_BUFFER_SIZE - ini_buffer_index; res = ardrone_control_read( &ini_buffer[ini_buffer_index], &buffer_size ); DEBUG_CONFIG_RECEIVE("Received <<%s>>\n",&ini_buffer[ini_buffer_index]); if(VP_SUCCEEDED(res)) { buffer_size += ini_buffer_index; ini_buffer[buffer_size]=0; // Makes sure the buffer ends with a zero // Parse received data if( buffer_size > 0 ) { //DEBUG_CONFIG_RECEIVE(" Searching value\n"); ini_buffer_end = ini_buffer[buffer_size-1] == '\0'; // End of configuration data ini_buffer_more = ini_buffer[buffer_size-1] != '\n'; // Need more configuration data to end parsing current line //if (ini_buffer_end) DEBUG_CONFIG_RECEIVE(" ini_buffer_end\n"); //if (ini_buffer_more) DEBUG_CONFIG_RECEIVE(" ini_buffer_more\n"); start_buffer = (char*)&ini_buffer[0]; buffer = strchr(start_buffer, '\n'); //DEBUG_CONFIG_RECEIVE("Le start buffer : <<%s>>\n",start_buffer); while( buffer != NULL ) { //DEBUG_CONFIG_RECEIVE(" Found an '\\n' \n"); value = start_buffer; param = strchr(value, '='); *buffer = '\0'; *param = '\0'; // Remove spaces at end of strings c = param - 1; while( *c == ' ' ) { *c = '\0'; c = c-1; } c = buffer-1; while( *c == ' ' ) { *c = '\0'; c = c-1; } // Remove spaces at beginning of strings while( *value == ' ' ) { value = value + 1; } param = param + 1; while( *param == ' ' ) { param = param + 1; } DEBUG_CONFIG_RECEIVE(" Decoding from control stream : <%s>=<%s>\n",value,param); iniparser_setstring( event->ini_dict, value, param ); start_buffer = buffer + 1; buffer = strchr(start_buffer, '\n'); } if( ini_buffer_end ) { /* Reading the condfiguration is finished, we ask the drone * to clear the ACK bit */ ardrone_at_update_control_mode(ACK_CONTROL_MODE, 0); set_state(event, CONFIG_RECEIVED); } else if( ini_buffer_more ) { // Compute number of bytes to copy int32_t size = (int32_t)&ini_buffer[buffer_size] - (int32_t)start_buffer; vp_os_memcpy( &ini_buffer[0], start_buffer, size ); ini_buffer_index = size; } else { /* The previous line was completely consumed - next data * from the network will be stored at the beginning of the * buffer. */ ini_buffer_index = 0; } } } else { res = C_FAIL; DEBUG_CONFIG_RECEIVE("%s %s %i - no data to read from the control socket.\n",__FILE__,__FUNCTION__,__LINE__); if(!(ardrone_state & ARDRONE_COMMAND_MASK)) set_state(event, CONFIG_REQUEST_INI); } break; case CUSTOM_CONFIG_RECEIVE: DEBUG_CONFIG_RECEIVE("%s %s %i - Trying to read the control socket.\n",__FILE__,__FUNCTION__,__LINE__); DEBUG_CONFIG_RECEIVE("%s %s %i\n",__FILE__,__FUNCTION__,__LINE__); /* Read data until a zero byte is received */ /* Clear old data from the buffer when receiving the first bytes */ if (custom_configuration_list_buffer!=NULL && custom_configuration_list_data_size==0){ vp_os_memset(custom_configuration_list_buffer,0,custom_configuration_list_buffer_size); } /* Enlarge the buffer if needed */ if (custom_configuration_list_data_size==custom_configuration_list_buffer_size) { custom_configuration_list_buffer_size += CUSTOM_CFG_BLOCK_SIZE; custom_configuration_list_buffer = vp_os_realloc(custom_configuration_list_buffer,custom_configuration_list_buffer_size); } /* Read data at the end of the buffer */ bytes_to_read = custom_configuration_list_buffer_size - custom_configuration_list_data_size; res = ardrone_control_read( &custom_configuration_list_buffer[custom_configuration_list_data_size], &bytes_to_read ); DEBUG_CONFIG_RECEIVE(" Reading %i bytes of the custom config. list\n",bytes_to_read); for (i=0;i<bytes_to_read;i++) { DEBUG_CONFIG_RECEIVE("<%i>",custom_configuration_list_buffer[i]); } /* Searches a zero */ if (VP_SUCCEEDED(res)) { custom_configuration_list_data_size += bytes_to_read; for (i=bytes_to_read;i>0;i--){ if (custom_configuration_list_buffer[custom_configuration_list_data_size - i] == 0) { /* Reading the condfiguration is finished, we ask the drone * to clear the ACK bit */ DEBUG_CONFIG_RECEIVE("Finished receiving\n"); ardrone_at_update_control_mode(ACK_CONTROL_MODE, 0); set_state(event, CUSTOM_CONFIG_RECEIVED); ardrone_control_reset_custom_configurations_list(available_configurations); ardrone_control_read_custom_configurations_list(custom_configuration_list_buffer, custom_configuration_list_data_size, available_configurations); /* Clean up */ vp_os_sfree((void *)&custom_configuration_list_buffer); custom_configuration_list_buffer_size = 0; custom_configuration_list_data_size = 0; res = C_OK; break; } } } else{ /* No data are available on the control socket. */ DEBUG_CONFIG_RECEIVE("%s %s %i - no data to read from the control socket.\n",__FILE__,__FUNCTION__,__LINE__); /* Reset the buffer */ custom_configuration_list_data_size = 0; /* The request for the configuration file should have been acknowledged by the drone. * If not, another request is sent. */ if(!(ardrone_state & ARDRONE_COMMAND_MASK)) set_state(event, CUSTOM_CONFIG_REQUEST); } break; case CONFIG_RECEIVED: case CUSTOM_CONFIG_RECEIVED: /* We finished reading the configuration, we wait for the drone to reset the ACK bit */ if( ardrone_state & ARDRONE_COMMAND_MASK ) { /* If the ACK bit is set, we must ask the drone to clear it before asking the configuration. */ PRINT("%s %s %i - Requesting ack. bit reset.\n",__FILE__,__FUNCTION__,__LINE__); ardrone_at_update_control_mode(ACK_CONTROL_MODE, 0); } else { PRINT("%s %s %i - Finished.\n",__FILE__,__FUNCTION__,__LINE__); event->status = ARDRONE_CONTROL_EVENT_FINISH_SUCCESS; } res = C_OK; break; default: res = C_FAIL; break; } return res; }