/** * mongo_bson_append: * @bson: (in): A #MongoBson. * @type: (in) (type MongoBsonType): A #MongoBsonType. * @key: (in): The key for the field to append. * @data1: (in): The data for the first chunk of the data. * @len1: (in): The length of @data1. * @data2: (in): The data for the second chunk of the data. * @len2: (in): The length of @data2. * * This utility function helps us build a buffer for a #MongoBson given * the various #MongoBsonType<!-- -->'s and two-part data sections of * some fields. * * If @data2 is set, @data1 must also be set. */ static void mongo_bson_append (MongoBson *bson, guint8 type, const gchar *key, const guint8 *data1, gsize len1, const guint8 *data2, gsize len2) { const guint8 trailing = 0; gint32 doc_len; g_return_if_fail(bson != NULL); g_return_if_fail(bson->buf != NULL); g_return_if_fail(type != 0); g_return_if_fail(key != NULL); g_return_if_fail(g_utf8_validate(key, -1, NULL)); g_return_if_fail(data1 != NULL || len1 == 0); g_return_if_fail(data2 != NULL || len2 == 0); g_return_if_fail(!data2 || data1); /* * Overwrite our trailing byte with the type for this key. */ bson->buf->data[bson->buf->len - 1] = type; /* * Append the field name as a BSON cstring. */ g_byte_array_append(bson->buf, (guint8 *)key, strlen(key) + 1); /* * Append the data sections if needed. */ if (data1) { g_byte_array_append(bson->buf, data1, len1); if (data2) { g_byte_array_append(bson->buf, data2, len2); } } /* * Append our trailing byte. */ g_byte_array_append(bson->buf, &trailing, 1); /* * Update the document length of the buffer. */ doc_len = GINT_TO_LE(bson->buf->len); memcpy(bson->buf->data, &doc_len, sizeof doc_len); }
/** * mongo_bson_append_string: * @bson: (in): A #MongoBson. * @key: (in): A string containing the key. * @value: (in): A string containing the value. * * Stores the string @value in the document under @key. */ void mongo_bson_append_string (MongoBson *bson, const gchar *key, const gchar *value) { gint32 value_len; gint32 value_len_swab; g_return_if_fail(bson != NULL); g_return_if_fail(key != NULL); g_return_if_fail(g_utf8_validate(value, -1, NULL)); value = value ? value : ""; value_len = strlen(value) + 1; value_len_swab = GINT_TO_LE(value_len); mongo_bson_append(bson, MONGO_BSON_UTF8, key, (const guint8 *)&value_len_swab, sizeof value_len_swab, (const guint8 *)value, value_len); }
/** * mongo_bson_new_empty: * * Creates a new instance of #MongoBson. This function is similar to * mongo_bson_new() except that it does not pre-populate the newly created * #MongoBson instance with an _id field. * * Returns: An empty #MongoBson that should be freed with mongo_bson_unref(). */ MongoBson * mongo_bson_new_empty (void) { MongoBson *bson; gint32 len = GINT_TO_LE(5); guint8 trailing = 0; bson = g_slice_new0(MongoBson); bson->ref_count = 1; bson->buf = g_byte_array_sized_new(16); g_byte_array_append(bson->buf, (guint8 *)&len, sizeof len); g_byte_array_append(bson->buf, (guint8 *)&trailing, sizeof trailing); g_assert(bson); g_assert(bson->buf); g_assert_cmpint(bson->buf->len, ==, 5); return bson; }
/*! \brief feed_import_data_to_ecu() Forwards the data in the VEX file to the ECU. NOTE this may have problems with firmware using multiple tables in a page, as the VEX format 1.0 does NOT handle that condition. \param vex (Vex_Import *) pointer to the Vex_Impot datastructure. */ G_MODULE_EXPORT void feed_import_data_to_ecu(Vex_Import *vex) { gint i = 0; gchar *tmpbuf = NULL; guint8 **ecu_data = NULL; guint8 **ecu_data_backup = NULL; void *data = NULL; gchar * msgbuf = NULL; guchar *ptr = NULL; guint16 *ptr16 = NULL; guint32 *ptr32 = NULL; gint total = 0; gint canID = 0; gint page = -1; gint base = 0; DataSize size = 0; gint mult = 0; gint table = -1; Firmware_Details *firmware = NULL; firmware = DATA_GET(global_data,"firmware"); ecu_data = firmware->ecu_data; ecu_data_backup = firmware->ecu_data_backup; /* Since we assume the page is where the table is this can cause * major problems with some firmwares that use two tables inside * of one page.... */ page = vex->page; table = vex->table; if ((table < 0) || (table >= firmware->total_tables)) { dbg_func_f(CRITICAL,g_strdup_printf(__FILE__": feed_import_data_to_ecu()\n\ttable passed (%i) is out of range(%i)\n",table,firmware->total_tables)); return; } /* If dimensions do NOT match, ABORT!!! */ if (firmware->table_params[table]->x_bincount != vex->total_x_bins) { msgbuf = g_strdup_printf(_("VEX Import: number of RPM bins inside VEXfile and FIRMWARE DO NOT MATCH (%i!=%i), aborting!!!\n"),firmware->table_params[table]->x_bincount,vex->total_x_bins); update_logbar_f("tools_view","warning",msgbuf,FALSE,FALSE,FALSE); dbg_func_f(CRITICAL,g_strdup(msgbuf)); g_free(msgbuf); return; } if (firmware->table_params[table]->y_bincount != vex->total_y_bins) { msgbuf = g_strdup_printf(_("VEX Import: number of LOAD bins inside VEXfile and FIRMWARE DO NOT MATCH (%i!=%i), aborting!!!\n"),firmware->table_params[table]->y_bincount,vex->total_y_bins); update_logbar_f("tools_view","warning",msgbuf,FALSE,FALSE,FALSE); dbg_func_f(CRITICAL,g_strdup(msgbuf)); g_free(msgbuf); return; } /* Backup the ALL pages of data first... */ for (i=0;i<firmware->total_pages;i++) { if (!firmware->page_params[i]->dl_by_default) continue; memset((void *)ecu_data_backup[i], 0, firmware->page_params[i]->length); memcpy(ecu_data_backup[i], ecu_data[i],firmware->page_params[i]->length); } canID = firmware->canID; page = firmware->table_params[table]->x_page; base = firmware->table_params[table]->x_base; size = firmware->table_params[table]->x_size; mult = get_multiplier_f(size); if (firmware->chunk_support) { total = vex->total_x_bins; data = g_malloc0(mult*total);; if (mult == 1) { ptr = (guchar *)data; for (i=0;i<total;i++) ptr[i]=vex->x_bins[i]; } if (mult == 2) { ptr16 = (guint16 *)data; for (i=0;i<total;i++) { if (firmware->bigendian) ptr16[i]=GINT16_TO_BE(vex->x_bins[i]); else ptr16[i]=GINT16_TO_LE(vex->x_bins[i]); } } if (mult == 4) { ptr32 = (guint32 *)data; for (i=0;i<total;i++) { if (firmware->bigendian) ptr32[i]=GINT_TO_BE(vex->x_bins[i]); else ptr32[i]=GINT_TO_LE(vex->x_bins[i]); } } ms_chunk_write(canID,page,base,(total*mult),data); } else { for (i=0;i<vex->total_x_bins;i++) { if (vex->x_bins[i] != ms_get_ecu_data_last(canID,page,base+(i*mult),size)) ms_send_to_ecu(canID,page,base+i,size, vex->x_bins[i], TRUE); } } canID = firmware->canID; page = firmware->table_params[table]->y_page; base = firmware->table_params[table]->y_base; size = firmware->table_params[table]->y_size; mult = get_multiplier_f(size); if (firmware->chunk_support) { total = vex->total_y_bins; data = g_malloc0(mult*total); if (mult == 1) { ptr = (guchar *)data; for (i=0;i<total;i++) ptr[i]=vex->y_bins[i]; } if (mult == 2) { ptr16 = (guint16 *)data; for (i=0;i<total;i++) { if (firmware->bigendian) ptr16[i]=GINT16_TO_BE(vex->y_bins[i]); else ptr16[i]=GINT16_TO_LE(vex->y_bins[i]); } } if (mult == 4) { ptr32 = (guint32 *)data; for (i=0;i<total;i++) { if (firmware->bigendian) ptr32[i]=GINT_TO_BE(vex->y_bins[i]); else ptr32[i]=GINT_TO_LE(vex->y_bins[i]); } } ms_chunk_write(canID,page,base,(total*mult),data); } else { for (i=0;i<vex->total_y_bins;i++) { if (vex->y_bins[i] != ms_get_ecu_data_last(canID,page,base+i,size)) ms_send_to_ecu(canID,page,base+(i*mult),size,vex->y_bins[i], TRUE); } } canID = firmware->canID; page = firmware->table_params[table]->z_page; base = firmware->table_params[table]->z_base; size = firmware->table_params[table]->z_size; mult = get_multiplier_f(size); if (firmware->chunk_support) { total = (vex->total_y_bins)*(vex->total_x_bins); data = g_malloc0(mult*total); if (mult == 1) { ptr = (guchar *)data; for (i=0;i<total;i++) ptr[i]=vex->tbl_bins[i]; } if (mult == 2) { ptr16 = (guint16 *)data; for (i=0;i<total;i++) { if (firmware->bigendian) ptr16[i]=GINT16_TO_BE(vex->tbl_bins[i]); else ptr16[i]=GINT16_TO_LE(vex->tbl_bins[i]); } } if (mult == 4) { ptr32 = (guint32 *)data; for (i=0;i<total;i++) { if (firmware->bigendian) ptr32[i]=GINT_TO_BE(vex->tbl_bins[i]); else ptr32[i]=GINT_TO_LE(vex->tbl_bins[i]); } } ms_chunk_write(canID,page,base,(total*mult),data); } else { for (i=0;i<((vex->total_y_bins)*(vex->total_x_bins));i++) { if (vex->tbl_bins[i] != ms_get_ecu_data_last(canID,page,base+i,size)) ms_send_to_ecu(canID,page,base+(i*mult),size,vex->tbl_bins[i], TRUE); } } io_cmd_f(firmware->burn_all_command,NULL); tmpbuf = g_strdup_printf(_("VEX Import: VEtable on page %i updated with data from the VEX file\n"),vex->page); update_logbar_f("tools_view",NULL,tmpbuf,FALSE,FALSE,FALSE); g_free(tmpbuf); }