Statistics
| Branch: | Revision:

grapes / src / ChunkTrading / chunk_signaling.c @ f217ce38

History | View | Annotate | Download (5.58 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

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

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

    
42
#define SIG_META_LEN 1024
43
#define SIG_BUF_LEN 2048
44

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

    
53

    
54
int chunkSignalingInit(struct nodeID *myID)
55
{
56
  return 1;
57
}
58

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

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

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

    
105
  return 1;
106
}
107

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

    
117
  sigmex = malloc(SIG_META_LEN);
118
  if (!sigmex) {
119
    fprintf(stderr, "Error allocating meta-buffer\n");
120

    
121
    return -1;
122
  }
123
  sigmex->type = type;
124
  sigmex->max_deliver = max_deliver;    
125
  sigmex->trans_id = trans_id;
126
  sigmex->third_peer = 0;
127
  meta_len = sizeof(*sigmex) - 1;
128
  if (owner_id) {
129
    meta_len += nodeid_dump(&sigmex->third_peer, owner_id, SIG_META_LEN - meta_len);
130
  }
131
  buff = malloc(SIG_BUF_LEN);
132
  if (!buff) {
133
    fprintf(stderr, "Error allocating buffer\n");
134
    free(sigmex);
135

    
136
    return -1;
137
  }
138

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

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

    
152
  return 1;
153
}
154

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

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

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

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

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

    
184
int sendAck(const struct nodeID *localID, const struct nodeID *to, struct chunkID_set *cset, uint16_t trans_id)
185
{
186
    return sendSignaling(localID, MSG_SIG_ACK, to, NULL, cset, 0, trans_id);
187
}
188

    
189
int requestBufferMap(const struct nodeID *localID, const struct nodeID *to, const struct nodeID *owner,
190
                     uint16_t trans_id)
191
{
192
  return sendSignaling(localID, MSG_SIG_BMREQ, to, (!owner?localID:owner), NULL,
193
                       0, trans_id);
194
}