G_MODULE_EXPORT gchar * request_interface_version(gint *len) { OutputData *output = NULL; GAsyncQueue *queue = NULL; FreeEMS_Packet *packet = NULL; gchar *version = NULL; GTimeVal tval; Serial_Params *serial_params = NULL; guint8 *buf = NULL; /* Raw packet */ guint8 pkt[INTVER_REQ_PKT_LEN]; gint res = 0; gint i = 0; guint8 sum = 0; gint tmit_len = 0; serial_params = DATA_GET(global_data,"serial_params"); g_return_val_if_fail(serial_params,NULL); if (DATA_GET(global_data,"offline")) return g_strdup("Offline"); pkt[HEADER_IDX] = 0; pkt[H_PAYLOAD_IDX] = (REQUEST_INTERFACE_VERSION & 0xff00 ) >> 8; pkt[L_PAYLOAD_IDX] = (REQUEST_INTERFACE_VERSION & 0x00ff ); for (i=0;i<INTVER_REQ_PKT_LEN-1;i++) sum += pkt[i]; pkt[INTVER_REQ_PKT_LEN-1] = sum; buf = finalize_packet((guint8 *)&pkt,INTVER_REQ_PKT_LEN,&tmit_len); queue = g_async_queue_new(); register_packet_queue(PAYLOAD_ID,queue,RESPONSE_INTERFACE_VERSION); if (!write_wrapper_f(serial_params->fd,buf, tmit_len, NULL)) { deregister_packet_queue(PAYLOAD_ID,queue,RESPONSE_INTERFACE_VERSION); g_free(buf); g_async_queue_unref(queue); return NULL; } g_free(buf); g_get_current_time(&tval); g_time_val_add(&tval,500000); packet = g_async_queue_timed_pop(queue,&tval); deregister_packet_queue(PAYLOAD_ID,queue,RESPONSE_INTERFACE_VERSION); g_async_queue_unref(queue); /* if (packet) printf("Firmware version PACKET ARRIVED!\n"); else printf("TIMEOUT\n"); */ if (packet) { version = g_strndup((const gchar *)(packet->data+packet->payload_base_offset),packet->payload_length); if (len) *len = packet->payload_length; freeems_packet_cleanup(packet); } return version; }
/* \brief Queries the ECU for a location ID list */ G_MODULE_EXPORT Location_Details *request_location_id_details(guint16 loc_id) { OutputData *output = NULL; GAsyncQueue *queue = NULL; FreeEMS_Packet *packet = NULL; GTimeVal tval; GList *list = NULL; Serial_Params *serial_params = NULL; guint8 *buf = NULL; Location_Details *details = NULL; /* Raw packet */ guint8 pkt[LOC_ID_DETAILS_REQ_PKT_LEN]; gint res = 0; gint i = 0; gint h = 0; gint l = 0; gint tmpi = 0; guint8 sum = 0; gint tmit_len = 0; serial_params = DATA_GET(global_data,"serial_params"); g_return_val_if_fail(serial_params,NULL); pkt[HEADER_IDX] = 0; pkt[H_PAYLOAD_IDX] = (REQUEST_RETRIEVE_LOCATION_ID_DETAILS & 0xff00 ) >> 8; pkt[L_PAYLOAD_IDX] = (REQUEST_RETRIEVE_LOCATION_ID_DETAILS & 0x00ff ); pkt[L_PAYLOAD_IDX+1] = (loc_id & 0xff00) >> 8; /* H location bits */ pkt[L_PAYLOAD_IDX+2] = (loc_id & 0x00ff); /* L location bits */ for (i=0;i<LOC_ID_DETAILS_REQ_PKT_LEN-1;i++) sum += pkt[i]; pkt[LOC_ID_DETAILS_REQ_PKT_LEN-1] = sum; buf = finalize_packet((guint8 *)&pkt,LOC_ID_DETAILS_REQ_PKT_LEN,&tmit_len); queue = g_async_queue_new(); register_packet_queue(PAYLOAD_ID,queue,RESPONSE_RETRIEVE_LOCATION_ID_DETAILS); if (!write_wrapper_f(serial_params->fd,buf, tmit_len, NULL)) { deregister_packet_queue(PAYLOAD_ID,queue,RESPONSE_RETRIEVE_LOCATION_ID_DETAILS); g_free(buf); g_async_queue_unref(queue); return NULL; } g_free(buf); g_get_current_time(&tval); g_time_val_add(&tval,500000); packet = g_async_queue_timed_pop(queue,&tval); deregister_packet_queue(PAYLOAD_ID,queue,RESPONSE_RETRIEVE_LOCATION_ID_DETAILS); g_async_queue_unref(queue); if (packet) { /*printf("packet payload length %i\n",packet->payload_length);*/ if (packet->payload_length != 12) printf("ERROR in locationID details response!\n"); details = g_new0(Location_Details, 1); tmpi = 0; h = packet->data[packet->payload_base_offset]; l = packet->data[packet->payload_base_offset+1]; details->flags = (h << 8) + l; /*printf("loc id details flags %i\n",details->flags);*/ h = packet->data[packet->payload_base_offset+2]; l = packet->data[packet->payload_base_offset+3]; details->parent = (h << 8) + l; /*printf("loc id details parent %i\n",details->parent);*/ details->ram_page = packet->data[packet->payload_base_offset+4]; details->flash_page = packet->data[packet->payload_base_offset+5]; /*printf("loc id details ram_page %i\n",details->ram_page);*/ /*printf("loc id details flash_page %i\n",details->flash_page);*/ h = packet->data[packet->payload_base_offset+6]; l = packet->data[packet->payload_base_offset+7]; details->ram_address = (h << 8) + l; /*printf("loc id details ram_address %0x\n",details->ram_address);*/ h = packet->data[packet->payload_base_offset+8]; l = packet->data[packet->payload_base_offset+9]; details->flash_address = (h << 8) + l; /*printf("loc id details flash_address %0x\n",details->flash_address);*/ h = packet->data[packet->payload_base_offset+10]; l = packet->data[packet->payload_base_offset+11]; details->length = (h << 8) + l; /*printf("loc id details length %i\n",details->length);*/ freeems_packet_cleanup(packet); } return details; }
/* \brief Queries the ECU for a location ID list */ G_MODULE_EXPORT GList *request_location_ids(gint * len) { OutputData *output = NULL; GAsyncQueue *queue = NULL; FreeEMS_Packet *packet = NULL; GTimeVal tval; GList *list = NULL; Serial_Params *serial_params = NULL; guint8 *buf = NULL; /* Raw packet */ guint8 pkt[LOC_ID_LIST_REQ_PKT_LEN]; gint res = 0; gint i = 0; gint h = 0; gint l = 0; gint tmpi = 0; guint8 sum = 0; gint tmit_len = 0; guint8 flag = BLOCK_BITS_AND; guint16 bits = 0; serial_params = DATA_GET(global_data,"serial_params"); g_return_val_if_fail(serial_params,NULL); pkt[HEADER_IDX] = 0; pkt[H_PAYLOAD_IDX] = (REQUEST_RETRIEVE_LIST_OF_LOCATION_IDS & 0xff00 ) >> 8; pkt[L_PAYLOAD_IDX] = (REQUEST_RETRIEVE_LIST_OF_LOCATION_IDS & 0x00ff ); pkt[L_PAYLOAD_IDX+1] = flag; /* AND/OR */ bits |= BLOCK_IS_INDEXABLE | BLOCK_IN_RAM; pkt[L_PAYLOAD_IDX+2] = (bits & 0xff00) >> 8; /* H bits */ pkt[L_PAYLOAD_IDX+3] = (bits & 0x00ff); /* L bits */ for (i=0;i<LOC_ID_LIST_REQ_PKT_LEN-1;i++) sum += pkt[i]; pkt[LOC_ID_LIST_REQ_PKT_LEN-1] = sum; buf = finalize_packet((guint8 *)&pkt,LOC_ID_LIST_REQ_PKT_LEN,&tmit_len); queue = g_async_queue_new(); register_packet_queue(PAYLOAD_ID,queue,RESPONSE_RETRIEVE_LIST_OF_LOCATION_IDS); if (!write_wrapper_f(serial_params->fd,buf, tmit_len, NULL)) { deregister_packet_queue(PAYLOAD_ID,queue,RESPONSE_RETRIEVE_LIST_OF_LOCATION_IDS); g_free(buf); g_async_queue_unref(queue); return NULL; } g_free(buf); g_get_current_time(&tval); g_time_val_add(&tval,500000); packet = g_async_queue_timed_pop(queue,&tval); deregister_packet_queue(PAYLOAD_ID,queue,RESPONSE_RETRIEVE_LIST_OF_LOCATION_IDS); g_async_queue_unref(queue); if (packet) { for (i=0;i<packet->payload_length;i++) { tmpi = 0; h = packet->data[packet->payload_base_offset+i]; i++; l = packet->data[packet->payload_base_offset+i]; tmpi = (h << 8) + l; list = g_list_append(list,GINT_TO_POINTER(tmpi)); } if (len) *len = packet->payload_length; freeems_packet_cleanup(packet); } return list; }
/*! \brief Simple communication test, Assembles a packet, sends it, subscribes to the response and waits for it, or a timeout. \returns TRUE on success, FALSE on failure */ G_MODULE_EXPORT gboolean comms_test(void) { GAsyncQueue *queue = NULL; LibreEMS_Packet *packet = NULL; GCond *cond = NULL; gboolean res = FALSE; gint len = 0; /* Packet sends back Interface Version */ /* START, Header, Payload ID H, PAyload ID L, CKsum, STOP */ guint8 *buf = NULL; /* Raw packet */ guint8 pkt[INTERFACE_VERSION_REQ_PKT_LEN]; gint tmit_len = 0; ENTER(); Serial_Params *serial_params = NULL; serial_params = (Serial_Params *)DATA_GET(global_data,"serial_params"); queue = (GAsyncQueue *)DATA_GET(global_data,"packet_queue"); MTXDBG(SERIAL_RD,_("Entered...\n")); if (!serial_params) { EXIT(); return FALSE; } queue = g_async_queue_new(); register_packet_queue(PAYLOAD_ID,queue,RESPONSE_BASIC_DATALOG); packet = (LibreEMS_Packet *)g_async_queue_timeout_pop(queue,250000); deregister_packet_queue(PAYLOAD_ID,queue,RESPONSE_BASIC_DATALOG); if (packet) { MTXDBG(SERIAL_RD,_("Found streaming ECU!!\n")); g_async_queue_unref(queue); libreems_packet_cleanup(packet); DATA_SET(global_data,"connected",GINT_TO_POINTER(TRUE)); EXIT(); return TRUE; } else { /* Assume ECU is in non-streaming mode, try and probe it */ gint sum = 0; MTXDBG(SERIAL_RD,_("Requesting LibreEMS Interface Version\n")); register_packet_queue(PAYLOAD_ID,queue,RESPONSE_INTERFACE_VERSION); pkt[HEADER_IDX] = 0; pkt[H_PAYLOAD_IDX] = (REQUEST_INTERFACE_VERSION & 0xff00 ) >> 8; pkt[L_PAYLOAD_IDX] = (REQUEST_INTERFACE_VERSION & 0x00ff ); for (gint i=0;i<INTERFACE_VERSION_REQ_PKT_LEN-1;i++) sum += pkt[i]; pkt[INTERFACE_VERSION_REQ_PKT_LEN-1] = sum; buf = finalize_packet((guint8 *)&pkt,INTERFACE_VERSION_REQ_PKT_LEN,&tmit_len); if (!write_wrapper_f(serial_params->fd, buf, tmit_len, &len)) { g_free(buf); deregister_packet_queue(PAYLOAD_ID,queue,RESPONSE_INTERFACE_VERSION); g_async_queue_unref(queue); EXIT(); return FALSE; } g_free(buf); packet = (LibreEMS_Packet *)g_async_queue_timeout_pop(queue,250000); deregister_packet_queue(PAYLOAD_ID,queue,RESPONSE_INTERFACE_VERSION); g_async_queue_unref(queue); if (packet) { MTXDBG(SERIAL_RD,_("Found via probing!!\n")); libreems_packet_cleanup(packet); DATA_SET(global_data,"connected",GINT_TO_POINTER(TRUE)); EXIT(); return TRUE; } } DATA_SET(global_data,"connected",GINT_TO_POINTER(FALSE)); MTXDBG(SERIAL_RD,_("No device found...\n")); EXIT(); return FALSE; }