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;
}
Example #2
0
// 解密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;
			}
		}
	}
}