/** * @brief Set a new piezo feedback mode for a piezo buzzer * @param[in] index Index of piezo device for which to set a new mode * @param[in] mode New feedback mode to set for specified piezo device * @param[in] duration Duration to maintain tone * @param[in] frequency Frequency of tone to generate * @return Result code (0=success) */ uint16_t kg_cmd_feedback_set_piezo_mode(uint8_t index, uint8_t mode, uint8_t duration, uint16_t frequency) { if (mode >= KG_PIEZO_MODE_MAX) { return KG_PROTOCOL_ERROR_PARAMETER_RANGE; } else { // "index" is currently ignored, as there is only one piezo device in the design feedback_set_piezo_mode((feedback_piezo_mode_t)mode, duration, frequency); // send kg_evt_feedback_piezo_mode packet (if we aren't setting it from an API command) if (!inBinPacket) { uint8_t payload[5] = { index, mode, duration, frequency & 0xFF, frequency >> 8 }; skipPacket = 0; if (kg_evt_feedback_piezo_mode) skipPacket = kg_evt_feedback_piezo_mode(index, mode, duration, frequency); if (!skipPacket) send_keyglove_packet(KG_PACKET_TYPE_EVENT, 5, KG_PACKET_CLASS_FEEDBACK, KG_PACKET_ID_EVT_FEEDBACK_PIEZO_MODE, payload); } }
/** * @brief Command processing routine for "system" packet class * @param[in] rxPacket Incoming KGAPI packet buffer * @return Protocol error, if any (0 for success) * @see protocol_parse() * @see KGAPI command: kg_cmd_system_ping() * @see KGAPI command: kg_cmd_system_reset() * @see KGAPI command: kg_cmd_system_get_info() * @see KGAPI command: kg_cmd_system_get_memory() * @see KGAPI command: kg_cmd_system_set_timer() * @see KGAPI command: kg_cmd_system_get_battery_status() */ uint8_t process_protocol_command_system(uint8_t *rxPacket) { // check for valid command IDs uint8_t protocol_error = 0; switch (rxPacket[3]) { case KG_PACKET_ID_CMD_SYSTEM_PING: // 0x01 // system_ping()(uint32_t runtime) // parameters = 0 bytes if (rxPacket[1] != 0) { // incorrect parameter length protocol_error = KG_PROTOCOL_ERROR_PARAMETER_LENGTH; } else { // run command uint32_t runtime; uint16_t result = kg_cmd_system_ping(&runtime); // build response uint8_t payload[4] = { runtime & 0xFF, (runtime >> 8) & 0xFF, (runtime >> 16) & 0xFF, (runtime >> 24) & 0xFF }; // send response send_keyglove_packet(KG_PACKET_TYPE_COMMAND, 4, rxPacket[2], rxPacket[3], payload); } break; case KG_PACKET_ID_CMD_SYSTEM_RESET: // 0x02 // system_reset(uint8_t type)(uint16_t result) // parameters = 1 byte if (rxPacket[1] != 1) { // incorrect parameter length protocol_error = KG_PROTOCOL_ERROR_PARAMETER_LENGTH; } else { // run command uint16_t result = kg_cmd_system_reset(rxPacket[4]); // build and send response if needed if (result != 0xFFFF) { // build response uint8_t payload[2] = { result & 0xFF, (result >> 8) & 0xFF }; // send response send_keyglove_packet(KG_PACKET_TYPE_COMMAND, 2, rxPacket[2], rxPacket[3], payload); } } break; case KG_PACKET_ID_CMD_SYSTEM_GET_INFO: // 0x03 // system_get_info()(uint8_t major, uint8_t minor, uint8_t patch, uint32_t timestamp) // parameters = 0 bytes if (rxPacket[1] != 0) { // incorrect parameter length protocol_error = KG_PROTOCOL_ERROR_PARAMETER_LENGTH; } else { // run command uint8_t major; uint8_t minor; uint8_t patch; uint32_t timestamp; uint16_t result = kg_cmd_system_get_info(&major, &minor, &patch, ×tamp); // build response uint8_t payload[7] = { major, minor, patch, timestamp & 0xFF, (timestamp >> 8) & 0xFF, (timestamp >> 16) & 0xFF, (timestamp >> 24) & 0xFF }; // send response send_keyglove_packet(KG_PACKET_TYPE_COMMAND, 7, rxPacket[2], rxPacket[3], payload); } break; case KG_PACKET_ID_CMD_SYSTEM_GET_MEMORY: // 0x04 // system_get_memory()(uint32_t free_ram, uint32_t total_ram) // parameters = 0 bytes if (rxPacket[1] != 0) { // incorrect parameter length protocol_error = KG_PROTOCOL_ERROR_PARAMETER_LENGTH; } else { // run command uint32_t free_ram; uint32_t total_ram; uint16_t result = kg_cmd_system_get_memory(&free_ram, &total_ram); // build response uint8_t payload[8] = { free_ram & 0xFF, (free_ram >> 8) & 0xFF, (free_ram >> 16) & 0xFF, (free_ram >> 24) & 0xFF, total_ram & 0xFF, (total_ram >> 8) & 0xFF, (total_ram >> 16) & 0xFF, (total_ram >> 24) & 0xFF }; // send response send_keyglove_packet(KG_PACKET_TYPE_COMMAND, 8, rxPacket[2], rxPacket[3], payload); } break; case KG_PACKET_ID_CMD_SYSTEM_SET_TIMER: // 0x05 // system_set_timer(uint8_t handle, uint16_t interval, uint8_t oneshot)(uint16_t result) // parameters = 4 bytes if (rxPacket[1] != 4) { // incorrect parameter length protocol_error = KG_PROTOCOL_ERROR_PARAMETER_LENGTH; } else { // run command uint16_t result = kg_cmd_system_set_timer(rxPacket[4], rxPacket[5] | (rxPacket[6] << 8), rxPacket[7]); // build response uint8_t payload[2] = { result & 0xFF, (result >> 8) & 0xFF }; // send response send_keyglove_packet(KG_PACKET_TYPE_COMMAND, 2, rxPacket[2], rxPacket[3], payload); } break; case KG_PACKET_ID_CMD_SYSTEM_GET_BATTERY_STATUS: // 0x06 // system_get_battery_status()(uint8_t status, uint8_t level) // parameters = 0 bytes if (rxPacket[1] != 0) { // incorrect parameter length protocol_error = KG_PROTOCOL_ERROR_PARAMETER_LENGTH; } else { // run command uint8_t status; uint8_t level; uint16_t result = kg_cmd_system_get_battery_status(&status, &level); // build response uint8_t payload[2] = { status, level }; // send response send_keyglove_packet(KG_PACKET_TYPE_COMMAND, 2, rxPacket[2], rxPacket[3], payload); } break; default: protocol_error = KG_PROTOCOL_ERROR_INVALID_COMMAND; } return protocol_error; } /* 0x01 */ uint8_t (*kg_evt_system_boot)(uint8_t major, uint8_t minor, uint8_t patch, uint32_t timestamp) = 0; /* 0x02 */ uint8_t (*kg_evt_system_ready)() = 0; /* 0x03 */ uint8_t (*kg_evt_system_error)(uint16_t code) = 0; /* 0x04 */ uint8_t (*kg_evt_system_timer_tick)(uint8_t handle, uint32_t seconds, uint8_t subticks) = 0; /* 0x05 */ uint8_t (*kg_evt_system_battery_status)(uint8_t status, uint8_t level) = 0;
/** * @brief Command processing routine for "bluetooth" packet class * @param[in] rxPacket Incoming KGAPI packet buffer * @return Protocol error, if any (0 for success) * @see protocol_parse() * @see KGAPI command: kg_cmd_bluetooth_get_mode() * @see KGAPI command: kg_cmd_bluetooth_set_mode() * @see KGAPI command: kg_cmd_bluetooth_reset() * @see KGAPI command: kg_cmd_bluetooth_get_mac() * @see KGAPI command: kg_cmd_bluetooth_get_pairings() * @see KGAPI command: kg_cmd_bluetooth_discover() * @see KGAPI command: kg_cmd_bluetooth_pair() * @see KGAPI command: kg_cmd_bluetooth_delete_pairing() * @see KGAPI command: kg_cmd_bluetooth_clear_pairings() * @see KGAPI command: kg_cmd_bluetooth_get_connections() * @see KGAPI command: kg_cmd_bluetooth_connect() * @see KGAPI command: kg_cmd_bluetooth_disconnect() */ uint8_t process_protocol_command_bluetooth(uint8_t *rxPacket) { // check for valid command IDs uint8_t protocol_error = 0; switch (rxPacket[3]) { case KG_PACKET_ID_CMD_BLUETOOTH_GET_MODE: // 0x01 // bluetooth_get_mode()(uint16_t result, uint8_t mode) // parameters = 0 bytes if (rxPacket[1] != 0) { // incorrect parameter length protocol_error = KG_PROTOCOL_ERROR_PARAMETER_LENGTH; } else { // run command uint8_t mode; uint16_t result = kg_cmd_bluetooth_get_mode(&mode); // build response uint8_t payload[3] = { result & 0xFF, (result >> 8) & 0xFF, mode }; // send response send_keyglove_packet(KG_PACKET_TYPE_COMMAND, 3, rxPacket[2], rxPacket[3], payload); } break; case KG_PACKET_ID_CMD_BLUETOOTH_SET_MODE: // 0x02 // bluetooth_set_mode(uint8_t mode)(uint16_t result) // parameters = 1 byte if (rxPacket[1] != 1) { // incorrect parameter length protocol_error = KG_PROTOCOL_ERROR_PARAMETER_LENGTH; } else { // run command uint16_t result = kg_cmd_bluetooth_set_mode(rxPacket[4]); // build response uint8_t payload[2] = { result & 0xFF, (result >> 8) & 0xFF }; // send response send_keyglove_packet(KG_PACKET_TYPE_COMMAND, 2, rxPacket[2], rxPacket[3], payload); } break; case KG_PACKET_ID_CMD_BLUETOOTH_RESET: // 0x03 // bluetooth_reset()(uint16_t result) // parameters = 0 bytes if (rxPacket[1] != 0) { // incorrect parameter length protocol_error = KG_PROTOCOL_ERROR_PARAMETER_LENGTH; } else { // run command uint16_t result = kg_cmd_bluetooth_reset(); // build response uint8_t payload[2] = { result & 0xFF, (result >> 8) & 0xFF }; // send response send_keyglove_packet(KG_PACKET_TYPE_COMMAND, 2, rxPacket[2], rxPacket[3], payload); } break; case KG_PACKET_ID_CMD_BLUETOOTH_GET_MAC: // 0x04 // bluetooth_get_mac()(uint16_t result, macaddr_t address) // parameters = 0 bytes if (rxPacket[1] != 0) { // incorrect parameter length protocol_error = KG_PROTOCOL_ERROR_PARAMETER_LENGTH; } else { // run command uint8_t address[6]; uint16_t result = kg_cmd_bluetooth_get_mac(address); // build response uint8_t payload[8] = { result & 0xFF, (result >> 8) & 0xFF, 0,0,0,0,0,0 }; memcpy(payload + 2, address, 6); // send response send_keyglove_packet(KG_PACKET_TYPE_COMMAND, 8, rxPacket[2], rxPacket[3], payload); } break; case KG_PACKET_ID_CMD_BLUETOOTH_GET_PAIRINGS: // 0x05 // bluetooth_get_pairings()(uint16_t result, uint8_t count) // parameters = 0 bytes if (rxPacket[1] != 0) { // incorrect parameter length protocol_error = KG_PROTOCOL_ERROR_PARAMETER_LENGTH; } else { // run command uint8_t count; uint16_t result = kg_cmd_bluetooth_get_pairings(&count); // build response uint8_t payload[3] = { result & 0xFF, (result >> 8) & 0xFF, count }; // send response send_keyglove_packet(KG_PACKET_TYPE_COMMAND, 3, rxPacket[2], rxPacket[3], payload); } break; case KG_PACKET_ID_CMD_BLUETOOTH_DISCOVER: // 0x06 // bluetooth_discover(uint8_t duration)(uint16_t result) // parameters = 1 byte if (rxPacket[1] != 1) { // incorrect parameter length protocol_error = KG_PROTOCOL_ERROR_PARAMETER_LENGTH; } else { // run command uint16_t result = kg_cmd_bluetooth_discover(rxPacket[4]); // build response uint8_t payload[2] = { result & 0xFF, (result >> 8) & 0xFF }; // send response send_keyglove_packet(KG_PACKET_TYPE_COMMAND, 2, rxPacket[2], rxPacket[3], payload); } break; case KG_PACKET_ID_CMD_BLUETOOTH_PAIR: // 0x07 // bluetooth_pair(macaddr_t address)(uint16_t result) // parameters = 6 bytes if (rxPacket[1] != 6) { // incorrect parameter length protocol_error = KG_PROTOCOL_ERROR_PARAMETER_LENGTH; } else { // run command uint16_t result = kg_cmd_bluetooth_pair(rxPacket + 4); // build response uint8_t payload[2] = { result & 0xFF, (result >> 8) & 0xFF }; // send response send_keyglove_packet(KG_PACKET_TYPE_COMMAND, 2, rxPacket[2], rxPacket[3], payload); } break; case KG_PACKET_ID_CMD_BLUETOOTH_DELETE_PAIRING: // 0x08 // bluetooth_delete_pairing(uint8_t pairing)(uint16_t result) // parameters = 1 byte if (rxPacket[1] != 1) { // incorrect parameter length protocol_error = KG_PROTOCOL_ERROR_PARAMETER_LENGTH; } else { // run command uint16_t result = kg_cmd_bluetooth_delete_pairing(rxPacket[4]); // build response uint8_t payload[2] = { result & 0xFF, (result >> 8) & 0xFF }; // send response send_keyglove_packet(KG_PACKET_TYPE_COMMAND, 2, rxPacket[2], rxPacket[3], payload); } break; case KG_PACKET_ID_CMD_BLUETOOTH_CLEAR_PAIRINGS: // 0x09 // bluetooth_clear_pairings()(uint16_t result) // parameters = 0 bytes if (rxPacket[1] != 0) { // incorrect parameter length protocol_error = KG_PROTOCOL_ERROR_PARAMETER_LENGTH; } else { // run command uint16_t result = kg_cmd_bluetooth_clear_pairings(); // build response uint8_t payload[2] = { result & 0xFF, (result >> 8) & 0xFF }; // send response send_keyglove_packet(KG_PACKET_TYPE_COMMAND, 2, rxPacket[2], rxPacket[3], payload); } break; case KG_PACKET_ID_CMD_BLUETOOTH_GET_CONNECTIONS: // 0x0A // bluetooth_get_connections()(uint16_t result, uint8_t count) // parameters = 0 bytes if (rxPacket[1] != 0) { // incorrect parameter length protocol_error = KG_PROTOCOL_ERROR_PARAMETER_LENGTH; } else { // run command uint8_t count; uint16_t result = kg_cmd_bluetooth_get_connections(&count); // build response uint8_t payload[3] = { result & 0xFF, (result >> 8) & 0xFF, count }; // send response send_keyglove_packet(KG_PACKET_TYPE_COMMAND, 3, rxPacket[2], rxPacket[3], payload); } break; case KG_PACKET_ID_CMD_BLUETOOTH_CONNECT: // 0x0B // bluetooth_connect(uint8_t pairing, uint8_t profile)(uint16_t result) // parameters = 2 bytes if (rxPacket[1] != 2) { // incorrect parameter length protocol_error = KG_PROTOCOL_ERROR_PARAMETER_LENGTH; } else { // run command uint16_t result = kg_cmd_bluetooth_connect(rxPacket[4], rxPacket[5]); // build response uint8_t payload[2] = { result & 0xFF, (result >> 8) & 0xFF }; // send response send_keyglove_packet(KG_PACKET_TYPE_COMMAND, 2, rxPacket[2], rxPacket[3], payload); } break; case KG_PACKET_ID_CMD_BLUETOOTH_DISCONNECT: // 0x0C // bluetooth_disconnect(uint8_t handle)(uint16_t result) // parameters = 1 byte if (rxPacket[1] != 1) { // incorrect parameter length protocol_error = KG_PROTOCOL_ERROR_PARAMETER_LENGTH; } else { // run command uint16_t result = kg_cmd_bluetooth_disconnect(rxPacket[4]); // build response uint8_t payload[2] = { result & 0xFF, (result >> 8) & 0xFF }; // send response send_keyglove_packet(KG_PACKET_TYPE_COMMAND, 2, rxPacket[2], rxPacket[3], payload); } break; default: protocol_error = KG_PROTOCOL_ERROR_INVALID_COMMAND; } return protocol_error; } /* 0x01 */ uint8_t (*kg_evt_bluetooth_mode)(uint8_t mode); /* 0x02 */ uint8_t (*kg_evt_bluetooth_ready)(); /* 0x03 */ uint8_t (*kg_evt_bluetooth_inquiry_response)(uint8_t *address, uint8_t *cod, int8_t rssi, uint8_t status, uint8_t pairing, uint8_t name_len, uint8_t *name_data); /* 0x04 */ uint8_t (*kg_evt_bluetooth_inquiry_complete)(uint8_t count); /* 0x05 */ uint8_t (*kg_evt_bluetooth_pairing_status)(uint8_t pairing, uint8_t *address, uint8_t priority, uint8_t profiles_supported, uint8_t profiles_active, uint8_t handle_list_len, uint8_t *handle_list_data); /* 0x06 */ uint8_t (*kg_evt_bluetooth_pairing_failed)(uint8_t *address); /* 0x07 */ uint8_t (*kg_evt_bluetooth_pairings_cleared)(); /* 0x08 */ uint8_t (*kg_evt_bluetooth_connection_status)(uint8_t handle, uint8_t *address, uint8_t pairing, uint8_t profile, uint8_t status); /* 0x09 */ uint8_t (*kg_evt_bluetooth_connection_closed)(uint8_t handle, uint16_t reason);