/** @internal @This handles input. * * @param upipe description structure of the pipe * @param uref uref structure * @param upump_p reference to pump that generated the buffer */ static void upipe_htons_input(struct upipe *upipe, struct uref *uref, struct upump **upump_p) { struct ubuf *ubuf; size_t size = 0; int remain, bufsize = -1, offset = 0; uint8_t *buf = NULL; /* block size */ if (unlikely(!ubase_check(uref_block_size(uref, &size)))) { upipe_warn(upipe, "could not read uref block size"); uref_free(uref); return; } /* copy ubuf if shared or not 16b-unaligned or segmented */ bufsize = -1; if (!ubase_check(uref_block_write(uref, 0, &bufsize, &buf)) || ((uintptr_t)buf & 1) || bufsize != size) { ubuf = ubuf_block_copy(uref->ubuf->mgr, uref->ubuf, 0, size); if (unlikely(!ubuf)) { upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); uref_free(uref); return; } uref_attach_ubuf(uref, ubuf); } else { uref_block_unmap(uref, 0); } /* process ubuf chunks */ while (size > 0) { bufsize = -1; if (unlikely(!ubase_check(uref_block_write(uref, offset, &bufsize, &buf)))) { upipe_warn(upipe, "unexpected buffer error"); uref_free(uref); return; } if (unlikely((uintptr_t)buf & 1)) { upipe_warn_va(upipe, "unaligned buffer: %p", buf); } for (remain = bufsize; remain > 1; remain -= 2) { *(uint16_t *)buf = htons(*(uint16_t *)buf); buf += 2; } uref_block_unmap(uref, offset); offset += bufsize; size -= bufsize; } upipe_htons_output(upipe, uref, upump_p); }
/** @internal @This handles input buffers. * * @param upipe description structure of the pipe * @param uref input buffer to handle * @param upump_p reference to the pump that generated the buffer */ static void upipe_dvbcsa_enc_input(struct upipe *upipe, struct uref *uref, struct upump **upump_p) { struct upipe_dvbcsa_enc *upipe_dvbcsa_enc = upipe_dvbcsa_enc_from_upipe(upipe); struct upipe_dvbcsa_common *common = upipe_dvbcsa_enc_to_common(upipe_dvbcsa_enc); if (unlikely(!upipe_dvbcsa_enc->key)) /* no key set, forward */ return upipe_dvbcsa_enc_output(upipe, uref, upump_p); uint32_t ts_header_size = TS_HEADER_SIZE; uint8_t buf[TS_HEADER_SIZE]; const uint8_t *ts_header = uref_block_peek(uref, 0, sizeof (buf), buf); if (unlikely(!ts_header)) { upipe_err(upipe, "fail to read ts header"); uref_free(uref); return; } uint8_t scrambling = ts_get_scrambling(ts_header); bool has_payload = ts_has_payload(ts_header); bool has_adaptation = ts_has_adaptation(ts_header); uint16_t pid = ts_get_pid(ts_header); uref_block_peek_unmap(uref, 0, buf, ts_header); if (!has_payload || scrambling || !upipe_dvbcsa_common_check_pid(common, pid)) return upipe_dvbcsa_enc_output(upipe, uref, upump_p); if (unlikely(has_adaptation)) { uint8_t af_length; int ret = uref_block_extract(uref, ts_header_size, 1, &af_length); if (unlikely(!ubase_check(ret))) { upipe_err(upipe, "fail to extract adaptation field length"); uref_free(uref); return; } if (unlikely(af_length >= 183)) { upipe_warn(upipe, "invalid adaptation field received"); uref_free(uref); return; } ts_header_size += af_length + 1; } struct ubuf *ubuf = ubuf_block_copy(uref->ubuf->mgr, uref->ubuf, 0, -1); if (unlikely(!ubuf)) { upipe_err(upipe, "fail to allocate buffer"); uref_free(uref); return; } uref_attach_ubuf(uref, ubuf); int size = -1; uint8_t *ts; int ret = ubuf_block_write(ubuf, 0, &size, &ts); if (unlikely(!ubase_check(ret))) { upipe_err(upipe, "fail to write buffer"); uref_free(uref); return; } ts_set_scrambling(ts, 0x2); dvbcsa_encrypt(upipe_dvbcsa_enc->key, ts + ts_header_size, size - ts_header_size); return upipe_dvbcsa_enc_output(upipe, uref, upump_p); }