Mercurial > cgi-bin > hgwebdir.cgi > VMS > C_Libraries > BestEffortMessaging
view LossyCom.c @ 2:b6dd31dbab8c
Receiving only messages for the current endpoint
| author | Merten Sach <msach@mailbox.tu-berlin.de> |
|---|---|
| date | Mon, 12 Mar 2012 18:35:10 +0100 |
| parents | 826448e34e80 |
| children | 5c0fb7c519d7 |
line source
2 /*
3 * For a detailed description see header file.
4 */
6 #include "LossyCom.h"
8 #include "VMS_Implementations/VMS_impl/vmalloc.h"
10 /*
11 * Initializes the central exchange structure.
12 * Allocates memory to fit the number of endpoints.
13 * Returns NULL if an error occurs.
14 */
15 lossyCom__exchange_t* lossyCom__initialize(uint16_t numEndpoints)
16 {
17 lossyCom__exchange_t* exchange;
19 exchange = VMS_WL__malloc(sizeof(lossyCom__exchange_t));
20 if(exchange == NULL)
21 return NULL;
23 exchange->triggerCounter = 0;
24 exchange->numEndpoints = numEndpoints;
25 exchange->outboxArray = VMS_WL__malloc(sizeof(lossyCom__msg_t)*numEndpoints);
26 if(exchange->outboxArray == NULL){
27 VMS_WL__free(exchange);
28 return NULL;
29 }
31 return exchange;
32 }
34 /*
35 * Connects the local endpoint to the central exchange structure.
36 * This registers a message handler that handles all the incomming messages.
37 * Also an endpointID is set this ID has to be between 0 and total number of
38 * endpoints-1 and the number has to be unique.
39 */
40 void lossyCom__initialize_endpoint(lossyCom__endpoint_t* localEndpoint,
41 lossyCom__exchange_t* centralExchange,
42 lossyCom__endpointID_t endpointID,
43 lossyCom__msgHandler msgHandler,
44 void* msgHandlerData)
45 {
46 localEndpoint->localTriggerCopy = 0;
47 localEndpoint->endpointID = endpointID;
48 localEndpoint->centralExchange = centralExchange;
49 localEndpoint->msgHandler = msgHandler;
50 localEndpoint->msgHandlerData = msgHandlerData;
51 }
53 /*
54 * This broadcasts a message to all connected receivers
55 */
56 void inline lossyCom__broadcastMsg(lossyCom__endpoint_t* localEndpoint,
57 lossyCom__msgBody_t msg)
58 {
59 lossyCom__sendMsg(localEndpoint,
60 BROADCAST_ID,
61 msg);
62 }
64 /*
65 * This sends a message another endpoint. Again it is not guaranteed that the
66 * message is received. But in most cases it will.
67 */
68 void inline lossyCom__sendMsg(lossyCom__endpoint_t* localEndpoint,
69 lossyCom__endpointID_t receiverEndpointID,
70 lossyCom__msgBody_t msg)
71 {
72 lossyCom__msg_t msgDraft;
73 uint16_t triggerCopy;
75 //build message
76 msgDraft = (0 | msg);
77 msgDraft |= ((lossyCom__msg_t)receiverEndpointID << ENDPOINT_ID_SHIFT);
79 triggerCopy = localEndpoint->centralExchange->triggerCounter +1;
80 msgDraft |= ((lossyCom__msg_t)triggerCopy << TRIGGER_SHIFT);
82 //write msg to central exchange
83 localEndpoint->centralExchange->outboxArray[localEndpoint->endpointID] =
84 msgDraft;
86 localEndpoint->centralExchange->triggerCounter = triggerCopy;
87 //printf("send updated trigger to %d\n", triggerCopy);
88 }
90 void inline lossyCom__receiveMsg(lossyCom__endpoint_t* localEndpoint)
91 {
92 uint16_t currentTriggerCopy;
93 lossyCom__endpointID_t senderEndpointID;
94 lossyCom__endpointID_t receiverID;
95 lossyCom__msg_t msgCopy;
96 uint16_t msgTrigger;
97 lossyCom__msgBody_t msgBody;
99 senderEndpointID = 0;
100 currentTriggerCopy = localEndpoint->centralExchange->triggerCounter;
102 //new message arrived if trigger counter is higher than the last time read
103 if(currentTriggerCopy > localEndpoint->localTriggerCopy)
104 {
105 while(senderEndpointID < localEndpoint->centralExchange->numEndpoints)
106 {
107 if(senderEndpointID != localEndpoint->endpointID)
108 {
109 msgCopy = localEndpoint->centralExchange->outboxArray[senderEndpointID];
110 msgTrigger = 0xFFFF & (msgCopy >> TRIGGER_SHIFT);
111 // check if the message is new (msg trigger > archived trigger)
112 // and already valid (msgTrigger <= currentTriggerCopy)
113 if(msgTrigger > localEndpoint->localTriggerCopy &&
114 msgTrigger <= currentTriggerCopy)
115 {
116 //printf("receive search until %d \n", currentTriggerCopy);
117 //let the message handler parse the message
118 msgBody = 0xFFFFFFFF & msgCopy;
119 receiverID = 0xFFFF & (msgCopy >> ENDPOINT_ID_SHIFT);
120 //only receive broadcast and p2p for own receiverID
121 if(receiverID == BROADCAST_ID ||
122 receiverID == localEndpoint->endpointID)
123 {
124 (*(localEndpoint->msgHandler))(senderEndpointID,
125 msgBody,
126 localEndpoint->msgHandlerData);
127 }
128 }
129 }
130 senderEndpointID++;
131 }
132 }
133 //save last TriggerCounter of last parsed Msg
134 localEndpoint->localTriggerCopy = currentTriggerCopy;
135 }
