示例#1
0
bool checkreturn pb_encode_fixed64(pb_ostream_t *stream, const void *value)
{
    const uint64_t *words = (const uint64_t*)value;
    uint_least8_t bytes[8];
    #ifdef __BIG_ENDIAN__
    bytes[0] = (uint_least8_t)(*words >> 56) & 0xFF;
    bytes[1] = (uint_least8_t)(*words >> 48) & 0xFF;
    bytes[2] = (uint_least8_t)(*words >> 40) & 0xFF;
    bytes[3] = (uint_least8_t)(*words >> 32) & 0xFF;
    bytes[4] = (uint_least8_t)(*words >> 24) & 0xFF;
    bytes[5] = (uint_least8_t)(*words >> 16) & 0xFF;
    bytes[6] = (uint_least8_t)(*words >> 8) & 0xFF;
    bytes[7] = (uint_least8_t)(*words) & 0xFF;
    return pb_write(stream, bytes, 8);
    #else
    bytes[7] = (uint_least8_t)(*words >> 56) & 0xFF;
    bytes[6] = (uint_least8_t)(*words >> 48) & 0xFF;
    bytes[5] = (uint_least8_t)(*words >> 40) & 0xFF;
    bytes[4] = (uint_least8_t)(*words >> 32) & 0xFF;
    bytes[3] = (uint_least8_t)(*words >> 24) & 0xFF;
    bytes[2] = (uint_least8_t)(*words >> 16) & 0xFF;
    bytes[1] = (uint_least8_t)(*words >> 8) & 0xFF;
    bytes[0] = (uint_least8_t)(*words) & 0xFF;
    return pb_write(stream, bytes, 8);
    #endif
}
示例#2
0
/* Read a string from the pbuf, update pos and return 0 on success */
void
pb_write_str(struct pbuf* pbuf, const char* str, uint32_t len, int* pos)
{
    uint32_t padding = 0;
    /* Write the string length and string */
    pb_write_arrl(pbuf, &len, sizeof(len), pos);
    pb_write(pbuf, str, len, pos);
    /* Write the padding */
    pb_write(pbuf, &padding, ROUNDUP(*pos, 4) - *pos, pos);
}
示例#3
0
bool checkreturn pb_enc_fixed32(pb_ostream_t *stream, const pb_field_t *field, const void *src)
{
    #ifdef __BIG_ENDIAN__
    uint8_t bytes[4] = {0};
    memcpy(bytes, src, 4);
    uint8_t lebytes[4] = {bytes[3], bytes[2], bytes[1], bytes[0]};
    return pb_write(stream, lebytes, 4);
    #else
    return pb_write(stream, (uint8_t*)src, 4);
    #endif
}
示例#4
0
/* Encode a fixed32, sfixed32 or float value.
 * You need to pass a pointer to a 4-byte wide C variable. */
static int  pb_encode_fixed32(pb_ostream_t *stream, const void *value) {
#ifdef __BIG_ENDIAN__
    const uint8_t *bytes = value;
    uint8_t lebytes[4];
    lebytes[0] = bytes[3];
    lebytes[1] = bytes[2];
    lebytes[2] = bytes[1];
    lebytes[3] = bytes[0];
    return pb_write(stream, lebytes, 4);
#else
    return pb_write(stream, (const uint8_t *) value, 4);
#endif
}
示例#5
0
bool checkreturn pb_encode_string(pb_ostream_t *stream, const uint8_t *buffer, size_t size)
{
    if (!pb_encode_varint(stream, (uint64_t)size))
        return false;
    
    return pb_write(stream, buffer, size);
}
示例#6
0
/* Encode an integer in the varint format.
 * This works for bool, enum, int32, int64, uint32 and uint64 field types. */
static int  pb_encode_varint(pb_ostream_t *stream, uint64_t value) {
    uint8_t buffer[10];
    size_t i = 0;

    if (value == 0)
        return pb_write(stream, (uint8_t *) &value, 1);

    while (value) {
        buffer[i] = (uint8_t)((value & 0x7F) | 0x80);
        value >>= 7;
        i++;
    }
    buffer[i - 1] &= 0x7F; /* Unset top bit on last byte */

    return pb_write(stream, buffer, i);
}
示例#7
0
/* Encode a string or bytes type field. For strings, pass strlen(s) as size. */
static int  pb_encode_string(pb_ostream_t *stream, const uint8_t *buffer,
        size_t size) {
    if (!pb_encode_varint(stream, (uint64_t) size))
        return 0;

    return pb_write(stream, buffer, size);
}
示例#8
0
/* Encode a fixed64, sfixed64 or double value.
 * You need to pass a pointer to a 8-byte wide C variable. */
