invalid default value ‘operation_params‘ 不合法的默认值?

文章讨论了在MySQL中创建表时遇到的关于默认值的问题。特别是对于`operation_params`列的`VARCHAR(200)`类型,默认值写个东西可能不合法。同样,`create_time`列使用`CURRENT_TIMESTAMP`作为默认值在某些MySQL版本中可能导致错误。解决方案提到可能是版本兼容性问题,建议升级到5.7.以上的版本。同时,提供了将`create_time`默认值设为`NULL`以允许在插入数据时手动填写的替代方案。

operation_params VARCHAR(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT

'写个东西' COMMENT '这是日志记录',

问题: invalid default value 'operation_params' 不合法的默认值?

我的认为:'operation_params' VARCHAR(200) 后面的VARCHAR(200) 数据类型错了???

不合法的默认值:值给错了,就找这一句里的默认值。

比如案例:

create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',

报错:invalid default value 'create_time'

不合法的默认值?

查看数据类型:DATETIME的格式: yyyy-MM-dd HH:mm:ss SSS

我的系统时间格式:11:55 2023/1/18 为这样

改为

create_time DATETIME DEFAULT NULL COMMENT '创建时间',

没有NOT NULL 或者NULL 非空约束。

默认值设置为NULL,添加数据时候填上什么是什么。

COMMENT '创建时间' 在填入时间的时候给的提示。

别人的纠错:

认为是低版本的mysql(5.7.-)的不支持CURRENT_TIMESTAMP?

解决:重装mysql(5.7.+)版本的。

来源:

https://www.cnblogs.com/han-1034683568/p/11418264.html

/// Client for a vhost-user device. The API is a thin abstraction over the vhost-user protocol. pub struct BackendClient { connection: Connection<FrontendReq>, // Cached virtio features from the backend. virtio_features: u64, // Cached acked virtio features from the driver. acked_virtio_features: u64, // Cached vhost-user protocol features. acked_protocol_features: u64, } impl BackendClient { /// Create a new instance. pub fn new(connection: Connection<FrontendReq>) -> Self { BackendClient { connection, virtio_features: 0, acked_virtio_features: 0, acked_protocol_features: 0, } } /// Get a bitmask of supported virtio/vhost features. pub fn get_features(&mut self) -> Result<u64> { let hdr = self.send_request_header(FrontendReq::GET_FEATURES, None)?; let val = self.recv_reply::<VhostUserU64>(&hdr)?; self.virtio_features = val.value; Ok(self.virtio_features) } /// Inform the vhost subsystem which features to enable. /// This should be a subset of supported features from get_features(). pub fn set_features(&mut self, features: u64) -> Result<()> { let val = VhostUserU64::new(features); let hdr = self.send_request_with_body(FrontendReq::SET_FEATURES, &val, None)?; self.acked_virtio_features = features & self.virtio_features; self.wait_for_ack(&hdr) } /// Set the current process as the owner of the vhost backend. /// This must be run before any other vhost commands. pub fn set_owner(&self) -> Result<()> { let hdr = self.send_request_header(FrontendReq::SET_OWNER, None)?; self.wait_for_ack(&hdr) } /// Used to be sent to request disabling all rings /// This is no longer used. pub fn reset_owner(&self) -> Result<()> { let hdr = self.send_request_header(FrontendReq::RESET_OWNER, None)?; self.wait_for_ack(&hdr) } /// Set the memory map regions on the backend so it can translate the vring /// addresses. In the ancillary data there is an array of file descriptors pub fn set_mem_table(&self, regions: &[VhostUserMemoryRegionInfo]) -> Result<()> { if regions.is_empty() || regions.len() > MAX_ATTACHED_FD_ENTRIES { return Err(VhostUserError::InvalidParam( "set_mem_table: regions empty or exceed max allowed regions per req.", )); } let mut ctx = VhostUserMemoryContext::new(); for region in regions.iter() { if region.memory_size == 0 || region.mmap_handle == INVALID_DESCRIPTOR { return Err(VhostUserError::InvalidParam( "set_mem_table: invalid memory region", )); } let reg = VhostUserMemoryRegion { guest_phys_addr: region.guest_phys_addr, memory_size: region.memory_size, user_addr: region.userspace_addr, mmap_offset: region.mmap_offset, }; ctx.append(&reg, region.mmap_handle); } let body = VhostUserMemory::new(ctx.regions.len() as u32); let hdr = self.send_request_with_payload( FrontendReq::SET_MEM_TABLE, &body, ctx.regions.as_bytes(), Some(ctx.fds.as_slice()), )?; self.wait_for_ack(&hdr) } /// Set base address for page modification logging. pub fn set_log_base(&self, base: u64, fd: Option<RawDescriptor>) -> Result<()> { let val = VhostUserU64::new(base); let should_have_fd = self.acked_protocol_features & VhostUserProtocolFeatures::LOG_SHMFD.bits() != 0; if should_have_fd != fd.is_some() { return Err(VhostUserError::InvalidParam("set_log_base: FD is missing")); } let _ = self.send_request_with_body( FrontendReq::SET_LOG_BASE, &val, fd.as_ref().map(std::slice::from_ref), )?; Ok(()) } /// Specify an event file descriptor to signal on log write. pub fn set_log_fd(&self, fd: RawDescriptor) -> Result<()> { let fds = [fd]; let hdr = self.send_request_header(FrontendReq::SET_LOG_FD, Some(&fds))?; self.wait_for_ack(&hdr) } /// Set the number of descriptors in the vring. pub fn set_vring_num(&self, queue_index: usize, num: u16) -> Result<()> { let val = VhostUserVringState::new(queue_index as u32, num.into()); let hdr = self.send_request_with_body(FrontendReq::SET_VRING_NUM, &val, None)?; self.wait_for_ack(&hdr) } /// Set the addresses for a given vring. pub fn set_vring_addr(&self, queue_index: usize, config_data: &VringConfigData) -> Result<()> { if config_data.flags & !(VhostUserVringAddrFlags::all().bits()) != 0 { return Err(VhostUserError::InvalidParam( "set_vring_addr: unsupported vring flags", )); } let val = VhostUserVringAddr::from_config_data(queue_index as u32, config_data); let hdr = self.send_request_with_body(FrontendReq::SET_VRING_ADDR, &val, None)?; self.wait_for_ack(&hdr) } /// Set the first index to look for available descriptors. // TODO: b/331466964 - Arguments and message format are wrong for packed queues. pub fn set_vring_base(&self, queue_index: usize, base: u16) -> Result<()> { let val = VhostUserVringState::new(queue_index as u32, base.into()); let hdr = self.send_request_with_body(FrontendReq::SET_VRING_BASE, &val, None)?; self.wait_for_ack(&hdr) } /// Get the available vring base offset. // TODO: b/331466964 - Return type is wrong for packed queues. pub fn get_vring_base(&self, queue_index: usize) -> Result<u32> { let req = VhostUserVringState::new(queue_index as u32, 0); let hdr = self.send_request_with_body(FrontendReq::GET_VRING_BASE, &req, None)?; let reply = self.recv_reply::<VhostUserVringState>(&hdr)?; Ok(reply.num) } /// Set the event to trigger when buffers have been used by the host. /// /// Bits (0-7) of the payload contain the vring index. Bit 8 is the invalid FD flag. This flag /// is set when there is no file descriptor in the ancillary data. This signals that polling /// will be used instead of waiting for the call. pub fn set_vring_call(&self, queue_index: usize, event: &Event) -> Result<()> { let hdr = self.send_fd_for_vring( FrontendReq::SET_VRING_CALL, queue_index, event.as_raw_descriptor(), )?; self.wait_for_ack(&hdr) } /// Set the event that will be signaled by the guest when buffers are available for the host to /// process. /// /// Bits (0-7) of the payload contain the vring index. Bit 8 is the invalid FD flag. This flag /// is set when there is no file descriptor in the ancillary data. This signals that polling /// should be used instead of waiting for a kick. pub fn set_vring_kick(&self, queue_index: usize, event: &Event) -> Result<()> { let hdr = self.send_fd_for_vring( FrontendReq::SET_VRING_KICK, queue_index, event.as_raw_descriptor(), )?; self.wait_for_ack(&hdr) } /// Set the event that will be signaled by the guest when error happens. /// /// Bits (0-7) of the payload contain the vring index. Bit 8 is the invalid FD flag. This flag /// is set when there is no file descriptor in the ancillary data. pub fn set_vring_err(&self, queue_index: usize, event: &Event) -> Result<()> { let hdr = self.send_fd_for_vring( FrontendReq::SET_VRING_ERR, queue_index, event.as_raw_descriptor(), )?; self.wait_for_ack(&hdr) } /// Front-end and back-end negotiate a channel over which to transfer the back-end’s internal /// state during migration. /// /// Requires VHOST_USER_PROTOCOL_F_DEVICE_STATE to be negotiated. pub fn set_device_state_fd( &self, transfer_direction: VhostUserTransferDirection, migration_phase: VhostUserMigrationPhase, fd: &impl AsRawDescriptor, ) -> Result<Option<File>> { if self.acked_protocol_features & VhostUserProtocolFeatures::DEVICE_STATE.bits() == 0 { return Err(VhostUserError::InvalidOperation); } // Send request. let req = DeviceStateTransferParameters { transfer_direction: match transfer_direction { VhostUserTransferDirection::Save => 0, VhostUserTransferDirection::Load => 1, }, migration_phase: match migration_phase { VhostUserMigrationPhase::Stopped => 0, }, }; let hdr = self.send_request_with_body( FrontendReq::SET_DEVICE_STATE_FD, &req, Some(&[fd.as_raw_descriptor()]), )?; // Receive reply. let (reply, files) = self.recv_reply_with_files::<VhostUserU64>(&hdr)?; let has_err = reply.value & 0xff != 0; let invalid_fd = reply.value & 0x100 != 0; if has_err { return Err(VhostUserError::BackendInternalError); } match (invalid_fd, files.len()) { (true, 0) => Ok(None), (false, 1) => Ok(files.into_iter().next()), _ => Err(VhostUserError::IncorrectFds), } } /// After transferring the back-end’s internal state during migration, check whether the /// back-end was able to successfully fully process the state. pub fn check_device_state(&self) -> Result<()> { if self.acked_protocol_features & VhostUserProtocolFeatures::DEVICE_STATE.bits() == 0 { return Err(VhostUserError::InvalidOperation); } let hdr = self.send_request_header(FrontendReq::CHECK_DEVICE_STATE, None)?; let reply = self.recv_reply::<VhostUserU64>(&hdr)?; if reply.value != 0 { return Err(VhostUserError::BackendInternalError); } Ok(()) } /// Get the protocol feature bitmask from the underlying vhost implementation. pub fn get_protocol_features(&self) -> Result<VhostUserProtocolFeatures> { if self.virtio_features & 1 << VHOST_USER_F_PROTOCOL_FEATURES == 0 { return Err(VhostUserError::InvalidOperation); } let hdr = self.send_request_header(FrontendReq::GET_PROTOCOL_FEATURES, None)?; let val = self.recv_reply::<VhostUserU64>(&hdr)?; Ok(VhostUserProtocolFeatures::from_bits_truncate(val.value)) } /// Enable protocol features in the underlying vhost implementation. pub fn set_protocol_features(&mut self, features: VhostUserProtocolFeatures) -> Result<()> { if self.virtio_features & 1 << VHOST_USER_F_PROTOCOL_FEATURES == 0 { return Err(VhostUserError::InvalidOperation); } if features.contains(VhostUserProtocolFeatures::SHARED_MEMORY_REGIONS) && !features.contains(VhostUserProtocolFeatures::BACKEND_REQ) { return Err(VhostUserError::FeatureMismatch); } let val = VhostUserU64::new(features.bits()); let hdr = self.send_request_with_body(FrontendReq::SET_PROTOCOL_FEATURES, &val, None)?; // Don't wait for ACK here because the protocol feature negotiation process hasn't been // completed yet. self.acked_protocol_features = features.bits(); self.wait_for_ack(&hdr) } /// Query how many queues the backend supports. pub fn get_queue_num(&self) -> Result<u64> { if !self.is_feature_mq_available() { return Err(VhostUserError::InvalidOperation); } let hdr = self.send_request_header(FrontendReq::GET_QUEUE_NUM, None)?; let val = self.recv_reply::<VhostUserU64>(&hdr)?; if val.value > VHOST_USER_MAX_VRINGS { return Err(VhostUserError::InvalidMessage); } Ok(val.value) } /// Signal backend to enable or disable corresponding vring. /// /// Backend must not pass data to/from the ring until ring is enabled by /// VHOST_USER_SET_VRING_ENABLE with parameter 1, or after it has been /// disabled by VHOST_USER_SET_VRING_ENABLE with parameter 0. pub fn set_vring_enable(&self, queue_index: usize, enable: bool) -> Result<()> { // set_vring_enable() is supported only when PROTOCOL_FEATURES has been enabled. if self.acked_virtio_features & 1 << VHOST_USER_F_PROTOCOL_FEATURES == 0 { return Err(VhostUserError::InvalidOperation); } let val = VhostUserVringState::new(queue_index as u32, enable.into()); let hdr = self.send_request_with_body(FrontendReq::SET_VRING_ENABLE, &val, None)?; self.wait_for_ack(&hdr) } /// Fetch the contents of the virtio device configuration space. pub fn get_config( &self, offset: u32, size: u32, flags: VhostUserConfigFlags, buf: &[u8], ) -> Result<(VhostUserConfig, VhostUserConfigPayload)> { let body = VhostUserConfig::new(offset, size, flags); if !body.is_valid() { return Err(VhostUserError::InvalidParam( "get_config: VhostUserConfig is invalid", )); } // depends on VhostUserProtocolFeatures::CONFIG if self.acked_protocol_features & VhostUserProtocolFeatures::CONFIG.bits() == 0 { return Err(VhostUserError::InvalidOperation); } // vhost-user spec states that: // "Request payload: virtio device config space" // "Reply payload: virtio device config space" let hdr = self.send_request_with_payload(FrontendReq::GET_CONFIG, &body, buf, None)?; let (body_reply, buf_reply, rfds) = self.recv_reply_with_payload::<VhostUserConfig>(&hdr)?; if !rfds.is_empty() { return Err(VhostUserError::InvalidMessage); } else if body_reply.size == 0 { return Err(VhostUserError::BackendInternalError); } else if body_reply.size != body.size || body_reply.size as usize != buf.len() || body_reply.offset != body.offset { return Err(VhostUserError::InvalidMessage); } Ok((body_reply, buf_reply)) } /// Change the virtio device configuration space. It also can be used for live migration on the /// destination host to set readonly configuration space fields. pub fn set_config(&self, offset: u32, flags: VhostUserConfigFlags, buf: &[u8]) -> Result<()> { let body = VhostUserConfig::new( offset, buf.len() .try_into() .map_err(VhostUserError::InvalidCastToInt)?, flags, ); if !body.is_valid() { return Err(VhostUserError::InvalidParam( "set_config: VhostUserConfig is invalid", )); } // depends on VhostUserProtocolFeatures::CONFIG if self.acked_protocol_features & VhostUserProtocolFeatures::CONFIG.bits() == 0 { return Err(VhostUserError::InvalidOperation); } let hdr = self.send_request_with_payload(FrontendReq::SET_CONFIG, &body, buf, None)?; self.wait_for_ack(&hdr) } /// Setup backend communication channel. pub fn set_backend_req_fd(&self, fd: &dyn AsRawDescriptor) -> Result<()> { if self.acked_protocol_features & VhostUserProtocolFeatures::BACKEND_REQ.bits() == 0 { return Err(VhostUserError::InvalidOperation); } let fds = [fd.as_raw_descriptor()]; let hdr = self.send_request_header(FrontendReq::SET_BACKEND_REQ_FD, Some(&fds))?; self.wait_for_ack(&hdr) } /// Retrieve shared buffer for inflight I/O tracking. pub fn get_inflight_fd( &self, inflight: &VhostUserInflight, ) -> Result<(VhostUserInflight, File)> { if self.acked_protocol_features & VhostUserProtocolFeatures::INFLIGHT_SHMFD.bits() == 0 { return Err(VhostUserError::InvalidOperation); } let hdr = self.send_request_with_body(FrontendReq::GET_INFLIGHT_FD, inflight, None)?; let (inflight, files) = self.recv_reply_with_files::<VhostUserInflight>(&hdr)?; match into_single_file(files) { Some(file) => Ok((inflight, file)), None => Err(VhostUserError::IncorrectFds), } } /// Set shared buffer for inflight I/O tracking. pub fn set_inflight_fd(&self, inflight: &VhostUserInflight, fd: RawDescriptor) -> Result<()> { if self.acked_protocol_features & VhostUserProtocolFeatures::INFLIGHT_SHMFD.bits() == 0 { return Err(VhostUserError::InvalidOperation); } if inflight.mmap_size == 0 || inflight.num_queues == 0 || inflight.queue_size == 0 || fd == INVALID_DESCRIPTOR { return Err(VhostUserError::InvalidParam( "set_inflight_fd: invalid fd or params", )); } let hdr = self.send_request_with_body(FrontendReq::SET_INFLIGHT_FD, inflight, Some(&[fd]))?; self.wait_for_ack(&hdr) } /// Query the maximum amount of memory slots supported by the backend. pub fn get_max_mem_slots(&self) -> Result<u64> { if self.acked_protocol_features & VhostUserProtocolFeatures::CONFIGURE_MEM_SLOTS.bits() == 0 { return Err(VhostUserError::InvalidOperation); } let hdr = self.send_request_header(FrontendReq::GET_MAX_MEM_SLOTS, None)?; let val = self.recv_reply::<VhostUserU64>(&hdr)?; Ok(val.value) } /// Add a new guest memory mapping for vhost to use. pub fn add_mem_region(&self, region: &VhostUserMemoryRegionInfo) -> Result<()> { if self.acked_protocol_features & VhostUserProtocolFeatures::CONFIGURE_MEM_SLOTS.bits() == 0 { return Err(VhostUserError::InvalidOperation); } if region.memory_size == 0 || region.mmap_handle == INVALID_DESCRIPTOR { return Err(VhostUserError::InvalidParam( "add_mem_region: region empty or mmap handle invalid", )); } let body = VhostUserSingleMemoryRegion::new( region.guest_phys_addr, region.memory_size, region.userspace_addr, region.mmap_offset, ); let fds = [region.mmap_handle]; let hdr = self.send_request_with_body(FrontendReq::ADD_MEM_REG, &body, Some(&fds))?; self.wait_for_ack(&hdr) } /// Remove a guest memory mapping from vhost. pub fn remove_mem_region(&self, region: &VhostUserMemoryRegionInfo) -> Result<()> { if self.acked_protocol_features & VhostUserProtocolFeatures::CONFIGURE_MEM_SLOTS.bits() == 0 { return Err(VhostUserError::InvalidOperation); } if region.memory_size == 0 { return Err(VhostUserError::InvalidParam( "remove_mem_region: cannot remove zero sized region", )); } let body = VhostUserSingleMemoryRegion::new( region.guest_phys_addr, region.memory_size, region.userspace_addr, region.mmap_offset, ); let hdr = self.send_request_with_body(FrontendReq::REM_MEM_REG, &body, None)?; self.wait_for_ack(&hdr) } /// Gets the shared memory regions used by the device. pub fn get_shared_memory_regions(&self) -> Result<Vec<VhostSharedMemoryRegion>> { let hdr = self.send_request_header(FrontendReq::GET_SHARED_MEMORY_REGIONS, None)?; let (body_reply, buf_reply, rfds) = self.recv_reply_with_payload::<VhostUserU64>(&hdr)?; let struct_size = mem::size_of::<VhostSharedMemoryRegion>(); if !rfds.is_empty() || buf_reply.len() != body_reply.value as usize * struct_size { return Err(VhostUserError::InvalidMessage); } let mut regions = Vec::new(); let mut offset = 0; for _ in 0..body_reply.value { regions.push( // Can't fail because the input is the correct size. VhostSharedMemoryRegion::read_from(&buf_reply[offset..(offset + struct_size)]) .unwrap(), ); offset += struct_size; } Ok(regions) } fn send_request_header( &self, code: FrontendReq, fds: Option<&[RawDescriptor]>, ) -> VhostUserResult<VhostUserMsgHeader<FrontendReq>> { let hdr = self.new_request_header(code, 0); self.connection.send_header_only_message(&hdr, fds)?; Ok(hdr) } fn send_request_with_body<T: Sized + AsBytes>( &self, code: FrontendReq, msg: &T, fds: Option<&[RawDescriptor]>, ) -> VhostUserResult<VhostUserMsgHeader<FrontendReq>> { let hdr = self.new_request_header(code, mem::size_of::<T>() as u32); self.connection.send_message(&hdr, msg, fds)?; Ok(hdr) } fn send_request_with_payload<T: Sized + AsBytes>( &self, code: FrontendReq, msg: &T, payload: &[u8], fds: Option<&[RawDescriptor]>, ) -> VhostUserResult<VhostUserMsgHeader<FrontendReq>> { if let Some(fd_arr) = fds { if fd_arr.len() > MAX_ATTACHED_FD_ENTRIES { return Err(VhostUserError::InvalidParam( "send_request_with_payload: too many FDs supplied with message", )); } } let len = mem::size_of::<T>() .checked_add(payload.len()) .ok_or(VhostUserError::OversizedMsg)?; let hdr = self.new_request_header( code, len.try_into().map_err(VhostUserError::InvalidCastToInt)?, ); self.connection .send_message_with_payload(&hdr, msg, payload, fds)?; Ok(hdr) } fn send_fd_for_vring( &self, code: FrontendReq, queue_index: usize, fd: RawDescriptor, ) -> VhostUserResult<VhostUserMsgHeader<FrontendReq>> { // Bits (0-7) of the payload contain the vring index. Bit 8 is the invalid FD flag. // This flag is set when there is no file descriptor in the ancillary data. This signals // that polling will be used instead of waiting for the call. let msg = VhostUserU64::new(queue_index as u64); let hdr = self.new_request_header(code, mem::size_of::<VhostUserU64>() as u32); self.connection.send_message(&hdr, &msg, Some(&[fd]))?; Ok(hdr) } fn recv_reply<T: Sized + FromBytes + AsBytes + Default + VhostUserMsgValidator>( &self, hdr: &VhostUserMsgHeader<FrontendReq>, ) -> VhostUserResult<T> { if hdr.is_reply() { return Err(VhostUserError::InvalidParam( "recv_reply: header is not a reply", )); } let (reply, body, rfds) = self.connection.recv_message::<T>()?; if !reply.is_reply_for(hdr) || !rfds.is_empty() || !body.is_valid() { return Err(VhostUserError::InvalidMessage); } Ok(body) } fn recv_reply_with_files<T: Sized + AsBytes + FromBytes + Default + VhostUserMsgValidator>( &self, hdr: &VhostUserMsgHeader<FrontendReq>, ) -> VhostUserResult<(T, Vec<File>)> { if hdr.is_reply() { return Err(VhostUserError::InvalidParam( "with_files: expected a reply, but the header is not marked as a reply", )); } let (reply, body, files) = self.connection.recv_message::<T>()?; if !reply.is_reply_for(hdr) || !body.is_valid() { return Err(VhostUserError::InvalidMessage); } Ok((body, files)) } fn recv_reply_with_payload<T: Sized + AsBytes + FromBytes + Default + VhostUserMsgValidator>( &self, hdr: &VhostUserMsgHeader<FrontendReq>, ) -> VhostUserResult<(T, Vec<u8>, Vec<File>)> { if hdr.is_reply() { return Err(VhostUserError::InvalidParam( "with_payload: expected a reply, but the header is not marked as a reply", )); } let (reply, body, buf, files) = self.connection.recv_message_with_payload::<T>()?; if !reply.is_reply_for(hdr) || !files.is_empty() || !body.is_valid() { return Err(VhostUserError::InvalidMessage); } Ok((body, buf, files)) } fn wait_for_ack(&self, hdr: &VhostUserMsgHeader<FrontendReq>) -> VhostUserResult<()> { if self.acked_protocol_features & VhostUserProtocolFeatures::REPLY_ACK.bits() == 0 || !hdr.is_need_reply() { return Ok(()); } let (reply, body, rfds) = self.connection.recv_message::<VhostUserU64>()?; if !reply.is_reply_for(hdr) || !rfds.is_empty() || !body.is_valid() { return Err(VhostUserError::InvalidMessage); } if body.value != 0 { return Err(VhostUserError::BackendInternalError); } Ok(()) } fn is_feature_mq_available(&self) -> bool { self.acked_protocol_features & VhostUserProtocolFeatures::MQ.bits() != 0 } #[inline] fn new_request_header( &self, request: FrontendReq, size: u32, ) -> VhostUserMsgHeader<FrontendReq> { VhostUserMsgHeader::new(request, 0x1, size) } }
05-30
/* * veritysetup - setup cryptographic volumes for dm-verity * * Copyright (C) 2012-2018, Red Hat, Inc. All rights reserved. * Copyright (C) 2012-2018, Milan Broz * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "cryptsetup.h" #define PACKAGE_VERITY "veritysetup" static int use_superblock = 1; static const char *fec_device = NULL; static int fec_roots = DEFAULT_VERITY_FEC_ROOTS; static const char *hash_algorithm = NULL; static int hash_type = 1; static int data_block_size = DEFAULT_VERITY_DATA_BLOCK; static int hash_block_size = DEFAULT_VERITY_HASH_BLOCK; static uint64_t data_blocks = 0; static const char *salt_string = NULL; static uint64_t hash_offset = 0; static uint64_t fec_offset = 0; static const char *opt_uuid = NULL; static int opt_restart_on_corruption = 0; static int opt_ignore_corruption = 0; static int opt_ignore_zero_blocks = 0; static int opt_check_at_most_once = 0; static int opt_version_mode = 0; static const char **action_argv; static int action_argc; static int _prepare_format(struct crypt_params_verity *params, const char *data_device, uint32_t flags) { char *salt = NULL; int len; params->hash_name = hash_algorithm ?: DEFAULT_VERITY_HASH; params->data_device = data_device; params->fec_device = fec_device; params->fec_roots = fec_roots; if (salt_string && !strcmp(salt_string, "-")) { params->salt_size = 0; params->salt = NULL; } else if (salt_string) { len = crypt_hex_to_bytes(salt_string, &salt, 0); if (len < 0) { log_err(_("Invalid salt string specified.")); return -EINVAL; } params->salt_size = len; params->salt = salt; } else { params->salt_size = DEFAULT_VERITY_SALT_SIZE; params->salt = NULL; } params->data_block_size = data_block_size; params->hash_block_size = hash_block_size; params->data_size = data_blocks; params->hash_area_offset = hash_offset; params->fec_area_offset = fec_offset; params->hash_type = hash_type; params->flags = flags; return 0; } static int action_format(int arg) { struct crypt_device *cd = NULL; struct crypt_params_verity params = {}; uint32_t flags = CRYPT_VERITY_CREATE_HASH; int r; /* Try to create hash image if doesn't exist */ r = open(action_argv[1], O_WRONLY | O_EXCL | O_CREAT, S_IRUSR | S_IWUSR); if (r < 0 && errno != EEXIST) { log_err(_("Cannot create hash image %s for writing."), action_argv[1]); return -EINVAL; } else if (r >= 0) { log_dbg("Created hash image %s.", action_argv[1]); close(r); } /* Try to create FEC image if doesn't exist */ if (fec_device) { r = open(fec_device, O_WRONLY | O_EXCL | O_CREAT, S_IRUSR | S_IWUSR); if (r < 0 && errno != EEXIST) { log_err(_("Cannot create FEC image %s for writing."), fec_device); return -EINVAL; } else if (r >= 0) { log_dbg("Created FEC image %s.", fec_device); close(r); } } if ((r = crypt_init(&cd, action_argv[1]))) goto out; if (!use_superblock) flags |= CRYPT_VERITY_NO_HEADER; r = _prepare_format(&params, action_argv[0], flags); if (r < 0) goto out; r = crypt_format(cd, CRYPT_VERITY, NULL, NULL, opt_uuid, NULL, 0, &params); if (!r) crypt_dump(cd); out: crypt_free(cd); free(CONST_CAST(char*)params.salt); return r; } static int _activate(const char *dm_device, const char *data_device, const char *hash_device, const char *root_hash, uint32_t flags) { struct crypt_device *cd = NULL; struct crypt_params_verity params = {}; uint32_t activate_flags = CRYPT_ACTIVATE_READONLY; char *root_hash_bytes = NULL; ssize_t hash_size; int r; if ((r = crypt_init(&cd, hash_device))) goto out; if (opt_ignore_corruption) activate_flags |= CRYPT_ACTIVATE_IGNORE_CORRUPTION; if (opt_restart_on_corruption) activate_flags |= CRYPT_ACTIVATE_RESTART_ON_CORRUPTION; if (opt_ignore_zero_blocks) activate_flags |= CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS; if (opt_check_at_most_once) activate_flags |= CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE; if (use_superblock) { params.flags = flags; params.hash_area_offset = hash_offset; params.fec_area_offset = fec_offset; params.fec_device = fec_device; params.fec_roots = fec_roots; r = crypt_load(cd, CRYPT_VERITY, &params); } else { r = _prepare_format(&params, data_device, flags | CRYPT_VERITY_NO_HEADER); if (r < 0) goto out; r = crypt_format(cd, CRYPT_VERITY, NULL, NULL, NULL, NULL, 0, &params); } if (r < 0) goto out; r = crypt_set_data_device(cd, data_device); if (r < 0) goto out; hash_size = crypt_get_volume_key_size(cd); if (crypt_hex_to_bytes(root_hash, &root_hash_bytes, 0) != hash_size) { log_err(_("Invalid root hash string specified.")); r = -EINVAL; goto out; } r = crypt_activate_by_volume_key(cd, dm_device, root_hash_bytes, hash_size, activate_flags); out: crypt_free(cd); free(root_hash_bytes); free(CONST_CAST(char*)params.salt); return r; } static int action_open(int arg) { return _activate(action_argv[1], action_argv[0], action_argv[2], action_argv[3], 0); } static int action_verify(int arg) { return _activate(NULL, action_argv[0], action_argv[1], action_argv[2], CRYPT_VERITY_CHECK_HASH); } static int action_close(int arg) { struct crypt_device *cd = NULL; int r; r = crypt_init_by_name(&cd, action_argv[0]); if (r == 0) r = crypt_deactivate(cd, action_argv[0]); crypt_free(cd); return r; } static int action_status(int arg) { crypt_status_info ci; struct crypt_active_device cad; struct crypt_params_verity vp = {}; struct crypt_device *cd = NULL; struct stat st; char *backing_file; unsigned i, path = 0; int r = 0; /* perhaps a path, not a dm device name */ if (strchr(action_argv[0], '/') && !stat(action_argv[0], &st)) path = 1; ci = crypt_status(NULL, action_argv[0]); switch (ci) { case CRYPT_INVALID: r = -EINVAL; break; case CRYPT_INACTIVE: if (path) log_std("%s is inactive.\n", action_argv[0]); else log_std("%s/%s is inactive.\n", crypt_get_dir(), action_argv[0]); r = -ENODEV; break; case CRYPT_ACTIVE: case CRYPT_BUSY: if (path) log_std("%s is active%s.\n", action_argv[0], ci == CRYPT_BUSY ? " and is in use" : ""); else log_std("%s/%s is active%s.\n", crypt_get_dir(), action_argv[0], ci == CRYPT_BUSY ? " and is in use" : ""); r = crypt_init_by_name_and_header(&cd, action_argv[0], NULL); if (r < 0 || !crypt_get_type(cd)) goto out; log_std(" type: %s\n", crypt_get_type(cd)); r = crypt_get_active_device(cd, action_argv[0], &cad); if (r < 0) goto out; log_std(" status: %s\n", cad.flags & CRYPT_ACTIVATE_CORRUPTED ? "corrupted" : "verified"); r = crypt_get_verity_info(cd, &vp); if (r < 0) goto out; log_std(" hash type: %u\n", vp.hash_type); log_std(" data block: %u\n", vp.data_block_size); log_std(" hash block: %u\n", vp.hash_block_size); log_std(" hash name: %s\n", vp.hash_name); log_std(" salt: "); if (vp.salt_size) for(i = 0; i < vp.salt_size; i++) log_std("%02hhx", (const char)vp.salt[i]); else log_std("-"); log_std("\n"); log_std(" data device: %s\n", vp.data_device); if (crypt_loop_device(vp.data_device)) { backing_file = crypt_loop_backing_file(vp.data_device); log_std(" data loop: %s\n", backing_file); free(backing_file); } log_std(" size: %" PRIu64 " sectors\n", cad.size); log_std(" mode: %s\n", cad.flags & CRYPT_ACTIVATE_READONLY ? "readonly" : "read/write"); log_std(" hash device: %s\n", vp.hash_device); if (crypt_loop_device(vp.hash_device)) { backing_file = crypt_loop_backing_file(vp.hash_device); log_std(" hash loop: %s\n", backing_file); free(backing_file); } log_std(" hash offset: %" PRIu64 " sectors\n", vp.hash_area_offset * vp.hash_block_size / 512); if (vp.fec_device) { log_std(" FEC device: %s\n", vp.fec_device); if (crypt_loop_device(vp.fec_device)) { backing_file = crypt_loop_backing_file(vp.fec_device); log_std(" FEC loop: %s\n", backing_file); free(backing_file); } log_std(" FEC offset: %" PRIu64 " sectors\n", vp.fec_area_offset * vp.hash_block_size / 512); log_std(" FEC roots: %u\n", vp.fec_roots); } if (cad.flags & (CRYPT_ACTIVATE_IGNORE_CORRUPTION| CRYPT_ACTIVATE_RESTART_ON_CORRUPTION| CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS| CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE)) log_std(" flags: %s%s%s%s\n", (cad.flags & CRYPT_ACTIVATE_IGNORE_CORRUPTION) ? "ignore_corruption " : "", (cad.flags & CRYPT_ACTIVATE_RESTART_ON_CORRUPTION) ? "restart_on_corruption " : "", (cad.flags & CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS) ? "ignore_zero_blocks " : "", (cad.flags & CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE) ? "check_at_most_once" : ""); } out: crypt_free(cd); if (r == -ENOTSUP) r = 0; return r; } static int action_dump(int arg) { struct crypt_device *cd = NULL; struct crypt_params_verity params = {}; int r; if ((r = crypt_init(&cd, action_argv[0]))) return r; params.hash_area_offset = hash_offset; params.fec_area_offset = fec_offset; r = crypt_load(cd, CRYPT_VERITY, &params); if (!r) crypt_dump(cd); crypt_free(cd); return r; } static struct action_type { const char *type; int (*handler)(int); int required_action_argc; const char *arg_desc; const char *desc; } action_types[] = { { "format", action_format, 2, N_("<data_device> <hash_device>"),N_("format device") }, { "verify", action_verify, 3, N_("<data_device> <hash_device> <root_hash>"),N_("verify device") }, { "open", action_open, 4, N_("<data_device> <name> <hash_device> <root_hash>"),N_("open device as <name>") }, { "close", action_close, 1, N_("<name>"),N_("close device (deactivate and remove mapping)") }, { "status", action_status, 1, N_("<name>"),N_("show active device status") }, { "dump", action_dump, 1, N_("<hash_device>"),N_("show on-disk information") }, { NULL, NULL, 0, NULL, NULL } }; static void help(poptContext popt_context, enum poptCallbackReason reason __attribute__((unused)), struct poptOption *key, const char *arg __attribute__((unused)), void *data __attribute__((unused))) { struct action_type *action; if (key->shortName == '?') { log_std("%s %s\n", PACKAGE_VERITY, PACKAGE_VERSION); poptPrintHelp(popt_context, stdout, 0); log_std(_("\n" "<action> is one of:\n")); for(action = action_types; action->type; action++) log_std("\t%s %s - %s\n", action->type, _(action->arg_desc), _(action->desc)); log_std(_("\n" "<name> is the device to create under %s\n" "<data_device> is the data device\n" "<hash_device> is the device containing verification data\n" "<root_hash> hash of the root node on <hash_device>\n"), crypt_get_dir()); log_std(_("\nDefault compiled-in dm-verity parameters:\n" "\tHash: %s, Data block (bytes): %u, " "Hash block (bytes): %u, Salt size: %u, Hash format: %u\n"), DEFAULT_VERITY_HASH, DEFAULT_VERITY_DATA_BLOCK, DEFAULT_VERITY_HASH_BLOCK, DEFAULT_VERITY_SALT_SIZE, 1); exit(EXIT_SUCCESS); } else usage(popt_context, EXIT_SUCCESS, NULL, NULL); } static int run_action(struct action_type *action) { int r; log_dbg("Running command %s.", action->type); r = action->handler(0); show_status(r); return translate_errno(r); } int main(int argc, const char **argv) { static char *popt_tmp; static const char *null_action_argv[] = {NULL}; static struct poptOption popt_help_options[] = { { NULL, '\0', POPT_ARG_CALLBACK, help, 0, NULL, NULL }, { "help", '?', POPT_ARG_NONE, NULL, 0, N_("Show this help message"), NULL }, { "usage", '\0', POPT_ARG_NONE, NULL, 0, N_("Display brief usage"), NULL }, POPT_TABLEEND }; static struct poptOption popt_options[] = { { NULL, '\0', POPT_ARG_INCLUDE_TABLE, popt_help_options, 0, N_("Help options:"), NULL }, { "version", '\0', POPT_ARG_NONE, &opt_version_mode, 0, N_("Print package version"), NULL }, { "verbose", 'v', POPT_ARG_NONE, &opt_verbose, 0, N_("Shows more detailed error messages"), NULL }, { "debug", '\0', POPT_ARG_NONE, &opt_debug, 0, N_("Show debug messages"), NULL }, { "no-superblock", 0, POPT_ARG_VAL, &use_superblock, 0, N_("Do not use verity superblock"), NULL }, { "format", 0, POPT_ARG_INT, &hash_type, 0, N_("Format type (1 - normal, 0 - original Chrome OS)"), N_("number") }, { "data-block-size", 0, POPT_ARG_INT, &data_block_size, 0, N_("Block size on the data device"), N_("bytes") }, { "hash-block-size", 0, POPT_ARG_INT, &hash_block_size, 0, N_("Block size on the hash device"), N_("bytes") }, { "fec-roots", 0, POPT_ARG_INT, &fec_roots, 0, N_("FEC parity bytes"), N_("bytes") }, { "data-blocks", 0, POPT_ARG_STRING, &popt_tmp, 1, N_("The number of blocks in the data file"), N_("blocks") }, { "fec-device", 0, POPT_ARG_STRING, &fec_device, 0, N_("Path to device with error correction data"), N_("path") }, { "hash-offset", 0, POPT_ARG_STRING, &popt_tmp, 2, N_("Starting offset on the hash device"), N_("bytes") }, { "fec-offset", 0, POPT_ARG_STRING, &popt_tmp, 3, N_("Starting offset on the FEC device"), N_("bytes") }, { "hash", 'h', POPT_ARG_STRING, &hash_algorithm, 0, N_("Hash algorithm"), N_("string") }, { "salt", 's', POPT_ARG_STRING, &salt_string, 0, N_("Salt"), N_("hex string") }, { "uuid", '\0', POPT_ARG_STRING, &opt_uuid, 0, N_("UUID for device to use"), NULL }, { "restart-on-corruption", 0,POPT_ARG_NONE,&opt_restart_on_corruption, 0, N_("Restart kernel if corruption is detected"), NULL }, { "ignore-corruption", 0, POPT_ARG_NONE, &opt_ignore_corruption, 0, N_("Ignore corruption, log it only"), NULL }, { "ignore-zero-blocks", 0, POPT_ARG_NONE, &opt_ignore_zero_blocks, 0, N_("Do not verify zeroed blocks"), NULL }, { "check-at-most-once", 0, POPT_ARG_NONE, &opt_check_at_most_once, 0, N_("Verify data block only the first time it is read"), NULL }, POPT_TABLEEND }; poptContext popt_context; struct action_type *action; const char *aname; int r; crypt_set_log_callback(NULL, tool_log, NULL); setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); popt_context = poptGetContext("verity", argc, argv, popt_options, 0); poptSetOtherOptionHelp(popt_context, _("[OPTION...] <action> <action-specific>")); while((r = poptGetNextOpt(popt_context)) > 0) { unsigned long long ull_value; char *endp; errno = 0; ull_value = strtoull(popt_tmp, &endp, 10); if (*endp || !*popt_tmp || !isdigit(*popt_tmp) || (errno == ERANGE && ull_value == ULLONG_MAX) || (errno != 0 && ull_value == 0)) r = POPT_ERROR_BADNUMBER; switch(r) { case 1: data_blocks = ull_value; break; case 2: hash_offset = ull_value; break; case 3: fec_offset = ull_value; break; } if (r < 0) break; } if (r < -1) usage(popt_context, EXIT_FAILURE, poptStrerror(r), poptBadOption(popt_context, POPT_BADOPTION_NOALIAS)); if (opt_version_mode) { log_std("%s %s\n", PACKAGE_VERITY, PACKAGE_VERSION); poptFreeContext(popt_context); exit(EXIT_SUCCESS); } if (!(aname = poptGetArg(popt_context))) usage(popt_context, EXIT_FAILURE, _("Argument <action> missing."), poptGetInvocationName(popt_context)); action_argc = 0; action_argv = poptGetArgs(popt_context); /* Make return values of poptGetArgs more consistent in case of remaining argc = 0 */ if(!action_argv) action_argv = null_action_argv; /* Count args, somewhat unnice, change? */ while(action_argv[action_argc] != NULL) action_argc++; /* Handle aliases */ if (!strcmp(aname, "create") && action_argc > 1) { /* create command had historically switched arguments */ if (action_argv[0] && action_argv[1]) { const char *tmp = action_argv[0]; action_argv[0] = action_argv[1]; action_argv[1] = tmp; } aname = "open"; } else if (!strcmp(aname, "remove")) { aname = "close"; } for (action = action_types; action->type; action++) if (strcmp(action->type, aname) == 0) break; if (!action->type) usage(popt_context, EXIT_FAILURE, _("Unknown action."), poptGetInvocationName(popt_context)); if (action_argc < action->required_action_argc) { char buf[128]; snprintf(buf, 128,_("%s: requires %s as arguments"), action->type, action->arg_desc); usage(popt_context, EXIT_FAILURE, buf, poptGetInvocationName(popt_context)); } if (data_block_size < 0 || hash_block_size < 0 || hash_type < 0) { usage(popt_context, EXIT_FAILURE, _("Negative number for option not permitted."), poptGetInvocationName(popt_context)); } if ((opt_ignore_corruption || opt_restart_on_corruption || opt_ignore_zero_blocks) && strcmp(aname, "open")) usage(popt_context, EXIT_FAILURE, _("Option --ignore-corruption, --restart-on-corruption or --ignore-zero-blocks is allowed only for open operation.\n"), poptGetInvocationName(popt_context)); if (opt_ignore_corruption && opt_restart_on_corruption) usage(popt_context, EXIT_FAILURE, _("Option --ignore-corruption and --restart-on-corruption cannot be used together.\n"), poptGetInvocationName(popt_context)); if (opt_debug) { opt_verbose = 1; crypt_set_debug_level(-1); dbg_version_and_cmd(argc, argv); } r = run_action(action); poptFreeContext(popt_context); return r; } 解读以上代码
06-24
/* * This file is part of the openHiTLS project. * * openHiTLS is licensed under the Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: * * http://license.coscl.org.cn/MulanPSL2 * * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. * See the Mulan PSL v2 for more details. */ /** * @defgroup crypt * @brief crypto module */ /** * @defgroup crypt_algid * @ingroup crypt * @brief id of algorithms */ #ifndef CRYPT_ALGID_H #define CRYPT_ALGID_H #include "bsl_obj.h" #ifdef __cplusplus extern "C" { #endif // __cplusplus /** * @ingroup crypt_algid * * RAND algorithm ID */ typedef enum { CRYPT_RAND_SHA1 = BSL_CID_RAND_SHA1, CRYPT_RAND_SHA224 = BSL_CID_RAND_SHA224, CRYPT_RAND_SHA256 = BSL_CID_RAND_SHA256, CRYPT_RAND_SHA384 = BSL_CID_RAND_SHA384, CRYPT_RAND_SHA512 = BSL_CID_RAND_SHA512, CRYPT_RAND_HMAC_SHA1 = BSL_CID_RAND_HMAC_SHA1, CRYPT_RAND_HMAC_SHA224 = BSL_CID_RAND_HMAC_SHA224, CRYPT_RAND_HMAC_SHA256 = BSL_CID_RAND_HMAC_SHA256, CRYPT_RAND_HMAC_SHA384 = BSL_CID_RAND_HMAC_SHA384, CRYPT_RAND_HMAC_SHA512 = BSL_CID_RAND_HMAC_SHA512, CRYPT_RAND_AES128_CTR = BSL_CID_RAND_AES128_CTR, CRYPT_RAND_AES192_CTR = BSL_CID_RAND_AES192_CTR, CRYPT_RAND_AES256_CTR = BSL_CID_RAND_AES256_CTR, CRYPT_RAND_AES128_CTR_DF = BSL_CID_RAND_AES128_CTR_DF, CRYPT_RAND_AES192_CTR_DF = BSL_CID_RAND_AES192_CTR_DF, CRYPT_RAND_AES256_CTR_DF = BSL_CID_RAND_AES256_CTR_DF, CRYPT_RAND_SM3 = BSL_CID_RAND_SM3, CRYPT_RAND_SM4_CTR_DF = BSL_CID_RAND_SM4_CTR_DF, CRYPT_RAND_ALGID_MAX = BSL_CID_UNKNOWN } CRYPT_RAND_AlgId; /** * @ingroup crypt_algid * * Hash algorithm ID */ typedef enum { CRYPT_MD_MD5 = BSL_CID_MD5, CRYPT_MD_SHA1 = BSL_CID_SHA1, CRYPT_MD_SHA224 = BSL_CID_SHA224, CRYPT_MD_SHA256 = BSL_CID_SHA256, CRYPT_MD_SHA384 = BSL_CID_SHA384, CRYPT_MD_SHA512 = BSL_CID_SHA512, CRYPT_MD_SHA3_224 = BSL_CID_SHA3_224, CRYPT_MD_SHA3_256 = BSL_CID_SHA3_256, CRYPT_MD_SHA3_384 = BSL_CID_SHA3_384, CRYPT_MD_SHA3_512 = BSL_CID_SHA3_512, CRYPT_MD_SHAKE128 = BSL_CID_SHAKE128, CRYPT_MD_SHAKE256 = BSL_CID_SHAKE256, CRYPT_MD_SM3 = BSL_CID_SM3, CRYPT_MD_MAX = BSL_CID_UNKNOWN } CRYPT_MD_AlgId; /** * @ingroup crypt_algid * * MAC algorithm ID */ typedef enum { CRYPT_MAC_HMAC_MD5 = BSL_CID_HMAC_MD5, CRYPT_MAC_HMAC_SHA1 = BSL_CID_HMAC_SHA1, CRYPT_MAC_HMAC_SHA224 = BSL_CID_HMAC_SHA224, CRYPT_MAC_HMAC_SHA256 = BSL_CID_HMAC_SHA256, CRYPT_MAC_HMAC_SHA384 = BSL_CID_HMAC_SHA384, CRYPT_MAC_HMAC_SHA512 = BSL_CID_HMAC_SHA512, CRYPT_MAC_HMAC_SHA3_224 = BSL_CID_HMAC_SHA3_224, CRYPT_MAC_HMAC_SHA3_256 = BSL_CID_HMAC_SHA3_256, CRYPT_MAC_HMAC_SHA3_384 = BSL_CID_HMAC_SHA3_384, CRYPT_MAC_HMAC_SHA3_512 = BSL_CID_HMAC_SHA3_512, CRYPT_MAC_HMAC_SM3 = BSL_CID_HMAC_SM3, CRYPT_MAC_CMAC_AES128 = BSL_CID_CMAC_AES128, CRYPT_MAC_CMAC_AES192 = BSL_CID_CMAC_AES192, CRYPT_MAC_CMAC_AES256 = BSL_CID_CMAC_AES256, CRYPT_MAC_CMAC_SM4 = BSL_CID_CMAC_SM4, CRYPT_MAC_CBC_MAC_SM4 = BSL_CID_CBC_MAC_SM4, CRYPT_MAC_GMAC_AES128 = BSL_CID_GMAC_AES128, CRYPT_MAC_GMAC_AES192 = BSL_CID_GMAC_AES192, CRYPT_MAC_GMAC_AES256 = BSL_CID_GMAC_AES256, CRYPT_MAC_SIPHASH64 = BSL_CID_SIPHASH64, CRYPT_MAC_SIPHASH128 = BSL_CID_SIPHASH128, CRYPT_MAC_MAX = BSL_CID_UNKNOWN } CRYPT_MAC_AlgId; /** * @ingroup crypt_algid * * Asymmetric algorithm ID */ typedef enum { CRYPT_PKEY_DSA = BSL_CID_DSA, CRYPT_PKEY_ED25519 = BSL_CID_ED25519, CRYPT_PKEY_X25519 = BSL_CID_X25519, CRYPT_PKEY_RSA = BSL_CID_RSA, CRYPT_PKEY_DH = BSL_CID_DH, CRYPT_PKEY_ECDSA = BSL_CID_ECDSA, CRYPT_PKEY_ECDH = BSL_CID_ECDH, CRYPT_PKEY_SM2 = BSL_CID_SM2DSA, CRYPT_PKEY_PAILLIER = BSL_CID_PAILLIER, CRYPT_PKEY_ELGAMAL = BSL_CID_ELGAMAL, CRYPT_PKEY_SLH_DSA = BSL_CID_SLH_DSA, CRYPT_PKEY_ML_KEM = BSL_CID_ML_KEM, CRYPT_PKEY_ML_DSA = BSL_CID_ML_DSA, CRYPT_PKEY_HYBRID_KEM = BSL_CID_HYBRID_KEM, CRYPT_PKEY_XMSS = BSL_CID_XMSS, CRYPT_PKEY_MAX = BSL_CID_UNKNOWN } CRYPT_PKEY_AlgId; /** * @ingroup cipher_algid * @brief Symmetric algorithm mode ID * * There is a mapping relationship with the g_ealCipherMethod list. Attention any modification must be synchronized. */ typedef enum { CRYPT_CIPHER_AES128_CBC = BSL_CID_AES128_CBC, CRYPT_CIPHER_AES192_CBC = BSL_CID_AES192_CBC, CRYPT_CIPHER_AES256_CBC = BSL_CID_AES256_CBC, CRYPT_CIPHER_AES128_CTR = BSL_CID_AES128_CTR, CRYPT_CIPHER_AES192_CTR = BSL_CID_AES192_CTR, CRYPT_CIPHER_AES256_CTR = BSL_CID_AES256_CTR, CRYPT_CIPHER_AES128_ECB = BSL_CID_AES128_ECB, CRYPT_CIPHER_AES192_ECB = BSL_CID_AES192_ECB, CRYPT_CIPHER_AES256_ECB = BSL_CID_AES256_ECB, CRYPT_CIPHER_AES128_XTS = BSL_CID_AES128_XTS, CRYPT_CIPHER_AES256_XTS = BSL_CID_AES256_XTS, CRYPT_CIPHER_AES128_CCM = BSL_CID_AES128_CCM, CRYPT_CIPHER_AES192_CCM = BSL_CID_AES192_CCM, CRYPT_CIPHER_AES256_CCM = BSL_CID_AES256_CCM, CRYPT_CIPHER_AES128_GCM = BSL_CID_AES128_GCM, CRYPT_CIPHER_AES192_GCM = BSL_CID_AES192_GCM, CRYPT_CIPHER_AES256_GCM = BSL_CID_AES256_GCM, CRYPT_CIPHER_CHACHA20_POLY1305 = BSL_CID_CHACHA20_POLY1305, CRYPT_CIPHER_SM4_XTS = BSL_CID_SM4_XTS, CRYPT_CIPHER_SM4_CBC = BSL_CID_SM4_CBC, CRYPT_CIPHER_SM4_ECB = BSL_CID_SM4_ECB, CRYPT_CIPHER_SM4_CTR = BSL_CID_SM4_CTR, CRYPT_CIPHER_SM4_GCM = BSL_CID_SM4_GCM, CRYPT_CIPHER_SM4_CFB = BSL_CID_SM4_CFB, CRYPT_CIPHER_SM4_OFB = BSL_CID_SM4_OFB, CRYPT_CIPHER_AES128_CFB = BSL_CID_AES128_CFB, CRYPT_CIPHER_AES192_CFB = BSL_CID_AES192_CFB, CRYPT_CIPHER_AES256_CFB = BSL_CID_AES256_CFB, CRYPT_CIPHER_AES128_OFB = BSL_CID_AES128_OFB, CRYPT_CIPHER_AES192_OFB = BSL_CID_AES192_OFB, CRYPT_CIPHER_AES256_OFB = BSL_CID_AES256_OFB, CRYPT_CIPHER_MAX = BSL_CID_UNKNOWN, } CRYPT_CIPHER_AlgId; /** * @ingroup crypt_algid * * Parameter ID of an asymmetric algorithm. The most significant 16 bits indicate the algorithm ID, * and the least significant 16 bits map the ID definition of the algorithm LowLevel. */ typedef enum { CRYPT_DH_RFC2409_768 = BSL_CID_DH_RFC2409_768, CRYPT_DH_RFC2409_1024 = BSL_CID_DH_RFC2409_1024, CRYPT_DH_RFC3526_1536 = BSL_CID_DH_RFC3526_1536, CRYPT_DH_RFC3526_2048 = BSL_CID_DH_RFC3526_2048, CRYPT_DH_RFC3526_3072 = BSL_CID_DH_RFC3526_3072, CRYPT_DH_RFC3526_4096 = BSL_CID_DH_RFC3526_4096, CRYPT_DH_RFC3526_6144 = BSL_CID_DH_RFC3526_6144, CRYPT_DH_RFC3526_8192 = BSL_CID_DH_RFC3526_8192, CRYPT_DH_RFC7919_2048 = BSL_CID_DH_RFC7919_2048, CRYPT_DH_RFC7919_3072 = BSL_CID_DH_RFC7919_3072, CRYPT_DH_RFC7919_4096 = BSL_CID_DH_RFC7919_4096, CRYPT_DH_RFC7919_6144 = BSL_CID_DH_RFC7919_6144, CRYPT_DH_RFC7919_8192 = BSL_CID_DH_RFC7919_8192, CRYPT_ECC_NISTP224 = BSL_CID_NIST_PRIME224, CRYPT_ECC_NISTP256 = BSL_CID_PRIME256V1, CRYPT_ECC_NISTP384 = BSL_CID_SECP384R1, CRYPT_ECC_NISTP521 = BSL_CID_SECP521R1, CRYPT_ECC_BRAINPOOLP256R1 = BSL_CID_ECC_BRAINPOOLP256R1, CRYPT_ECC_BRAINPOOLP384R1 = BSL_CID_ECC_BRAINPOOLP384R1, CRYPT_ECC_BRAINPOOLP512R1 = BSL_CID_ECC_BRAINPOOLP512R1, CRYPT_ECC_SM2 = BSL_CID_SM2PRIME256, CRYPT_HYBRID_X25519_MLKEM512 = BSL_CID_X25519_MLKEM512, CRYPT_HYBRID_X25519_MLKEM768 = BSL_CID_X25519_MLKEM768, CRYPT_HYBRID_X25519_MLKEM1024 = BSL_CID_X25519_MLKEM1024, CRYPT_HYBRID_ECDH_NISTP256_MLKEM512 = BSL_CID_ECDH_NISTP256_MLKEM512, CRYPT_HYBRID_ECDH_NISTP256_MLKEM768 = BSL_CID_ECDH_NISTP256_MLKEM768, CRYPT_HYBRID_ECDH_NISTP256_MLKEM1024 = BSL_CID_ECDH_NISTP256_MLKEM1024, CRYPT_HYBRID_ECDH_NISTP384_MLKEM512 = BSL_CID_ECDH_NISTP384_MLKEM512, CRYPT_HYBRID_ECDH_NISTP384_MLKEM768 = BSL_CID_ECDH_NISTP384_MLKEM768, CRYPT_HYBRID_ECDH_NISTP384_MLKEM1024 = BSL_CID_ECDH_NISTP384_MLKEM1024, CRYPT_HYBRID_ECDH_NISTP521_MLKEM512 = BSL_CID_ECDH_NISTP521_MLKEM512, CRYPT_HYBRID_ECDH_NISTP521_MLKEM768 = BSL_CID_ECDH_NISTP521_MLKEM768, CRYPT_HYBRID_ECDH_NISTP521_MLKEM1024 = BSL_CID_ECDH_NISTP521_MLKEM1024, CRYPT_MLDSA_TYPE_MLDSA_44 = BSL_CID_ML_DSA_44, CRYPT_MLDSA_TYPE_MLDSA_65 = BSL_CID_ML_DSA_65, CRYPT_MLDSA_TYPE_MLDSA_87 = BSL_CID_ML_DSA_87, CRYPT_KEM_TYPE_MLKEM_512 = BSL_CID_ML_KEM_512, CRYPT_KEM_TYPE_MLKEM_768 = BSL_CID_ML_KEM_768, CRYPT_KEM_TYPE_MLKEM_1024 = BSL_CID_ML_KEM_1024, CRYPT_SLH_DSA_SHA2_128S = BSL_CID_SLH_DSA_SHA2_128S, CRYPT_SLH_DSA_SHAKE_128S = BSL_CID_SLH_DSA_SHAKE_128S, CRYPT_SLH_DSA_SHA2_128F = BSL_CID_SLH_DSA_SHA2_128F, CRYPT_SLH_DSA_SHAKE_128F = BSL_CID_SLH_DSA_SHAKE_128F, CRYPT_SLH_DSA_SHA2_192S = BSL_CID_SLH_DSA_SHA2_192S, CRYPT_SLH_DSA_SHAKE_192S = BSL_CID_SLH_DSA_SHAKE_192S, CRYPT_SLH_DSA_SHA2_192F = BSL_CID_SLH_DSA_SHA2_192F, CRYPT_SLH_DSA_SHAKE_192F = BSL_CID_SLH_DSA_SHAKE_192F, CRYPT_SLH_DSA_SHA2_256S = BSL_CID_SLH_DSA_SHA2_256S, CRYPT_SLH_DSA_SHAKE_256S = BSL_CID_SLH_DSA_SHAKE_256S, CRYPT_SLH_DSA_SHA2_256F = BSL_CID_SLH_DSA_SHA2_256F, CRYPT_SLH_DSA_SHAKE_256F = BSL_CID_SLH_DSA_SHAKE_256F, CRYPT_XMSS_SHA2_10_256 = BSL_CID_XMSS_SHA2_10_256, CRYPT_XMSS_SHA2_16_256 = BSL_CID_XMSS_SHA2_16_256, CRYPT_XMSS_SHA2_20_256 = BSL_CID_XMSS_SHA2_20_256, CRYPT_XMSS_SHA2_10_512 = BSL_CID_XMSS_SHA2_10_512, CRYPT_XMSS_SHA2_16_512 = BSL_CID_XMSS_SHA2_16_512, CRYPT_XMSS_SHA2_20_512 = BSL_CID_XMSS_SHA2_20_512, CRYPT_XMSS_SHAKE_10_256 = BSL_CID_XMSS_SHAKE_10_256, CRYPT_XMSS_SHAKE_16_256 = BSL_CID_XMSS_SHAKE_16_256, CRYPT_XMSS_SHAKE_20_256 = BSL_CID_XMSS_SHAKE_20_256, CRYPT_XMSS_SHAKE_10_512 = BSL_CID_XMSS_SHAKE_10_512, CRYPT_XMSS_SHAKE_16_512 = BSL_CID_XMSS_SHAKE_16_512, CRYPT_XMSS_SHAKE_20_512 = BSL_CID_XMSS_SHAKE_20_512, CRYPT_XMSS_SHA2_10_192 = BSL_CID_XMSS_SHA2_10_192, CRYPT_XMSS_SHA2_16_192 = BSL_CID_XMSS_SHA2_16_192, CRYPT_XMSS_SHA2_20_192 = BSL_CID_XMSS_SHA2_20_192, CRYPT_XMSS_SHAKE256_10_256 = BSL_CID_XMSS_SHAKE256_10_256, CRYPT_XMSS_SHAKE256_16_256 = BSL_CID_XMSS_SHAKE256_16_256, CRYPT_XMSS_SHAKE256_20_256 = BSL_CID_XMSS_SHAKE256_20_256, CRYPT_XMSS_SHAKE256_10_192 = BSL_CID_XMSS_SHAKE256_10_192, CRYPT_XMSS_SHAKE256_16_192 = BSL_CID_XMSS_SHAKE256_16_192, CRYPT_XMSS_SHAKE256_20_192 = BSL_CID_XMSS_SHAKE256_20_192, CRYPT_XMSSMT_SHA2_20_2_256 = BSL_CID_XMSSMT_SHA2_20_2_256, CRYPT_XMSSMT_SHA2_20_4_256 = BSL_CID_XMSSMT_SHA2_20_4_256, CRYPT_XMSSMT_SHA2_40_2_256 = BSL_CID_XMSSMT_SHA2_40_2_256, CRYPT_XMSSMT_SHA2_40_4_256 = BSL_CID_XMSSMT_SHA2_40_4_256, CRYPT_XMSSMT_SHA2_40_8_256 = BSL_CID_XMSSMT_SHA2_40_8_256, CRYPT_XMSSMT_SHA2_60_3_256 = BSL_CID_XMSSMT_SHA2_60_3_256, CRYPT_XMSSMT_SHA2_60_6_256 = BSL_CID_XMSSMT_SHA2_60_6_256, CRYPT_XMSSMT_SHA2_60_12_256 = BSL_CID_XMSSMT_SHA2_60_12_256, CRYPT_XMSSMT_SHA2_20_2_512 = BSL_CID_XMSSMT_SHA2_20_2_512, CRYPT_XMSSMT_SHA2_20_4_512 = BSL_CID_XMSSMT_SHA2_20_4_512, CRYPT_XMSSMT_SHA2_40_2_512 = BSL_CID_XMSSMT_SHA2_40_2_512, CRYPT_XMSSMT_SHA2_40_4_512 = BSL_CID_XMSSMT_SHA2_40_4_512, CRYPT_XMSSMT_SHA2_40_8_512 = BSL_CID_XMSSMT_SHA2_40_8_512, CRYPT_XMSSMT_SHA2_60_3_512 = BSL_CID_XMSSMT_SHA2_60_3_512, CRYPT_XMSSMT_SHA2_60_6_512 = BSL_CID_XMSSMT_SHA2_60_6_512, CRYPT_XMSSMT_SHA2_60_12_512 = BSL_CID_XMSSMT_SHA2_60_12_512, CRYPT_XMSSMT_SHAKE_20_2_256 = BSL_CID_XMSSMT_SHAKE_20_2_256, CRYPT_XMSSMT_SHAKE_20_4_256 = BSL_CID_XMSSMT_SHAKE_20_4_256, CRYPT_XMSSMT_SHAKE_40_2_256 = BSL_CID_XMSSMT_SHAKE_40_2_256, CRYPT_XMSSMT_SHAKE_40_4_256 = BSL_CID_XMSSMT_SHAKE_40_4_256, CRYPT_XMSSMT_SHAKE_40_8_256 = BSL_CID_XMSSMT_SHAKE_40_8_256, CRYPT_XMSSMT_SHAKE_60_3_256 = BSL_CID_XMSSMT_SHAKE_60_3_256, CRYPT_XMSSMT_SHAKE_60_6_256 = BSL_CID_XMSSMT_SHAKE_60_6_256, CRYPT_XMSSMT_SHAKE_60_12_256 = BSL_CID_XMSSMT_SHAKE_60_12_256, CRYPT_XMSSMT_SHAKE_20_2_512 = BSL_CID_XMSSMT_SHAKE_20_2_512, CRYPT_XMSSMT_SHAKE_20_4_512 = BSL_CID_XMSSMT_SHAKE_20_4_512, CRYPT_XMSSMT_SHAKE_40_2_512 = BSL_CID_XMSSMT_SHAKE_40_2_512, CRYPT_XMSSMT_SHAKE_40_4_512 = BSL_CID_XMSSMT_SHAKE_40_4_512, CRYPT_XMSSMT_SHAKE_40_8_512 = BSL_CID_XMSSMT_SHAKE_40_8_512, CRYPT_XMSSMT_SHAKE_60_3_512 = BSL_CID_XMSSMT_SHAKE_60_3_512, CRYPT_XMSSMT_SHAKE_60_6_512 = BSL_CID_XMSSMT_SHAKE_60_6_512, CRYPT_XMSSMT_SHAKE_60_12_512 = BSL_CID_XMSSMT_SHAKE_60_12_512, CRYPT_XMSSMT_SHA2_20_2_192 = BSL_CID_XMSSMT_SHA2_20_2_192, CRYPT_XMSSMT_SHA2_20_4_192 = BSL_CID_XMSSMT_SHA2_20_4_192, CRYPT_XMSSMT_SHA2_40_2_192 = BSL_CID_XMSSMT_SHA2_40_2_192, CRYPT_XMSSMT_SHA2_40_4_192 = BSL_CID_XMSSMT_SHA2_40_4_192, CRYPT_XMSSMT_SHA2_40_8_192 = BSL_CID_XMSSMT_SHA2_40_8_192, CRYPT_XMSSMT_SHA2_60_3_192 = BSL_CID_XMSSMT_SHA2_60_3_192, CRYPT_XMSSMT_SHA2_60_6_192 = BSL_CID_XMSSMT_SHA2_60_6_192, CRYPT_XMSSMT_SHA2_60_12_192 = BSL_CID_XMSSMT_SHA2_60_12_192, CRYPT_XMSSMT_SHAKE256_20_2_256 = BSL_CID_XMSSMT_SHAKE256_20_2_256, CRYPT_XMSSMT_SHAKE256_20_4_256 = BSL_CID_XMSSMT_SHAKE256_20_4_256, CRYPT_XMSSMT_SHAKE256_40_2_256 = BSL_CID_XMSSMT_SHAKE256_40_2_256, CRYPT_XMSSMT_SHAKE256_40_4_256 = BSL_CID_XMSSMT_SHAKE256_40_4_256, CRYPT_XMSSMT_SHAKE256_40_8_256 = BSL_CID_XMSSMT_SHAKE256_40_8_256, CRYPT_XMSSMT_SHAKE256_60_3_256 = BSL_CID_XMSSMT_SHAKE256_60_3_256, CRYPT_XMSSMT_SHAKE256_60_6_256 = BSL_CID_XMSSMT_SHAKE256_60_6_256, CRYPT_XMSSMT_SHAKE256_60_12_256 = BSL_CID_XMSSMT_SHAKE256_60_12_256, CRYPT_XMSSMT_SHAKE256_20_2_192 = BSL_CID_XMSSMT_SHAKE256_20_2_192, CRYPT_XMSSMT_SHAKE256_20_4_192 = BSL_CID_XMSSMT_SHAKE256_20_4_192, CRYPT_XMSSMT_SHAKE256_40_2_192 = BSL_CID_XMSSMT_SHAKE256_40_2_192, CRYPT_XMSSMT_SHAKE256_40_4_192 = BSL_CID_XMSSMT_SHAKE256_40_4_192, CRYPT_XMSSMT_SHAKE256_40_8_192 = BSL_CID_XMSSMT_SHAKE256_40_8_192, CRYPT_XMSSMT_SHAKE256_60_3_192 = BSL_CID_XMSSMT_SHAKE256_60_3_192, CRYPT_XMSSMT_SHAKE256_60_6_192 = BSL_CID_XMSSMT_SHAKE256_60_6_192, CRYPT_XMSSMT_SHAKE256_60_12_192 = BSL_CID_XMSSMT_SHAKE256_60_12_192, CRYPT_PKEY_PARAID_MAX = BSL_CID_UNKNOWN } CRYPT_PKEY_ParaId; /** * @ingroup crypt_algid * * Elliptic Curve Point Encoding Format */ typedef enum { CRYPT_POINT_COMPRESSED, CRYPT_POINT_UNCOMPRESSED, /**< default format. */ CRYPT_POINT_HYBRID, CRYPT_POINT_MAX } CRYPT_PKEY_PointFormat; /** * @ingroup crypt_algid * * KDF algorithm ID */ typedef enum { CRYPT_KDF_SCRYPT = BSL_CID_SCRYPT, CRYPT_KDF_PBKDF2 = BSL_CID_PBKDF2, CRYPT_KDF_KDFTLS12 = BSL_CID_KDFTLS12, CRYPT_KDF_HKDF = BSL_CID_HKDF, CRYPT_KDF_MAX = BSL_CID_UNKNOWN } CRYPT_KDF_AlgId; #ifdef __cplusplus } #endif // __cplusplus #endif // CRYPT_ALGID_H /* * This file is part of the openHiTLS project. * * openHiTLS is licensed under the Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: * * http://license.coscl.org.cn/MulanPSL2 * * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. * See the Mulan PSL v2 for more details. */ #ifndef CRYPT_RSA_H #define CRYPT_RSA_H #include "hitls_build.h" #ifdef HITLS_CRYPTO_RSA #include <stdlib.h> #include <stdint.h> #include "crypt_local_types.h" #include "bsl_params.h" #ifdef __cplusplus extern "C" { #endif /* __cpluscplus */ #define RSA_MIN_MODULUS_BITS 1024 #define RSA_MAX_MODULUS_BITS 16384 #define RSA_SMALL_MODULUS_BYTES (3072 / 8) #define RSA_MAX_PUBEXP_BYTES (64 / 8) #define RSA_MIN_MODULUS_LEN (RSA_MIN_MODULUS_BITS / 8) #define RSA_MAX_MODULUS_LEN (RSA_MAX_MODULUS_BITS / 8) /* RSA */ typedef struct RSA_Ctx CRYPT_RSA_Ctx; typedef struct RSA_Para CRYPT_RSA_Para; /* RSA method */ /** * @ingroup rsa * @brief Allocate rsa context memory space. * * @retval (CRYPT_RSA_Ctx *) Pointer to the memory space of the allocated context * @retval NULL Invalid null pointer. */ CRYPT_RSA_Ctx *CRYPT_RSA_NewCtx(void); // create key structure /** * @ingroup rsa * @brief Allocate rsa context memory space. * * @param libCtx [IN] Library context * * @retval (CRYPT_RSA_Ctx *) Pointer to the memory space of the allocated context * @retval NULL Invalid null pointer. */ CRYPT_RSA_Ctx *CRYPT_RSA_NewCtxEx(void *libCtx); /** * @ingroup rsa * @brief Copy the RSA context. After the duplication is complete, call the CRYPT_RSA_FreeCtx to release the memory. * * @param ctx [IN] RSA context * * @return CRYPT_RSA_Ctx Rsa context pointer * If the operation fails, a null value is returned. */ CRYPT_RSA_Ctx *CRYPT_RSA_DupCtx(CRYPT_RSA_Ctx *keyCtx); /** * @ingroup rsa * @brief Create rsa key parameter structure * * @param para [IN] RSA External parameter * * @retval (CRYPT_RSA_Para *) Pointer to the allocated memory space of the structure * @retval NULL Invalid null pointer. */ CRYPT_RSA_Para *CRYPT_RSA_NewParaEx(const BSL_Param *para); /** * @ingroup rsa * @brief Release rsa key parameter structure * * @param para [IN] Storage pointer in the parameter structure to be released. The parameter is set NULL by the invoker. */ void CRYPT_RSA_FreePara(CRYPT_RSA_Para *para); /** * @ingroup rsa * @brief release rsa key context structure * * @param ctx [IN] Pointer to the context structure to be released. The ctx is set NULL by the invoker. */ void CRYPT_RSA_FreeCtx(CRYPT_RSA_Ctx *ctx); /** * @ingroup rsa * @brief Set the data of the key parameter structure to the key structure. * * @param ctx [OUT] Key structure for which related parameters need to be set * @param para [IN] Key parameter structure * * @retval CRYPT_NULL_INPUT Invalid null pointer input. * @retval CRYPT_RSA_ERR_KEY_BITS The expected key length does not meet the requirements. * @retval CRYPT_RSA_ERR_E_VALUE The expected value of e does not meet the requirements. * @retval CRYPT_MEM_ALLOC_FAIL internal memory allocation error * @retval CRYPT_SUCCESS set successfully. */ int32_t CRYPT_RSA_SetPara(CRYPT_RSA_Ctx *ctx, const CRYPT_RsaPara *para); /** * @ingroup rsa * @brief Obtain the valid length of the key. * * @param ctx [IN] Structure from which the key length is expected to be obtained * * @retval 0: The input is incorrect or the corresponding key structure does not have a valid key length. * @retval uint32_t: Valid key length */ uint32_t CRYPT_RSA_GetBits(const CRYPT_RSA_Ctx *ctx); #ifdef HITLS_CRYPTO_RSA_GEN /** * @ingroup rsa * @brief Generate the RSA key pair. * * @param ctx [IN/OUT] rsa context structure * * @retval CRYPT_NULL_INPUT Error null pointer input * @retval CRYPT_RSA_ERR_KEY_BITS The value of e in the context structure does not meet the requirements. * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure * @retval BN error An error occurs in the internal BigNum operation. * @retval CRYPT_SUCCESS The key pair is successfully generated. */ int32_t CRYPT_RSA_Gen(CRYPT_RSA_Ctx *ctx); #endif #if defined(HITLS_CRYPTO_RSA_ENCRYPT) || defined(HITLS_CRYPTO_RSA_VERIFY) || defined(HITLS_CRYPTO_RSA_SIGN) /** * @ingroup rsa * @brief RSA public key encryption * * @param ctx [IN] RSA context structure * @param input [IN] Information to be encrypted * @param inputLen [IN] Length of the information to be encrypted * @param out [OUT] Pointer to the encrypted information output. * @param outLen [IN/OUT] Pointer to the length of the encrypted information. * Before being transferred, the value must be set to the maximum length of the array. * * @retval CRYPT_NULL_INPUT Invalid null pointer input * @retval CRYPT_RSA_NO_KEY_INFO does not contain the key information. * @retval CRYPT_RSA_ERR_INPUT_VALUE The entered value does not meet the calculation conditions. * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure * @retval CRYPT_SECUREC_FAIL A security function error occurs. * @retval BN error An error occurs in the internal BigNum operation. * @retval CRYPT_SUCCESS encryption succeeded. */ int32_t CRYPT_RSA_PubEnc(const CRYPT_RSA_Ctx *ctx, const uint8_t *input, uint32_t inputLen, uint8_t *out, uint32_t *outLen); #endif /** * @ingroup rsa * @brief RSA private key decryption * * @param ctx [IN] RSA context structure * @param input [IN] Information to be decrypted * @param inputLen [IN] Length of the information to be decrypted * @param out [OUT] Pointer to the decrypted information output. * @param outLen [IN/OUT] Pointer to the length of the decrypted information. * Before being transferred, the value must be set to the maximum length of the array. * * @retval CRYPT_NULL_INPUT Invalid null pointer input * @retval CRYPT_RSA_ERR_DEC_BITS Incorrect length of the encrypted private key. * @retval CRYPT_RSA_NO_KEY_INFO does not contain the key information. * @retval CRYPT_RSA_ERR_INPUT_VALUE The entered value does not meet the calculation conditions. * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure * @retval CRYPT_SECUREC_FAIL A security function error occurs. * @retval BN error. An error occurs in the internal BigNum operation. * @retval CRYPT_SUCCESS Decrypted Successfully */ int32_t CRYPT_RSA_PrvDec(const CRYPT_RSA_Ctx *ctx, const uint8_t *input, uint32_t inputLen, uint8_t *out, uint32_t *outLen); /** * @ingroup rsa * @brief RSA Set the private key information. * * @param ctx [OUT] rsa context structure * @param prv [IN] Private key data * * @retval CRYPT_NULL_INPUT Error null pointer input * @retval CRYPT_RSA_ERR_KEY_BITS The key length does not meet the requirements. * @retval CRYPT_RSA_NO_KEY_INFO does not contain the key information. * @retval CRYPT_RSA_ERR_INPUT_VALUE The entered value does not meet the calculation conditions. * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure * @retval BN error. An error occurs in the internal BigNum operation. * @retval CRYPT_SUCCESS The private key is successfully set. */ int32_t CRYPT_RSA_SetPrvKey(CRYPT_RSA_Ctx *ctx, const CRYPT_RsaPrv *prv); /** * @ingroup rsa * @brief RSA Set the public key information. * * @param ctx [OUT] RSA context structure * @param pub [IN] Public key data * * @retval CRYPT_NULL_INPUT Error null pointer input * @retval CRYPT_RSA_ERR_KEY_BITS The key length does not meet the requirements. * @retval CRYPT_RSA_ERR_INPUT_VALUE The entered value does not meet the calculation conditions. * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure * @retval BN error. An error occurs in the internal BigNum operation. * @retval CRYPT_SUCCESS The public key is successfully set. */ int32_t CRYPT_RSA_SetPubKey(CRYPT_RSA_Ctx *ctx, const CRYPT_RsaPub *pub); /** * @ingroup rsa * @brief RSA Obtain the private key information. * * @param ctx [IN] RSA context structure * @param prv [OUT] Private key data * * @retval CRYPT_NULL_INPUT Invalid null pointer input * @retval BN error. An error occurs in the internal BigNum operation. * @retval CRYPT_SUCCESS The private key is obtained successfully. */ int32_t CRYPT_RSA_GetPrvKey(const CRYPT_RSA_Ctx *ctx, CRYPT_RsaPrv *prv); /** * @ingroup rsa * @brief RSA Obtain the public key information. * * @param ctx [IN] RSA context structure * @param pub [OUT] Public key data * * @retval CRYPT_NULL_INPUT Invalid null pointer input * @retval BN error. An error occurs in the internal BigNum operation. * @retval CRYPT_SUCCESS The public key is obtained successfully. */ int32_t CRYPT_RSA_GetPubKey(const CRYPT_RSA_Ctx *ctx, CRYPT_RsaPub *pub); #ifdef HITLS_BSL_PARAMS /** * @ingroup rsa * @brief RSA Set the private key information. * * @param ctx [OUT] rsa context structure * @param para [IN] Private key data * * @retval CRYPT_NULL_INPUT Error null pointer input * @retval CRYPT_RSA_ERR_KEY_BITS The key length does not meet the requirements. * @retval CRYPT_RSA_NO_KEY_INFO does not contain the key information. * @retval CRYPT_RSA_ERR_INPUT_VALUE The entered value does not meet the calculation conditions. * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure * @retval BN error. An error occurs in the internal BigNum operation. * @retval CRYPT_SUCCESS The private key is successfully set. */ int32_t CRYPT_RSA_SetPrvKeyEx(CRYPT_RSA_Ctx *ctx, const BSL_Param *para); /** * @ingroup rsa * @brief RSA Set the public key information. * * @param ctx [OUT] RSA context structure * @param para [IN] Public key data * * @retval CRYPT_NULL_INPUT Error null pointer input * @retval CRYPT_RSA_ERR_KEY_BITS The key length does not meet the requirements. * @retval CRYPT_RSA_ERR_INPUT_VALUE The entered value does not meet the calculation conditions. * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure * @retval BN error. An error occurs in the internal BigNum operation. * @retval CRYPT_SUCCESS The public key is successfully set. */ int32_t CRYPT_RSA_SetPubKeyEx(CRYPT_RSA_Ctx *ctx, const BSL_Param *para); /** * @ingroup rsa * @brief RSA Obtain the private key information. * * @param ctx [IN] RSA context structure * @param para [OUT] Private key data * * @retval CRYPT_NULL_INPUT Invalid null pointer input * @retval BN error. An error occurs in the internal BigNum operation. * @retval CRYPT_SUCCESS The private key is obtained successfully. */ int32_t CRYPT_RSA_GetPrvKeyEx(const CRYPT_RSA_Ctx *ctx, BSL_Param *para); /** * @ingroup rsa * @brief RSA Obtain the public key information. * * @param ctx [IN] RSA context structure * @param para [OUT] Public key data * * @retval CRYPT_NULL_INPUT Invalid null pointer input * @retval BN error. An error occurs in the internal BigNum operation. * @retval CRYPT_SUCCESS The public key is obtained successfully. */ int32_t CRYPT_RSA_GetPubKeyEx(const CRYPT_RSA_Ctx *ctx, BSL_Param *para); /** * @ingroup rsa * @brief Set the data of the key parameter structure to the key structure. * * @param ctx [OUT] Key structure for which related parameters need to be set * @param para [IN] Key parameter structure * * @retval CRYPT_NULL_INPUT Invalid null pointer input. * @retval CRYPT_RSA_ERR_KEY_BITS The expected key length does not meet the requirements. * @retval CRYPT_RSA_ERR_E_VALUE The expected value of e does not meet the requirements. * @retval CRYPT_MEM_ALLOC_FAIL internal memory allocation error * @retval CRYPT_SUCCESS set successfully. */ int32_t CRYPT_RSA_SetParaEx(CRYPT_RSA_Ctx *ctx, const BSL_Param *para); #endif int32_t CRYPT_RSA_Ctrl(CRYPT_RSA_Ctx *ctx, int32_t opt, void *val, uint32_t len); #ifdef HITLS_CRYPTO_RSA_BSSA #ifdef HITLS_CRYPTO_RSA_SIGN /** * @ingroup RSA * @brief RSA blind operation for blind signature * * @param ctx [IN] RSA Context structure * @param algId [IN] hash Id for input * @param input [IN] Message to be blinded * @param inputLen [IN] Length of input message * @param out [OUT] Blinded message * @param outLen [OUT] Length of blinded message * * @retval CRYPT_SUCCESS on success * For other error codes, see crypt_errno.h. */ int32_t CRYPT_RSA_Blind(CRYPT_RSA_Ctx *ctx, int32_t algId, const uint8_t *input, uint32_t inputLen, uint8_t *out, uint32_t *outLen); #endif #ifdef HITLS_CRYPTO_RSA_VERIFY /** * @ingroup RSA * @brief RSA unblind operation for blind signature * * @param ctx [IN] RSA Context structure * @param input [IN] Blind signature to be unblinded * @param inputLen [IN] Length of blind signature * @param out [OUT] Final unblinded signature * @param outLen [OUT] Length of unblinded signature * * @retval CRYPT_SUCCESS on success * For other error codes, see crypt_errno.h. */ int32_t CRYPT_RSA_UnBlind(const CRYPT_RSA_Ctx *ctx, const uint8_t *input, uint32_t inputLen, uint8_t *out, uint32_t *outLen); #endif #endif #ifdef HITLS_CRYPTO_RSA_EMSA_PSS #if defined(HITLS_CRYPTO_RSA_SIGN) || defined(HITLS_CRYPTO_RSA_BSSA) /** * @ingroup rsa * @brief Set the PSS for the original data. * * @param ctx [IN] CRYPT_RSA_Ctx * @param hashMethod [IN] pss Required Hash Method * @param mgfMethod [IN] pss Internal hash method required by the mgf. * @param saltLen [IN] Length of the input salt. * @param data [IN] Original data * @param dataLen [IN] Length of the original data * @param pad [OUT] pss Output buffer * @param padLen [OUT] Maximum length of the array output by the PSS. * * @retval CRYPT_NULL_INPUT Error null pointer input * @retval CRYPT_RSA_ERR_PSS_SALT_DATA The salt value does not meet the requirements. * @retval CRYPT_RSA_ERR_KEY_BITS The key length does not meet the requirements. * @retval CRYPT_RSA_ERR_PSS_SALT_LEN The salt length does not meet the requirements. * @retval CRYPT_RSA_BUFF_LEN_NOT_ENOUGH The length of the reserved buffer is insufficient. * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure * @retval CRYPT_SUCCESS Succeeded in setting the PSS. */ int32_t CRYPT_RSA_SetPss(CRYPT_RSA_Ctx *ctx, const EAL_MdMethod *hashMethod, const EAL_MdMethod *mgfMethod, uint32_t saltLen, const uint8_t *data, uint32_t dataLen, uint8_t *pad, uint32_t padLen); #endif // HITLS_CRYPTO_RSA_SIGN || HITLS_CRYPTO_RSA_BSSA #ifdef HITLS_CRYPTO_RSA_VERIFY /** * @ingroup rsa * @brief Compare the original data from the PSS. * * @param ctx [IN] CRYPT_RSA_Ctx * @param hashMethod [IN] pss Required the hash method * @param mgfMethod [IN] pss Internal hash method required by the mgf. * @param saltLen [IN] Salt value length * @param data [IN] Original data * @param dataLen [IN] Length of the original data * @param pad [IN] Data after PSS is set. * @param padLen [IN] Data length after PSS is set. * * @retval CRYPT_NULL_INPUT Invalid null pointer input * @retval CRYPT_RSA_ERR_PSS_SALT_DATA The salt value does not meet the requirements. * @retval CRYPT_RSA_ERR_PSS_SALT_LEN The salt length does not meet the requirements. * @retval CRYPT_RSA_BUFF_LEN_NOT_ENOUGH The length required for padding does not match the input parameter. * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure * @retval CRYPT_SUCCESS pss comparison succeeded. */ int32_t CRYPT_RSA_VerifyPss(CRYPT_RSA_Ctx *ctx, const EAL_MdMethod *hashMethod, const EAL_MdMethod *mgfMethod, uint32_t saltLen, const uint8_t *data, uint32_t dataLen, const uint8_t *pad, uint32_t padLen); #endif // HITLS_CRYPTO_RSA_VERIFY #endif // HITLS_CRYPTO_RSA_EMSA_PSS #ifdef HITLS_CRYPTO_RSA_EMSA_PKCSV15 /** * @ingroup rsa * @brief Set pkcsv1.5 padding. * * @param hashId [IN] the hash method required by pkcsv1.5 setting. * @param data [IN] Original data * @param dataLen [IN] Length of the original data * @param pad [OUT] Pointer to the array for receiving the padding. * @param padLen [IN] Array length for receiving padding. * * @retval CRYPT_NULL_INPUT Invalid null pointer input * @retval CRYPT_RSA_NO_KEY_INFO The key information is insufficient. * @retval CRYPT_SECUREC_FAIL The security function fails. * @retval CRYPT_RSA_BUFF_LEN_NOT_ENOUGH The length required by the padding does not match the input parameter. * @retval CRYPT_RSA_ERR_INPUT_VALUE The hash algorithm ID is not supported. * @retval CRYPT_SUCCESS The pkcsv1.5 padding is successfully set. */ int32_t CRYPT_RSA_SetPkcsV15Type1(CRYPT_MD_AlgId hashId, const uint8_t *data, uint32_t dataLen, uint8_t *pad, uint32_t padLen); #ifdef HITLS_CRYPTO_RSA_VERIFY /** * @ingroup rsa * @brief Verify pkcsv1.5 padding. * * @param hashId [IN] the hash method corresponding to pkcsv1.5 verification. * @param pad [IN] Data after padding * @param padLen [IN] Data length after padding * @param data [IN] Original data * @param dataLen [IN] Length of the original data * * @retval CRYPT_NULL_INPUT Invalid null pointer input * @retval CRYPT_RSA_ERR_PKCSV15_SALT_DATA Incorrect padding value. * @retval CRYPT_SECUREC_FAIL Security Function Failure * @retval CRYPT_RSA_BUFF_LEN_NOT_ENOUGH The length required for padding does not match the input parameter. * @retval CRYPT_RSA_ERR_INPUT_VALUE The hash algorithm ID is not supported. * @retval CRYPT_SUCCESS Verify pkcsv1.5 is padded successfully. */ int32_t CRYPT_RSA_VerifyPkcsV15Type1(CRYPT_MD_AlgId hashId, const uint8_t *pad, uint32_t padLen, const uint8_t *data, uint32_t dataLen); #endif // HITLS_CRYPTO_RSA_VERIFY #endif // HITLS_CRYPTO_RSA_EMSA_PKCSV15 #if defined(HITLS_CRYPTO_RSA_SIGN) || defined(HITLS_CRYPTO_RSA_VERIFY) /** * @ingroup rsa * @brief Obtain the maximum length of RSA signature data. * * @param ctx [IN] Maximum length of the RSA signature data that is expected to be obtained * * @retval 0 The input is incorrect or the corresponding key structure does not contain valid key information. * @retval uint32_t Maximum length of the signature data */ uint32_t CRYPT_RSA_GetSignLen(const CRYPT_RSA_Ctx *ctx); #endif #ifdef HITLS_CRYPTO_RSA_VERIFY int32_t CRYPT_RSA_VerifyData(CRYPT_RSA_Ctx *ctx, const uint8_t *data, uint32_t dataLen, const uint8_t *sign, uint32_t signLen); int32_t CRYPT_RSA_Verify(CRYPT_RSA_Ctx *ctx, int32_t algId, const uint8_t *data, uint32_t dataLen, const uint8_t *sign, uint32_t signLen); #endif #ifdef HITLS_CRYPTO_RSA_SIGN int32_t CRYPT_RSA_SignData(CRYPT_RSA_Ctx *ctx, const uint8_t *data, uint32_t dataLen, uint8_t *sign, uint32_t *signLen); int32_t CRYPT_RSA_Sign(CRYPT_RSA_Ctx *ctx, int32_t algId, const uint8_t *data, uint32_t dataLen, uint8_t *sign, uint32_t *signLen); #endif #ifdef HITLS_CRYPTO_RSA_ENCRYPT /** * @ingroup rsa * @brief RSA public key encryption * * @param ctx [IN] RSA context structure * @param data [IN] Information to be encrypted * @param dataLen [IN] Length of the information to be encrypted * @param out [OUT] Pointer to the encrypted information output. * @param outLen [OUT] Pointer to the length of the encrypted information * * @retval CRYPT_NULL_INPUT Invalid null pointer input * @retval CRYPT_RSA_NO_KEY_INFO does not contain the key information. * @retval CRYPT_RSA_ERR_INPUT_VALUE The entered value does not meet the calculation conditions. * @retval CRYPT_RSA_BUFF_LEN_NOT_ENOUGH Outbuf Insufficient * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure * @retval CRYPT_SECUREC_FAIL A safe function error occurs. * @retval BN error. An error occurs in the internal BigNum operation. * @retval CRYPT_EAL_ALG_NOT_SUPPORT does not register the encryption method. * @retval CRYPT_SUCCESS encryption succeeded. */ int32_t CRYPT_RSA_Encrypt(CRYPT_RSA_Ctx *ctx, const uint8_t *data, uint32_t dataLen, uint8_t *out, uint32_t *outLen); #endif #ifdef HITLS_CRYPTO_RSA_DECRYPT /** * @ingroup rsa * @brief RSA private key decryption * * @param ctx [IN] RSA context structure * @param data [IN] Information to be decrypted * @param dataLen [IN] Length of the information to be decrypted * @param out [OUT] Pointer to the output information after decryption. * @param outLen [OUT] Pointer to the length of the decrypted information * * @retval CRYPT_NULL_INPUT Error null pointer input * @retval CRYPT_RSA_NO_KEY_INFO does not contain the key information. * @retval CRYPT_RSA_ERR_INPUT_VALUE The entered value does not meet the calculation conditions. * @retval CRYPT_RSA_BUFF_LEN_NOT_ENOUGH Outbuf Insufficient * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure * @retval CRYPT_SECUREC_FAIL A security function error occurs. * @retval CRYPT_EAL_ALG_NOT_SUPPORT does not register the decryption method. * @retval BN error. An error occurs in the internal BigNum operation. * @retval CRYPT_SUCCESS Decryption succeeded. */ int32_t CRYPT_RSA_Decrypt(CRYPT_RSA_Ctx *ctx, const uint8_t *data, uint32_t dataLen, uint8_t *out, uint32_t *outLen); #endif #ifdef HITLS_CRYPTO_RSA_VERIFY /** * @ingroup rsa * @brief RSA public key decryption * * @param ctx [IN] RSA context structure * @param data [IN] Information to be decrypted * @param dataLen [IN] Length of the information to be decrypted * @param out [OUT] Pointer to the output information after decryption. * @param outLen [IN/OUT] Pointer to the length of the decrypted information. * Before being transferred, the value must be set to the maximum length of the array. * * @retval CRYPT_NULL_INPUT Invalid null pointer input * @retval CRYPT_RSA_NO_KEY_INFO does not contain the key information. * @retval CRYPT_RSA_PAD_NO_SET_ERROR The padding type is not set. * @retval CRYPT_RSA_BUFF_LEN_NOT_ENOUGH The space is insufficient after decryption. * @retval CRYPT_RSA_ERR_INPUT_VALUE The input parameter does not meet the requirements. * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure * @retval Other error codes, for example, the CRYPT_RSA_UnPackPkcsV15Type1 de-padding function. * @retval CRYPT_SUCCESS Decrypted Successfully */ int32_t CRYPT_RSA_Recover(CRYPT_RSA_Ctx *ctx, const uint8_t *data, uint32_t dataLen, uint8_t *out, uint32_t *outLen); #endif /** * @ingroup rsa * @brief RSA compare the public key * * @param a [IN] RSA context structure * @param b [IN] RSA context structure * * @retval CRYPT_SUCCESS is the same * @retval CRYPT_NULL_INPUT Invalid null pointer input * @retval CRYPT_RSA_NO_KEY_INFO No public key * @retval CRYPT_RSA_PUBKEY_NOT_EQUAL Public Keys are not equal */ int32_t CRYPT_RSA_Cmp(const CRYPT_RSA_Ctx *a, const CRYPT_RSA_Ctx *b); #ifdef HITLS_CRYPTO_RSAES_OAEP #ifdef HITLS_CRYPTO_RSA_ENCRYPT /** * @ingroup rsa * @brief oaep padding * * @param hashMethod [IN] Hash method. Only sha1, sha244, sha256, sha384, and sha512 are supported. * @param mgfMethod [IN] Hash method required by mgf * @param in [IN] Original data * @param inLen [IN] Original data length * @param param [IN] oaep parameter, which can be null * @param paramLen [IN] oaep Parameter length * @param pad [IN] Data after padding * @param padLen [IN] Data length after padding * * @retval CRYPT_NULL_INPUT Error null pointer input * @retval CRYPT_RSA_ERR_INPUT_VALUE The entered value does not meet the calculation conditions. * @retval CRYPT_SECUREC_FAIL A security function error occurs. * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure * @retval CRYPT_RSA_BUFF_LEN_NOT_ENOUGH Outbuf Insufficient * */ int32_t CRYPT_RSA_SetPkcs1Oaep(CRYPT_RSA_Ctx *ctx, const uint8_t *in, uint32_t inLen, uint8_t *pad, uint32_t padLen); #endif // HITLS_CRYPTO_RSA_ENCRYPT #ifdef HITLS_CRYPTO_RSA_DECRYPT /** * @ingroup rsa * @brief Verify the oaep padding. * * @param pad [IN] oaep parameter, which can be null * @param in [IN] Data after padding * @param inLen [IN] Data length after padding * @param param [IN] oaep parameter, which can be null * @param paramLen [IN] oaep Parameter length * @param msg [IN] Data after the de-padding * @param msgLen [IN/OUT] The input parameter is the length of the msg buffer, * and the output parameter is the length of the msg after the de-padding. * * @retval CRYPT_NULL_INPUT Error null pointer input * @retval CRYPT_RSA_ERR_INPUT_VALUE The entered value does not meet the calculation conditions. * @retval CRYPT_SECUREC_FAIL A security function error occurs. * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure * */ int32_t CRYPT_RSA_VerifyPkcs1Oaep(RSA_PadingPara *pad, const uint8_t *in, uint32_t inLen, const uint8_t *param, uint32_t paramLen, uint8_t *msg, uint32_t *msgLen); #endif // HITLS_CRYPTO_RSA_DECRYPT #endif // HITLS_CRYPTO_RSAES_OAEP #if defined(HITLS_CRYPTO_RSA_ENCRYPT) && \ (defined(HITLS_CRYPTO_RSAES_PKCSV15_TLS) || defined(HITLS_CRYPTO_RSAES_PKCSV15)) int32_t CRYPT_RSA_SetPkcsV15Type2(void *libCtx, const uint8_t *in, uint32_t inLen, uint8_t *out, uint32_t outLen); #endif #ifdef HITLS_CRYPTO_RSA_DECRYPT #ifdef HITLS_CRYPTO_RSAES_PKCSV15 int32_t CRYPT_RSA_VerifyPkcsV15Type2(const uint8_t *in, uint32_t inLen, uint8_t *out, uint32_t *outLen); #endif #ifdef HITLS_CRYPTO_RSAES_PKCSV15_TLS int32_t CRYPT_RSA_VerifyPkcsV15Type2TLS(const uint8_t *in, uint32_t inLen, uint8_t *out, uint32_t *outLen); #endif #endif // HITLS_CRYPTO_RSA_DECRYPT /** * @ingroup rsa * @brief rsa get security bits * * @param ctx [IN] rsa Context structure * * @retval security bits */ int32_t CRYPT_RSA_GetSecBits(const CRYPT_RSA_Ctx *ctx); #ifdef HITLS_CRYPTO_RSA_CHECK /** * @ingroup rsa * @brief check the key pair consistency * * @param checkType [IN] check type * @param pkey1 [IN] rsa key context structure * @param pkey2 [IN] rsa key context structure * * @retval CRYPT_SUCCESS check success. * Others. For details, see error code in errno. */ int32_t CRYPT_RSA_Check(uint32_t checkType, const CRYPT_RSA_Ctx *pkey1, const CRYPT_RSA_Ctx *pkey2); #endif // HITLS_CRYPTO_RSA_CHECK #ifdef HITLS_CRYPTO_PROVIDER /** * @ingroup RSA * @brief RSA import key * * @param ctx [IN/OUT] RSA context structure * @param params [IN] parameters */ int32_t CRYPT_RSA_Import(CRYPT_RSA_Ctx *ctx, const BSL_Param *params); /** * @ingroup RSA * @brief RSA export key * * @param ctx [IN] RSA context structure * @param params [IN/OUT] key parameters */ int32_t CRYPT_RSA_Export(const CRYPT_RSA_Ctx *ctx, BSL_Param *params); #endif // HITLS_CRYPTO_PROVIDER #ifdef __cplusplus } #endif #endif // HITLS_CRYPTO_RSA #endif // CRYPT_RSA_H 这是头文件以及rsa的源代码,请根据这些来编写上述的demo
09-07
/* * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once #include "esp_err.h" #include "esp_intr_alloc.h" #include "hal/ledc_types.h" #include "driver/gpio.h" #ifdef __cplusplus extern "C" { #endif #if SOC_LEDC_SUPPORT_APB_CLOCK /** * @brief Frequency of one of the LEDC peripheral clock sources, APB_CLK * @note This macro should have no use in your application, we keep it here only for backward compatible */ #define LEDC_APB_CLK_HZ _Pragma ("GCC warning \"'LEDC_APB_CLK_HZ' macro is deprecated\"") (APB_CLK_FREQ) #endif #if SOC_LEDC_SUPPORT_REF_TICK /** * @brief Frequency of one of the LEDC peripheral clock sources, REF_TICK * @note This macro should have no use in your application, we keep it here only for backward compatible */ #define LEDC_REF_CLK_HZ _Pragma ("GCC warning \"'LEDC_REF_CLK_HZ' macro is deprecated\"") (REF_CLK_FREQ) #endif #define LEDC_ERR_DUTY (0xFFFFFFFF) #define LEDC_ERR_VAL (-1) /** * @brief Strategies to be applied to the LEDC channel during system Light-sleep period */ typedef enum { LEDC_SLEEP_MODE_NO_ALIVE_NO_PD = 0, /*!< The default mode: no LEDC output, and no power off the LEDC power domain. */ LEDC_SLEEP_MODE_NO_ALIVE_ALLOW_PD, /*!< The low-power-consumption mode: no LEDC output, and allow to power off the LEDC power domain. This can save power, but at the expense of more RAM being consumed to save register context. This option is only available on targets that support TOP domain to be powered down. */ LEDC_SLEEP_MODE_KEEP_ALIVE, /*!< The high-power-consumption mode: keep LEDC output when the system enters Light-sleep. */ LEDC_SLEEP_MODE_INVALID, /*!< Invalid LEDC sleep mode strategy */ } ledc_sleep_mode_t; /** * @brief Configuration parameters of LEDC channel for ledc_channel_config function */ typedef struct { int gpio_num; /*!< the LEDC output gpio_num, if you want to use gpio16, gpio_num = 16 */ ledc_mode_t speed_mode; /*!< LEDC speed speed_mode, high-speed mode (only exists on esp32) or low-speed mode */ ledc_channel_t channel; /*!< LEDC channel (0 - LEDC_CHANNEL_MAX-1) */ ledc_intr_type_t intr_type; /*!< configure interrupt, Fade interrupt enable or Fade interrupt disable */ ledc_timer_t timer_sel; /*!< Select the timer source of channel (0 - LEDC_TIMER_MAX-1) */ uint32_t duty; /*!< LEDC channel duty, the range of duty setting is [0, (2**duty_resolution)] */ int hpoint; /*!< LEDC channel hpoint value, the range is [0, (2**duty_resolution)-1] */ ledc_sleep_mode_t sleep_mode; /*!< choose the desired behavior for the LEDC channel in Light-sleep */ struct { unsigned int output_invert: 1;/*!< Enable (1) or disable (0) gpio output invert */ } flags; /*!< LEDC flags */ } ledc_channel_config_t; /** * @brief Configuration parameters of LEDC timer for ledc_timer_config function */ typedef struct { ledc_mode_t speed_mode; /*!< LEDC speed speed_mode, high-speed mode (only exists on esp32) or low-speed mode */ ledc_timer_bit_t duty_resolution; /*!< LEDC channel duty resolution */ ledc_timer_t timer_num; /*!< The timer source of channel (0 - LEDC_TIMER_MAX-1) */ uint32_t freq_hz; /*!< LEDC timer frequency (Hz) */ ledc_clk_cfg_t clk_cfg; /*!< Configure LEDC source clock from ledc_clk_cfg_t. Note that LEDC_USE_RC_FAST_CLK and LEDC_USE_XTAL_CLK are non-timer-specific clock sources. You can not have one LEDC timer uses RC_FAST_CLK as the clock source and have another LEDC timer uses XTAL_CLK as its clock source. All chips except esp32 and esp32s2 do not have timer-specific clock sources, which means clock source for all timers must be the same one. */ bool deconfigure; /*!< Set this field to de-configure a LEDC timer which has been configured before Note that it will not check whether the timer wants to be de-configured is binded to any channel. Also, the timer has to be paused first before it can be de-configured. When this field is set, duty_resolution, freq_hz, clk_cfg fields are ignored. */ } ledc_timer_config_t; typedef intr_handle_t ledc_isr_handle_t; /** * @brief LEDC callback event type */ typedef enum { LEDC_FADE_END_EVT /**< LEDC fade end event */ } ledc_cb_event_t; /** * @brief LEDC callback parameter */ typedef struct { ledc_cb_event_t event; /**< Event name */ uint32_t speed_mode; /**< Speed mode of the LEDC channel group */ uint32_t channel; /**< LEDC channel (0 - LEDC_CHANNEL_MAX-1) */ uint32_t duty; /**< LEDC current duty of the channel, the range of duty is [0, (2**duty_resolution)] */ } ledc_cb_param_t; /** * @brief Type of LEDC event callback * @param param LEDC callback parameter * @param user_arg User registered data * @return Whether a high priority task has been waken up by this function */ typedef bool (*ledc_cb_t)(const ledc_cb_param_t *param, void *user_arg); /** * @brief Group of supported LEDC callbacks * @note The callbacks are all running under ISR environment */ typedef struct { ledc_cb_t fade_cb; /**< LEDC fade_end callback function */ } ledc_cbs_t; /** * @brief LEDC channel configuration * Configure LEDC channel with the given channel/output gpio_num/interrupt/source timer/frequency(Hz)/LEDC duty * * @param ledc_conf Pointer of LEDC channel configure struct * * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error */ esp_err_t ledc_channel_config(const ledc_channel_config_t *ledc_conf); /** * @brief Helper function to find the maximum possible duty resolution in bits for ledc_timer_config() * * @param src_clk_freq LEDC timer source clock frequency (Hz) (See doxygen comments of `ledc_clk_cfg_t` or get from `esp_clk_tree_src_get_freq_hz`) * @param timer_freq Desired LEDC timer frequency (Hz) * * @return * - 0 The timer frequency cannot be achieved * - Others The largest duty resolution value to be set */ uint32_t ledc_find_suitable_duty_resolution(uint32_t src_clk_freq, uint32_t timer_freq); /** * @brief LEDC timer configuration * Configure LEDC timer with the given source timer/frequency(Hz)/duty_resolution * * @param timer_conf Pointer of LEDC timer configure struct * * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error * - ESP_FAIL Can not find a proper pre-divider number base on the given frequency and the current duty_resolution. * - ESP_ERR_INVALID_STATE Timer cannot be de-configured because timer is not configured or is not paused */ esp_err_t ledc_timer_config(const ledc_timer_config_t *timer_conf); /** * @brief LEDC update channel parameters * * @note Call this function to activate the LEDC updated parameters. * After ledc_set_duty, we need to call this function to update the settings. * And the new LEDC parameters don't take effect until the next PWM cycle. * @note ledc_set_duty, ledc_set_duty_with_hpoint and ledc_update_duty are not thread-safe, do not call these functions to * control one LEDC channel in different tasks at the same time. * A thread-safe version of API is ledc_set_duty_and_update * @note If `CONFIG_LEDC_CTRL_FUNC_IN_IRAM` is enabled, this function will be placed in the IRAM by linker, * makes it possible to execute even when the Cache is disabled. * @note This function is allowed to run within ISR context. * * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. * @param channel LEDC channel (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t * * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error */ esp_err_t ledc_update_duty(ledc_mode_t speed_mode, ledc_channel_t channel); /** * @brief Set LEDC output gpio. * * @note This function only routes the LEDC signal to GPIO through matrix, other LEDC resources initialization are not involved. * Please use `ledc_channel_config()` instead to fully configure a LEDC channel. * * @param gpio_num The LEDC output gpio * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. * @param channel LEDC channel (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t * * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error */ esp_err_t ledc_set_pin(int gpio_num, ledc_mode_t speed_mode, ledc_channel_t channel); /** * @brief LEDC stop. * Disable LEDC output, and set idle level * * @note If `CONFIG_LEDC_CTRL_FUNC_IN_IRAM` is enabled, this function will be placed in the IRAM by linker, * makes it possible to execute even when the Cache is disabled. * @note This function is allowed to run within ISR context. * * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. * @param channel LEDC channel (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t * @param idle_level Set output idle level after LEDC stops. * * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error */ esp_err_t ledc_stop(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t idle_level); /** * @brief LEDC set channel frequency (Hz) * * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. * @param timer_num LEDC timer index (0-3), select from ledc_timer_t * @param freq_hz Set the LEDC frequency * * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error * - ESP_FAIL Can not find a proper pre-divider number base on the given frequency and the current duty_resolution. */ esp_err_t ledc_set_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num, uint32_t freq_hz); /** * @brief LEDC get channel frequency (Hz) * * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. * @param timer_num LEDC timer index (0-3), select from ledc_timer_t * * @return * - 0 error * - Others Current LEDC frequency */ uint32_t ledc_get_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num); /** * @brief LEDC set duty and hpoint value * Only after calling ledc_update_duty will the duty update. * * @note ledc_set_duty, ledc_set_duty_with_hpoint and ledc_update_duty are not thread-safe, do not call these functions to * control one LEDC channel in different tasks at the same time. * A thread-safe version of API is ledc_set_duty_and_update * @note For ESP32, hardware does not support any duty change while a fade operation is running in progress on that channel. * Other duty operations will have to wait until the fade operation has finished. * * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. * @param channel LEDC channel (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t * @param duty Set the LEDC duty, the range of duty setting is [0, (2**duty_resolution)] * @param hpoint Set the LEDC hpoint value, the range is [0, (2**duty_resolution)-1] * * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error */ esp_err_t ledc_set_duty_with_hpoint(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t duty, uint32_t hpoint); /** * @brief LEDC get hpoint value, the counter value when the output is set high level. * * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. * @param channel LEDC channel (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t * * @return * - LEDC_ERR_VAL if parameter error * - Others Current hpoint value of LEDC channel */ int ledc_get_hpoint(ledc_mode_t speed_mode, ledc_channel_t channel); /** * @brief LEDC set duty * This function do not change the hpoint value of this channel. if needed, please call ledc_set_duty_with_hpoint. * only after calling ledc_update_duty will the duty update. * * @note ledc_set_duty, ledc_set_duty_with_hpoint and ledc_update_duty are not thread-safe, do not call these functions to * control one LEDC channel in different tasks at the same time. * A thread-safe version of API is ledc_set_duty_and_update. * @note For ESP32, hardware does not support any duty change while a fade operation is running in progress on that channel. * Other duty operations will have to wait until the fade operation has finished. * * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. * @param channel LEDC channel (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t * @param duty Set the LEDC duty, the range of duty setting is [0, (2**duty_resolution)] * * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error */ esp_err_t ledc_set_duty(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t duty); /** * @brief LEDC get duty * This function returns the duty at the present PWM cycle. * You shouldn't expect the function to return the new duty in the same cycle of calling ledc_update_duty, * because duty update doesn't take effect until the next cycle. * * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. * @param channel LEDC channel (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t * * @return * - LEDC_ERR_DUTY if parameter error * - Others Current LEDC duty */ uint32_t ledc_get_duty(ledc_mode_t speed_mode, ledc_channel_t channel); /** * @brief LEDC set gradient * Set LEDC gradient, After the function calls the ledc_update_duty function, the function can take effect. * * @note For ESP32, hardware does not support any duty change while a fade operation is running in progress on that channel. * Other duty operations will have to wait until the fade operation has finished. * * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. * @param channel LEDC channel (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t * @param duty Set the start of the gradient duty, the range of duty setting is [0, (2**duty_resolution)] * @param fade_direction Set the direction of the gradient * @param step_num Set the number of the gradient * @param duty_cycle_num Set how many LEDC tick each time the gradient lasts * @param duty_scale Set gradient change amplitude * * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error */ esp_err_t ledc_set_fade(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t duty, ledc_duty_direction_t fade_direction, uint32_t step_num, uint32_t duty_cycle_num, uint32_t duty_scale); /** * @brief Register LEDC interrupt handler, the handler is an ISR. * The handler will be attached to the same CPU core that this function is running on. * * @param fn Interrupt handler function. * @param arg User-supplied argument passed to the handler function. * @param intr_alloc_flags Flags used to allocate the interrupt. One or multiple (ORred) * ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info. * @param handle Pointer to return handle. If non-NULL, a handle for the interrupt will * be returned here. * * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error * - ESP_ERR_NOT_FOUND Failed to find available interrupt source */ esp_err_t ledc_isr_register(void (*fn)(void *), void *arg, int intr_alloc_flags, ledc_isr_handle_t *handle); /** * @brief Configure LEDC timer settings * * This function does not take care of whether the chosen clock source is enabled or not, also does not handle the clock source * to meet channel sleep mode choice. * * If the chosen clock source is a new clock source to the LEDC timer, please use `ledc_timer_config`; * If the clock source is kept to be the same, but frequency needs to be updated, please use `ledc_set_freq`. * * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. * @param timer_sel Timer index (0-3), there are 4 timers in LEDC module * @param clock_divider Timer clock divide value, the timer clock is divided from the selected clock source * @param duty_resolution Resolution of duty setting in number of bits. The range is [1, SOC_LEDC_TIMER_BIT_WIDTH] * @param clk_src Select LEDC source clock. * * @return * - (-1) Parameter error * - Other Current LEDC duty */ esp_err_t ledc_timer_set(ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t clock_divider, uint32_t duty_resolution, ledc_clk_src_t clk_src) __attribute__((deprecated("Please use ledc_timer_config() or ledc_set_freq()"))); /** * @brief Reset LEDC timer * * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. * @param timer_sel LEDC timer index (0-3), select from ledc_timer_t * * @return * - ESP_ERR_INVALID_ARG Parameter error * - ESP_OK Success */ esp_err_t ledc_timer_rst(ledc_mode_t speed_mode, ledc_timer_t timer_sel); /** * @brief Pause LEDC timer counter * * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. * @param timer_sel LEDC timer index (0-3), select from ledc_timer_t * * @return * - ESP_ERR_INVALID_ARG Parameter error * - ESP_OK Success */ esp_err_t ledc_timer_pause(ledc_mode_t speed_mode, ledc_timer_t timer_sel); /** * @brief Resume LEDC timer * * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. * @param timer_sel LEDC timer index (0-3), select from ledc_timer_t * * @return * - ESP_ERR_INVALID_ARG Parameter error * - ESP_OK Success */ esp_err_t ledc_timer_resume(ledc_mode_t speed_mode, ledc_timer_t timer_sel); /** * @brief Bind LEDC channel with the selected timer * * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. * @param channel LEDC channel index (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t * @param timer_sel LEDC timer index (0-3), select from ledc_timer_t * * @return * - ESP_ERR_INVALID_ARG Parameter error * - ESP_OK Success */ esp_err_t ledc_bind_channel_timer(ledc_mode_t speed_mode, ledc_channel_t channel, ledc_timer_t timer_sel); /** * @brief Set LEDC fade function. * * @note Call ledc_fade_func_install() once before calling this function. * Call ledc_fade_start() after this to start fading. * @note ledc_set_fade_with_step, ledc_set_fade_with_time and ledc_fade_start are not thread-safe, do not call these functions to * control one LEDC channel in different tasks at the same time. * A thread-safe version of API is ledc_set_fade_step_and_start * @note For ESP32, hardware does not support any duty change while a fade operation is running in progress on that channel. * Other duty operations will have to wait until the fade operation has finished. * * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. * @param channel LEDC channel index (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t * @param target_duty Target duty of fading [0, (2**duty_resolution)] * @param scale Controls the increase or decrease step scale. * @param cycle_num increase or decrease the duty every cycle_num cycles * * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error * - ESP_ERR_INVALID_STATE Channel not initialized * - ESP_FAIL Fade function init error */ esp_err_t ledc_set_fade_with_step(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t target_duty, uint32_t scale, uint32_t cycle_num); /** * @brief Set LEDC fade function, with a limited time. * * @note Call ledc_fade_func_install() once before calling this function. * Call ledc_fade_start() after this to start fading. * @note ledc_set_fade_with_step, ledc_set_fade_with_time and ledc_fade_start are not thread-safe, do not call these functions to * control one LEDC channel in different tasks at the same time. * A thread-safe version of API is ledc_set_fade_step_and_start * @note For ESP32, hardware does not support any duty change while a fade operation is running in progress on that channel. * Other duty operations will have to wait until the fade operation has finished. * * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. * @param channel LEDC channel index (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t * @param target_duty Target duty of fading [0, (2**duty_resolution)] * @param desired_fade_time_ms The intended time of the fading ( ms ). * Note that the actual time it takes to complete the fade could vary by a factor of up to 2x shorter * or longer than the expected time due to internal rounding errors in calculations. * Specifically: * * The total number of cycles (total_cycle_num = desired_fade_time_ms * freq / 1000) * * The difference in duty cycle (duty_delta = |target_duty - current_duty|) * The fade may complete faster than expected if total_cycle_num larger than duty_delta. Conversely, * it may take longer than expected if total_cycle_num is less than duty_delta. * The closer the ratio of total_cycle_num/duty_delta (or its inverse) is to a whole number (the floor value), * the more accurately the actual fade duration will match the intended time. * If an exact fade time is expected, please consider to split the entire fade into several smaller linear fades. * The split should make each fade step has a divisible total_cycle_num/duty_delta (or its inverse) ratio. * * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error * - ESP_ERR_INVALID_STATE Channel not initialized * - ESP_FAIL Fade function init error */ esp_err_t ledc_set_fade_with_time(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t target_duty, int desired_fade_time_ms); /** * @brief Install LEDC fade function. This function will occupy interrupt of LEDC module. * * @param intr_alloc_flags Flags used to allocate the interrupt. One or multiple (ORred) * ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info. * * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Intr flag error * - ESP_ERR_NOT_FOUND Failed to find available interrupt source * - ESP_ERR_INVALID_STATE Fade function already installed */ esp_err_t ledc_fade_func_install(int intr_alloc_flags); /** * @brief Uninstall LEDC fade function. */ void ledc_fade_func_uninstall(void); /** * @brief Start LEDC fading. * * @note Call ledc_fade_func_install() once before calling this function. * Call this API right after ledc_set_fade_with_time or ledc_set_fade_with_step before to start fading. * @note Starting fade operation with this API is not thread-safe, use with care. * @note For ESP32, hardware does not support any duty change while a fade operation is running in progress on that channel. * Other duty operations will have to wait until the fade operation has finished. * * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. * @param channel LEDC channel number * @param fade_mode Whether to block until fading done. See ledc_types.h ledc_fade_mode_t for more info. * Note that this function will not return until fading to the target duty if LEDC_FADE_WAIT_DONE mode is selected. * * @return * - ESP_OK Success * - ESP_ERR_INVALID_STATE Channel not initialized or fade function not installed. * - ESP_ERR_INVALID_ARG Parameter error. */ esp_err_t ledc_fade_start(ledc_mode_t speed_mode, ledc_channel_t channel, ledc_fade_mode_t fade_mode); #if SOC_LEDC_SUPPORT_FADE_STOP /** * @brief Stop LEDC fading. The duty of the channel is guaranteed to be fixed at most one PWM cycle after the function returns. * * @note This API can be called if a new fixed duty or a new fade want to be set while the last fade operation is still running in progress. * @note Call this API will abort the fading operation only if it was started by calling ledc_fade_start with LEDC_FADE_NO_WAIT mode. * @note If a fade was started with LEDC_FADE_WAIT_DONE mode, calling this API afterwards has no use in stopping the fade. Fade will continue until it reaches the target duty. * * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. * @param channel LEDC channel number * * @return * - ESP_OK Success * - ESP_ERR_INVALID_STATE Channel not initialized * - ESP_ERR_INVALID_ARG Parameter error * - ESP_FAIL Fade function init error */ esp_err_t ledc_fade_stop(ledc_mode_t speed_mode, ledc_channel_t channel); #endif //SOC_LEDC_SUPPORT_FADE_STOP /** * @brief A thread-safe API to set duty for LEDC channel and return when duty updated. * * @note For ESP32, hardware does not support any duty change while a fade operation is running in progress on that channel. * Other duty operations will have to wait until the fade operation has finished. * * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. * @param channel LEDC channel (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t * @param duty Set the LEDC duty, the range of duty setting is [0, (2**duty_resolution)] * @param hpoint Set the LEDC hpoint value, the range is [0, (2**duty_resolution)-1] * * @return * - ESP_OK Success * - ESP_ERR_INVALID_STATE Channel not initialized * - ESP_ERR_INVALID_ARG Parameter error * - ESP_FAIL Fade function init error */ esp_err_t ledc_set_duty_and_update(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t duty, uint32_t hpoint); /** * @brief A thread-safe API to set and start LEDC fade function, with a limited time. * * @note Call ledc_fade_func_install() once, before calling this function. * @note For ESP32, hardware does not support any duty change while a fade operation is running in progress on that channel. * Other duty operations will have to wait until the fade operation has finished. * * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. * @param channel LEDC channel index (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t * @param target_duty Target duty of fading [0, (2**duty_resolution)] * @param desired_fade_time_ms The intended time of the fading ( ms ). * Note that the actual time it takes to complete the fade could vary by a factor of up to 2x shorter * or longer than the expected time due to internal rounding errors in calculations. * Specifically: * * The total number of cycles (total_cycle_num = desired_fade_time_ms * freq / 1000) * * The difference in duty cycle (duty_delta = |target_duty - current_duty|) * The fade may complete faster than expected if total_cycle_num larger than duty_delta. Conversely, * it may take longer than expected if total_cycle_num is less than duty_delta. * The closer the ratio of total_cycle_num/duty_delta (or its inverse) is to a whole number (the floor value), * the more accurately the actual fade duration will match the intended time. * If an exact fade time is expected, please consider to split the entire fade into several smaller linear fades. * The split should make each fade step has a divisible total_cycle_num/duty_delta (or its inverse) ratio. * @param fade_mode choose blocking or non-blocking mode * * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error * - ESP_ERR_INVALID_STATE Channel not initialized * - ESP_FAIL Fade function init error */ esp_err_t ledc_set_fade_time_and_start(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t target_duty, uint32_t desired_fade_time_ms, ledc_fade_mode_t fade_mode); /** * @brief A thread-safe API to set and start LEDC fade function. * * @note Call ledc_fade_func_install() once before calling this function. * @note For ESP32, hardware does not support any duty change while a fade operation is running in progress on that channel. * Other duty operations will have to wait until the fade operation has finished. * * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. * @param channel LEDC channel index (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t * @param target_duty Target duty of fading [0, (2**duty_resolution)] * @param scale Controls the increase or decrease step scale. * @param cycle_num increase or decrease the duty every cycle_num cycles * @param fade_mode choose blocking or non-blocking mode * * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error * - ESP_ERR_INVALID_STATE Channel not initialized * - ESP_FAIL Fade function init error */ esp_err_t ledc_set_fade_step_and_start(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t target_duty, uint32_t scale, uint32_t cycle_num, ledc_fade_mode_t fade_mode); /** * @brief LEDC callback registration function * * @note The callback is called from an ISR, it must never attempt to block, and any FreeRTOS API called must be ISR capable. * * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. * @param channel LEDC channel index (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t * @param cbs Group of LEDC callback functions * @param user_arg user registered data for the callback function * * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error * - ESP_ERR_INVALID_STATE Channel not initialized * - ESP_FAIL Fade function init error */ esp_err_t ledc_cb_register(ledc_mode_t speed_mode, ledc_channel_t channel, ledc_cbs_t *cbs, void *user_arg); #if SOC_LEDC_GAMMA_CURVE_FADE_SUPPORTED /** * @brief Structure for the fade parameters for one hardware fade to be written to gamma wr register * * @verbatim * duty ^ ONE HW LINEAR FADE * | * | * | * | * start_duty + scale * n = end_duty |. . . . . . . . . . . . . . . . . . . . . . . . . .+- * | | * | | * | +--------+ * | | . * | | . * | -------+ . * | . . * | . . * | . . * | . . * ^ --- |. . . . . . . . . .+-------- . * scale| | | . * | | | . * v --- |. . . . .+---------+ . * | | . . * | | . . * start_duty +---------+ . . * | . . . * | . . . * +-----------------------------------------------------------> * PWM cycle * | | | | * | 1 step | 1 step | | * |<------->|<------->| | * | m cycles m cycles | * | | * <---------------------------------------------------> * n total steps * cycles = m * n * @endverbatim * * @note Be aware of the maximum value available on each element */ typedef struct { uint32_t dir : 1; /*!< Duty change direction. Set 1 as increase, 0 as decrease */ uint32_t cycle_num : SOC_LEDC_FADE_PARAMS_BIT_WIDTH; /*!< Number of PWM cycles of each step [0, 2**SOC_LEDC_FADE_PARAMS_BIT_WIDTH-1] */ uint32_t scale : SOC_LEDC_FADE_PARAMS_BIT_WIDTH; /*!< Duty change of each step [0, 2**SOC_LEDC_FADE_PARAMS_BIT_WIDTH-1] */ uint32_t step_num : SOC_LEDC_FADE_PARAMS_BIT_WIDTH; /*!< Total number of steps in one hardware fade [0, 2**SOC_LEDC_FADE_PARAMS_BIT_WIDTH-1] */ } ledc_fade_param_config_t; /** * @brief Set a LEDC multi-fade * * @note Call `ledc_fade_func_install()` once before calling this function. * Call `ledc_fade_start()` after this to start fading. * @note This function is not thread-safe, do not call it to control one LEDC channel in different tasks at the same time. * A thread-safe version of API is ledc_set_multi_fade_and_start * @note This function does not prohibit from duty overflow. User should take care of this by themselves. If duty * overflow happens, the PWM signal will suddenly change from 100% duty cycle to 0%, or the other way around. * * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. * @param channel LEDC channel index (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t * @param start_duty Set the start of the gradient duty, the range of duty setting is [0, (2**duty_resolution)] * @param fade_params_list Pointer to the array of fade parameters for a multi-fade * @param list_len Length of the fade_params_list, i.e. number of fade ranges for a multi-fade (1 - SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX) * * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error * - ESP_ERR_INVALID_STATE Channel not initialized * - ESP_FAIL Fade function init error */ esp_err_t ledc_set_multi_fade(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t start_duty, const ledc_fade_param_config_t *fade_params_list, uint32_t list_len); /** * @brief A thread-safe API to set and start LEDC multi-fade function * * @note Call `ledc_fade_func_install()` once before calling this function. * @note Fade will always begin from the current duty cycle. Make sure it is stable and synchronized to the desired * initial value before calling this function. Otherwise, you may see unexpected duty change. * @note This function does not prohibit from duty overflow. User should take care of this by themselves. If duty * overflow happens, the PWM signal will suddenly change from 100% duty cycle to 0%, or the other way around. * * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. * @param channel LEDC channel index (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t * @param start_duty Set the start of the gradient duty, the range of duty setting is [0, (2**duty_resolution)] * @param fade_params_list Pointer to the array of fade parameters for a multi-fade * @param list_len Length of the fade_params_list, i.e. number of fade ranges for a multi-fade (1 - SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX) * @param fade_mode Choose blocking or non-blocking mode * * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error * - ESP_ERR_INVALID_STATE Channel not initialized * - ESP_FAIL Fade function init error */ esp_err_t ledc_set_multi_fade_and_start(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t start_duty, const ledc_fade_param_config_t *fade_params_list, uint32_t list_len, ledc_fade_mode_t fade_mode); /** * @brief Helper function to fill the fade params for a multi-fade. Useful if desires a gamma curve fading. * * @note The fade params are calculated based on the given start_duty and end_duty. If the duty is not at * the start duty (gamma-corrected) when the fade begins, you may see undesired brightness change. * Therefore, please always remember thet when passing the fade_params to either `ledc_set_multi_fade` or * `ledc_set_multi_fade_and start`, the start_duty argument has to be the gamma-corrected start_duty. * * @param[in] speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. * @param[in] channel LEDC channel index (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t * @param[in] start_duty Duty cycle [0, (2**duty_resolution)] where the multi-fade begins with. This value should be a non-gamma-corrected duty cycle. * @param[in] end_duty Duty cycle [0, (2**duty_resolution)] where the multi-fade ends with. This value should be a non-gamma-corrected duty cycle. * @param[in] linear_phase_num Number of linear fades to simulate a gamma curved fade (1 - SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX) * @param[in] max_fade_time_ms The maximum time of the fading ( ms ). * @param[in] gamma_correction_operator User provided gamma correction function. The function argument should be able to * take any value within [0, (2**duty_resolution)]. And returns the gamma-corrected duty cycle. * @param[in] fade_params_list_size The size of the fade_params_list user allocated (1 - SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX) * @param[out] fade_params_list Pointer to the array of ledc_fade_param_config_t structure * @param[out] hw_fade_range_num Number of fade ranges for this multi-fade * * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error * - ESP_ERR_INVALID_STATE Channel not initialized * - ESP_FAIL Required number of hardware ranges exceeds the size of the ledc_fade_param_config_t array user allocated */ esp_err_t ledc_fill_multi_fade_param_list(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t start_duty, uint32_t end_duty, uint32_t linear_phase_num, uint32_t max_fade_time_ms, uint32_t (* gamma_correction_operator)(uint32_t), uint32_t fade_params_list_size, ledc_fade_param_config_t *fade_params_list, uint32_t *hw_fade_range_num); /** * @brief Get the fade parameters that are stored in gamma ram for a certain fade range * * Gamma ram is where saves the fade parameters for each fade range. The fade parameters are written in during fade * configuration. When fade begins, the duty will change according to the parameters in gamma ram. * * @param[in] speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. * @param[in] channel LEDC channel index (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t * @param[in] range Range index (0 - (SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX-1)), it specifies to which range in gamma ram to read * @param[out] dir Pointer to accept fade direction value * @param[out] cycle Pointer to accept fade cycle value * @param[out] scale Pointer to accept fade scale value * @param[out] step Pointer to accept fade step value * * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error * - ESP_ERR_INVALID_STATE Channel not initialized */ esp_err_t ledc_read_fade_param(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t range, uint32_t *dir, uint32_t *cycle, uint32_t *scale, uint32_t *step); #endif // SOC_LEDC_GAMMA_CURVE_FADE_SUPPORTED #ifdef __cplusplus } #endif
10-29
我已经使用我的方法能够正确获取网关,是我新增了一个变量标志auto_ping_select_eth0=1时获取eth0网关。还有一个问题,我要指定使用eth0的网络去执行ping操作。还是在这段代码中吗,能否找到具体位置,能否修改呢? /****************************************************************************** * Copyright (c) 2020-2020 TP-Link Technologies CO.,LTD. * * Filename: diagnose_main.c * Version: 1.0 * Description: 自动诊断部分 * Author: 赖滨绍<laibinshao@tp-link.com.cn> * Date: 2020-12-10 ******************************************************************************/ #include <sys/types.h> #include <arpa/inet.h> #include <errno.h> #include "diagnose_main.h" #include "msg_utils.h" #include "telnet.h" #define ITEMS_TIMEOUT_VAL 15 /*网络诊断超时时间*/ #define MAX_CLIENTS_NUM 10 /*接受客户端请求诊断数量*/ #define CLIENT_GET_TIMEOUT 30 /*客户端get请求最大次数*/ #define CLIENT_RECLAIM_INTERVAL 50 /*客户端诊断实例资源回收超时*/ DIAG_ADDR g_default_address; /*网络诊断地址*/ LOCAL S32 g_diagnose_timerid = ERROR; /*网络诊断超时定时器*/ LOCAL S8 g_is_auto_diagnose = 0; /*是否收到自诊断消息*/ PHY_STATUS g_phy_stat; /*物理链路状态*/ TASK_STRUCT g_client_array[MAX_CLIENTS_NUM]; /*记录客户端信息*/ NETWORK_STRUCT g_network_array[ADDR_COUNTS]; /*网络地址诊断信息*/ CONNECT_INFO g_connect_info; STORAGE_INFO g_storage_info; FIRMWARE_STRUCT g_firmware_info; VIDEO_ENCRYPTION g_video_encryption; #ifdef CONFIG_MOBILE_ACCESS_SET_SUPPORT #define NET_DETECTION_DEFAULT_DNS1 "8.8.8.8" #define NET_DETECTION_DEFAULT_DNS2 "www.google.com" LOCAL S8 g_is_lte_diagnose = 0; /* 是否是lte模块发起的自诊断信息 */ LOCAL S8 g_is_other_model_diagnose = 0; /* 其他模块发起的自诊断信息 */ #endif LOCAL S8 g_task_running = 0; /*当前是否进行了除网络诊断外的其他诊断*/ /*********************************************************************************************** *函数: *描述:加载数据模型中的诊断地址 *参数: *返回值: ***********************************************************************************************/ S32 load_network_address() { int index = 0; DIAG_ADDR target_addr; memset(&target_addr, 0, sizeof(DIAG_ADDR)); if (0 == ds_read(DIAGNOSE_ADDR_PATH, (void*)(&target_addr), sizeof(DIAG_ADDR))) { DIAGNOSE_WARNING("diagnose read address error."); return ERROR; } /*第0位保留为网关地址*/ for(index = 1; index < ADDR_COUNTS; index++) { strncpy(g_default_address.diag_addr[index], target_addr.diag_addr[index], ADDR_LEN); } DIAGNOSE_DEBUG("internet1:%s internet2:%s basecloud:%s", g_default_address.diag_addr[1], g_default_address.diag_addr[2], g_default_address.diag_addr[3]); return OK; } /*********************************************************************************************** *函数: *描述:关注数据据块,加载网关地址 *参数: *返回值: ***********************************************************************************************/ void load_gateway_address() { LINK_STATUS link_status = {0}; #ifdef CONFIG_MOBILE_ACCESS_SET_SUPPORT LTE_CONFIG_INFO_DATA lte_config = {0}; LTE_DHCP_IP lte_dhcp_ip = {0}; ds_read(LTE_INFO_DATA_PATH, (U8*)&lte_config, sizeof(LTE_CONFIG_INFO_DATA)); if(lte_config.internet_wired_enable == 0 || (lte_config.internet_wired_enable == 2 && lte_config.auto_switch_wired == 0 && lte_config.auto_ping_select_eth0 == 0)) { ds_read(LTE_DHCP_IP_PATH, (U8*)&lte_dhcp_ip, sizeof(LTE_DHCP_IP)); ip_to_str(lte_dhcp_ip.gateway, g_default_address.diag_addr[0]); }else #endif { ds_read(LINK_STATUS_PATH, &link_status, sizeof(LINK_STATUS)); ip_to_str(link_status.gateway, g_default_address.diag_addr[0]); } DIAGNOSE_ERROR("gateway:%s, internet1:%s,internet2:%s,cloud:%s",g_default_address.diag_addr[0], g_default_address.diag_addr[1],g_default_address.diag_addr[2],g_default_address.diag_addr[3]); } #ifdef CONFIG_MOBILE_ACCESS_SET_SUPPORT /*********************************************************************************************** *函数: *描述:关注lte模块net_det数据块,加载用户自定义地址 *参数: *返回值: ***********************************************************************************************/ void load_user_defined_address() { LTE_CONFIG_NET_DETECTION net_det = {0}; if(0 == ds_read(LTE_NET_DET_PATH, (U8*)&net_det, sizeof(LTE_CONFIG_NET_DETECTION))) { DIAGNOSE_ERROR("read path: %s\n failed.", LTE_NET_DET_PATH); return; } DIAGNOSE_ERROR("[LTE] add default dns address:%s", NET_DETECTION_DEFAULT_DNS1); strncpy(g_default_address.diag_addr[NET_4G_DET_DNS1], NET_DETECTION_DEFAULT_DNS1, ADDR_LEN); DIAGNOSE_ERROR("[LTE] add default dns address:%s", NET_DETECTION_DEFAULT_DNS2); strncpy(g_default_address.diag_addr[NET_4G_DET_DNS2], NET_DETECTION_DEFAULT_DNS2, ADDR_LEN); if(strlen(net_det.hostname_1) != 0) { DIAGNOSE_ERROR("add user defined address:%s.", net_det.hostname_1); strncpy(g_default_address.diag_addr[NET_USER_DEFINED1], net_det.hostname_1, ADDR_LEN); }else { memset(g_default_address.diag_addr[NET_USER_DEFINED1], 0, ADDR_LEN); } if(strlen(net_det.hostname_2) != 0) { DIAGNOSE_ERROR("add user defined address:%s.", net_det.hostname_2); strncpy(g_default_address.diag_addr[NET_USER_DEFINED2], net_det.hostname_2, ADDR_LEN); }else { memset(g_default_address.diag_addr[NET_USER_DEFINED2], 0, ADDR_LEN); } DIAGNOSE_ERROR("user defined addrees1:%s, user define address2:%s.", g_default_address.diag_addr[NET_USER_DEFINED1], g_default_address.diag_addr[NET_USER_DEFINED2]); } #endif /*********************************************************************************************** *函数:ip_to_str *描述:将网络字节序IP转成字符形式 *参数: *返回值: ***********************************************************************************************/ S32 ip_to_str(U32 ip_addr, char* str_ip) { struct in_addr dst; if (NULL == str_ip) { return ERROR; } memset(str_ip, 0, IP_LEN); dst.s_addr = ip_addr; if (NULL == inet_ntop(AF_INET, (void*)&dst, str_ip, IP_LEN)) { return ERROR; } return OK; } void diagnose_stop(void) { int index =0; g_task_running = 0; if (g_is_auto_diagnose) { #ifdef CONFIG_MOBILE_ACCESS_SET_SUPPORT if(g_is_lte_diagnose) { lte_diagnose_reply_result(); g_is_lte_diagnose = 0; }else #endif { diagnose_reply_result(); /*诊断完成后发送诊断消息*/ } g_is_auto_diagnose = 0; } DIAGNOSE_DEBUG("diagnose stop, save diagnose result to network config\n"); diagnose_result_save_config(); if (ERROR != g_diagnose_timerid) { inet_del_timer(g_diagnose_timerid); g_diagnose_timerid = ERROR; } for (index = 0; index < ADDR_COUNTS; index++) { if (TESTED != g_network_array[index].status) { g_network_array[index].status = TESTED; g_network_array[index].res = DIAGNOSE_FAILED; } if (g_network_array[index].do_telnet) { if (g_network_array[index].tel_state != TESTED) { g_network_array[index].tel_res = DIAGNOSE_FAILED; } telnet_stop(&g_network_array[index]); } } } /*********************************************************************************************** *函数:check_signal_quality *描述:获取无线信号强度 *参数: *返回值: ***********************************************************************************************/ S32 check_signal_quality(CONNECT_INFO* ptr_wireless) { DS_HANDLE_CONTEXT ds_context; JSON_OBJPTR data_obj = NULL; const char* ptr_value = NULL; int error_code = OK; PHY_STATUS phy_status = {0}; if (NULL == ptr_wireless) { return ERROR; } ds_read(PHY_STATUS_PATH, &phy_status, sizeof(PHY_STATUS)); if (1 == phy_status.ether || 0 == phy_status.wlan) { strncpy(ptr_wireless->link_type, "ethernet", LINK_TYPE_LEN); return OK; } /*构造jason请求sd信息*/ memset(&ds_context, 0, sizeof(DS_HANDLE_CONTEXT)); if (NULL == (ds_context.req_obj = jso_new_obj())) { return ERROR; } if (NULL == (data_obj = jso_new_obj())) { error_code = ERROR; goto out; } jso_obj_add(ds_context.req_obj, "network", data_obj); jso_add_string(data_obj, "get_connection_type", ""); jso_add_string(ds_context.req_obj, "method", "do"); ds_context.group_mask = ROOT_MASK; ds_context.method = METHOD_DO; ds_handle(&ds_context); if (NULL == ds_context.res_obj) { error_code = ERROR; goto out; } if (NULL == (ptr_value = jso_obj_get_string_origin(ds_context.res_obj, "link_type"))) { error_code = ERROR; goto out; } strncpy(ptr_wireless->link_type, ptr_value, LINK_TYPE_LEN); if (0 == strcmp(ptr_value, "ethernet")) { /*有线连接*/ error_code = OK; goto out; } /*无线连接*/ if (NULL == (ptr_value = jso_obj_get_string_origin(ds_context.res_obj, "ssid"))) { error_code = ERROR; goto out; } strncpy(ptr_wireless->ssid, ptr_value, WIFI_SSID_MAX_LEN); jso_obj_get_int(ds_context.res_obj, "rssi", &(ptr_wireless->rssi)); error_code = OK; DIAGNOSE_INFO("ssid:%s rssi:%d", ptr_wireless->ssid, ptr_wireless->rssi); out: if (NULL != ds_context.req_obj) { jso_free_obj(ds_context.req_obj); ds_context.req_obj = NULL; } if (NULL != ds_context.res_obj) { jso_free_obj(ds_context.res_obj); ds_context.res_obj = NULL; } return error_code; } /*********************************************************************************************** *函数: *描述:网络诊断数组初始化 *参数: *返回值: ***********************************************************************************************/ void address_array_init() { /*数组第0位放网关地址*/ memset(&g_network_array[NET_GATEWAY], 0, sizeof(NETWORK_STRUCT)); strncpy(g_network_array[NET_GATEWAY].para_name, "gateway", PARA_NAME_LEN); g_network_array[NET_GATEWAY].params_code = DIAGNOSE_GATEWAY; g_network_array[NET_GATEWAY].test = 1; /*数组第1位放外网地址1*/ memset(&g_network_array[NET_INTERNET1], 0, sizeof(NETWORK_STRUCT)); strncpy(g_network_array[NET_INTERNET1].para_name, "internet1", PARA_NAME_LEN); g_network_array[NET_INTERNET1].params_code = DIAGNOSE_ADDR1; g_network_array[NET_INTERNET1].test = 1; /*数组第2位放外网地址2*/ memset(&g_network_array[NET_INTERNET2], 0, sizeof(NETWORK_STRUCT)); strncpy(g_network_array[NET_INTERNET2].para_name, "internet2", PARA_NAME_LEN); g_network_array[NET_INTERNET2].params_code = DIAGNOSE_ADDR2; g_network_array[NET_INTERNET2].test = 1; /*数组第3位放云服务器地址*/ memset(&g_network_array[NET_BASE_CLOUD], 0, sizeof(NETWORK_STRUCT)); strncpy(g_network_array[NET_BASE_CLOUD].para_name, "cloud", PARA_NAME_LEN); g_network_array[NET_BASE_CLOUD].params_code = DIAGNOSE_BASE_CLOUD; g_network_array[NET_BASE_CLOUD].test = 1; g_network_array[NET_BASE_CLOUD].do_telnet = 1; #ifdef CONFIG_MOBILE_ACCESS_SET_SUPPORT memset(&g_network_array[NET_4G_DET_DNS1], 0, sizeof(NETWORK_STRUCT)); memset(&g_network_array[NET_4G_DET_DNS2], 0, sizeof(NETWORK_STRUCT)); memset(&g_network_array[NET_USER_DEFINED1], 0, sizeof(NETWORK_STRUCT)); memset(&g_network_array[NET_USER_DEFINED2], 0, sizeof(NETWORK_STRUCT)); LTE_CONFIG_NET_DETECTION net_det = {0}; if(0 == ds_read(LTE_NET_DET_PATH, (U8*)&net_det, sizeof(LTE_CONFIG_NET_DETECTION))) { DIAGNOSE_ERROR("read path %s failed.", LTE_NET_DET_PATH); return; } if(net_det.ping_enable == 1 && g_is_lte_diagnose == 1 && g_is_other_model_diagnose == 0) { /* 如果是LTE模块发起的ping检测只检测dns1 dns2和用户自定义地址 */ g_network_array[NET_INTERNET1].test = 0; g_network_array[NET_INTERNET2].test = 0; /* 如果是LTE模块发起的ping检测暂时检测网关地址 */ g_network_array[NET_GATEWAY].test = 0; /* 如果是LTE模块发起的ping检测对bata云进行telnet */ g_network_array[NET_BASE_CLOUD].do_telnet = 0; g_network_array[NET_BASE_CLOUD].test = 0; /* 数组第4位放LTE检测的DNS地址1 */ strncpy(g_network_array[NET_4G_DET_DNS1].para_name, "dns1", PARA_NAME_LEN); g_network_array[NET_4G_DET_DNS1].params_code = DIAGNOSE_LTE_DNS1; g_network_array[NET_4G_DET_DNS1].test = 1; /* 数组第5位放LTE检测的DNS地址2 */ strncpy(g_network_array[NET_4G_DET_DNS2].para_name, "dns2", PARA_NAME_LEN); g_network_array[NET_4G_DET_DNS2].params_code = DIAGNOSE_LTE_DNS2; g_network_array[NET_4G_DET_DNS2].test = 1; /* 数组第6位放用户自定义地址1(如果有配置的话) */ if(strlen(net_det.hostname_1) != 0) { strncpy(g_network_array[NET_USER_DEFINED1].para_name, "hostname_1", PARA_NAME_LEN); g_network_array[NET_USER_DEFINED1].params_code = DIAGNOSE_USER_ADDR1; g_network_array[NET_USER_DEFINED1].test = 1; } /* 数组第7位放用户自定义地址2(如果有配置的话) */ if(strlen(net_det.hostname_2) != 0) { strncpy(g_network_array[NET_USER_DEFINED2].para_name, "hostname_2", PARA_NAME_LEN); g_network_array[NET_USER_DEFINED2].params_code = DIAGNOSE_USER_ADDR2; g_network_array[NET_USER_DEFINED2].test = 1; } } #endif return; } /*********************************************************************************************** *函数: *描述:ping结束时,保存错误码,保存ip、域名及ping结果,设置相应标志 *参数: *返回值: ***********************************************************************************************/ void save_result_callback(struct _DIAGNOSE_CONTEXT* context) { int index = 0; if (NULL == context) { return; } g_network_array[context->index].status = TESTED; /*设置诊断状态为结束*/ if (NULL != context->dnsData) { strncpy(g_network_array[context->index].str_domain, context->dnsData->url, ADDR_LEN); /*保存域名*/ } if (0 == context->ipAddr && NULL != context->dnsData) /*dns解析失败*/ { g_network_array[context->index].res = DIAGNOSE_FAILED; goto exit; } ip_to_str(context->ipAddr, g_network_array[context->index].str_ip);/*保存ip地址*/ if (PING_SUCCESS != context->status) { g_network_array[context->index].res = DIAGNOSE_FAILED; /*设置诊断结果为失败*/ goto exit; } g_network_array[context->index].res = DIAGNOSE_SUCCESS; /*设置诊断结果为成功*/ DIAGNOSE_DEBUG("save %s OK", g_network_array[context->index].para_name); exit: /*是否所有诊断结束*/ for (index = 0; index < ADDR_COUNTS; index++) { if (0 == g_network_array[index].test) { continue; } if (g_network_array[index].do_telnet && TESTED != g_network_array[index].tel_state) { break; } if (TESTED != g_network_array[index].status) { break; } } if (ADDR_COUNTS == index) { diagnose_stop(); } return; } /*********************************************************************************************** *函数: *描述:发起ping请求 *参数: *返回值:ERROR:ping失败 OK:ping 发起成功 ***********************************************************************************************/ S32 ping_start(char* addr, U32 index, U32* context_id) { U32 icmpid = 0; IP_ADDR ip_addr = {0}; DIAGNOSE_DNS_DATA* dns_data = NULL; if (NULL == addr || NULL == context_id) { return ERROR; } /*ip合法检查*/ if (0 == inet_pton(AF_INET, addr, (void*)&ip_addr)) { if (FALSE == valid_domain(addr)) { DIAGNOSE_WARNING("Invalid target domain name format."); return ERROR; } dns_data = (DIAGNOSE_DNS_DATA *)DIAGNOSE_MALLOC(sizeof(DIAGNOSE_DNS_DATA)); if (NULL == dns_data) { DIAGNOSE_WARNING("Failed to alloc memory, size=%d.", sizeof(DIAGNOSE_DNS_DATA)); return ERROR; } memset(dns_data, 0, sizeof(DIAGNOSE_DNS_DATA)); strncpy(dns_data->url, addr, ADDR_LEN); } else { if (FALSE == valid_ip_addr(ip_addr.ipAddr)) { DIAGNOSE_DEBUG("Invalid target ip format."); return ERROR; } } /*发起ping请求*/ DIAGNOSE_ERROR("start ping:%s", (NULL == dns_data) ? addr : dns_data->url); icmpid = diagnose_ping(dns_data, ip_addr.ipAddr, DEFAULT_PING_SIZE, DEFAULT_PING_TIMES, DEFAULT_PING_TIMEOUT, index, save_result_callback); if (CONTEXT_IDLE == icmpid) { DIAGNOSE_FREE(dns_data); return ERROR; } *context_id = icmpid; return OK; } /*********************************************************************************************** *函数:network_diagnose *描述:基础网络诊断 *参数: *返回值: ***********************************************************************************************/ S32 network_diagnose() { int index = 0; U32 context_id = 0; int ping_stat = 0; address_array_init(); for (index = 0; index < ADDR_COUNTS; index++) { if (0 == g_network_array[index].test) { continue; } ping_stat = ping_start(g_default_address.diag_addr[index], index, &context_id); if (OK != ping_stat) { DIAGNOSE_DEBUG("ping start failed"); g_network_array[index].res = DIAGNOSE_FAILED; g_network_array[index].status = TESTED; } else { g_network_array[index].status = TESTING; } if (g_network_array[index].do_telnet) { if (OK == telnet_start(g_default_address.diag_addr[index], &g_network_array[index])) { g_network_array[index].tel_state = TESTING; } else { g_network_array[index].tel_state = TESTED; g_network_array[index].tel_res = DIAGNOSE_FAILED; } } } g_diagnose_timerid = inet_add_timer(diagnose_timer_handle, 0, ITEMS_TIMEOUT_VAL, EXECUTE_SINGLE); if (ERROR == g_diagnose_timerid) { return ERROR; } return OK; } /*********************************************************************************************** *函数:get_sd_info *描述:通过ds_handle获得sd卡信息 *参数: *返回值: ***********************************************************************************************/ LOCAL S32 get_sd_info(STORAGE_INFO* ptr_storage) { const char* ptr = NULL; int error_code = OK; JSON_OBJPTR data_obj = NULL; JSON_OBJPTR data_array = NULL; JSON_OBJPTR array_obj = NULL; JSON_OBJPTR json_harddisk_manage = NULL; JSON_OBJPTR json_harddisk_info = NULL; JSON_OBJPTR json_harddisk_NO = NULL; JSON_OBJPTR json_harddisk_parse = NULL; DS_HANDLE_CONTEXT ds_context; if (NULL == ptr_storage) { return ERROR; } /*构造jason请求sd信息*/ memset(&ds_context, 0, sizeof(DS_HANDLE_CONTEXT)); if (NULL == (ds_context.req_obj = jso_new_obj())) { DIAGNOSE_WARNING("jso_new_obj failed."); return ERROR; } if (NULL == (data_obj = jso_new_obj())) { error_code = ERROR; goto out; } jso_obj_add(ds_context.req_obj, "harddisk_manage", data_obj); jso_add_string(ds_context.req_obj, "method", "get"); if (NULL == (data_array = jso_new_array())) { error_code = ERROR; goto out; } jso_obj_add(data_obj, "name", data_array); if (NULL == (array_obj = jso_new_string("harddisk"))) { error_code = ERROR; goto out; } jso_array_add(data_array, array_obj); if (NULL == (array_obj = jso_new_string("video"))) { error_code = ERROR; goto out; } jso_array_add(data_array, array_obj); if (NULL == (array_obj = jso_new_string("picture"))) { error_code = ERROR; goto out; } jso_array_add(data_array, array_obj); if (NULL == (data_array = jso_new_array())) { error_code = ERROR; goto out; } jso_obj_add(data_obj, "table", data_array); if (NULL == (array_obj = jso_new_string("hd_info"))) { error_code = ERROR; goto out; } jso_array_add(data_array, array_obj); /*发送请求*/ ds_context.group_mask = ROOT_MASK; ds_context.method = METHOD_GET; ds_handle(&ds_context); if(NULL == ds_context.res_obj) { error_code = ERROR; goto out; } /*读取返回值*/ if (NULL == (json_harddisk_manage = jso_obj_get(ds_context.res_obj, "harddisk_manage"))) { error_code = ERROR; goto out; } if (NULL == (json_harddisk_info = jso_obj_get(json_harddisk_manage, "hd_info"))) { error_code = ERROR; goto out; } if (NULL == (json_harddisk_NO = jso_array_get_idx(json_harddisk_info, 0))) { error_code = ERROR; goto out; } if (NULL == (json_harddisk_parse = jso_obj_get(json_harddisk_NO, "hd_info_1"))) { error_code = ERROR; goto out; } if (NULL != (ptr= jso_obj_get_string_origin(json_harddisk_parse, "total_space"))) /*sd总大小*/ { strncpy(ptr_storage->size.total, ptr, SD_SIZE_LEN); } if (NULL != (ptr = jso_obj_get_string_origin(json_harddisk_parse, "free_space"))) /*sd剩余空间*/ { strncpy(ptr_storage->size.free, ptr, SD_SIZE_LEN); } if (NULL != (ptr = jso_obj_get_string_origin(json_harddisk_parse,"record_duration")))/*sd已录时长*/ { strncpy(ptr_storage->recorded_time, ptr, SD_SIZE_LEN); } if (NULL != (ptr = jso_obj_get_string_origin(json_harddisk_parse, "status"))) /*sd状态*/ { strncpy(ptr_storage->available, ptr, SD_STATUS_LEN); } error_code = OK; out: if (NULL != ds_context.req_obj) { jso_free_obj(ds_context.req_obj); ds_context.req_obj = NULL; } if (NULL != ds_context.res_obj) { jso_free_obj(ds_context.res_obj); ds_context.res_obj = NULL; } return error_code; } /*********************************************************************************************** *函数:storage_diagnose *描述:存储诊断 *参数: *返回值: ***********************************************************************************************/ LOCAL S32 storage_diagnose(STORAGE_INFO* ptr_storage) { if (NULL == ptr_storage) { return ERROR; } DIAGNOSE_DEBUG("start storage diagnose"); /*云存储*/ ds_read(CSTG_UPLOAD_ENABLE_PATH, &(ptr_storage->upload_enable), sizeof(CSTG_UPLOAD_ENABLE)); ds_read(CSTG_IS_UPLOADING_PATH, &(ptr_storage->uploading), sizeof(CSTG_IS_UPLOADING)); /*本地存储*/ ds_read(PLAN_ADVANCE_PATH, &(ptr_storage->plan_advance), sizeof(PLAN_ADVANCE));/*预录和延录时间*/ get_sd_info(ptr_storage); /*请求sd 状态、总大小、剩余空间、已录时长*/ return OK; } /*********************************************************************************************** *函数: *描述:获取固件是否有更新 *参数: *返回值: ***********************************************************************************************/ S32 request_fw_status() { DS_HANDLE_CONTEXT ds_context = {0}; JSON_OBJPTR data_obj = NULL; if (NULL == (ds_context.req_obj = jso_new_obj())) { return ERROR; } if (NULL == (data_obj = jso_new_obj())) { return ERROR; } jso_obj_add(ds_context.req_obj, "cloud_status", data_obj); jso_add_string(ds_context.req_obj, "method", "get"); jso_add_string(data_obj, "name", "check_fw_ver"); ds_context.group_mask = ROOT_MASK; ds_context.method = METHOD_GET; ds_handle(&ds_context); if(NULL == ds_context.res_obj) { return ERROR; } return OK; } /*********************************************************************************************** *函数:firmware_diagnose *描述:固件诊断 *参数: *返回值: ***********************************************************************************************/ LOCAL S32 firmware_diagnose(FIRMWARE_STRUCT* ptr_firmware) { NEW_FIRMWARE new_firm; if (NULL == ptr_firmware) { return ERROR; } DIAGNOSE_DEBUG("start firmware diagnose"); memset(&new_firm, 0, sizeof(NEW_FIRMWARE)); if (0 == ds_read(CLOUD_CONFIG_NEWFW_PATH, &new_firm, sizeof(NEW_FIRMWARE))) { return ERROR; } ptr_firmware->fw_new_notify = new_firm.fw_new_notify; return OK; } /*********************************************************************************************** *函数:safety_diagnose *描述:安全诊断 *参数: *返回值: ***********************************************************************************************/ void safety_diagnose(VIDEO_ENCRYPTION* ptr_videoencryption) { if (NULL == ptr_videoencryption) { return; } DIAGNOSE_DEBUG("start safety diagnose"); ptr_videoencryption->is_encryption = 1; return; } S32 diagnose_msg_send(int res) { #ifdef CONFIG_MOBILE_ACCESS_SET_SUPPORT if(g_is_lte_diagnose) { LTE_NETWORK_DIAGNOSE_RPL_MSG msg = {0}; DIAGNOSE_ERROR("send lte model diagnose msg out id:%d", res); msg.res = res; return msg_send(LTE_NETWORK_DIAGNOSE_RPL_MID, (U8 *)&msg, sizeof(msg)); }else #endif { NETWORK_DIAGNOSE_RPL_MSG msg = {0}; DIAGNOSE_DEBUG("send diagnose msg out id:%d", res); msg.res = res; return msg_send(NETWORK_DIAGNOSE_RPL_MID, (U8 *)&msg, sizeof(msg)); } } S32 diagnose_reply_result(void) { int res = 0; if (LINK_DOWN == g_phy_stat.ether && LINK_DOWN == g_phy_stat.wlan) { res = NETWORK_PHY_DOWN; goto out; } if (DIAGNOSE_FAILED == g_network_array[NET_GATEWAY].res) { res = NETWORK_GATEWAY_FAILED; goto out; } if (DIAGNOSE_FAILED == g_network_array[NET_INTERNET1].res && DIAGNOSE_FAILED == g_network_array[NET_INTERNET2].res) { if (DIAGNOSE_FAILED == g_network_array[NET_BASE_CLOUD].res && DIAGNOSE_FAILED == g_network_array[NET_BASE_CLOUD].tel_res) { res = NETWORK_FAILED; goto out; } res = NETWORK_OK; goto out; } if (DIAGNOSE_FAILED == g_network_array[NET_BASE_CLOUD].res && DIAGNOSE_FAILED == g_network_array[NET_BASE_CLOUD].tel_res) { res = NETWORK_CLOUD_FAILED; goto out; } res = NETWORK_OK; out: return diagnose_msg_send(res); } #ifdef CONFIG_MOBILE_ACCESS_SET_SUPPORT S32 lte_diagnose_reply_result(void) { int res = 0; LTE_CONFIG_NET_DETECTION lte_net_detection; memset(&lte_net_detection, 0, sizeof(LTE_CONFIG_NET_DETECTION)); ds_read(LTE_NET_DET_PATH, &lte_net_detection, sizeof(LTE_CONFIG_NET_DETECTION)); INFO_INTERNET info_internet; memset(&info_internet, 0, sizeof(INFO_INTERNET)); ds_read(INFO_INTERNET_PATH, &info_internet, sizeof(INFO_INTERNET)); if (INTERNET_4G_CONNECTED != info_internet.link_status) { res = NETWORK_4G_DOWN; goto out; } if(strlen(lte_net_detection.hostname_1) != 0 || strlen(lte_net_detection.hostname_2) != 0) { if(DIAGNOSE_FAILED == g_network_array[NET_4G_DET_DNS1].res && DIAGNOSE_FAILED == g_network_array[NET_4G_DET_DNS2].res) { if(g_network_array[NET_USER_DEFINED1].test == 1 && g_network_array[NET_USER_DEFINED2].test == 1) { if(g_network_array[NET_USER_DEFINED1] .res == DIAGNOSE_FAILED && g_network_array[NET_USER_DEFINED2] .res == DIAGNOSE_FAILED) { res = NETWORK_DETECTION_FAILED; goto out; } }else { if((g_network_array[NET_USER_DEFINED1].test == 1 && g_network_array[NET_USER_DEFINED1] .res == DIAGNOSE_FAILED) || (g_network_array[NET_USER_DEFINED2].test == 1 && g_network_array[NET_USER_DEFINED2] .res == DIAGNOSE_FAILED)) { res = NETWORK_DETECTION_FAILED; goto out; } } } res = NETWORK_DETECTION_OK; goto out; }else { if (DIAGNOSE_FAILED == g_network_array[NET_4G_DET_DNS1].res && DIAGNOSE_FAILED == g_network_array[NET_4G_DET_DNS2].res) { res = NETWORK_DETECTION_FAILED; goto out; } } res = NETWORK_DETECTION_OK; out: return diagnose_msg_send(res); } #endif S32 diagnose_result_save_config(void) { int res = 0; LINK_STATUS link_status = {0}; #ifdef CONFIG_MOBILE_ACCESS_SET_SUPPORT LTE_CONFIG_INFO_DATA lte_config = {0}; ds_read(LTE_INFO_DATA_PATH, (U8*)&lte_config, sizeof(LTE_CONFIG_INFO_DATA)); if(lte_config.internet_wired_enable == 0 || (lte_config.internet_wired_enable == 2 && lte_config.auto_switch_wired == 0)) { INFO_INTERNET info_internet = {0}; ds_read(INFO_INTERNET_PATH, (U8*)&info_internet, sizeof(INFO_INTERNET)); if(INTERNET_4G_CONNECTED != info_internet.link_status) { res = NETWORK_PHY_DOWN; goto out; } if(DIAGNOSE_FAILED == g_network_array[NET_4G_DET_DNS1].res && DIAGNOSE_FAILED == g_network_array[NET_4G_DET_DNS2].res) { if(g_network_array[NET_USER_DEFINED1].test == 1 && g_network_array[NET_USER_DEFINED2].test == 1) { if(g_network_array[NET_USER_DEFINED1] .res == DIAGNOSE_FAILED && g_network_array[NET_USER_DEFINED2] .res == DIAGNOSE_FAILED) { res = NETWORK_DETECTION_FAILED; goto out; } }else if(g_network_array[NET_USER_DEFINED1].test == 0 && g_network_array[NET_USER_DEFINED2].test == 0) { res = NETWORK_DETECTION_FAILED; goto out; }else { if(g_network_array[NET_USER_DEFINED1] .res == DIAGNOSE_FAILED || g_network_array[NET_USER_DEFINED2] .res == DIAGNOSE_FAILED) { res = NETWORK_DETECTION_FAILED; goto out; } } } res = NETWORK_OK; }else #endif { if (LINK_DOWN == g_phy_stat.ether && LINK_DOWN == g_phy_stat.wlan) { res = NETWORK_PHY_DOWN; goto out; } if (DIAGNOSE_FAILED == g_network_array[NET_GATEWAY].res) { res = NETWORK_GATEWAY_FAILED; goto out; } if (DIAGNOSE_FAILED == g_network_array[NET_INTERNET1].res && DIAGNOSE_FAILED == g_network_array[NET_INTERNET2].res) { if (DIAGNOSE_FAILED == g_network_array[NET_BASE_CLOUD].res && DIAGNOSE_FAILED == g_network_array[NET_BASE_CLOUD].tel_res) { res = NETWORK_FAILED; goto out; } res = NETWORK_OK; goto out; } if (DIAGNOSE_FAILED == g_network_array[NET_BASE_CLOUD].res && DIAGNOSE_FAILED == g_network_array[NET_BASE_CLOUD].tel_res) { res = NETWORK_CLOUD_FAILED; goto out; } res = NETWORK_OK; } out: ds_read(LINK_STATUS_PATH, (U8 *)&link_status, sizeof(link_status)); if (link_status.internet_status != res) { DIAGNOSE_ERROR("internet status has changed: [%d] ===> [%d]", link_status.internet_status, res); link_status.internet_status = res; } ds_write(LINK_STATUS_PATH, (U8 *)&link_status, sizeof(link_status)); return OK; } /*********************************************************************************************** *函数:get_result *描述:web轮询诊断结果 *参数: type:本次诊断的参数,每一位代表一个诊断项 *返回值: ***********************************************************************************************/ LOCAL S32 get_result(JSON_OBJPTR jso_result, char* type, int cli_index) { JSON_OBJPTR data_obj = NULL; JSON_OBJPTR data_array = NULL; int index = 0; int finish = 0; char buffer[PARSE_BUFFER_LEN] = {'\0'}; char item_status[DIAGNOSE_BIT_LEN + 1] = {'\0'}; if (NULL == type || NULL == jso_result) { return SLP_EINVARG; } memset(item_status, '0', DIAGNOSE_BIT_LEN); if (NULL == (data_array = jso_new_array())) { DIAGNOSE_WARNING("Lookup failed, jso_new_array failed."); return SLP_ENOMEMORY; } /*无线信号*/ if (SET_TEST == type[DIAGNOSE_WIRELESS] && NULL != (data_obj = jso_new_obj())) { memset(buffer, 0, PARSE_BUFFER_LEN); snprintf(buffer, PARSE_BUFFER_LEN, "%d", g_connect_info.rssi); jso_add_string(data_obj, "link_type", g_connect_info.link_type); jso_add_string(data_obj, "rssi", buffer); jso_add_string(data_obj, "ssid", g_connect_info.ssid); jso_obj_add(jso_result, "wireless", data_obj); if (TESTED == g_connect_info.status) { item_status[DIAGNOSE_WIRELESS] = ITEM_FINISH; } else if (TESTING == g_connect_info.status) { item_status[DIAGNOSE_WIRELESS] = ITEM_TESTING; } } /*网络诊断*/ for (index = 0; index < ADDR_COUNTS; index++) { if (SET_TEST == type[g_network_array[index].params_code] && NULL != (data_obj = jso_new_obj())) { memset(buffer, 0, PARSE_BUFFER_LEN); snprintf(buffer, PARSE_BUFFER_LEN, "%d", g_network_array[index].res); jso_add_string(data_obj, "ip", g_network_array[index].str_ip); jso_add_string(data_obj, "domain", g_network_array[index].str_domain); jso_add_string(data_obj, "res", buffer); if (1 == g_network_array[index].do_telnet) { memset(buffer, 0, PARSE_BUFFER_LEN); snprintf(buffer, PARSE_BUFFER_LEN, "%d", g_network_array[index].tel_res); jso_add_string(data_obj, "telnet", buffer); } jso_obj_add(jso_result, g_network_array[index].para_name, data_obj); if (TESTED == g_network_array[index].status) { item_status[g_network_array[index].params_code] = ITEM_FINISH; } } } /*存储诊断*/ if(SET_TEST == type[DIAGNOSE_STORAGE] && NULL != (data_obj = jso_new_obj())) { memset(buffer, 0, PARSE_BUFFER_LEN); snprintf(buffer, PARSE_BUFFER_LEN, "%d", g_storage_info.upload_enable.enable); jso_add_string(data_obj, "cstg_enable", buffer); memset(buffer, 0, PARSE_BUFFER_LEN); snprintf(buffer, PARSE_BUFFER_LEN, "%d", g_storage_info.uploading.is_uploading); jso_add_string(data_obj, "cstg_uploading", buffer); jso_add_string(data_obj, "hd_status", g_storage_info.available); jso_add_string(data_obj, "total", g_storage_info.size.total); jso_add_string(data_obj, "free", g_storage_info.size.free); memset(buffer, 0, PARSE_BUFFER_LEN); snprintf(buffer, PARSE_BUFFER_LEN, "%d", 3); jso_add_string(data_obj, "record_type", buffer); jso_add_string(data_obj, "record_duration", g_storage_info.recorded_time); jso_add_string(data_obj, "hd_lifespan", g_storage_info.sd_lifespan); jso_obj_add(jso_result, "storage", data_obj); if (TESTED == g_storage_info.status) { item_status[DIAGNOSE_STORAGE] = ITEM_FINISH; } } /*固件诊断*/ if(SET_TEST == type[DIAGNOSE_FIRMWARE] && NULL != (data_obj = jso_new_obj())) { firmware_diagnose(&g_firmware_info); memset(buffer, 0, PARSE_BUFFER_LEN); snprintf(buffer, PARSE_BUFFER_LEN, "%d", g_firmware_info.fw_new_notify); jso_add_string(data_obj, "new_fw", buffer); jso_obj_add(jso_result, "firmware", data_obj); if (TESTED == g_firmware_info.status) { item_status[DIAGNOSE_FIRMWARE] = ITEM_FINISH; } } /*安全诊断*/ if(SET_TEST == type[DIAGNOSE_SAFETY] && NULL != (data_obj = jso_new_obj())) { memset(buffer, 0, PARSE_BUFFER_LEN); snprintf(buffer, PARSE_BUFFER_LEN, "%d", g_video_encryption.is_encryption); jso_add_string(data_obj, "is_encrypted", buffer); jso_obj_add(jso_result, "encrypted", data_obj); if (TESTED == g_video_encryption.status) { item_status[DIAGNOSE_SAFETY] = ITEM_FINISH; } } for (index = 0; index < DIAGNOSE_BIT_LEN; index++) { if (SET_TEST == type[index] && ITEM_FINISH != item_status[index]) { break; } } if (DIAGNOSE_BIT_LEN == index || AUTO_STOP == g_client_array[cli_index].is_stop) { finish = 1; goto exit; } g_client_array[cli_index].time_out++; if (g_client_array[cli_index].time_out > CLIENT_GET_TIMEOUT) { finish = 1; inet_del_timer(g_client_array[cli_index].timerid); memset(&g_client_array[cli_index], 0, sizeof(TASK_STRUCT)); } exit: jso_add_string(jso_result, "status", item_status); jso_add_string(jso_result, "finish", finish == 1 ? "1" : "0"); return SLP_ENONE; } void diagnose_timer_handle(S32 param) { DIAGNOSE_INFO("Ping test timeout!"); diagnose_stop(); } void init_global_var() { memset(&g_connect_info, 0, sizeof(g_connect_info)); memset(&g_storage_info, 0, sizeof(g_storage_info)); memset(&g_firmware_info, 0, sizeof(g_firmware_info)); memset(&g_video_encryption, 0, sizeof(g_video_encryption)); memset(g_network_array, 0, sizeof(NETWORK_STRUCT) * ADDR_COUNTS); memset(g_client_array, 0, sizeof(TASK_STRUCT) * MAX_CLIENTS_NUM); memset(&g_phy_stat, 0, sizeof(PHY_STATUS)); } /*********************************************************************************************** *函数: *描述:来自客户端的诊断,如web、App *参数: *返回值: ***********************************************************************************************/ LOCAL S32 client_diagnose() { if (0 == g_task_running) { memset(&g_connect_info, 0, sizeof(g_connect_info)); memset(&g_storage_info, 0, sizeof(g_storage_info)); memset(&g_firmware_info, 0, sizeof(g_firmware_info)); memset(&g_video_encryption, 0, sizeof(g_video_encryption)); request_fw_status(); check_signal_quality(&g_connect_info); g_connect_info.status = TESTED; storage_diagnose(&g_storage_info); g_storage_info.status = TESTED; firmware_diagnose(&g_firmware_info); g_firmware_info.status = TESTED; safety_diagnose(&g_video_encryption); g_video_encryption.status = TESTED; g_task_running = 1; } if (ERROR == g_diagnose_timerid) { network_diagnose(); } return OK; } void phy_status_change(void) { #ifdef CONFIG_MOBILE_ACCESS_SET_SUPPORT LTE_CONFIG_INFO_DATA lte_config = {0}; ds_read(LTE_INFO_DATA_PATH, (U8*)&lte_config, sizeof(LTE_CONFIG_INFO_DATA)); #endif ds_read(PHY_STATUS_PATH, &g_phy_stat, sizeof(PHY_STATUS)); if (LINK_DOWN == g_phy_stat.ether && LINK_DOWN == g_phy_stat.wlan) { DIAGNOSE_DEBUG("catch phy link down"); #ifdef CONFIG_MOBILE_ACCESS_SET_SUPPORT if(lte_config.internet_wired_enable == 1 || (lte_config.internet_wired_enable == 2 && lte_config.auto_switch_wired == 1)) #endif { diagnose_stop(); } } } /*开启自诊断*/ S32 diagnose_operation_handle(dms_handler_t *handler, U8 *mbuf, U32 mlen, U32 sender_dms_id) { /*开启网络诊断*/ g_is_auto_diagnose = 1; if (ERROR == g_diagnose_timerid) { #ifdef CONFIG_MOBILE_ACCESS_SET_SUPPORT NET_DIAGNOSE_MSG *msg = NULL; if(mbuf != NULL && mlen == sizeof(NET_DIAGNOSE_MSG)) { msg = (NET_DIAGNOSE_MSG*)mbuf; if(msg->model == MODEL_LTE) { g_is_lte_diagnose = 1; g_is_other_model_diagnose = 0; }else { g_is_other_model_diagnose = 1; } }else { g_is_other_model_diagnose = 1; } #endif network_diagnose(); } #ifdef CONFIG_MOBILE_ACCESS_SET_SUPPORT else if(ERROR != g_diagnose_timerid) { NET_DIAGNOSE_MSG *msg = NULL; if(mbuf != NULL && mlen == sizeof(NET_DIAGNOSE_MSG)) { msg = (NET_DIAGNOSE_MSG*)mbuf; if(msg->model == MODEL_LTE) { LTE_NETWORK_DIAGNOSE_RPL_MSG msg_sendto_lte = {0}; int res = TIMER_NOT_OVER; DIAGNOSE_ERROR("send lte model diagnose msg out id:%d", res); msg_sendto_lte.res = res; msg_send(LTE_NETWORK_DIAGNOSE_RPL_MID, (U8 *)&msg_sendto_lte, sizeof(msg)); } } } #endif return OK; } void client_array_reclaim_handle(S32 param) { if (param >= 0 && param < MAX_CLIENTS_NUM) { inet_del_timer(g_client_array[param].timerid); memset(&g_client_array[param], 0, sizeof(TASK_STRUCT)); } } S32 get_empty_client_ctx(int* client_index) { int index = 0; if (NULL == client_index) { return ERROR; } for (index = 0; index < MAX_CLIENTS_NUM; index++) { if (0 == strlen(g_client_array[index].instance_id)) { g_client_array[index].timerid = inet_add_timer(client_array_reclaim_handle, index, CLIENT_RECLAIM_INTERVAL, EXECUTE_SINGLE); if (ERROR == g_client_array[index].timerid) { return ERROR; } *client_index = index; return OK; } } return ERROR; } S32 get_client_instance_by_id(const char* instance_id, int* cli_index) { int index = 0; if (NULL == instance_id || NULL == cli_index) { return ERROR; } for (index = 0; index < MAX_CLIENTS_NUM; index++) { if (0 == strlen(g_client_array[index].instance_id)) { continue; } if (0 == strcmp(g_client_array[index].instance_id, instance_id)) { *cli_index = index; return OK; } } return ERROR; } S32 valid_param(const char* type) { int type_len = 0; int index = 0; if (NULL == type) { return SLP_EINVARG; } type_len = strlen(type); if (0 == type_len || type_len > DIAGNOSE_BIT_LEN) { return SLP_EINVARG; } for (index = 0; index < type_len; index++) { if (type[index] != '0' && type[index] != '1') { return IPC_DIAGNOSE_TYPE_NOT_SUPPORT; } if (index > DIAGNOSE_MAX && SET_TEST == type[index]) { return IPC_DIAGNOSE_TYPE_NOT_SUPPORT; } } return SLP_ENONE; } /*********************************************************************************************** *函数:start_oneclick_diagnose_callback *描述:快速诊断 *参数:读取诊断id,执行对应诊断内容 *返回值: ***********************************************************************************************/ S32 start_oneclick_diagnose_callback(DS_HANDLE_CONTEXT *context, JSON_OBJPTR param) { const char* ptr = NULL; char instance_id[DIAGNOSE_ID_LEN + 1] = {'\0'}; U64 time_stamp = 0; int rand_num = 0; int error_code = SLP_ENONE; int client_index = 0; #ifdef CONFIG_MOBILE_ACCESS_SET_SUPPORT LTE_CONFIG_INFO_DATA lte_config = {0}; LTE_CONFIG_NET_DETECTION net_det = {0}; #endif if (!context || !context->res_obj || !context->req_obj) { error_code = SLP_ESYSTEM; goto out; } ptr = jso_obj_get_string_origin(param, "type"); if (NULL == ptr) { error_code = IPC_DIAGNOSE_PARAMS_INVALID; goto out; } error_code = valid_param(ptr); if (SLP_ENONE != error_code) { goto out; } if (ERROR == get_empty_client_ctx(&client_index)) { error_code = IPC_DIAGNOSE_TASK_BUSY; goto out; } #ifdef CONFIG_MOBILE_ACCESS_SET_SUPPORT if(0 == ds_read(LTE_INFO_DATA_PATH, (U8*)&lte_config, sizeof(LTE_CONFIG_INFO_DATA))) { DIAGNOSE_ERROR("read config path %s fail.", LTE_INFO_DATA_PATH); error_code = IPC_DIAGNOSE_INTERNAL_ERROR; goto out; } if(0 == ds_read(LTE_NET_DET_PATH, (U8*)&net_det, sizeof(LTE_CONFIG_NET_DETECTION))) { DIAGNOSE_ERROR("read config path %s fail.", LTE_NET_DET_PATH); error_code = IPC_DIAGNOSE_INTERNAL_ERROR; goto out; } if((lte_config.internet_wired_enable == 0 || (lte_config.internet_wired_enable == 2 && lte_config.auto_switch_wired == 0)) && net_det.ping_enable == 1) { goto out; }else #endif { if (ERROR == client_diagnose()) { goto out; } } /*返回诊断id*/ srand((U32)time(NULL)); time_stamp = nvmp_get_us(); rand_num = rand() % 10000; snprintf(instance_id, DIAGNOSE_ID_LEN, "%llu-%u", time_stamp, rand_num); g_client_array[client_index].time_out = 0; g_client_array[client_index].is_stop = 0; strncpy(g_client_array[client_index].instance_id, instance_id, DIAGNOSE_ID_LEN); jso_add_string(context->res_obj, "diagnose_id", instance_id); return SLP_ENONE; out: snprintf(instance_id, DIAGNOSE_ID_LEN, "%d", 0); jso_add_string(context->res_obj, "diagnose_id", instance_id); return error_code; } S32 diagnose_result_callback(DS_HANDLE_CONTEXT *context, JSON_OBJPTR param) { const char* ptr = NULL; char str_type[DIAGNOSE_BIT_LEN + 1] = {'\0'}; /*诊断内容*/ char instance_id[DIAGNOSE_ID_LEN + 1] = {'\0'}; /*诊断实例id*/ int error_code = SLP_ENONE; int cli_index = 0; if (!context || !context->res_obj || !context->req_obj) { return SLP_ESYSTEM; } if (NULL == (ptr = jso_obj_get_string_origin(param, "diagnose_id"))) { return IPC_DIAGNOSE_PARAMS_INVALID; } strncpy(instance_id, ptr, DIAGNOSE_ID_LEN); if (ERROR == get_client_instance_by_id(instance_id, &cli_index)) { return IPC_DIAGNOSE_ID_NOT_FOUND; } if (NULL == (ptr = jso_obj_get_string_origin(param, "type"))) { return IPC_DIAGNOSE_PARAMS_INVALID; } error_code = valid_param(ptr); if (SLP_ENONE != error_code) { return error_code; } strncpy(str_type, ptr, DIAGNOSE_BIT_LEN); return get_result(context->res_obj, str_type, cli_index); } S32 stop_oneclick_diagnose_callback(DS_HANDLE_CONTEXT *context, JSON_OBJPTR param) { char instance_id[DIAGNOSE_ID_LEN + 1] = {'\0'}; const char* ptr = NULL; int cli_index = 0; if (!context || !context->res_obj || !context->req_obj) { return SLP_ESYSTEM; } ptr = jso_obj_get_string_origin(param, "diagnose_id"); if (NULL == ptr) { return IPC_DIAGNOSE_PARAMS_INVALID; } strncpy(instance_id, ptr, DIAGNOSE_ID_LEN); if (ERROR == get_client_instance_by_id(instance_id, &cli_index)) { return IPC_DIAGNOSE_ID_NOT_FOUND; } g_client_array[cli_index].is_stop = AUTO_STOP; if (g_client_array[cli_index].timerid > 0) { inet_del_timer(g_client_array[cli_index].timerid); } memset(&g_client_array[cli_index], 0, sizeof(TASK_STRUCT)); DIAGNOSE_DEBUG("stop get result ......."); return SLP_ENONE; }
10-23
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值