/** * @brief Parse a read/write request packet read over the kowhai protocol into a kowhai_protocol_payload_t structure * @param payload_packet a packet that needs parsing * @param packet_size number of bytes in the payload_packet * @param payload parse the payload_packet into the data and buffer sections of this structure * @return KOW_STATUS_OK on success otherwise a KOW_STATUS error code */ static int parse_data_payload(void* payload_packet, int packet_size, struct kowhai_protocol_payload_t* payload) { // parse symbols int required_size; int status = parse_symbols(payload_packet, packet_size, payload, &required_size); if (status != KOW_STATUS_OK) return status; // check packet is large enough for the rest of the payload spec required_size += sizeof(struct kowhai_protocol_data_payload_memory_spec_t); if (packet_size < required_size) return KOW_STATUS_PACKET_BUFFER_TOO_SMALL; // copy the rest of the payload spec memcpy(&payload->spec.data.memory, (uint8_t*)payload_packet + sizeof(payload->spec.data.symbols.count) + sizeof(union kowhai_symbol_t) * payload->spec.data.symbols.count, sizeof(struct kowhai_protocol_data_payload_memory_spec_t)); // check the packet is large enough to hold the payload buffer if (payload->spec.data.memory.size > packet_size - required_size) return KOW_STATUS_PACKET_BUFFER_TOO_SMALL; // set payload buffer pointer payload->buffer = (void*)((char*)payload_packet + sizeof(payload->spec.data.symbols.count) + sizeof(union kowhai_symbol_t) * payload->spec.data.symbols.count + sizeof(struct kowhai_protocol_data_payload_memory_spec_t)); return KOW_STATUS_OK; }
t_bool test_sym_prod( char const **str, size_t nb_prods, size_t nb_symbols, t_bool (*test)(t_prod **prod, t_symbol **syms, ...)) { t_prod **prods; t_symbol **syms; t_fifo *sym_lists[2]; t_bool result; sym_lists[0] = f_fifo_create(); sym_lists[1] = f_fifo_create(); f_fifo_add(sym_lists[1], create_symbol("END_OF_INPUT")); prods = parse_prods(str, nb_prods, sym_lists); syms = parse_symbols(str + nb_prods, nb_symbols, sym_lists); if (prods != NULL && syms != NULL && (fifo_len(sym_lists[0]) == 0 || compute_sets_all_syms(sym_lists[1], sym_lists[0]))) result = test(prods, syms, sym_lists[0], sym_lists[1], nb_prods, nb_symbols); else result = FALSE; destroy_prods(&prods, nb_prods); free(syms); f_fifo_destroy(&sym_lists[0], sym_del); f_fifo_destroy(&sym_lists[1], sym_del); return (result); }
int kowhai_protocol_parse(void* proto_packet, int packet_size, struct kowhai_protocol_t* protocol) { int required_size = sizeof(struct kowhai_protocol_header_t); memset(protocol, 0, sizeof(struct kowhai_protocol_t)); // check packet is large enough for header if (packet_size < required_size) return KOW_STATUS_PACKET_BUFFER_TOO_SMALL; memcpy(&protocol->header, proto_packet, required_size); switch (protocol->header.command) { case KOW_CMD_READ_DATA: return parse_symbols((void*)((uint8_t*)proto_packet + required_size), packet_size - required_size, &protocol->payload, &required_size); case KOW_CMD_WRITE_DATA: case KOW_CMD_WRITE_DATA_ACK: case KOW_CMD_READ_DATA_ACK: case KOW_CMD_READ_DATA_ACK_END: return parse_data_payload((void*)((uint8_t*)proto_packet + required_size), packet_size - required_size, &protocol->payload); case KOW_CMD_READ_DESCRIPTOR: // read descriptor command requires no more parameters return KOW_STATUS_OK; case KOW_CMD_READ_DESCRIPTOR_ACK: case KOW_CMD_READ_DESCRIPTOR_ACK_END: return parse_descriptor_payload((void*)((uint8_t*)proto_packet + required_size), packet_size - required_size, &protocol->payload); default: return KOW_STATUS_INVALID_PROTOCOL_COMMAND; } }
static gboolean parse_symbols_with_prerequisites (const gchar *keyboards_dir, const gchar *name, EekKeyboard *keyboard, GList **loaded, GError **error) { gchar *filename, *path; GList *prerequisites, *p; GError *prerequisites_error; gboolean retval; for (p = *loaded; p; p = p->next) { if (g_strcmp0 (p->data, name) == 0) { g_set_error (error, EEK_ERROR, EEK_ERROR_LAYOUT_ERROR, "%s already loaded", name); return FALSE; } } *loaded = g_list_prepend (*loaded, g_strdup (name)); filename = g_strdup_printf ("%s.xml", name); path = g_build_filename (keyboards_dir, "symbols", filename, NULL); g_free (filename); prerequisites_error = NULL; prerequisites = parse_prerequisites (path, &prerequisites_error); if (prerequisites_error != NULL) { g_propagate_error (error, prerequisites_error); return FALSE; } for (p = prerequisites; p; p = p->next) { retval = parse_symbols_with_prerequisites (keyboards_dir, p->data, keyboard, loaded, error); if (!retval) return FALSE; } g_list_free_full (prerequisites, (GDestroyNotify)g_free); retval = parse_symbols (path, keyboard, error); g_free (path); return retval; }
static target_addr_t solve_import(const char *p) { if (binmap) { target_addr_t rv; char *tmp = prepend('_', p); rv = parse_symbols(binmap, tmp); free(tmp); if (!rv) { die("undefined import '%s'\n", p); } return rv; } return hash(p); }
int main(int argc, char **argv) { node_t *data; node_t *symbols; data = (node_t *)malloc(sizeof(node_t)); symbols = (node_t *)malloc(sizeof(node_t)); /* Checking number of arguments and both mallocs */ if (argc != 2 || !data || !symbols) { return (1); } data = file_to_list(argv[1]); apply_to_list(data, trim); print_list(data); symbols = parse_symbols(data); print_list(symbols); free(data); return (0); }
int kowhai_protocol_parse(void* proto_packet, int packet_size, struct kowhai_protocol_t* protocol) { int required_size = sizeof(struct kowhai_protocol_header_t); memset(protocol, 0, sizeof(struct kowhai_protocol_t)); // check packet is large enough for header if (packet_size < required_size) return KOW_STATUS_PACKET_BUFFER_TOO_SMALL; memcpy(&protocol->header, proto_packet, required_size); switch (protocol->header.command) { case KOW_CMD_GET_VERSION: return KOW_STATUS_OK; case KOW_CMD_GET_VERSION_ACK: return parse_version((void*)((uint8_t*)proto_packet + required_size), packet_size - required_size, &protocol->payload); case KOW_CMD_GET_TREE_LIST: return KOW_STATUS_OK; case KOW_CMD_GET_TREE_LIST_ACK: case KOW_CMD_GET_TREE_LIST_ACK_END: case KOW_CMD_GET_FUNCTION_LIST_ACK: case KOW_CMD_GET_FUNCTION_LIST_ACK_END: return parse_id_list((void*)((uint8_t*)proto_packet + required_size), packet_size - required_size, &protocol->payload); case KOW_CMD_READ_DATA: return parse_symbols((void*)((uint8_t*)proto_packet + required_size), packet_size - required_size, &protocol->payload, &required_size); case KOW_CMD_WRITE_DATA: case KOW_CMD_WRITE_DATA_END: case KOW_CMD_WRITE_DATA_ACK: case KOW_CMD_READ_DATA_ACK: case KOW_CMD_READ_DATA_ACK_END: return parse_data_payload((void*)((uint8_t*)proto_packet + required_size), packet_size - required_size, &protocol->payload); case KOW_CMD_READ_DESCRIPTOR: // read descriptor command requires no more parameters return KOW_STATUS_OK; case KOW_CMD_READ_DESCRIPTOR_ACK: case KOW_CMD_READ_DESCRIPTOR_ACK_END: return parse_descriptor_payload((void*)((uint8_t*)proto_packet + required_size), packet_size - required_size, &protocol->payload); case KOW_CMD_GET_FUNCTION_LIST: case KOW_CMD_GET_FUNCTION_DETAILS: // get function list/details command requires no more parameters return KOW_STATUS_OK; case KOW_CMD_GET_FUNCTION_DETAILS_ACK: return parse_function_details((void*)((uint8_t*)proto_packet + required_size), packet_size - required_size, &protocol->payload.spec.function_details); case KOW_CMD_CALL_FUNCTION: case KOW_CMD_CALL_FUNCTION_ACK: case KOW_CMD_CALL_FUNCTION_RESULT: case KOW_CMD_CALL_FUNCTION_RESULT_END: return parse_function_call((void*)((uint8_t*)proto_packet + required_size), packet_size - required_size, &protocol->payload); case KOW_CMD_CALL_FUNCTION_FAILED: return KOW_STATUS_OK; case KOW_CMD_EVENT: case KOW_CMD_EVENT_END: return parse_event((void*)((uint8_t*)proto_packet + required_size), packet_size - required_size, &protocol->payload); case KOW_CMD_GET_SYMBOL_LIST: return KOW_STATUS_OK; case KOW_CMD_GET_SYMBOL_LIST_ACK: case KOW_CMD_GET_SYMBOL_LIST_ACK_END: return parse_string_list((void*)((uint8_t*)proto_packet + required_size), packet_size - required_size, &protocol->payload); // error codes case KOW_CMD_ERROR_INVALID_COMMAND: case KOW_CMD_ERROR_INVALID_FUNCTION_ID: case KOW_CMD_ERROR_INVALID_PAYLOAD_OFFSET: case KOW_CMD_ERROR_INVALID_PAYLOAD_SIZE: case KOW_CMD_ERROR_INVALID_SEQUENCE: case KOW_CMD_ERROR_INVALID_SYMBOL_PATH: case KOW_CMD_ERROR_INVALID_TREE_ID: case KOW_CMD_ERROR_NO_DATA: return KOW_STATUS_OK; default: return KOW_STATUS_INVALID_PROTOCOL_COMMAND; } }