static int checkreturn pb_encode_fixed64(pb_ostream_t *stream, const void *value) {
#ifdef __BIG_ENDIAN__
    const uint8_t *bytes = value;
    uint8_t lebytes[8];
    lebytes[0] = bytes[7];
    lebytes[1] = bytes[6];
    lebytes[2] = bytes[5];
    lebytes[3] = bytes[4];
    lebytes[4] = bytes[3];
    lebytes[5] = bytes[2];
    lebytes[6] = bytes[1];
    lebytes[7] = bytes[0];
    return pb_write(stream, lebytes, 8);
#else
    return pb_write(stream, (const uint8_t *) value, 8);
#endif
}
示例#9
0
bool checkreturn pb_encode_fixed32(pb_ostream_t *stream, const void *value)
{
    const uint32_t *words = (const uint32_t*)value;
    uint_least8_t bytes[4];
    #ifdef __BIG_ENDIAN__
    bytes[0] = (uint_least8_t)(*words >> 24) & 0xFF;
    bytes[1] = (uint_least8_t)(*words >> 16) & 0xFF;
    bytes[2] = (uint_least8_t)(*words >> 8) & 0xFF;
    bytes[3] = (uint_least8_t)(*words) & 0xFF;
    return pb_write(stream, bytes, 4);
    #else
    bytes[3] = (uint_least8_t)(*words >> 24) & 0xFF;
    bytes[2] = (uint_least8_t)(*words >> 16) & 0xFF;
    bytes[1] = (uint_least8_t)(*words >> 8) & 0xFF;
    bytes[0] = (uint_least8_t)(*words) & 0xFF;
    return pb_write(stream, bytes, 4);
    #endif
}
示例#10
0
bool checkreturn pb_encode_fixed32(pb_ostream_t *stream, const void *value)
{
	uint32_t val = *(const uint32_t*)value;
	pb_byte_t bytes[4];
	bytes[0] = (pb_byte_t)(val & 0xFF);
	bytes[1] = (pb_byte_t)((val >> 8) & 0xFF);
	bytes[2] = (pb_byte_t)((val >> 16) & 0xFF);
	bytes[3] = (pb_byte_t)((val >> 24) & 0xFF);
	return pb_write(stream, bytes, 4);
}
示例#11
0
void
pb_write_arrl(struct pbuf* pbuf, const uint32_t* arr, int size, int* pos)
{
    uint32_t nl_arr[size/sizeof(uint32_t)];
    int i;
    for(i = 0; i < size/sizeof(uint32_t); i++){
        nl_arr[i] = htonl(arr[i]);
    }
    pb_write(pbuf, nl_arr, sizeof(nl_arr), pos);
}
示例#12
0
/********************
 * Helper functions *
 ********************/
bool checkreturn pb_encode_varint(pb_ostream_t *stream, uint64_t value)
{
	pb_byte_t buffer[10];
	size_t i = 0;

	if (value <= 0x7F)
	{
		pb_byte_t v = (pb_byte_t)value;
		return pb_write(stream, &v, 1);
	}

	while (value)
	{
		buffer[i] = (pb_byte_t)((value & 0x7F) | 0x80);
		value >>= 7;
		i++;
	}
	buffer[i-1] &= 0x7F; /* Unset top bit on last byte */

	return pb_write(stream, buffer, i);
}
示例#13
0
bool checkreturn pb_encode_fixed64(pb_ostream_t *stream, const void *value)
{
	uint64_t val = *(const uint64_t*)value;
	pb_byte_t bytes[8];
	bytes[0] = (pb_byte_t)(val & 0xFF);
	bytes[1] = (pb_byte_t)((val >> 8) & 0xFF);
	bytes[2] = (pb_byte_t)((val >> 16) & 0xFF);
	bytes[3] = (pb_byte_t)((val >> 24) & 0xFF);
	bytes[4] = (pb_byte_t)((val >> 32) & 0xFF);
	bytes[5] = (pb_byte_t)((val >> 40) & 0xFF);
	bytes[6] = (pb_byte_t)((val >> 48) & 0xFF);
	bytes[7] = (pb_byte_t)((val >> 56) & 0xFF);
	return pb_write(stream, bytes, 8);
}
示例#14
0
/**
 * close the SACD device and clean up.
 */
