Example #1
0
void mac_node_set_address(node_t *node, const char *address)
{
    rs_assert(node != NULL);
    rs_assert(address != NULL);

    if (node->mac_info->address != NULL)
        free(node->mac_info->address);

    node->mac_info->address = strdup(address);
}
Example #2
0
bool mac_node_receive(node_t *node, node_t *incoming_node, mac_pdu_t *pdu)
{
    rs_assert(pdu!= NULL);
    rs_assert(node != NULL);

    bool all_ok = event_execute(mac_event_pdu_receive, node, incoming_node, pdu);

    mac_pdu_destroy(pdu);

    return all_ok;
}
Example #3
0
void mac_node_init(node_t *node, char *address)
{
    rs_assert(node!= NULL);
    rs_assert(address != NULL);

    node->mac_info = malloc(sizeof(mac_node_info_t));

    node->mac_info->address = strdup(address);
    node->mac_info->busy = FALSE;
    node->mac_info->error = FALSE;
}
Example #4
0
mac_pdu_t *mac_pdu_create(char *src_address, char *dst_address)
{
    rs_assert(src_address != NULL);
    rs_assert(dst_address != NULL);

    mac_pdu_t *pdu = malloc(sizeof(mac_pdu_t));

    pdu->src_address = strdup(src_address);
    pdu->dst_address = strdup(dst_address);

    pdu->type = -1;
    pdu->sdu = NULL;

    return pdu;
}
Example #5
0
int main(int argc, char** argv)
{
    if (argc != 2)
        return 1;
    
    RSRegion* reg = rs_region_open(argv[1], false);
    rs_assert(reg);

    int x = 0, z = 0;
    for (z = 0; z < 32; z++)
    {
        for (x = 0; x < 32; x++)
        {
            if (rs_region_contains_chunk(reg, x, z))
            {
                const char* comp = get_compression_string(rs_region_get_chunk_compression(reg, x, z));
                printf("(%i, %i) [%i] %i bytes (%s)\n", x, z, rs_region_get_chunk_timestamp(reg, x, z), rs_region_get_chunk_length(reg, x, z), comp);
            }
        }
    }
    
    rs_region_close(reg);

	return 0;
}
Example #6
0
void mac_pdu_set_sdu(mac_pdu_t *pdu, uint16 type, void *sdu)
{
    rs_assert(pdu != NULL);

    pdu->type = type;
    pdu->sdu = sdu;
}
Example #7
0
void mac_node_done(node_t *node)
{
    rs_assert(node != NULL);

    if (node->mac_info != NULL) {
        if (node->mac_info->address != NULL)
            free(node->mac_info->address);

        free(node->mac_info);
        node->mac_info = NULL;
    }
}
Example #8
0
void rs_region_close(RSRegion* self)
{
    rs_return_if_fail(self);
    
    if (self->write && self->cached_writes)
        rs_region_flush(self);
    rs_assert(self->cached_writes == NULL);
    
    rs_free(self->path);
    if (self->map)
        munmap(self->map, self->fsize);
    close(self->fd);
    rs_free(self);
}
Example #9
0
void _rs_error_log(bool error, const char* filename, unsigned int line, const char* func, const char* str, ...)
{
    va_list ap;
    va_start(ap, str);
    
    rs_assert(filename != NULL);
    rs_assert(func != NULL);
    rs_assert(str != NULL);
    
    if (error)
        printf("ERROR: ");
    else
        printf("CRITICAL: ");
    
    printf("%s:%i (%s) ", filename, line, func);
    vprintf(str, ap);
    printf("\n");
    
    va_end(ap);
    
    if (error)
        exit(1);
}
Example #10
0
int main(int argc, char** argv)
{
    if (argc != 3)
    {
        fprintf(stderr, "usage: %s [input] [output]\n", argv[0]);
        return 1;
    }
    
    RSRegion* reg = rs_region_open(argv[1], false);
    RSRegion* out = rs_region_open(argv[2], true);
    rs_assert(reg);
    rs_assert(out);

    int x = 0, z = 0;
    for (z = 0; z < 32; z++)
    {
        for (x = 0; x < 32; x++)
        {
            if (INSIDE_EXMAPLE(x, z) && rs_region_contains_chunk(reg, x, z))
            {
                void* data = rs_region_get_chunk_data(reg, x, z);
                uint32_t len = rs_region_get_chunk_length(reg, x, z);
                RSCompressionType comp = rs_region_get_chunk_compression(reg, x, z);
                uint32_t timestamp = rs_region_get_chunk_timestamp(reg, x, z);
                
                rs_region_set_chunk_data_full(out, x, z, data, len, comp, timestamp);
            }
        }
    }
    
    rs_region_flush(out);
    rs_region_close(out);
    rs_region_close(reg);

	return 0;
}
Example #11
0
bool mac_node_send(node_t *node, node_t *outgoing_node, uint16 type, void *sdu)
{
    rs_assert(node != NULL);

    mac_pdu_t *mac_pdu = mac_pdu_create(node->mac_info->address, outgoing_node != NULL ? outgoing_node->mac_info->address : "");
    mac_pdu_set_sdu(mac_pdu, type, sdu);

    if (!event_execute(mac_event_pdu_send, node, outgoing_node, mac_pdu)) {
        mac_pdu->sdu = NULL;
        mac_pdu_destroy(mac_pdu);

        return FALSE;
    }

    return TRUE;
}
Example #12
0
void rs_region_set_chunk_data_full(RSRegion* self, uint8_t x, uint8_t z, void* data, uint32_t len, RSCompressionType enc, uint32_t timestamp)
{
    rs_return_if_fail(self);
    rs_return_if_fail(x < 32 && z < 32);
    rs_return_if_fail(self->write);
    
    /* first, check if there's a cached write already, and clear it if
     * needed
     */
    RSList* cell = self->cached_writes;
    for (; cell != NULL; cell = cell->next)
    {
        struct ChunkWrite* write = cell->data;
        rs_assert(write);
        
        if (write->x == x && write->z == z)
            break;
    }
    
    if (cell)
    {
        struct ChunkWrite* write = cell->data;
        rs_free(write->data);
        rs_free(write);
        self->cached_writes = rs_list_remove(self->cached_writes, cell);
    }
    
    if (enc == RS_AUTO_COMPRESSION)
        enc = rs_get_compression_type(data, len);
    
    /* copy the data */
    void* data_copy = memcpy(rs_malloc(len), data, len);
    
    /* now, create a new write struct */
    struct ChunkWrite* job = rs_new0(struct ChunkWrite, 1);
    job->x = x;
    job->z = z;
    job->data = data_copy;
    job->length = len;
    job->encoding = enc;
    job->timestamp = timestamp;
    
    self->cached_writes = rs_list_push(self->cached_writes, job);
}
Example #13
0
mac_pdu_t *mac_pdu_duplicate(mac_pdu_t *pdu)
{
    rs_assert(pdu != NULL);

    mac_pdu_t *new_pdu = malloc(sizeof(mac_pdu_t));

    new_pdu->src_address = strdup(pdu->src_address);
    new_pdu->dst_address = strdup(pdu->dst_address);

    new_pdu->type = pdu->type;

    switch (pdu->type) {
        case MAC_TYPE_IP:
            new_pdu->sdu = ip_pdu_duplicate(pdu->sdu);

            break;
    }

    return new_pdu;
}
Example #14
0
void mac_pdu_destroy(mac_pdu_t *pdu)
{
    rs_assert(pdu != NULL);

    if (pdu->dst_address != NULL)
        free(pdu->dst_address);

    if (pdu->src_address != NULL)
        free(pdu->src_address);

    if (pdu->sdu != NULL) {
        switch (pdu->type) {

            case MAC_TYPE_IP :
                ip_pdu_destroy(pdu->sdu);
                break;

        }
    }

    free(pdu);
}
Example #15
0
/* writes are cached until this is called */
void rs_region_flush(RSRegion* self)
{
    rs_return_if_fail(self);
    
    RSList* cell;
    
    if (self->write && self->cached_writes)
    {
        /* check to see if this is a brand-new file */
        if (self->map == NULL)
        {
            /* it is! so we have to write everything */
            
            /* first, figure out how big the file needs to be */
            uint32_t final_size = 0;
            cell = self->cached_writes;
            for (; cell != NULL; cell = cell->next)
            {
                struct ChunkWrite* write = cell->data;
                rs_assert(write);
                
                /* be sure to account for extra size/compression info */
                final_size += write->length + 4 + 1;
                
                /* force size to be on sector boundaries */
                if (final_size % 4096 > 0)
                    final_size += (4096 - final_size % 4096);
            }
            
            /* add on 4096 * 2 to account for location/timestamp headers */
            final_size += 4096 * 2;
            
            rs_assert(final_size % 4096 == 0);
            
            /* resize the file, and remap */
            if (ftruncate(self->fd, final_size) < 0)
            {
                rs_error("file resize failed"); /* FIXME */
            }
            self->fsize = final_size;
            self->map = mmap(NULL, final_size, PROT_READ | PROT_WRITE, MAP_SHARED, self->fd, 0);
            if (self->map == MAP_FAILED)
            {
                rs_error("remap failed"); /* FIXME */
            }
            
            self->locations = (struct ChunkLocation*)(self->map);
            self->timestamps = (uint32_t*)(self->map + 4096);
            
            /* zero out the headers */
            memset(self->map, 0, 4096 * 2);
            
            /* now, we can iterate through the writes and copy them in */
            uint32_t cur_sector = 2;
            for (cell = self->cached_writes; cell != NULL; cell = cell->next)
            {
                struct ChunkWrite* write = cell->data;
                rs_assert(write);
                
                unsigned int i = write->x + write->z*32;
                
                /* handle chunk clears */
                if (write->length == 0)
                {
                    self->locations[i].offset = 0;
                    self->locations[i].sector_count = 0;
                    self->timestamps[i] = 0;
                    continue;
                }
                
                uint8_t sector_count = (write->length + 4 + 1) / 4096;
                if ((write->length + 4 + 1) % 4096 > 0)
                    sector_count++;
                
                self->locations[i].offset = rs_endian_uint24(cur_sector);
                self->locations[i].sector_count = sector_count;
                self->timestamps[i] = rs_endian_uint32(write->timestamp);
                
                /* convert compression types */
                uint8_t enc = 0;
                switch (write->encoding)
                {
                case RS_GZIP:
                    enc = 1; break;
                case RS_ZLIB:
                    enc = 2; break;
                default:
                    rs_return_if_reached(); /* unhandled compression type */
                };
                
                /* write the pre-data header (carefully) */
                void* dest = _rs_region_get_data(self, write->x, write->z);
                ((uint32_t*)dest)[0] = rs_endian_uint32(write->length + 1);
                ((uint8_t*)dest)[4] = enc;
                
                /* write out the data */
                rs_assert(write->data);
                memcpy(dest + 4 + 1, write->data, write->length);
                
                /* move along */
                cur_sector += sector_count;
            }
        } else {
            /* there's already header info in place, we just need to
             * shuffle things around and update it
             */
            
            /* for now, this is unsupported */
            rs_return_if_reached();
        }
    }
    
    /* clear the cached writes */
    cell = self->cached_writes;
    for (; cell != NULL; cell = cell->next)
    {
        struct ChunkWrite* write = cell->data;
        rs_free(write->data);
        rs_free(write);
    }
    rs_list_free(self->cached_writes);
    self->cached_writes = NULL;
    
    /* sync the memory */
    if (self->map && msync(self->map, self->fsize, MS_SYNC) < 0)
    {
        rs_error("sync failed"); /* FIXME */
    }
}