/* VPN_recv */ int32_t VPN_recv(int32_t fd, Buffer * buffer, uint32_t size, uint32_t flags) { int32_t ret; if(_client_check(NULL, fd) == NULL) return -1; #ifdef DEBUG fprintf(stderr, "DEBUG: %s(%d, buf, %u, %u)\n", __func__, fd, size, flags); #endif if(buffer_set_size(buffer, size) != 0) return -1; /* FIXME implement flags */ ret = recv(fd, buffer_get_data(buffer), size, 0); #ifdef DEBUG fprintf(stderr, "DEBUG: %s(%d, buf, %u, %u) => %d\n", __func__, fd, size, flags, ret); #endif if(buffer_set_size(buffer, (ret < 0) ? 0 : ret) != 0) { memset(buffer_get_data(buffer), 0, size); return -1; } return ret; }
/* buffer_set */ int buffer_set(Buffer * buffer, size_t size, char * data) { if(buffer_set_size(buffer, size) != 0) return -1; memcpy(buffer->data, data, size); return 0; }
DEFINE_FUNC_1(webp_decode_argb, data_buffer_value) { if (!val_is_buffer(data_buffer_value)) { val_throw(alloc_string("webp_decode_argb: Expected to be a buffer")); return alloc_null(); } buffer data_buffer = val_to_buffer(data_buffer_value); int data_len = buffer_size(data_buffer); char *data_ptr = buffer_data(data_buffer); int webp_width = -1, webp_height = -1; char *webp_data_ptr = (char *)WebPDecodeARGB((const unsigned char *)data_ptr, data_len, &webp_width, &webp_height); int webp_data_len = webp_width * webp_height * 4; if (webp_data_ptr == NULL) { val_throw(alloc_string("webp_decode_argb: Invalid webp data")); return alloc_null(); } buffer webp_buffer = alloc_buffer_len(0); buffer_append_sub(webp_buffer, webp_data_ptr, webp_data_len); buffer_set_size(webp_buffer, webp_data_len); value array = alloc_array(3); val_array_set_i(array, 0, alloc_int(webp_width)); val_array_set_i(array, 1, alloc_int(webp_height)); val_array_set_i(array, 2, buffer_val(webp_buffer)); if (webp_data_ptr != NULL) free(webp_data_ptr); return array; }
/* buffer_set_data */ int buffer_set_data(Buffer * buffer, size_t offset, char * data, size_t size) { if(offset + size > buffer->size) /* FIXME integer overflow */ if(buffer_set_size(buffer, offset + size) != 0) return 1; memcpy(&buffer->data[offset], data, size); return 0; }
void Bytes::Resize (int size) { if (size != _length) { if (!_value) { _value = alloc_empty_object (); } if (val_is_null (val_field (_value, id_b))) { value dataValue; if (useBuffer) { buffer b = alloc_buffer_len (size); dataValue = buffer_val (b); _data = (unsigned char*)buffer_data (b); } else { dataValue = alloc_raw_string (size); _data = (unsigned char*)val_string (dataValue); } alloc_field (_value, id_b, dataValue); } else { if (useBuffer) { buffer b = val_to_buffer (val_field (_value, id_b)); buffer_set_size (b, size); _data = (unsigned char*)buffer_data (b); } else { value s = alloc_raw_string (size); memcpy ((char *)val_string (s), val_string (val_field (_value, id_b)), size); alloc_field (_value, id_b, s); _data = (unsigned char*)val_string (s); } } alloc_field (_value, id_length, alloc_int (size)); } _length = size; }
int appmessage_serialize(AppMessage * message, Buffer * buffer) { Buffer * b; if((b = buffer_new(0, NULL)) == NULL) return -1; /* reset the output buffer */ buffer_set_size(buffer, 0); if(_serialize_type(message, buffer, b) != 0) return -1; switch(message->type) { case AMT_ACKNOWLEDGEMENT: return _serialize_acknowledgement(message, buffer, b); case AMT_CALL: return _serialize_call(message, buffer, b); default: return -error_set_code(1, "%s%u", "Unable to serialize message type ", message->type); } }
/** * \brief Prepares selector component for processing. * \param[in,out] dev Selector base component device. * \return Error code. */ static int selector_prepare(struct comp_dev *dev) { struct comp_data *cd = comp_get_drvdata(dev); struct comp_buffer *sinkb; struct comp_buffer *sourceb; struct sof_ipc_comp_config *config = COMP_GET_CONFIG(dev); int ret; trace_selector("selector_prepare()"); ret = comp_set_state(dev, COMP_TRIGGER_PREPARE); if (ret < 0) return ret; if (ret == COMP_STATUS_STATE_ALREADY_SET) return PPL_STATUS_PATH_STOP; /* selector component will have 1 source and 1 sink buffer */ sourceb = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); sinkb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); /* get source data format and period bytes */ comp_set_period_bytes(sourceb->source, dev->frames, &cd->source_format, &cd->source_period_bytes); /* get sink data format and period bytes */ comp_set_period_bytes(sinkb->sink, dev->frames, &cd->sink_format, &cd->sink_period_bytes); /* There is an assumption that sink component will report out * proper number of channels [1] for selector to actually * reduce channel count between source and sink */ trace_selector("selector_prepare(): source->params.channels = %u", sourceb->sink->params.channels); trace_selector("selector_prepare(): sink->params.channels = %u", sinkb->sink->params.channels); /* set downstream buffer size */ ret = buffer_set_size(sinkb, cd->sink_period_bytes * config->periods_sink); if (ret < 0) { trace_selector_error("selector_prepare() error: " "buffer_set_size() failed"); goto err; } /* validate */ if (cd->sink_period_bytes == 0) { trace_selector_error("selector_prepare() error: " "cd->sink_period_bytes = 0, dev->frames =" " %u, sinkb->sink->frame_bytes = %u", dev->frames, sinkb->sink->frame_bytes); ret = -EINVAL; goto err; } if (cd->source_period_bytes == 0) { trace_selector_error("selector_prepare() error: " "cd->source_period_bytes = 0, " "dev->frames = %u, " "sourceb->source->frame_bytes = %u", dev->frames, sourceb->source->frame_bytes); ret = -EINVAL; goto err; } cd->sel_func = sel_get_processing_function(dev); if (!cd->sel_func) { trace_selector_error("selector_prepare() error: " "invalid cd->sel_func, " "cd->source_format = %u, " "cd->sink_format = %u, " "cd->out_channels_count = %u", cd->source_format, cd->sink_format, cd->config.out_channels_count); ret = -EINVAL; goto err; } return PPL_STATUS_PATH_STOP; err: comp_set_state(dev, COMP_TRIGGER_RESET); return ret; }
static int write_elf(const struct rmod_context *ctx, const struct buffer *in, struct buffer *out) { int ret; int bit64; size_t loc; size_t rmod_data_size; struct elf_writer *ew; struct buffer rmod_data; struct buffer rmod_header; struct buffer program; struct buffer relocs; Elf64_Xword total_size; Elf64_Addr addr; Elf64_Ehdr ehdr; bit64 = ctx->pelf.ehdr.e_ident[EI_CLASS] == ELFCLASS64; /* * 3 sections will be added to the ELF file. * +------------------+ * | rmodule header | * +------------------+ * | program | * +------------------+ * | relocations | * +------------------+ */ /* Create buffer for header and relocations. */ rmod_data_size = sizeof(struct rmodule_header); if (bit64) rmod_data_size += ctx->nrelocs * sizeof(Elf64_Addr); else rmod_data_size += ctx->nrelocs * sizeof(Elf32_Addr); if (buffer_create(&rmod_data, rmod_data_size, "rmod")) return -1; buffer_splice(&rmod_header, &rmod_data, 0, sizeof(struct rmodule_header)); buffer_clone(&relocs, &rmod_data); buffer_seek(&relocs, sizeof(struct rmodule_header)); /* Reset current location. */ buffer_set_size(&rmod_header, 0); buffer_set_size(&relocs, 0); /* Program contents. */ buffer_splice(&program, in, ctx->phdr->p_offset, ctx->phdr->p_filesz); /* Create ELF writer with modified entry point. */ memcpy(&ehdr, &ctx->pelf.ehdr, sizeof(ehdr)); ew = elf_writer_init(&ehdr); if (ew == NULL) { ERROR("Failed to create ELF writer.\n"); buffer_delete(&rmod_data); return -1; } /* Write out rmodule_header. */ ctx->xdr->put16(&rmod_header, RMODULE_MAGIC); ctx->xdr->put8(&rmod_header, RMODULE_VERSION_1); ctx->xdr->put8(&rmod_header, 0); /* payload_begin_offset */ loc = sizeof(struct rmodule_header); ctx->xdr->put32(&rmod_header, loc); /* payload_end_offset */ loc += ctx->phdr->p_filesz; ctx->xdr->put32(&rmod_header, loc); /* relocations_begin_offset */ ctx->xdr->put32(&rmod_header, loc); /* relocations_end_offset */ if (bit64) loc += ctx->nrelocs * sizeof(Elf64_Addr); else loc += ctx->nrelocs * sizeof(Elf32_Addr); ctx->xdr->put32(&rmod_header, loc); /* module_link_start_address */ ctx->xdr->put32(&rmod_header, ctx->phdr->p_vaddr); /* module_program_size */ ctx->xdr->put32(&rmod_header, ctx->phdr->p_memsz); /* module_entry_point */ ctx->xdr->put32(&rmod_header, ctx->pelf.ehdr.e_entry); /* parameters_begin */ ctx->xdr->put32(&rmod_header, ctx->parameters_begin); /* parameters_end */ ctx->xdr->put32(&rmod_header, ctx->parameters_end); /* bss_begin */ ctx->xdr->put32(&rmod_header, ctx->bss_begin); /* bss_end */ ctx->xdr->put32(&rmod_header, ctx->bss_end); /* padding[4] */ ctx->xdr->put32(&rmod_header, 0); ctx->xdr->put32(&rmod_header, 0); ctx->xdr->put32(&rmod_header, 0); ctx->xdr->put32(&rmod_header, 0); /* Write the relocations. */ for (unsigned i = 0; i < ctx->nrelocs; i++) { if (bit64) ctx->xdr->put64(&relocs, ctx->emitted_relocs[i]); else ctx->xdr->put32(&relocs, ctx->emitted_relocs[i]); } total_size = 0; addr = 0; /* * There are 2 cases to deal with. The program has a large NOBITS * section and the relocations can fit entirely within occupied memory * region for the program. The other is that the relocations increase * the memory footprint of the program if it was loaded directly into * the region it would run. The rmdoule header is a fixed cost that * is considered a part of the program. */ total_size += buffer_size(&rmod_header); if (buffer_size(&relocs) + ctx->phdr->p_filesz > ctx->phdr->p_memsz) { total_size += buffer_size(&relocs); total_size += ctx->phdr->p_filesz; } else { total_size += ctx->phdr->p_memsz; } ret = add_section(ew, &rmod_header, ".header", addr, buffer_size(&rmod_header)); if (ret < 0) goto out; addr += buffer_size(&rmod_header); ret = add_section(ew, &program, ".program", addr, ctx->phdr->p_filesz); if (ret < 0) goto out; addr += ctx->phdr->p_filesz; if (ctx->nrelocs) { ret = add_section(ew, &relocs, ".relocs", addr, buffer_size(&relocs)); if (ret < 0) goto out; addr += buffer_size(&relocs); } if (total_size != addr) { ret = add_section(ew, NULL, ".empty", addr, total_size - addr); if (ret < 0) goto out; } /* * Ensure last section has a memory usage that meets the required * total size of the program in memory. */ ret = elf_writer_serialize(ew, out); if (ret < 0) ERROR("Failed to serialize ELF to buffer.\n"); out: buffer_delete(&rmod_data); elf_writer_destroy(ew); return ret; }
DEFINE_FUNC_5(webp_encode_argb, data_buffer_value, width_value, height_value, lossless_value, quality_factor_value) { int width = 0; int height = 0; float quality_factor = 100; int lossless = 1; int stride = 0; uint8_t* abgr = NULL; uint8_t* rgba = NULL; uint8_t* output = NULL; int output_size = 0; int pixels_size; int bytes_size; buffer data_buffer; if (val_is_int(width_value)) width = val_int(width_value); if (val_is_int(height_value)) height = val_int(height_value); if (val_is_bool(lossless_value)) lossless = val_bool(lossless_value); if (val_is_float(quality_factor_value)) quality_factor = val_float(quality_factor_value); stride = width * 4; pixels_size = width * height; bytes_size = pixels_size * 4; if (!val_is_buffer(data_buffer_value)) { val_throw(alloc_string("webp_encode_argb: Expected to be a buffer")); return alloc_null(); } data_buffer = val_to_buffer(data_buffer_value); if (bytes_size != buffer_size(data_buffer)) { val_throw(alloc_string("webp_encode_argb: Invalid buffer size")); return alloc_null(); } //if () abgr = (uint8_t *)buffer_data(data_buffer); rgba = (uint8_t *)malloc(bytes_size); uint8_t* _abgr = abgr; uint8_t* _rgba = rgba; int _pixels_size = pixels_size; while (_pixels_size-- > 0) { //_rgba[0] = _abgr[3]; _rgba[0] = _abgr[1]; _rgba[1] = _abgr[2]; _rgba[2] = _abgr[3]; _rgba[3] = _abgr[0]; _abgr += 4; _rgba += 4; } if (lossless) { output_size = WebPEncodeLosslessRGBA( rgba, //abgr, width, height, stride, &output ); } else { output_size = WebPEncodeRGBA( rgba, //abgr, width, height, stride, quality_factor, &output ); } printf("output_size: (%d, %d, %d) : %d\n", width, height, stride, output_size); buffer output_buffer = alloc_buffer_len(0); buffer_append_sub(output_buffer, (char *)output, output_size); buffer_set_size(output_buffer, output_size); if (output != NULL) free(output); if (rgba != NULL) free(rgba); return buffer_val(output_buffer); }
/* * Serialize the ELF file to the output buffer. Return < 0 on error, * 0 on success. */ int elf_writer_serialize(struct elf_writer *ew, struct buffer *out) { Elf64_Half i; Elf64_Xword metadata_size; Elf64_Xword program_size; Elf64_Off shstroffset; size_t shstrlen; struct buffer metadata; struct buffer phdrs; struct buffer data; struct buffer *strtab; INFO("Writing %zu sections.\n", ew->num_secs); /* Determine size of sections to be written. */ program_size = 0; /* Start with 1 byte for first byte of section header string table. */ shstrlen = 1; for (i = 0; i < ew->num_secs; i++) { struct elf_writer_section *sec = &ew->sections[i]; if (sec->shdr.sh_flags & SHF_ALLOC) ew->ehdr.e_phnum++; program_size += buffer_size(&sec->content); /* Keep track of the length sections' names. */ if (sec->name != NULL) { sec->shdr.sh_name = shstrlen; shstrlen += strlen(sec->name) + 1; } } ew->ehdr.e_shnum = ew->num_secs; metadata_size = 0; metadata_size += ew->ehdr.e_ehsize; metadata_size += ew->ehdr.e_shnum * ew->ehdr.e_shentsize; metadata_size += ew->ehdr.e_phnum * ew->ehdr.e_phentsize; shstroffset = metadata_size; /* Align up section header string size and metadata size to 4KiB */ metadata_size = ALIGN(metadata_size + shstrlen, 4096); if (buffer_create(out, metadata_size + program_size, "elfout")) { ERROR("Could not create output buffer for ELF.\n"); return -1; } INFO("Created %zu output buffer for ELF file.\n", buffer_size(out)); /* * Write out ELF header. Section headers come right after ELF header * followed by the program headers. Buffers need to be created first * to do the writing. */ ew->ehdr.e_shoff = ew->ehdr.e_ehsize; ew->ehdr.e_phoff = ew->ehdr.e_shoff + ew->ehdr.e_shnum * ew->ehdr.e_shentsize; buffer_splice(&metadata, out, 0, metadata_size); buffer_splice(&phdrs, out, ew->ehdr.e_phoff, ew->ehdr.e_phnum * ew->ehdr.e_phentsize); buffer_splice(&data, out, metadata_size, program_size); /* Set up the section header string table contents. */ strtab = &ew->shstrtab->content; buffer_splice(strtab, out, shstroffset, shstrlen); ew->shstrtab->shdr.sh_size = shstrlen; /* Reset current locations. */ buffer_set_size(&metadata, 0); buffer_set_size(&data, 0); buffer_set_size(&phdrs, 0); buffer_set_size(strtab, 0); /* ELF Header */ ehdr_write(ew, &metadata); /* Write out section headers, section strings, section content, and * program headers. */ ew->xdr->put8(strtab, 0); for (i = 0; i < ew->num_secs; i++) { Elf64_Phdr phdr; struct elf_writer_section *sec = &ew->sections[i]; /* Update section offsets. Be sure to not update SHT_NULL. */ if (sec == ew->shstrtab) sec->shdr.sh_offset = shstroffset; else if (i != 0) sec->shdr.sh_offset = buffer_size(&data) + metadata_size; shdr_write(ew, i, &metadata); /* Add section name to string table. */ if (sec->name != NULL) bputs(strtab, sec->name, strlen(sec->name) + 1); if (!(sec->shdr.sh_flags & SHF_ALLOC)) continue; bputs(&data, buffer_get(&sec->content), buffer_size(&sec->content)); phdr.p_type = PT_LOAD; phdr.p_offset = sec->shdr.sh_offset; phdr.p_vaddr = sec->shdr.sh_addr; phdr.p_paddr = sec->shdr.sh_addr; phdr.p_filesz = buffer_size(&sec->content); phdr.p_memsz = sec->shdr.sh_size; phdr.p_flags = 0; if (sec->shdr.sh_flags & SHF_EXECINSTR) phdr.p_flags |= PF_X | PF_R; if (sec->shdr.sh_flags & SHF_WRITE) phdr.p_flags |= PF_W; phdr.p_align = sec->shdr.sh_addralign; phdr_write(ew, &phdrs, &phdr); } return 0; }
/* video_init */ static VideoPhonePlugin * _video_init(PhonePluginHelper * helper) { VideoPhonePlugin * video; struct v4l2_capability cap; struct v4l2_cropcap cropcap; struct v4l2_crop crop; struct v4l2_format format; if((video = object_new(sizeof(*video))) == NULL) return NULL; video->helper = helper; /* FIXME let this be configurable */ video->fd = open("/dev/video0", O_RDWR); video->buffer = buffer_new(0, NULL); video->source = 0; video->window = NULL; /* check for errors */ if(video->buffer == NULL || video->fd < 0 || _video_ioctl(video, VIDIOC_QUERYCAP, &cap) == -1 || (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0 /* FIXME also implement mmap() and streaming */ || (cap.capabilities & V4L2_CAP_READWRITE) == 0) { helper->error(helper->phone, "Could not open the video capture device", 1); _video_destroy(video); return NULL; } /* reset cropping */ memset(&cropcap, 0, sizeof(cropcap)); cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if(_video_ioctl(video, VIDIOC_CROPCAP, &cropcap) == 0) { /* reset to default */ crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; crop.c = cropcap.defrect; if(_video_ioctl(video, VIDIOC_S_CROP, &crop) == -1 && errno == EINVAL) helper->error(helper->phone, "Cropping not supported", 0); } /* obtain the current format */ if(_video_ioctl(video, VIDIOC_G_FMT, &format) == -1 || buffer_set_size(video->buffer, format.fmt.pix.sizeimage) != 0) { _video_destroy(video); return NULL; } /* create the window */ video->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_resizable(GTK_WINDOW(video->window), FALSE); gtk_window_set_title(GTK_WINDOW(video->window), "Phone - Video"); g_signal_connect_swapped(video->window, "delete-event", G_CALLBACK( _video_on_closex), video); video->area = gtk_drawing_area_new(); gtk_widget_set_size_request(video->area, format.fmt.pix.width, format.fmt.pix.height); gtk_container_add(GTK_CONTAINER(video->window), video->area); gtk_widget_show_all(video->window); if(_video_on_refresh(video) == TRUE) video->source = g_timeout_add(1000, _video_on_refresh, video); return video; }
int parse_elf_to_xip_stage(const struct buffer *input, struct buffer *output, uint32_t *location, const char *ignore_section) { struct xip_context xipctx; struct rmod_context *rmodctx; struct reloc_filter filter; struct parsed_elf *pelf; size_t output_sz; uint32_t adjustment; struct buffer binput; struct buffer boutput; Elf64_Xword i; int ret = -1; xipctx.ignored_section_idx = 0; rmodctx = &xipctx.rmodctx; pelf = &rmodctx->pelf; if (rmodule_init(rmodctx, input)) return -1; /* Only support x86 XIP currently. */ if (rmodctx->pelf.ehdr.e_machine != EM_386) { ERROR("Only support XIP stages for x86\n"); goto out; } xipctx.ignored_section = find_ignored_section_header(pelf, ignore_section); if (xipctx.ignored_section != NULL) xipctx.ignored_section_idx = xipctx.ignored_section - pelf->shdr; filter.filter = rmod_filter; filter.context = &xipctx; if (rmodule_collect_relocations(rmodctx, &filter)) goto out; output_sz = sizeof(struct cbfs_stage) + pelf->phdr->p_filesz; if (buffer_create(output, output_sz, input->name) != 0) { ERROR("Unable to allocate memory: %m\n"); goto out; } buffer_clone(&boutput, output); memset(buffer_get(&boutput), 0, output_sz); buffer_set_size(&boutput, 0); /* Single loadable segment. The entire segment moves to final * location from based on virtual address of loadable segment. */ adjustment = *location - pelf->phdr->p_vaddr; DEBUG("Relocation adjustment: %08x\n", adjustment); fill_cbfs_stage(&boutput, CBFS_COMPRESS_NONE, (uint32_t)pelf->ehdr.e_entry + adjustment, (uint32_t)pelf->phdr->p_vaddr + adjustment, pelf->phdr->p_filesz, pelf->phdr->p_memsz); /* Need an adjustable buffer. */ buffer_clone(&binput, input); buffer_seek(&binput, pelf->phdr->p_offset); bputs(&boutput, buffer_get(&binput), pelf->phdr->p_filesz); buffer_clone(&boutput, output); buffer_seek(&boutput, sizeof(struct cbfs_stage)); /* Make adjustments to all the relocations within the program. */ for (i = 0; i < rmodctx->nrelocs; i++) { size_t reloc_offset; uint32_t val; struct buffer in, out; /* The relocations represent in-program addresses of the * linked program. Obtain the offset into the program to do * the adjustment. */ reloc_offset = rmodctx->emitted_relocs[i] - pelf->phdr->p_vaddr; buffer_clone(&out, &boutput); buffer_seek(&out, reloc_offset); buffer_clone(&in, &out); /* Appease around xdr semantics: xdr decrements buffer * size when get()ing and appends to size when put()ing. */ buffer_set_size(&out, 0); val = xdr_le.get32(&in); DEBUG("reloc %zx %08x -> %08x\n", reloc_offset, val, val + adjustment); xdr_le.put32(&out, val + adjustment); } /* Need to back up the location to include cbfs stage metadata. */ *location -= sizeof(struct cbfs_stage); ret = 0; out: rmodule_cleanup(rmodctx); return ret; }