static int sacd_net_input_close(sacd_input_t dev)
{
    if (!dev)
    {
        return 0;
    }
    else
    {
        ServerRequest request;
        ServerResponse response;
        pb_istream_t input = pb_istream_from_socket(&dev->fd);
        pb_ostream_t output = pb_ostream_from_socket(&dev->fd);
        uint8_t zero = 0;

        request.type = ServerRequest_Type_DISC_CLOSE;
        if (!pb_encode(&output, ServerRequest_fields, &request))
        {
            goto error;
        }

        pb_write(&output, &zero, 1);

        if (!pb_decode(&input, ServerResponse_fields, &response))
        {
            goto error;
        }

        if (response.result == 0 || response.type != ServerResponse_Type_DISC_CLOSED)
        {
            goto error;
        }
    }

error:

    if(dev)
    {
        socket_destroy(&dev->fd);
        socket_close();
        if (dev->input_buffer)
        {
            free(dev->input_buffer);
            dev->input_buffer = 0;
        }
        free(dev);
        dev = 0;
    }
    return 0;
}
示例#15
0
bool checkreturn pb_encode_submessage(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct)
{
    /* First calculate the message size using a non-writing substream. */
    pb_ostream_t substream = PB_OSTREAM_SIZING;
    size_t size;
    bool status;
    
    if (!pb_encode(&substream, fields, src_struct))
    {
#ifndef PB_NO_ERRMSG
        stream->errmsg = substream.errmsg;
#endif
        return false;
    }
    
    size = substream.bytes_written;
    
    if (!pb_encode_varint(stream, (uint64_t)size))
        return false;
    
    if (stream->callback == NULL)
        return pb_write(stream, NULL, size); /* Just sizing */
    
    if (stream->bytes_written + size > stream->max_size)
        PB_RETURN_ERROR(stream, "stream full");
        
    /* Use a substream to verify that a callback doesn't write more than
     * what it did the first time. */
    substream.callback = stream->callback;
    substream.state = stream->state;
    substream.max_size = size;
    substream.bytes_written = 0;
#ifndef PB_NO_ERRMSG
    substream.errmsg = NULL;
#endif
    
    status = pb_encode(&substream, fields, src_struct);
    
    stream->bytes_written += substream.bytes_written;
    stream->state = substream.state;
#ifndef PB_NO_ERRMSG
    stream->errmsg = substream.errmsg;
#endif
    
    if (substream.bytes_written != size)
        PB_RETURN_ERROR(stream, "submsg size changed");
    
    return status;
}
示例#16
0
void send_printer_status() {
  uint8_t out[16];
  uint8_t type;
  pb_ostream_t stream = pb_ostream_from_buffer(out, sizeof(out));
  bool status;
  PrinterStatus record;

  type = PRINTER_STATUS;
  pb_write(&stream, &type, 1);

  record.cardInserted = 1;
  record.keyInserted = get_interlock_state();
  record.overrideSwitch = get_interlock_state();
  record.laserOn = g_laser_gating;
  record.laserPowerFeedback = 42;
  status = pb_encode(&stream, PrinterStatus_fields, &record);
  if (status) {
    serialio_write(out, stream.bytes_written);
  }
}
示例#17
0
/* Eecode submessage in __messages protos */
static int pb_encode_submessage(pb_ostream_t *stream, const pc_JSON *gprotos, const pc_JSON *protos, pc_JSON *value) {
    /* First calculate the message size using a non-writing substream. */
    pb_ostream_t substream = { 0, 0, 0, 0 };
    size_t size;
    int status;

    if (!pb_encode(&substream, gprotos, protos, value)) {
        return 0;
    }

    size = substream.bytes_written;

    if (!pb_encode_varint(stream, (uint64_t) size)) {
        return 0;
    }

    if (stream->callback == NULL )
        return pb_write(stream, NULL, size); /* Just sizing */

    if (stream->bytes_written + size > stream->max_size)
        return 0;

    /* Use a substream to verify that a callback doesn't write more than
     * what it did the first time. */
    substream.callback = stream->callback;
    substream.state = stream->state;
    substream.max_size = size;
    substream.bytes_written = 0;

    status = pb_encode(&substream, gprotos, protos, value);

    stream->bytes_written += substream.bytes_written;
    stream->state = substream.state;

    if (substream.bytes_written != size) {
        return 0;
    }

    return status;
}
示例#18
0
bool checkreturn pb_enc_submessage(pb_ostream_t *stream, const pb_field_t *field, const void *src)
{
    pb_ostream_t substream = {0};
    size_t size;
    bool status;
    
    if (field->ptr == NULL)
        return false;
    
    if (!pb_encode(&substream, (pb_field_t*)field->ptr, src))
        return false;
    
    size = substream.bytes_written;
    
    if (!pb_encode_varint(stream, size))
        return false;
    
    if (stream->callback == NULL)
        return pb_write(stream, NULL, size); /* Just sizing */
    
    if (stream->bytes_written + size > stream->max_size)
        return false;
        
    /* Use a substream to verify that a callback doesn't write more than
     * what it did the first time. */
    substream.callback = stream->callback;
    substream.state = stream->state;
    substream.max_size = size;
    substream.bytes_written = 0;
    
    status = pb_encode(&substream, (pb_field_t*)field->ptr, src);
    
    stream->bytes_written += substream.bytes_written;
    
    if (substream.bytes_written != size)
        return false;
    
    return status;
}
示例#19
0
文件: pwdb.c 项目: druzac/pwdb
int
cmd_retrieve(struct arguments *args)
{
    int rc;
    struct db *db;
    char pass[MAX_PASS_LENGTH + 1], *fndpass;

    rc = -1;
    db = NULL;

    if (uuid_is_null(args->uuid) || !args->dbfile) {
        fprintf(stderr, "missing arguments for retrieve\n");
        goto out;
    }

    if (get_pass(PASS_PROMPT, pass, MAX_PASS_LENGTH + 1, stdin)) {
        fprintf(stderr, "%s\n", GET_PASS_FAIL);
        goto out;
    }

    if (!(db = pwsdb_open(pass, args->dbfile))) {
        fprintf(stderr, "couldn't open db\n");
        goto out;
    }

    if (!(fndpass = pwsdb_get_pass(db, args->uuid))) {
        fprintf(stderr, "couldn't find pass\n");
        goto out;
    }

    pb_write(fndpass);

    rc = 0;
 out:
    destroy_db(db);
    free(db);
    return rc;
}
示例#20
0
bool checkreturn pb_encode_submessage(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct)
{
    /* First calculate the message size using a non-writing substream. */
    pb_ostream_t substream = {0,0,0,0};
    size_t size;
    bool status;
    
    if (!pb_encode(&substream, fields, src_struct))
        return false;
    
    size = substream.bytes_written;
    
    if (!pb_encode_varint(stream, (uint64_t)size))
        return false;
    
    if (stream->callback == NULL)
        return pb_write(stream, NULL, size); /* Just sizing */
    
    if (stream->bytes_written + size > stream->max_size)
        return false;
        
    /* Use a substream to verify that a callback doesn't write more than
     * what it did the first time. */
    substream.callback = stream->callback;
    substream.state = stream->state;
    substream.max_size = size;
    substream.bytes_written = 0;
    
    status = pb_encode(&substream, fields, src_struct);
    
    stream->bytes_written += substream.bytes_written;
    stream->state = substream.state;
    
    if (substream.bytes_written != size)
        return false;
    
    return status;
}
示例#21
0
static uint32_t sacd_net_input_total_sectors(sacd_input_t dev)
{
    if (!dev)
    {
        return 0;
    }
    else
    {
        ServerRequest request;
        ServerResponse response;
        pb_istream_t input = pb_istream_from_socket(&dev->fd);
        pb_ostream_t output = pb_ostream_from_socket(&dev->fd);
        uint8_t zero = 0;

        request.type = ServerRequest_Type_DISC_SIZE;

        if (!pb_encode(&output, ServerRequest_fields, &request))
        {
            return 0;
        }

        /* We signal the end of request with a 0 tag. */
        pb_write(&output, &zero, 1);

        if (!pb_decode(&input, ServerResponse_fields, &response))
        {
            return 0;
        }

        if (response.type != ServerResponse_Type_DISC_SIZE)
        {
            return 0;
        }

        return (uint32_t) response.result;
    }
}
示例#22
0
/*
**  PB_PUT -- buffered put on pipe
**
**	This routine puts the named data out onto the pipe
**	determined by ppb->pb_proc.
**
**	Parameters:
**		dp -- a pointer to the data to write.
**		len -- the length of the data to write.
**		ppb -- a pointer to the pipe block.
**
**	Returns:
**		none
**
**	Side Effects:
**		none
**
**	Trace Flags:
**		18.8 - 18.15
*/
void
pb_put(register char *dp, register int len, register pb_t *ppb)
{
	register int	i;

#ifdef xCTR2
	if (tTf(18, 9))
		lprintf("pb_put: len %d\n", len);
#endif

	/*
	**  Top loop.
	**	Loop until we have run out of things to write.
	*/

	while (len > 0) {
		/* compute the length to move */
		i = min(ppb->pb_nleft, len);
#ifdef xCM_DEBUG
		if (i <= 0)
			syserr("pb_put: zero");
#endif

		/* move data into buffer and adjust ptrs & counts */
		bmove(dp, ppb->pb_xptr, i);
		dp += i;
		len -= i;
		ppb->pb_xptr += i;
		ppb->pb_nleft -= i;
		ppb->pb_nused += i;

		/* flush block if full */
		if (ppb->pb_nleft <= 0)
			pb_write(ppb);
	}
}
示例#23
0
/* Callbacks don't need this function because they usually know the data type
 * without examining the field structure.
 * Therefore it is static for now.
 */
