~ubuntu-branches/ubuntu/saucy/resiprocate/saucy-proposed

« back to all changes in this revision

Viewing changes to reTurn/AsyncSocketBase.cxx

  • Committer: Package Import Robot
  • Author(s): Daniel Pocock
  • Date: 2012-05-17 19:29:59 UTC
  • Revision ID: package-import@ubuntu.com-20120517192959-vv00m77isztdy64q
Tags: upstream-1.8.2
ImportĀ upstreamĀ versionĀ 1.8.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "AsyncSocketBase.hxx"
 
2
#include "AsyncSocketBaseHandler.hxx"
 
3
#include <boost/bind.hpp>
 
4
#include <rutil/WinLeakCheck.hxx>
 
5
 
 
6
using namespace std;
 
7
 
 
8
#define NO_CHANNEL ((unsigned short)-1)
 
9
 
 
10
namespace reTurn {
 
11
 
 
12
AsyncSocketBase::AsyncSocketBase(asio::io_service& ioService) : 
 
13
  mIOService(ioService),
 
14
  mReceiving(false),
 
15
  mConnected(false),
 
16
  mAsyncSocketBaseHandler(0)
 
17
{
 
18
}
 
19
 
 
20
AsyncSocketBase::~AsyncSocketBase()
 
21
{
 
22
   if(mAsyncSocketBaseHandler) mAsyncSocketBaseHandler->onSocketDestroyed();
 
23
}
 
24
 
 
25
void 
 
26
AsyncSocketBase::send(const StunTuple& destination, boost::shared_ptr<DataBuffer>& data)
 
27
{
 
28
   mIOService.post(boost::bind(&AsyncSocketBase::doSend, shared_from_this(), destination, data, 0));
 
29
}
 
30
 
 
31
void 
 
32
AsyncSocketBase::send(const StunTuple& destination, unsigned short channel, boost::shared_ptr<DataBuffer>& data)
 
33
{
 
34
   mIOService.post(boost::bind(&AsyncSocketBase::doSend, shared_from_this(), destination, channel, data, 0));
 
35
}
 
36
 
 
37
void
 
38
AsyncSocketBase::doSend(const StunTuple& destination, boost::shared_ptr<DataBuffer>& data, unsigned int bufferStartPos)
 
39
{
 
40
   doSend(destination, NO_CHANNEL, data, bufferStartPos);
 
41
}
 
42
 
 
43
void
 
44
AsyncSocketBase::doSend(const StunTuple& destination, unsigned short channel, boost::shared_ptr<DataBuffer>& data, unsigned int bufferStartPos)
 
45
{
 
46
   bool writeInProgress = !mSendDataQueue.empty();
 
47
   if(channel == NO_CHANNEL)
 
48
   {
 
49
      boost::shared_ptr<DataBuffer> empty;
 
50
      mSendDataQueue.push_back(SendData(destination, empty, data, bufferStartPos));
 
51
   }
 
52
   else
 
53
   {
 
54
      // Add Turn Framing
 
55
      boost::shared_ptr<DataBuffer> frame = allocateBuffer(4);
 
56
      channel = htons(channel);
 
57
      memcpy(&(*frame)[0], &channel, 2);
 
58
      unsigned short msgsize = htons((unsigned short)data->size());
 
59
      memcpy(&(*frame)[2], (void*)&msgsize, 2);  // UDP doesn't need size - but shouldn't hurt to send it anyway
 
60
 
 
61
      mSendDataQueue.push_back(SendData(destination, frame, data, bufferStartPos));
 
62
   }
 
63
   if (!writeInProgress)
 
64
   {
 
65
      sendFirstQueuedData();
 
66
   }
 
67
}
 
68
 
 
69
void 
 
70
AsyncSocketBase::handleSend(const asio::error_code& e)
 
71
{
 
72
   if(!e)
 
73
   {
 
74
      onSendSuccess();
 
75
   }
 
76
   else
 
77
   {
 
78
      onSendFailure(e);
 
79
   }
 
80
 
 
81
   // TODO - check if closed here, and if so don't try and send more
 
82
 
 
83
   // Clear this data from the queue and see if there is more data to send
 
84
   mSendDataQueue.pop_front();
 
85
   if (!mSendDataQueue.empty())
 
86
   {
 
87
      sendFirstQueuedData();
 
88
   }
 
89
}
 
90
 
 
91
void 
 
92
AsyncSocketBase::sendFirstQueuedData()
 
93
{
 
94
   std::vector<asio::const_buffer> bufs;
 
95
   if(mSendDataQueue.front().mFrameData.get() != 0) // If we have frame data
 
96
   {
 
97
      bufs.push_back(asio::buffer(mSendDataQueue.front().mFrameData->data(), mSendDataQueue.front().mFrameData->size()));
 
98
   }
 
99
   bufs.push_back(asio::buffer(mSendDataQueue.front().mData->data()+mSendDataQueue.front().mBufferStartPos, mSendDataQueue.front().mData->size()-mSendDataQueue.front().mBufferStartPos));
 
100
   transportSend(mSendDataQueue.front().mDestination, bufs);
 
101
}
 
102
 
 
103
void 
 
104
AsyncSocketBase::receive()
 
105
{
 
106
   mIOService.post(boost::bind(&AsyncSocketBase::doReceive, shared_from_this()));
 
107
}
 
108
 
 
109
void
 
110
AsyncSocketBase::doReceive()
 
111
{
 
112
   if(!mReceiving)
 
113
   {
 
114
      mReceiving=true;
 
115
      mReceiveBuffer = allocateBuffer(RECEIVE_BUFFER_SIZE);
 
116
      transportReceive();
 
117
   }
 
118
}
 
119
 
 
120
void 
 
121
AsyncSocketBase::framedReceive()
 
122
{
 
123
   mIOService.post(boost::bind(&AsyncSocketBase::doFramedReceive, shared_from_this()));
 
124
}
 
125
 
 
126
void
 
127
AsyncSocketBase::doFramedReceive()
 
128
{
 
129
   if(!mReceiving)
 
130
   {
 
131
      mReceiving=true;
 
132
      mReceiveBuffer = allocateBuffer(RECEIVE_BUFFER_SIZE);
 
133
      transportFramedReceive();
 
134
   }
 
135
}
 
136
 
 
137
void 
 
138
AsyncSocketBase::handleReceive(const asio::error_code& e, std::size_t bytesTransferred)
 
139
{
 
140
   mReceiving = false;
 
141
 
 
142
   if(!e)
 
143
   {
 
144
      // Handoff received buffer to appliction, and prepare receive buffer for next call
 
145
      mReceiveBuffer->truncate(bytesTransferred);
 
146
      onReceiveSuccess(getSenderEndpointAddress(), getSenderEndpointPort(), mReceiveBuffer);
 
147
   }
 
148
   else
 
149
   {
 
150
      onReceiveFailure(e);
 
151
   }
 
152
}
 
153
 
 
154
void 
 
155
AsyncSocketBase::close()
 
156
{
 
157
   mIOService.post(boost::bind(&AsyncSocketBase::transportClose, shared_from_this()));
 
158
}
 
159
 
 
160
boost::shared_ptr<DataBuffer>  
 
161
AsyncSocketBase::allocateBuffer(unsigned int size)
 
162
{
 
163
   return boost::shared_ptr<DataBuffer>(new DataBuffer(size));
 
164
}
 
165
 
 
166
} // namespace
 
167
 
 
168
 
 
169
/* ====================================================================
 
170
 
 
171
 Copyright (c) 2007-2008, Plantronics, Inc.
 
172
 All rights reserved.
 
173
 
 
174
 Redistribution and use in source and binary forms, with or without
 
175
 modification, are permitted provided that the following conditions are 
 
176
 met:
 
177
 
 
178
 1. Redistributions of source code must retain the above copyright 
 
179
    notice, this list of conditions and the following disclaimer. 
 
180
 
 
181
 2. Redistributions in binary form must reproduce the above copyright
 
182
    notice, this list of conditions and the following disclaimer in the
 
183
    documentation and/or other materials provided with the distribution. 
 
184
 
 
185
 3. Neither the name of Plantronics nor the names of its contributors 
 
186
    may be used to endorse or promote products derived from this 
 
187
    software without specific prior written permission. 
 
188
 
 
189
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 
190
 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 
191
 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
 
192
 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
 
193
 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 
194
 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
 
195
 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
 
196
 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
 
197
 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
 
198
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
 
199
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
200
 
 
201
 ==================================================================== */
 
202