add HLH_Ref
[HLH_utils.git] / HLH_UDPSock.cpp
blobef6e3b4b8fbd7f63788f7058c27a16f740dbfaef
1 /*******************************************************************************
2 * File Name : HLH_UDPSock.cpp
3 *
4 * Author : Henry He
5 * Created Time : 2009-10-10 16:36:17
6 * Description :
7 ******************************************************************************/
12 /*******************************************************************************
13 * Desc : Includes Files
14 ******************************************************************************/
16 #include "HLH_utils/HLH_UDPSock.h"
19 /*******************************************************************************
20 * Desc : Macro Definations
21 ******************************************************************************/
24 /*******************************************************************************
25 * Desc : Type Definations
26 ******************************************************************************/
29 /*******************************************************************************
30 * Desc : Global Variables
31 ******************************************************************************/
34 /*******************************************************************************
35 * Desc : File Variables
36 ******************************************************************************/
43 /******************************************************************************
44 * Desc : Member Functions
45 ******************************************************************************/
51 /******************************************************************************
52 * Func : HLH_UDPSock::HLH_UDPSock
53 * Desc : Constuctor of HLH_UDPSock
54 * Args : NONE
55 * Outs : NONE
56 ******************************************************************************/
57 HLH_UDPSock::HLH_UDPSock ()
59 m_zhmMutex.Init ();
60 m_bCreated = false;
64 /******************************************************************************
65 * Func : HLH_UDPSock::~HLH_UDPSock
66 * Desc : Deconstructor of HLH_UDPSock
67 * Args : NONE
68 * Outs : NONE
69 ******************************************************************************/
70 HLH_UDPSock::~HLH_UDPSock ()
72 Destroy ();
79 /******************************************************************************
80 * Desc : Operations
81 ******************************************************************************/
87 /******************************************************************************
88 * Func : HLH_UDPSock::Create
89 * Desc : Create UDP socket and bind it to zhsBindAddr,
90 * then create thread to handle receive event
91 * Args : zhsBindAddr address of bindding
92 * Outs : If success return 0, otherwise return error code.
93 ******************************************************************************/
94 int HLH_UDPSock::Create (const HLH_SockAddr &zhsBindAddr)
97 int nRetVal;
99 // Lock before process
100 m_zhmMutex.Lock ();
102 // Check if this instance created
103 if (m_bCreated) {
104 // Unlock this instance
105 m_zhmMutex.Unlock ();
107 HLH_DEBUG ( HLH_DEBUG_MAIN, ("already created") );
108 return HLH_UDPSOCK_ERR_ALREADY_CREATED;
111 // Init supper class HLH_Sock first
112 nRetVal = HLH_Sock::Create (HLH_SOCK_TYPE_DGRAM, zhsBindAddr, false);
113 if (nRetVal < 0) {
114 HLH_DEBUG ( HLH_DEBUG_MAIN, ("create HLH_Sock failed") );
115 goto fail;
118 // Clear the receive handler list
119 m_slRecvHandlerList.clear ();
121 // Start receive thread
122 nRetVal = m_zhtRecvThread.Start (RecvThreadFunc, this);
123 if (nRetVal < 0) {
124 HLH_DEBUG ( HLH_DEBUG_MAIN, ("start received thread failed") );
125 goto fail;
128 // Notify that this instance created
129 m_bCreated = true;
130 m_bConnected = false;
132 // Unlock after process
133 m_zhmMutex.Unlock ();
135 return 0;
137 fail:
139 // Close the socket if needed
140 if ( HLH_Sock::IsCreated () ) {
141 HLH_Sock::Destroy ();
144 // Unlock after process
145 m_zhmMutex.Unlock ();
147 return HLH_UDPSOCK_ERR_CANT_CREATE;
151 /******************************************************************************
152 * Func : HLH_UDPSock::Destroy
153 * Desc : Destroy this UDP socket
154 * Args : NONE
155 * Outs : NONE
156 ******************************************************************************/
157 void HLH_UDPSock::Destroy ()
159 // Stop receive thread
160 m_zhtRecvThread.Stop ();
162 // Lock this instance
163 m_zhmMutex.Lock ();
166 // Check if this instance created
167 if (!m_bCreated) {
168 // Unlock this instance
169 m_zhmMutex.Unlock ();
171 return;
174 // Clear receiver list
175 m_slRecvHandlerList.clear ();
177 // Destroy this socket
178 HLH_Sock::Destroy ();
180 m_bCreated = false;
181 m_bConnected = false;
183 // Unlock this instance
184 m_zhmMutex.Unlock ();
188 /******************************************************************************
189 * Func : HLH_UDPSock::IsCreated
190 * Desc : Whether this instance created
191 * Args : NONE
192 * Outs : If success return 0, otherwise return error code.
193 ******************************************************************************/
194 bool HLH_UDPSock::IsCreated ()
196 bool bCreated;
198 m_zhmMutex.Lock ();
199 bCreated = m_bCreated;
200 m_zhmMutex.Unlock ();
202 return bCreated;
208 /******************************************************************************
209 * Func : HLH_UDPSock::AddRecvHandler
210 * Desc : Add receive handler to this socket
211 * Args : zorOnRecv Funtion to handle receive event
212 * pvOnRecvParam Parameter to \c zorOnRecv ()
213 * Outs : if success, return 0, otherwise return error code
214 ******************************************************************************/
215 void HLH_UDPSock::AddRecvHandler (OnRecvFunc zorOnRecv, void *pvOnRecvParam)
218 RecvHandler zrhRecvHandler;
220 // Lock before process
221 m_zhmMutex.Lock ();
223 // Put this handler into the list
224 zrhRecvHandler.m_zorOnRecv = zorOnRecv;
225 zrhRecvHandler.m_pvOnRecvParam = pvOnRecvParam;
227 m_slRecvHandlerList.push_back (zrhRecvHandler);
229 // Lock after process
230 m_zhmMutex.Unlock ();
234 /******************************************************************************
235 * Func : HLH_UDPSock::DelRecvHandler
236 * Desc : Delete receive handler from receive handler list
237 * Args : zorOnRecv Funtion to handle receive event
238 * pvOnRecvParam Parameter to \c zorOnRecv ()
239 * Outs : NONE
240 ******************************************************************************/
241 void HLH_UDPSock::DelRecvHandler (OnRecvFunc zorOnRecv, void *pvOnRecvParam)
244 RecvHandler zrhRecvHandler;
246 // Lock before process
247 m_zhmMutex.Lock ();
249 // Remove this receiver handler
250 zrhRecvHandler.m_zorOnRecv = zorOnRecv;
251 zrhRecvHandler.m_pvOnRecvParam = pvOnRecvParam;
253 m_slRecvHandlerList.remove (zrhRecvHandler);
255 // Unlock after process
256 m_zhmMutex.Unlock ();
260 /******************************************************************************
261 * Func : HLH_UDPSock::ClearRecvHandlerList
262 * Desc : Clear the receive handler list
263 * Args : NONE
264 * Outs : NONE
265 ******************************************************************************/
266 void HLH_UDPSock::ClearRecvHandlerList ()
268 // Lock before process
269 m_zhmMutex.Lock ();
271 // Clear the receive handler list
272 m_slRecvHandlerList.clear ();
274 // Unlock after process
275 m_zhmMutex.Unlock ();
278 /******************************************************************************
279 * Func : HLH_UDPSock::__RecvThreadFunc
280 * Desc : Thread function to call receive handler functions
281 * Args : zhtRecvThread Thread that call \c RecvThreadFunc ()
282 * Outs :
283 ******************************************************************************/
284 void HLH_UDPSock::__RecvThreadFunc ( HLH_Thread &zhtRecvThread )
287 int nRetVal;
289 UINT32 unLen;
290 UINT32 unPollType;
291 HLH_Time zhtPollTime;
293 UINT8 acRecvBuf [HLH_UDPSOCK_MAX_RECEIVE_LENGTH];
294 HLH_SockAddr zhsPeerAddr;
295 HLH_SockAddr zhsConnAddr;
297 std::list<RecvHandler>::iterator slIt;
299 // Signal to zhtRecvThread that this thread functions runned
300 zhtRecvThread.ThreadStarted ();
304 // Can't process socket not created
305 if ( !IsCreated () ) {
306 HLH_DEBUG ( HLH_DEBUG_MAIN, ("not created") );
307 return;
311 do {
313 // Poll for receive events
314 unPollType = HLH_SOCK_POLL_READ;
315 zhtPollTime.SetTime (HLH_UDPSOCK_DEFAULT_POLLWAIT_SECONDS, 0);
317 nRetVal = PollWait (unPollType, zhtPollTime);
319 // If there is any data received
320 if ( nRetVal > 0 ) {
322 // Receive the data
323 nRetVal = RecvFrom (acRecvBuf, sizeof(acRecvBuf), zhsPeerAddr);
324 if (nRetVal < 0) {
325 // XXX: do nothing if receive error
326 goto check_stop;
328 unLen = nRetVal;
330 // If connected, check the source ip, otherwise accept all
331 nRetVal = GetConnectAddr (zhsConnAddr);
332 if ( nRetVal < 0 || zhsConnAddr == zhsPeerAddr ) {
333 // Call receive handler call back function
334 for ( slIt = m_slRecvHandlerList.begin ();
335 slIt != m_slRecvHandlerList.end (); slIt ++ ) {
336 slIt->m_zorOnRecv (slIt->m_pvOnRecvParam, acRecvBuf, unLen, zhsPeerAddr);
338 } else {
339 HLH_DEBUG ( HLH_DEBUG_MAIN, ("ignore package") );
344 check_stop:
345 // Check if stop request
346 if ( zhtRecvThread.IsStopping () ) {
347 return;
350 } while (1);
355 /******************************************************************************
356 * Func : HLH_UDPSock::RecvThreadFunc
357 * Desc : Wrapper of __RecvThreadFunc
358 * Args : zhtRecvThread Thread that call this function
359 * Outs : Always return NULL.
360 ******************************************************************************/
361 void * HLH_UDPSock::RecvThreadFunc (HLH_Thread &zhtRecvThread, void *pvThis)
363 ASSERT (pvThis != NULL);
364 ( (HLH_UDPSock*) pvThis )->__RecvThreadFunc (zhtRecvThread);
365 return NULL;
369 /******************************************************************************
370 * Func : HLH_UDPSock::Connect
371 * Desc : Reload of HLH_Sock::Connect ()
372 * Args : zhsPeekAddr address to connect
373 * Outs : if success, return 0, otherwise return error code
374 ******************************************************************************/
375 int HLH_UDPSock::Connect (const HLH_SockAddr &zhsSockAddr)
377 int nRetVal;
379 // Lock this instance
380 m_zhmMutex.Lock ();
382 nRetVal = HLH_Sock::Connect (zhsSockAddr);
383 if (nRetVal < 0) {
384 goto failed;
387 // Notify that this instance is created
388 m_bConnected = true;
389 m_zhsConnectAddr = zhsSockAddr;
391 // Unlock this instance
392 m_zhmMutex.Unlock ();
394 return 0;
396 failed:
397 // Unlock this instance
398 m_zhmMutex.Unlock ();
400 return HLH_UDPSOCK_ERR_FAILED;
403 /******************************************************************************
404 * Func : HLH_UDPSock::GetConnectAddr
405 * Desc : Get the address of peer if connected
406 * Args : zhsConnectAddr Space to save the address get
407 * Outs : If success return 0, otherwise return error code.
408 ******************************************************************************/
409 int HLH_UDPSock::GetConnectAddr (HLH_SockAddr & zhsConnectAddr)
411 // Lock this instance
412 m_zhmMutex.Lock ();
413 if (!m_bCreated || !m_bConnected) {
414 // Unlock this instance
415 m_zhmMutex.Unlock ();
416 HLH_DEBUG ( HLH_DEBUG_UTILS, ("not connected") );
417 return HLH_UDPSOCK_ERR_NOT_CREATED;
420 zhsConnectAddr = m_zhsConnectAddr;
422 // Unlock this instance
423 m_zhmMutex.Unlock ();
425 return 0;