static bool checkreturn encode_array(pb_ostream_t *stream, const pb_field_t *field,
                         const void *pData, size_t count, pb_encoder_t func)
{
    size_t i;
    const void *p;
    size_t size;
    
    if (count == 0)
        return true;
    
    if (PB_LTYPE(field->type) <= PB_LTYPE_LAST_PACKABLE)
    {
        if (!pb_encode_tag(stream, PB_WT_STRING, field->tag))
            return false;
        
        /* Determine the total size of packed array. */
        if (PB_LTYPE(field->type) == PB_LTYPE_FIXED32)
        {
            size = 4 * count;
        }
        else if (PB_LTYPE(field->type) == PB_LTYPE_FIXED64)
        {
            size = 8 * count;
        }
        else
        {
            pb_ostream_t sizestream = {0,0,0,0};
            p = pData;
            for (i = 0; i < count; i++)
            {
                if (!func(&sizestream, field, p))
                    return false;
                p = (const char*)p + field->data_size;
            }
            size = sizestream.bytes_written;
        }
        
        if (!pb_encode_varint(stream, (uint64_t)size))
            return false;
        
        if (stream->callback == NULL)
            return pb_write(stream, NULL, size); /* Just sizing.. */
        
        /* Write the data */
        p = pData;
        for (i = 0; i < count; i++)
        {
            if (!func(stream, field, p))
                return false;
            p = (const char*)p + field->data_size;
        }
    }
    else
    {
        p = pData;
        for (i = 0; i < count; i++)
        {
            if (!pb_encode_tag_for_field(stream, field))
                return false;
            if (!func(stream, field, p))
                return false;
            p = (const char*)p + field->data_size;
        }
    }
    
    return true;
}
示例#24
0
static void client_thread(void *userdata)
{
	p_socket client = (p_socket) userdata;
    ServerRequest request;
    ServerResponse response;
    uint8_t zero = 0;
    uint8_t *output_buf = (uint8_t *) malloc(MAX_PROCESSING_BLOCK_SIZE * SACD_LSN_SIZE + 1024);
    pb_istream_t input = pb_istream_from_socket(client);
    pb_ostream_t output;
    sacd_reader_t   *sacd_reader = 0;
    scarletbook_handle_t *handle = 0;
    int non_encrypted_disc = 0;
    int checked_for_non_encrypted_disc = 0;
    uint32_t encrypted_start_1 = 0;
    uint32_t encrypted_start_2 = 0;
    uint32_t encrypted_end_1 = 0;
    uint32_t encrypted_end_2 = 0;
    uint32_t block_size = 0;
    uint32_t end_lsn = 0;

	client_connected = 1;
	
	response.data.bytes = (uint8_t *) malloc(MAX_PROCESSING_BLOCK_SIZE * SACD_LSN_SIZE);

    for (;;)
    {
        if (!pb_decode(&input, ServerRequest_fields, &request))
        {
            break;
        }

        response.has_data = false;
        response.data.size = 0;
        response.result = -1;
    
        switch(request.type)
        {
        case ServerRequest_Type_DISC_READ:
            {
                response.type = ServerResponse_Type_DISC_READ;
                if (handle && sacd_reader)
                {
                    int encrypted = 0;
                    end_lsn = request.sector_offset + request.sector_count;
     
                    // check what block ranges are encrypted..
                    if (request.sector_offset < encrypted_start_1)
                    {
                        block_size = min(encrypted_start_1 - request.sector_offset, MAX_PROCESSING_BLOCK_SIZE);
                        encrypted = 0;
                    }
                    else if (request.sector_offset >= encrypted_start_1 && request.sector_offset <= encrypted_end_1)
                    {
                        block_size = min(encrypted_end_1 + 1 - request.sector_offset, MAX_PROCESSING_BLOCK_SIZE);
                        encrypted = 1;
                    }
                    else if (request.sector_offset > encrypted_end_1 && request.sector_offset < encrypted_start_2)
                    {
                        block_size = min(encrypted_start_2 - request.sector_offset, MAX_PROCESSING_BLOCK_SIZE);
                        encrypted = 0;
                    }
                    else if (request.sector_offset >= encrypted_start_2 && request.sector_offset <= encrypted_end_2)
                    {
                        block_size = min(encrypted_end_2 + 1 - request.sector_offset, MAX_PROCESSING_BLOCK_SIZE);
                        encrypted = 1;
                    }
                    block_size = min(end_lsn - request.sector_offset, block_size);

                    response.result = sacd_read_block_raw(sacd_reader, request.sector_offset, block_size, response.data.bytes);
                    response.has_data = response.result > 0;
                    response.data.size = response.result * SACD_LSN_SIZE;
                    
                    // the ATAPI call which returns the flag if the disc is encrypted or not is unknown at this point. 
                    // user reports tell me that the only non-encrypted discs out there are DSD 3 14/16 discs. 
                    // this is a quick hack/fix for these discs.
                    if (encrypted && checked_for_non_encrypted_disc == 0)
                    {
                        switch (handle->area[0].area_toc->frame_format)
                        {
                        case FRAME_FORMAT_DSD_3_IN_14:
                        case FRAME_FORMAT_DSD_3_IN_16:
                            non_encrypted_disc = *(uint64_t *)(response.data.bytes + 16) == 0;
                            break;
                        }

                        checked_for_non_encrypted_disc = 1;
                    }

                    // encrypted blocks need to be decrypted first
                    if (encrypted && non_encrypted_disc == 0)
                    {
                        sacd_decrypt(sacd_reader, response.data.bytes, block_size);
                    }
                }
            }
            break;
        case ServerRequest_Type_DISC_OPEN:
            response.type = ServerResponse_Type_DISC_OPENED;
            sacd_reader = sacd_open("/dev_bdvd");
            if (sacd_reader) 
            {
                handle = scarletbook_open(sacd_reader, 0);
                checked_for_non_encrypted_disc = 0;
                non_encrypted_disc = 0;
                
                if (handle)
                {
                    // set the encryption range
                    if (handle->area[0].area_toc != 0)
                    {
                        encrypted_start_1 = handle->area[0].area_toc->track_start;
                        encrypted_end_1 = handle->area[0].area_toc->track_end;
                    }
                    if (handle->area[1].area_toc != 0)
                    {
                        encrypted_start_2 = handle->area[1].area_toc->track_start;
                        encrypted_end_2 = handle->area[1].area_toc->track_end;
                    }

                    response.result = sacd_authenticate(sacd_reader);
                }
            }
            break;
        case ServerRequest_Type_DISC_CLOSE:
            {
                response.type = ServerResponse_Type_DISC_CLOSED;
                if (handle)
                {
                    scarletbook_close(handle);
                    handle = 0;
                }
                if (sacd_reader)
                {
                    sacd_close(sacd_reader);
                    sacd_reader = 0;
                }
                response.result = 0;
            }
            break;
        case ServerRequest_Type_DISC_SIZE:
            response.type = ServerResponse_Type_DISC_SIZE;
            if (sacd_reader)
            {
                response.result = sacd_get_total_sectors(sacd_reader);
            }
            break;
        }

        // reset output stream
        output = pb_ostream_from_buffer(output_buf, MAX_PROCESSING_BLOCK_SIZE * SACD_LSN_SIZE + 1024);
        
        if (!pb_encode(&output, ServerResponse_fields, &response))
        {
            break;
        }
    
        /* We signal the end of a request with a 0 tag. */
        pb_write(&output, &zero, 1);
        
        // write the output buffer to the opened socket
        {
            bool ret;
            size_t written; 
            ret = (socket_send(client, (char *) output_buf, output.bytes_written, &written, 0, 0) == IO_DONE && written == output.bytes_written);

            if (!ret)
                break;
        }
    
        if (request.type == ServerRequest_Type_DISC_CLOSE)
        {
            break;
        }
    }

    if (handle)
        scarletbook_close(handle);
        
    if (sacd_reader)
        sacd_close(sacd_reader);
    
    free(response.data.bytes);
    free(output_buf);
	
	closesocket((int) *client);
	client_connected = 0;
	
	sysThreadExit(0);
} 
示例#25
0
static ssize_t sacd_net_input_read(sacd_input_t dev, int pos, int blocks, void *buffer)
{
    if (!dev)
    {
        return 0;
    }
    else
    {
        uint8_t output_buf[16];
        ServerRequest request;
        ServerResponse response;
        pb_ostream_t output = pb_ostream_from_buffer(output_buf, sizeof(output_buf));
        pb_istream_t input = pb_istream_from_socket(&dev->fd);
        uint8_t zero = 0;

        request.type = ServerRequest_Type_DISC_READ;
        request.sector_offset = pos;
        request.sector_count = blocks;

        if (!pb_encode(&output, ServerRequest_fields, &request))
        {
            return 0;
        }

        /* We signal the end of request with a 0 tag. */
        pb_write(&output, &zero, 1);

        // write the output buffer to the opened socket
        {
            bool ret;
            size_t written; 
            ret = (socket_send(&dev->fd, (char *) output_buf, output.bytes_written, &written, 0, 0) == IO_DONE && written == output.bytes_written); 

            if (!ret)
                return 0;
        }

#if 0
        response.data.bytes = buffer;
        {
            size_t got; 
            uint8_t *buf_ptr = dev->input_buffer;
            size_t buf_left = blocks * SACD_LSN_SIZE + 16;

            input = pb_istream_from_buffer(dev->input_buffer, MAX_PROCESSING_BLOCK_SIZE * SACD_LSN_SIZE + 1024);

            if (socket_recv(&dev->fd, (char *) buf_ptr, buf_left, &got, MSG_PARTIAL, 0) != IO_DONE)
                return 0;

            while(got > 0 && !pb_decode(&input, ServerResponse_fields, &response))
            {
                buf_ptr += got;
                buf_left -= got;

                if (socket_recv(&dev->fd, (char *) buf_ptr, buf_left, &got, MSG_PARTIAL, 0) != IO_DONE)
                    return 0;

                input = pb_istream_from_buffer(dev->input_buffer, MAX_PROCESSING_BLOCK_SIZE * SACD_LSN_SIZE + 1024);
            }
        }
#else
        response.data.bytes = buffer;
        if (!pb_decode(&input, ServerResponse_fields, &response))
        {
            return 0;
        }
#endif
        if (response.type != ServerResponse_Type_DISC_READ)
        {
            return 0;
        }

        if (response.has_data)
        {
            return response.result;
        }
    }

    return 0;
}
示例#26
0
/* Encode a static array. Handles the size calculations and possible packing. */
static bool checkreturn encode_array(pb_ostream_t *stream, const pb_field_t *field,
                         const void *pData, size_t count, pb_encoder_t func)
{
    size_t i;
    const void *p;
    size_t size;
    
    if (count == 0)
        return true;

    if (PB_ATYPE(field->type) != PB_ATYPE_POINTER && count > field->array_size)
        PB_RETURN_ERROR(stream, "array max size exceeded");
    
    /* We always pack arrays if the datatype allows it. */
    if (PB_LTYPE(field->type) <= PB_LTYPE_LAST_PACKABLE)
    {
        if (!pb_encode_tag(stream, PB_WT_STRING, field->tag))
            return false;
        
        /* Determine the total size of packed array. */
        if (PB_LTYPE(field->type) == PB_LTYPE_FIXED32)
        {
            size = 4 * count;
        }
        else if (PB_LTYPE(field->type) == PB_LTYPE_FIXED64)
        {
            size = 8 * count;
        }
        else
        { 
            pb_ostream_t sizestream = PB_OSTREAM_SIZING;
            p = pData;
            for (i = 0; i < count; i++)
            {
                if (!func(&sizestream, field, p))
                    return false;
                p = (const char*)p + field->data_size;
            }
            size = sizestream.bytes_written;
        }
        
        if (!pb_encode_varint(stream, (uint64_t)size))
            return false;
        
        if (stream->callback == NULL)
            return pb_write(stream, NULL, size); /* Just sizing.. */
        
        /* Write the data */
        p = pData;
        for (i = 0; i < count; i++)
        {
            if (!func(stream, field, p))
                return false;
            p = (const char*)p + field->data_size;
        }
    }
    else
    {
        p = pData;
        for (i = 0; i < count; i++)
        {
            if (!pb_encode_tag_for_field(stream, field))
                return false;

            /* Normally the data is stored directly in the array entries, but
             * for pointer-type string and bytes fields, the array entries are
             * actually pointers themselves also. So we have to dereference once
             * more to get to the actual data. */
            if (PB_ATYPE(field->type) == PB_ATYPE_POINTER &&
                (PB_LTYPE(field->type) == PB_LTYPE_STRING ||
                 PB_LTYPE(field->type) == PB_LTYPE_BYTES))
            {
                if (!func(stream, field, *(const void* const*)p))
                    return false;      
            }
            else
            {
                if (!func(stream, field, p))
                    return false;
            }
            p = (const char*)p + field->data_size;
        }
    }
    
    return true;
}
示例#27
0
/**
 * initialize and open a SACD device or file.
 */
