|
1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #include "app_protintf_udp.h" |
|
17 #include <in_sock.h> |
|
18 |
|
19 using namespace Messages; |
|
20 |
|
21 |
|
22 CApplicationProtocolIntfBase* CApplicationProtocolIntfUdp::NewL ( TInt aPort ) |
|
23 { |
|
24 CApplicationProtocolIntfUdp* self = new (ELeave)CApplicationProtocolIntfUdp( aPort ); |
|
25 return self; |
|
26 } |
|
27 |
|
28 CApplicationProtocolIntfUdp::CApplicationProtocolIntfUdp ( TInt aPort ) |
|
29 : CApplicationProtocolIntfBase ( aPort, KProtocolInetUdp ) |
|
30 { |
|
31 LOG_NODE_CREATE ( KESockFlowTag, CApplicationProtocolIntfUdp ); |
|
32 } |
|
33 CApplicationProtocolIntfUdp::~CApplicationProtocolIntfUdp() |
|
34 { |
|
35 Shutdown(); |
|
36 LOG_NODE_DESTROY(KESockFlowTag, CApplicationProtocolIntfUdp); |
|
37 } |
|
38 |
|
39 void CApplicationProtocolIntfUdp::ReceivedL ( const TRuntimeCtxId& aSender, const TNodeId& aRecipient, TSignatureBase& aMessage ) |
|
40 { |
|
41 if ( aMessage.MessageId().Realm() == TAppProtIntfMessage::ERealmId ) |
|
42 { |
|
43 CApplicationProtocolIntfBase::ReceivedL ( aSender, aRecipient, aMessage ); |
|
44 switch ( aMessage.MessageId().MessageId() ) |
|
45 { |
|
46 case TAppProtIntfMessage::TJoinWithMulticastAddress::EId: |
|
47 { |
|
48 const TAppProtIntfMessage::TJoinWithMulticastAddress& msg = message_cast<const TAppProtIntfMessage::TJoinWithMulticastAddress> ( aMessage ); |
|
49 iMulticastAddr = msg.iAddr; |
|
50 InitiateLinkL ( address_cast<TNodeCtxId> ( aSender ), KSockDatagram, KProtocolInetUdp ); |
|
51 } |
|
52 break; |
|
53 } |
|
54 } |
|
55 |
|
56 // The below message are self posted. Just to keep the operation to continue. |
|
57 if ( aMessage.MessageId().Realm() == ESock::TCFMessage::ERealmId ) |
|
58 { |
|
59 switch ( aMessage.MessageId ().MessageId () ) |
|
60 { |
|
61 case CApplicationProtocolIntfBase::TRecvFrom::EId: |
|
62 { |
|
63 __ASSERT_DEBUG ( iLinks.Count() > 0, User::Invariant() ); |
|
64 if ( iLinks[0].Flags () != TClientType::ELeaving ) |
|
65 { |
|
66 iSocketHandler.RecvFrom (); |
|
67 } |
|
68 } |
|
69 break; |
|
70 |
|
71 } |
|
72 } |
|
73 } |
|
74 |
|
75 TInt CApplicationProtocolIntfUdp::Startup () |
|
76 { |
|
77 TInt ret = KErrNone; |
|
78 TInetAddr addr; |
|
79 addr.SetAddress ( iMulticastAddr.iAddr ); |
|
80 addr.SetPort ( iMulticastAddr.iPort ); |
|
81 |
|
82 if ( addr.IsMulticast() ) |
|
83 { |
|
84 if ( addr.Family() != KAfInet6 ) |
|
85 { |
|
86 addr.ConvertToV4Mapped(); |
|
87 } |
|
88 TPckgBuf<TIp6Mreq> mReqBuf; |
|
89 mReqBuf().iAddr = addr.Ip6Address(); |
|
90 mReqBuf().iInterface = 0; |
|
91 |
|
92 ret = iSocket.SetOpt( KSoIp6JoinGroup, KSolInetIp, mReqBuf ); // Join the multicast group |
|
93 } |
|
94 iSocketHandler.RecvFrom(); // Start the receive |
|
95 return ret; |
|
96 } |
|
97 |
|
98 void CApplicationProtocolIntfUdp::Shutdown () |
|
99 { |
|
100 TInetAddr addr; |
|
101 addr.SetAddress ( iMulticastAddr.iAddr ); |
|
102 addr.SetPort ( iMulticastAddr.iPort ); |
|
103 |
|
104 if ( addr.IsMulticast() ) |
|
105 { |
|
106 if ( addr.Family() != KAfInet6 ) |
|
107 { |
|
108 addr.ConvertToV4Mapped(); |
|
109 } |
|
110 TPckgBuf<TIp6Mreq> mReqBuf; |
|
111 mReqBuf().iAddr = addr.Ip6Address(); |
|
112 mReqBuf().iInterface = 0; |
|
113 |
|
114 TInt ret = iSocket.SetOpt( KSoIp6LeaveGroup, KSolInetIp, mReqBuf ); // leave the multicast group |
|
115 ASSERT ( ret == KErrNone ); |
|
116 } |
|
117 |
|
118 CApplicationProtocolIntfBase::Shutdown (); |
|
119 } |
|
120 |
|
121 void CApplicationProtocolIntfUdp::RecvFromComplete ( RMBufChain& aData, const TSockAddr& aAddr ) |
|
122 { |
|
123 __ASSERT_DEBUG ( iLinks.Count() > 0, User::Invariant() ); |
|
124 |
|
125 // if client is in leaving state, no need of any posts |
|
126 if ( iLinks[0].Flags() != TClientType::ELeaving ) |
|
127 { |
|
128 TInetAddr inetAddr ( aAddr ); |
|
129 TAppProtAddr protAddr ( inetAddr.Address(), inetAddr.Port() ); |
|
130 |
|
131 TAppProtIntfMessage::TDataReceived msg ( protAddr, aData ); |
|
132 |
|
133 PostToLink ( iLinks[0], msg ); // We do assume that we have only one link ( atleast for the timebeing ). |
|
134 // Note: If we have more link then we need to make copies of RMBufChain before posting. Otherwise the ownership |
|
135 // of the RMBufChain will be an issue? |
|
136 TNodeCtxId ctx ( MeshMachine::KActivityNull, NodeId () ); |
|
137 PostToLink ( ctx, CApplicationProtocolIntfBase::TRecvFrom ().CRef () ); // Self post to keep continue with the receiving |
|
138 } |
|
139 else |
|
140 { |
|
141 aData.Free (); |
|
142 } |
|
143 } |