Statistics
| Branch: | Revision:

grapes / som / ChunkTrading / chunk_signaling.c @ 8576a795

History | View | Annotate | Download (5.35 KB)

1
/*
2
 *  Copyright (c) 2009 Alessandro Russo.
3
 *
4
 *  This is free software;
5
 *  see lgpl-2.1.txt
6
 *
7
 * Chunk Signaling API - Higher Abstraction
8
 *
9
 * The Chunk Signaling HA provides a set of primitives for chunks signaling negotiation with other peers, in order to collect information for the effective chunk exchange with other peers. <br>
10
 * This is a part of the Data Exchange Protocol which provides high level abstraction for chunks' negotiations, like requesting and proposing chunks.
11
 *
12
 */
13

    
14
#include <stdio.h>
15
#include <stdint.h>
16
#include <string.h>
17
#include <stdlib.h>
18
#include <arpa/inet.h>
19

    
20
#include "chunk.h"
21
#include "msg_types.h"
22
#include "chunkidset.h"
23
#include "trade_sig_la.h"
24
#include "trade_sig_ha.h"
25
#include "int_coding.h"
26

    
27
//Type of signaling message
28
//Request a ChunkIDSet
29
#define MSG_SIG_REQ 1
30
//Diliver a ChunkIDSet (reply to a request)
31
#define MSG_SIG_DEL 2
32
//Offer a ChunkIDSet
33
#define MSG_SIG_OFF 4
34
//Accept a ChunkIDSet (reply to an offer)
35
#define MSG_SIG_ACC 6
36
//Receive the BufferMap
37
#define MSG_SIG_BMOFF 10
38
//Request the BufferMap
39
#define MSG_SIG_BMREQ 12
40

    
41
struct sig_nal {
42
    uint8_t type;//type of signal.
43
    uint8_t max_deliver;//Max number of chunks to deliver.
44
    //uint16_t cb_size;//size of the buffer map to send
45
    uint16_t trans_id;//future use...
46
    uint8_t third_peer;//for buffer map exchange from other peers, just the first byte!
47
} __attribute__((packed));
48

    
49
//set the local node ID
50
static struct nodeID *localID;
51

    
52
int chunkSignalingInit(struct nodeID *myID)
53
{
54
    if(!myID)
55
        return -1;
56
    localID = myID;
57
    return 1;
58
}
59

    
60
int parseSignaling(uint8_t *buff, int buff_len, struct nodeID **owner_id,
61
                   struct chunkID_set **cset, int *max_deliver, int *trans_id,
62
                   enum signaling_type *sig_type)
63
{
64
    int meta_len = 0;
65
    void *meta;
66

    
67
    *cset = decodeChunkSignaling(&meta, &meta_len, buff, buff_len);
68
    if (meta_len) {
69
        struct sig_nal *signal = meta;
70
        int dummy;
71

    
72
        switch (signal->type) {
73
            case MSG_SIG_OFF:
74
                *sig_type = sig_offer;
75
                break;
76
            case MSG_SIG_ACC:
77
                *sig_type = sig_accept;
78
                break;
79
            case MSG_SIG_REQ:
80
                *sig_type = sig_request;
81
                break;
82
            case MSG_SIG_DEL:
83
                *sig_type = sig_deliver;
84
                break;
85
            case MSG_SIG_BMOFF:
86
                *sig_type = sig_send_buffermap;
87
                break;
88
            case MSG_SIG_BMREQ:
89
                *sig_type = sig_request_buffermap;
90
                break;
91
            default:
92
                fprintf(stderr, "Error invalid signaling message: type %d\n", signal->type);
93
                return -1;
94
        }
95
        *max_deliver = signal->max_deliver;
96
        *trans_id = signal->trans_id;
97
        *owner_id = (meta_len > sizeof(struct sig_nal) - 1 ? nodeid_undump(&(signal->third_peer), &dummy) : NULL);
98
        free(meta);
99
    } else {
100
        return -1;
101
    }
102

    
103
    return 1;
104
}
105

    
106
static int sendSignaling(int type, struct nodeID *to_id,
107
                         const struct nodeID *owner_id,
108
                         const struct chunkID_set *cset, int max_deliver,
109
                         int trans_id)
110
{
111
    int buff_len, meta_len, msg_len;
112
    uint8_t *buff;
113
    struct sig_nal *sigmex;
114

    
115
    sigmex = malloc(1024);
116
    if (!sigmex) {
117
        fprintf(stderr, "Error allocating meta-buffer\n");
118

    
119
        return -1;
120
    }
121
    sigmex->type = type;
122
    sigmex->max_deliver = max_deliver;    
123
    sigmex->trans_id = trans_id;
124
    sigmex->third_peer = 0;
125
    meta_len = sizeof(*sigmex) - 1;
126
    if (owner_id) {
127
        meta_len += nodeid_dump(&sigmex->third_peer, owner_id);
128
    }
129
    buff_len = 1 + (cset ? chunkID_set_size(cset):0) * 4 + 12 + meta_len; // this should be enough
130
    buff = malloc(buff_len);
131
    if (!buff) {
132
        fprintf(stderr, "Error allocating buffer\n");
133
        free(sigmex);
134

    
135
        return -1;
136
    }
137

    
138
    buff[0] = MSG_TYPE_SIGNALLING;
139
    msg_len = 1 + encodeChunkSignaling(cset, sigmex, meta_len, buff+1, buff_len-1);
140
    free(sigmex);
141
    if (msg_len <= 0) {
142
      fprintf(stderr, "Error in encoding chunk set for sending a buffermap\n");
143
      free(buff);
144

    
145
      return -1;
146
    } else {
147
      send_to_peer(localID, to_id, buff, msg_len);
148
    }    
149
    free(buff);
150

    
151
    return 1;
152
}
153

    
154
int requestChunks(struct nodeID *to, const ChunkIDSet *cset,
155
                  int max_deliver, int trans_id)
156
{
157
    return sendSignaling(MSG_SIG_REQ, to, NULL, cset, max_deliver, trans_id);
158
}
159

    
160
int deliverChunks(struct nodeID *to, ChunkIDSet *cset, int trans_id)
161
{
162
    return sendSignaling(MSG_SIG_DEL, to, NULL, cset, 0, trans_id);
163
}
164

    
165
int offerChunks(struct nodeID *to, struct chunkID_set *cset,
166
                int max_deliver, int trans_id)
167
{
168
    return sendSignaling(MSG_SIG_OFF, to, NULL, cset, max_deliver, trans_id);
169
}
170

    
171
int acceptChunks(struct nodeID *to, struct chunkID_set *cset, int trans_id)
172
{
173
    return sendSignaling(MSG_SIG_ACC, to, NULL, cset, 0, trans_id);
174
}
175

    
176
int sendBufferMap(struct nodeID *to, const struct nodeID *owner,
177
                  struct chunkID_set *bmap, int trans_id)
178
{
179
    return sendSignaling(MSG_SIG_BMOFF, to, (!owner ? localID : owner), bmap,
180
                         0, trans_id);
181
}
182

    
183
int requestBufferMap(struct nodeID *to, const struct nodeID *owner,
184
                     int trans_id)
185
{
186
    return sendSignaling(MSG_SIG_BMREQ, to, (!owner?localID:owner), NULL,
187
                         0, trans_id);
188
}