const char *config_get_string(config_t config, const char *section, const char *name) { struct config_item *item = config_find_item(&config->sections, section, name); if (!item) item = config_find_item(&config->defaults, section, name); if (!item) return NULL; return item->value; }
/* write a new configuration item to config space in flash memory. * data will be 4-byte aligned when writing, but original length information * will be retained. * * @return 0 if successful, -2 when no space for storing data is available, * -1 when there is not enough space for the requested length */ int config_write(const uint32_t type, const uint32_t length, const void* data) { uint32_t *dst = (uint32_t*) config_find_item(CONFIG_UNSET); if(dst == NULL) return -2; if(dst + length + 3 >= (uint32_t*)(CONFIG_ADDRESS + CONFIG_SIZE)) return -1; flash_unlock(); /* write header information */ flash_program_word((uint32_t)(dst++), type); flash_program_word((uint32_t)(dst++), length); /* word-wise reading/writing */ uint32_t p = 0; for(; p + 3 < length; p+=sizeof(uint32_t)) { uint32_t v = *((uint32_t*)(data+p)); flash_program_word((uint32_t)(dst++), v); } /* read remainder of partial last word */ if(p < length) { uint32_t v = ((uint8_t*)data)[p++]; if(p < length) v = v | (((uint8_t*)data)[p++] << 8); if(p < length) v = v | (((uint8_t*)data)[p++] << 16); flash_program_word((uint32_t)(dst++), v); } flash_lock(); return 0; }
void config_add(struct config* conf, const char* section, const char* key, const char* val) { struct configsection* sect; if((sect=config_find_section(conf, section))) { struct configitem* item; if((item=config_find_item(conf, key, section))) { if(item->val) free(item->val); if(val) item->val=strdup(val); else item->val=NULL; } else item_add(sect, key, val); } else { section_new(conf, section); config_add(conf, section, key, val); } }
static int tapi2p_callback(struct libwebsocket_context *ctx, struct libwebsocket *wsi, enum libwebsocket_callback_reasons reason, void* user, void* in, size_t len) { switch(reason) { case LWS_CALLBACK_ESTABLISHED: lwsl_notice("Handshaked with client.\n"); libwebsocket_callback_on_writable(ctx, wsi); break; case LWS_CALLBACK_SERVER_WRITEABLE: { if(corefd==-1) { char* conn_reply="Could not connect to tapi2p. Is tapi2p core running?"; websocket_send(wsi, conn_reply, strlen(conn_reply)); } else if(!welcome_message_sent) { struct config* conf=getconfig(); if(conf) { struct configitem* ci=config_find_item(conf, "Nick", "Account"); if(ci && ci->val) { json_t *root=json_object(); json_object_set_new(root, "cmd", json_integer(Message)); json_object_set_new(root, "data", json_string("Welcome to tapi2p, ")); json_object_set_new(root, "own_nick", json_string(ci->val)); char *jsonstr=json_dumps(root, 0); welcome_message_sent=1; websocket_send(wsi, jsonstr, strlen(jsonstr)); free(jsonstr); json_decref(root); lwsl_notice("Sent welcome message.\n"); } } } else if(unsent_data>0) { pthread_mutex_lock(&datalock); while(unsent_data) { char* data=data_to_send[--unsent_data]; printf("Sent: %s\n", data); websocket_send(wsi, data, strlen(data)); free(data); } pthread_mutex_unlock(&datalock); } usleep(10000); libwebsocket_callback_on_writable(ctx, wsi); break; } case LWS_CALLBACK_CLOSED: lwsl_notice("Connection to client closed.\n"); break; case LWS_CALLBACK_RECEIVE: lwsl_notice("Message from client\n"); printf("Json: %s %d\n", (char*)in, len); send_json((char*) in, len); break; } return 0; }
/* convenience function for accessing configuration consisting of one word of data */ uint32_t config_get_uint32(const uint32_t type) { void *dst = config_find_item(type); if(dst == NULL) return 0; return *((uint32_t*)(dst + sizeof(struct config_item))); }
bool config_has_default_value(const config_t *config, const char *section, const char *name) { return config_find_item(&config->defaults, section, name) != NULL; }
bool config_has_user_value(const config_t *config, const char *section, const char *name) { return config_find_item(&config->sections, section, name) != NULL; }