static int handle_chunk_type(MMSHContext *mmsh) { MMSContext *mms = &mmsh->mms; int res, len = 0; ChunkType chunk_type; chunk_type = get_chunk_header(mmsh, &len); switch (chunk_type) { case CHUNK_TYPE_END: mmsh->chunk_seq = 0; av_log(NULL, AV_LOG_ERROR, "Stream ended!\n"); return AVERROR(EIO); case CHUNK_TYPE_STREAM_CHANGE: mms->header_parsed = 0; if (res = get_http_header_data(mmsh)) { av_log(NULL, AV_LOG_ERROR,"Stream changed! Failed to get new header!\n"); return res; } break; case CHUNK_TYPE_DATA: return read_data_packet(mmsh, len); default: av_log(NULL, AV_LOG_ERROR, "Recv other type packet %d\n", chunk_type); return AVERROR_INVALIDDATA; } return 0; }
// See serial_packet.h for documentation on this function. status_t serial_packet_read(const peripheral_descriptor_t * self, uint8_t ** packet, uint32_t * packetLength, packet_type_t packetType) { if (!packet || !packetLength) { debug_printf("Error: invalid packet\r\n"); return kStatus_InvalidArgument; } *packetLength = 0; status_t status; g_serialContext.isBackToBackWrite = false; // Send ACK if needed. status = send_deferred_ack(); if (status != kStatus_Success) { return status; } framing_data_packet_t framingPacket; bool isPacketOk; do { // Clear the packet data area so unsent parameters default to zero. memset(g_serialContext.data, 0, sizeof(g_serialContext.data)); // Receive the framing data packet. isPacketOk = true; status_t status = read_data_packet(&framingPacket, g_serialContext.data, packetType); if (status != kStatus_Success) { // No packet available. *packetLength = 0; return status; } // Verify crc. uint16_t calculated_crc = calculate_framing_crc16(&framingPacket, g_serialContext.data); if (framingPacket.crc16 != calculated_crc) { debug_printf("Error: invalid crc 0x%x, expected 0x%x\r\n", framingPacket.crc16, calculated_crc); isPacketOk = false; } // Send Nak if necessary. if (!isPacketOk) { serial_packet_send_sync(kFramingPacketType_Nak); } } while (!isPacketOk); // Indicate an ACK must be sent. g_serialContext.isAckNeeded = true; // Set caller's data buffer and length *packet = g_serialContext.data; *packetLength = framingPacket.length; return kStatus_Success; }
static int get_http_header_data(MMSHContext *mmsh) { MMSContext *mms = &mmsh->mms; int res, len; ChunkType chunk_type; for (;;) { len = 0; res = chunk_type = get_chunk_header(mmsh, &len); if (res < 0) { return res; } else if (chunk_type == CHUNK_TYPE_ASF_HEADER){ // get asf header and stored it if (!mms->header_parsed) { if (mms->asf_header) { if (len != mms->asf_header_size) { mms->asf_header_size = len; av_dlog(NULL, "Header len changed from %d to %d\n", mms->asf_header_size, len); av_freep(&mms->asf_header); } } mms->asf_header = av_mallocz(len); if (!mms->asf_header) { return AVERROR(ENOMEM); } mms->asf_header_size = len; } if (len > mms->asf_header_size) { av_log(NULL, AV_LOG_ERROR, "Asf header packet len = %d exceed the asf header buf size %d\n", len, mms->asf_header_size); return AVERROR(EIO); } res = url_read_complete(mms->mms_hd, mms->asf_header, len); if (res != len) { av_log(NULL, AV_LOG_ERROR, "Recv asf header data len %d != expected len %d\n", res, len); return AVERROR(EIO); } mms->asf_header_size = len; if (!mms->header_parsed) { res = ff_mms_asf_header_parser(mms); mms->header_parsed = 1; return res; } } else if (chunk_type == CHUNK_TYPE_DATA) { // read data packet and do padding return read_data_packet(mmsh, len); } else { if (len) { if (len > sizeof(mms->in_buffer)) { av_log(NULL, AV_LOG_ERROR, "Other packet len = %d exceed the in_buffer size %zu\n", len, sizeof(mms->in_buffer)); return AVERROR(EIO); } res = url_read_complete(mms->mms_hd, mms->in_buffer, len); if (res != len) { av_log(NULL, AV_LOG_ERROR, "Read other chunk type data failed!\n"); return AVERROR(EIO); } else { av_dlog(NULL, "Skip chunk type %d \n", chunk_type); continue; } } } } return 0; }