static sacd_input_t sacd_net_input_open(const char *target)
{
    ServerRequest request;
    ServerResponse response;
    sacd_input_t dev = 0;
    const char *err = 0;
    t_timeout tm;
    pb_istream_t input;
    pb_ostream_t output;
    uint8_t zero = 0;

    /* Allocate the library structure */
    dev = (sacd_input_t) calloc(sizeof(*dev), 1);
    if (dev == NULL)
    {
        fprintf(stderr, "libsacdread: Could not allocate memory.\n");
        return NULL;
    }

    dev->input_buffer = (uint8_t *) malloc(MAX_PROCESSING_BLOCK_SIZE * SACD_LSN_SIZE + 1024);
    if (dev->input_buffer == NULL)
    {
        fprintf(stderr, "libsacdread: Could not allocate memory.\n");
        goto error;
    }

    socket_open();

    socket_create(&dev->fd, AF_INET, SOCK_STREAM, 0);
    socket_setblocking(&dev->fd);

    timeout_markstart(&tm); 
    err = inet_tryconnect(&dev->fd, 
            substr(target, 0, strchr(target, ':') - target), 
            atoi(strchr(target, ':') + 1), &tm);
    if (err)
    {
        fprintf(stderr, "Failed to connect\n");
        goto error;
    }
    socket_setblocking(&dev->fd);

    input = pb_istream_from_socket(&dev->fd);

    output = pb_ostream_from_socket(&dev->fd);

    request.type = ServerRequest_Type_DISC_OPEN;

    if (!pb_encode(&output, ServerRequest_fields, &request))
    {
        fprintf(stderr, "Failed to encode request\n");
        goto error;
    }

    /* We signal the end of request with a 0 tag. */
    pb_write(&output, &zero, 1);

    if (!pb_decode(&input, ServerResponse_fields, &response))
    {
        fprintf(stderr, "Failed to decode response\n");
        goto error;
    }

    if (response.result != 0 || response.type != ServerResponse_Type_DISC_OPENED)
    {
        fprintf(stderr, "Response result non-zero or disc opened\n");
        goto error;
    }

    return dev;

error:

    sacd_input_close(dev);

    return 0;
}