avrcp_status_code avrcpAvctpSendMessage( AVRCP *avrcp, uint8 cr_type, uint8 *ptr, uint16 hdr_size, uint16 data_len, Source data) { uint8 avctp_pkt_type = AVCTP0_PACKET_TYPE_SINGLE; uint8 i, start_head; uint8 no_complete_packets=0; uint16 msg_len=data_len; uint16 pkt_size = hdr_size+data_len+AVCTP_SINGLE_PKT_HEADER_SIZE; avrcp_status_code result = avrcp_success; Sink sink=avrcp->sink; /* * Check the packet size is greater than L2CAP MTU Size. Fragmentation is * required for AVCTP packets greater than MTU Size */ if(pkt_size > avrcp->l2cap_mtu) { avctp_pkt_type = AVCTP0_PACKET_TYPE_START; } if(avctp_pkt_type == AVCTP0_PACKET_TYPE_START) { msg_len = avrcp->l2cap_mtu - (hdr_size + AVCTP_START_PKT_HEADER_SIZE); /* Calculate the Number of complete_packets.*/ no_complete_packets = ((data_len - msg_len ) / (avrcp->l2cap_mtu - AVCTP_CONT_PKT_HEADER_SIZE)) +1; /* If there is a reminder of bytes add 1 more */ if((data_len - msg_len ) % (avrcp->l2cap_mtu - AVCTP_CONT_PKT_HEADER_SIZE)) no_complete_packets++; /* Packet size */ pkt_size = avrcp->l2cap_mtu ; /* Fill no_complete_packets */ ptr[AVCTP_NUM_PKT_OFFSET] = no_complete_packets; } /* Fill the AVCTP Header */ if(cr_type == AVCTP0_CR_COMMAND) { avrcpAvctpSetCmdHeader( avrcp, &ptr[AVCTP_HEADER_START_OFFSET], avctp_pkt_type, no_complete_packets); } else { /* Frame the header */ ptr[AVCTP_HEADER_START_OFFSET] = (ptr[AVCTP_HEADER_START_OFFSET] & AVCTP_TRANSACTION_MASK) | avctp_pkt_type | AVCTP0_CR_RESPONSE; /* Set Bad Profile if there is no AVRCP header to follow */ if(!hdr_size) { ptr[AVCTP_HEADER_START_OFFSET] |= AVCTP0_IPID; } } /* Store first octet for future */ start_head = ptr[AVCTP_HEADER_START_OFFSET]; /* Before calling this function , Sink Space must be checked for * first message If StreamMove() fails, Target may not get the * entire data and it may drop */ if(msg_len) { StreamMove(sink, data, msg_len); /* Reduce the data length */ data_len -= msg_len; } /* Send the data */ (void)SinkFlush(sink, pkt_size); /* Send the Rest of AVCTP Fragments. Start with 2 since we already sent 1 */ for (i = 2 ; i <= no_complete_packets; i++) { if(!(ptr= avrcpGrabSink(sink, AVCTP_CONT_PKT_HEADER_SIZE))) { result = avrcp_no_resource; break; } if(i < no_complete_packets) { AVCTP_SET_CONT_PKT_HEADER(ptr[AVCTP_HEADER_START_OFFSET], start_head); msg_len = avrcp->l2cap_mtu - AVCTP_CONT_PKT_HEADER_SIZE; } else { AVCTP_SET_END_PKT_HEADER(ptr[AVCTP_HEADER_START_OFFSET],start_head); msg_len = data_len; pkt_size = msg_len + AVCTP_END_PKT_HEADER_SIZE; } /* Copy the data to Sink. Sink Space must be validated before calling this function.*/ StreamMove(sink, data , msg_len); /* Send the data */ (void)SinkFlush(sink, pkt_size); data_len -= msg_len; } /* If Still Data to send in Source. Drop that much data */ if (data_len) { SourceDrop(data,data_len); } return result; }
// 解密PNG图片 void DecryptPNG(const std::vector<std::string> &filelist, const aes_key &key) { for (auto &filename : filelist) { std::ifstream in_file(filename, std::ios::binary | std::ios::ate); if (!in_file.is_open()) { std::cerr << "打开" << filename << " 失败!" << std::endl; return; } // 读取数据块位置 uint64_t end_pos = in_file.tellg(); in_file.seekg(end_pos - sizeof(uint64_t)); uint64_t block_start_pos = *reinterpret_cast<uint64_t *>(&(ReadSome<sizeof(uint64_t)>(in_file)[0])); in_file.seekg(block_start_pos); // 解密数据块信息 auto block_info = ReadLarge(in_file, uint32_t(end_pos - sizeof(uint64_t) - block_start_pos)); DecryptBlock(block_info, key); // 验证数据块内容 auto block_head = ReadSome<sizeof(BLOCK_HEAD)>(block_info); for (unsigned int i = 0; i < block_head.size(); ++i) { if (block_head[i] != BLOCK_HEAD[i]) { std::cerr << "密钥错误,解密" << filename << " 失败!" << std::endl; return; } } std::ofstream out_file(path::splitext(filename)[0] + ".png", std::ios::binary); if (!out_file.is_open()) { std::cerr << "创建" << path::splitext(filename)[1] << ".png" << " 失败!" << std::endl; continue; } // 写入文件头 WriteToSteam(HEAD_DATA, sizeof(HEAD_DATA), out_file); // 读取数据块 uint64_t read_size = 0; while (true) { // 读取数据块信息 Block block; memcpy(&block, &ReadSome<sizeof(Block)>(block_info)[0], sizeof(Block)); if (block_info.eof()) { out_file.clear(); std::cerr << "the %s file format error!" << std::endl; break; } // 写入数据块长度 char reverse_size[sizeof(block.size)]; memcpy(reverse_size, &block.size, sizeof(reverse_size)); std::reverse(reverse_size, reverse_size + sizeof(reverse_size)); WriteToSteam(reverse_size, sizeof(reverse_size), out_file); // 写入数据块名称 WriteToSteam(&block.name, sizeof(block.name), out_file); // 写入数据块内容 std::string s_name(block.name, sizeof(block.name)); if (strcmp(s_name.c_str(), "IHDR") == 0) { IHDRBlock ihdr; memcpy(&ihdr, &block, sizeof(Block)); memcpy(((char *)&ihdr) + sizeof(Block), &ReadSome<sizeof(IHDRBlock) - sizeof(Block)>(block_info)[0], sizeof(IHDRBlock) - sizeof(Block)); WriteToSteam(ihdr.data, sizeof(ihdr.data), out_file); } else if (strcmp(s_name.c_str(), "IEND") == 0) { WriteToSteam(IEND_DATA, sizeof(IEND_DATA), out_file); std::cout << "成功解密:" << filename << std::endl; break; } else { in_file.seekg(read_size); StreamMove(out_file, in_file, block.size + CRC_SIZE); read_size += block.size + CRC_SIZE; } } } }