diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..972b0c4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +**/target +**/Cargo.lock diff --git a/Cargo.toml b/Cargo.toml index cc2d7ff..9e175e1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,10 +1,11 @@ [package] name = "usbd-ccid" -version = "0.0.0-unreleased" +version = "0.1.0" authors = ["Nicolas Stalder "] -edition = "2018" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +edition = "2021" +license = "Apache-2.0 OR MIT" +documentation = "https://docs.rs/usbd-ccid" +repository = "https://github.com/trussed-dev/usbd-ccid" [dependencies] delog = "0.1.0" diff --git a/LICENSE-APACHE b/LICENSE-APACHE new file mode 100644 index 0000000..cd482d8 --- /dev/null +++ b/LICENSE-APACHE @@ -0,0 +1,201 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, +and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by +the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all +other entities that control, are controlled by, or are under common +control with that entity. For the purposes of this definition, +"control" means (i) the power, direct or indirect, to cause the +direction or management of such entity, whether by contract or +otherwise, or (ii) ownership of fifty percent (50%) or more of the +outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity +exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, +including but not limited to software source code, documentation +source, and configuration files. + +"Object" form shall mean any form resulting from mechanical +transformation or translation of a Source form, including but +not limited to compiled object code, generated documentation, +and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or +Object form, made available under the License, as indicated by a +copyright notice that is included in or attached to the work +(an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object +form, that is based on (or derived from) the Work and for which the +editorial revisions, annotations, elaborations, or other modifications +represent, as a whole, an original work of authorship. For the purposes +of this License, Derivative Works shall not include works that remain +separable from, or merely link (or bind by name) to the interfaces of, +the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including +the original version of the Work and any modifications or additions +to that Work or Derivative Works thereof, that is intentionally +submitted to Licensor for inclusion in the Work by the copyright owner +or by an individual or Legal Entity authorized to submit on behalf of +the copyright owner. For the purposes of this definition, "submitted" +means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, +and issue tracking systems that are managed by, or on behalf of, the +Licensor for the purpose of discussing and improving the Work, but +excluding communication that is conspicuously marked or otherwise +designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity +on behalf of whom a Contribution has been received by Licensor and +subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of +this License, each Contributor hereby grants to You a perpetual, +worldwide, non-exclusive, no-charge, royalty-free, irrevocable +copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the +Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of +this License, each Contributor hereby grants to You a perpetual, +worldwide, non-exclusive, no-charge, royalty-free, irrevocable +(except as stated in this section) patent license to make, have made, +use, offer to sell, sell, import, and otherwise transfer the Work, +where such license applies only to those patent claims licensable +by such Contributor that are necessarily infringed by their +Contribution(s) alone or by combination of their Contribution(s) +with the Work to which such Contribution(s) was submitted. If You +institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work +or a Contribution incorporated within the Work constitutes direct +or contributory patent infringement, then any patent licenses +granted to You under this License for that Work shall terminate +as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the +Work or Derivative Works thereof in any medium, with or without +modifications, and in Source or Object form, provided that You +meet the following conditions: + +(a) You must give any other recipients of the Work or +Derivative Works a copy of this License; and + +(b) You must cause any modified files to carry prominent notices +stating that You changed the files; and + +(c) You must retain, in the Source form of any Derivative Works +that You distribute, all copyright, patent, trademark, and +attribution notices from the Source form of the Work, +excluding those notices that do not pertain to any part of +the Derivative Works; and + +(d) If the Work includes a "NOTICE" text file as part of its +distribution, then any Derivative Works that You distribute must +include a readable copy of the attribution notices contained +within such NOTICE file, excluding those notices that do not +pertain to any part of the Derivative Works, in at least one +of the following places: within a NOTICE text file distributed +as part of the Derivative Works; within the Source form or +documentation, if provided along with the Derivative Works; or, +within a display generated by the Derivative Works, if and +wherever such third-party notices normally appear. The contents +of the NOTICE file are for informational purposes only and +do not modify the License. You may add Your own attribution +notices within Derivative Works that You distribute, alongside +or as an addendum to the NOTICE text from the Work, provided +that such additional attribution notices cannot be construed +as modifying the License. + +You may add Your own copyright statement to Your modifications and +may provide additional or different license terms and conditions +for use, reproduction, or distribution of Your modifications, or +for any such Derivative Works as a whole, provided Your use, +reproduction, and distribution of the Work otherwise complies with +the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, +any Contribution intentionally submitted for inclusion in the Work +by You to the Licensor shall be under the terms and conditions of +this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify +the terms of any separate license agreement you may have executed +with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade +names, trademarks, service marks, or product names of the Licensor, +except as required for reasonable and customary use in describing the +origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or +agreed to in writing, Licensor provides the Work (and each +Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied, including, without limitation, any warranties or conditions +of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A +PARTICULAR PURPOSE. You are solely responsible for determining the +appropriateness of using or redistributing the Work and assume any +risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, +whether in tort (including negligence), contract, or otherwise, +unless required by applicable law (such as deliberate and grossly +negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, +incidental, or consequential damages of any character arising as a +result of this License or out of the use or inability to use the +Work (including but not limited to damages for loss of goodwill, +work stoppage, computer failure or malfunction, or any and all +other commercial damages or losses), even if such Contributor +has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing +the Work or Derivative Works thereof, You may choose to offer, +and charge a fee for, acceptance of support, warranty, indemnity, +or other liability obligations and/or rights consistent with this +License. However, in accepting such obligations, You may act only +on Your own behalf and on Your sole responsibility, not on behalf +of any other Contributor, and only if You agree to indemnify, +defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason +of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + +To apply the Apache License to your work, attach the following +boilerplate notice, with the fields enclosed by brackets "[]" +replaced with your own identifying information. (Don't include +the brackets!) The text should be enclosed in the appropriate +comment syntax for the file format. We also recommend that a +file or class name and description of purpose be included on the +same "printed page" as the copyright notice for easier +identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/LICENSE-MIT b/LICENSE-MIT new file mode 100644 index 0000000..1b92736 --- /dev/null +++ b/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2020 SoloKeys + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/src/class.rs b/src/class.rs index 0d59713..bf7b7fa 100644 --- a/src/class.rs +++ b/src/class.rs @@ -111,7 +111,7 @@ where fn get_string(&self, index: StringIndex, _lang_id: u16) -> Option<&str> { (self.string_index == index) - .then(|| FUNCTIONAL_INTERFACE_STRING) + .then_some(FUNCTIONAL_INTERFACE_STRING) } #[inline(never)] diff --git a/src/pipe.rs b/src/pipe.rs index a226d9f..19131ba 100644 --- a/src/pipe.rs +++ b/src/pipe.rs @@ -30,7 +30,7 @@ pub enum State { } #[derive(Copy, Clone, Debug, PartialEq, Eq)] -#[allow(dead_code)] +#[allow(dead_code, clippy::enum_variant_names)] enum Error { CmdAborted = 0xff, IccMute = 0xfe, @@ -74,7 +74,7 @@ where card_issuers_data: Option<&[u8]>, ) -> Self { - assert!(MAX_MSG_LENGTH >= PACKET_SIZE); + // assert!(MAX_MSG_LENGTH >= PACKET_SIZE); Self { write, @@ -375,7 +375,7 @@ where if self.outbox.is_some() { panic!(); } // if let Some(message) = self.interchange.response() { - let message: &mut Vec = unsafe { (&mut *self.interchange.interchange.get()).rp_mut() }; + let message: &mut Vec = unsafe { (*self.interchange.interchange.get()).rp_mut() }; let chunk_size = core::cmp::min(PACKET_SIZE - 10, message.len() - self.sent); let chunk = &message[self.sent..][..chunk_size]; @@ -466,7 +466,7 @@ where fn send_packet_assuming_possible(&mut self, packet: RawPacket) { - if !self.outbox.is_none() { + if self.outbox.is_some() { // Previous transaction will fail, but we'll be ready for new transactions. self.state = State::Idle; info!("overwriting last session.."); diff --git a/src/types/packet.rs b/src/types/packet.rs index ea840ca..26611e6 100644 --- a/src/types/packet.rs +++ b/src/types/packet.rs @@ -21,6 +21,7 @@ pub enum Error { UnknownCommand(u8), } +#[allow(clippy::large_enum_variant)] pub enum Message { Command(Command), Response(Response), @@ -32,11 +33,11 @@ pub trait Packet: core::ops::Deref { fn slot(&self) -> u8 { // we have only one slot assert!(self[5] == 0); - *&self[5] + self[5] } #[inline] - fn seq(&self) -> u8 { *&self[6] } + fn seq(&self) -> u8 { self[6] } } @@ -118,23 +119,23 @@ impl core::fmt::Debug for DataBlock<'_> { // fn seq(&self) -> u8 { self.seq } // } -impl Into for DataBlock<'_> { - fn into(self) -> RawPacket { +impl From> for RawPacket { + fn from(block: DataBlock<'_>) -> RawPacket { let mut packet = RawPacket::new(); - let len = self.data.len(); + let len = block.data.len(); packet.resize_default(10 + len).ok(); packet[0] = 0x80; packet[1..][..4].copy_from_slice(&len.to_le_bytes()); packet[5] = 0; - packet[6] = self.seq; + packet[6] = block.seq; // status packet[7] = 0; // error packet[8] = 0; // chain parameter - packet[9] = self.chain as u8; - packet[10..][..len].copy_from_slice(self.data); + packet[9] = block.chain as u8; + packet[10..][..len].copy_from_slice(block.data); packet } @@ -313,12 +314,9 @@ pub enum Chain { impl Chain { pub fn transfer_ongoing(&self) -> bool { - match self { - Chain::BeginsAndEnds | + matches!(self, Chain::BeginsAndEnds | Chain::Ends | - Chain::ExpectingMore => true, - _ => false, - } + Chain::ExpectingMore) } } @@ -339,28 +337,25 @@ impl core::fmt::Debug for Command { .field("seq", &self.seq()) ; - match self { - Command::XfrBlock(block) => { - let l = core::cmp::min(self.len(), 8); - let escaped_bytes: heapless::Vec = - block.data().iter().take(l) - .flat_map(|byte| core::ascii::escape_default(*byte)) - .collect(); - let data_as_str = &core::str::from_utf8(&escaped_bytes).unwrap(); + if let Command::XfrBlock(block) = self { + let l = core::cmp::min(self.len(), 8); + let escaped_bytes: heapless::Vec = + block.data().iter().take(l) + .flat_map(|byte| core::ascii::escape_default(*byte)) + .collect(); + let data_as_str = &core::str::from_utf8(&escaped_bytes).unwrap(); - debug_struct - .field("chain", &block.chain()) - .field("len", &block.data().len()) - ; + debug_struct + .field("chain", &block.chain()) + .field("len", &block.data().len()) + ; - if l < self.len() { - debug_struct.field("data[..8]", &format_args!("b'{}'", data_as_str)) - } else { - debug_struct.field("data", &format_args!("b'{}'", data_as_str)) - } - ; + if l < self.len() { + debug_struct.field("data[..8]", &format_args!("b'{}'", data_as_str)) + } else { + debug_struct.field("data", &format_args!("b'{}'", data_as_str)) } - _ => {} + ; } // let mut debug_struct = match self.msg_type() {