|
1 // Copyright (c) 2003-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 // CTcpServer |
|
15 // System Include |
|
16 // |
|
17 // |
|
18 |
|
19 #include <stdio.h> |
|
20 #include <stdlib.h> |
|
21 #include <assert.h> |
|
22 |
|
23 |
|
24 /*************************************************************************************** |
|
25 * |
|
26 * Local Include |
|
27 * |
|
28 **************************************************************************************/ |
|
29 #include "CTcpServer.h" |
|
30 |
|
31 |
|
32 /*************************************************************************************** |
|
33 * |
|
34 * PUBLIC METHOD: Constructor |
|
35 * |
|
36 **************************************************************************************/ |
|
37 CTcpServer::CTcpServer() |
|
38 { |
|
39 |
|
40 } |
|
41 |
|
42 |
|
43 /*************************************************************************************** |
|
44 * |
|
45 ` * PUBLIC METHOD: Destructor |
|
46 * |
|
47 **************************************************************************************/ |
|
48 CTcpServer::~CTcpServer() |
|
49 { |
|
50 disconnect(); |
|
51 release(); |
|
52 } |
|
53 |
|
54 |
|
55 /*************************************************************************************** |
|
56 * |
|
57 * PUBLIC METHOD: StartServer |
|
58 * |
|
59 **************************************************************************************/ |
|
60 int CTcpServer::StartServer( char* aLocalInterface, char* aLocalPort ) |
|
61 { |
|
62 int r; |
|
63 r =initialise(); |
|
64 |
|
65 if(r != ITS_OK) |
|
66 return r; |
|
67 |
|
68 r = setArguments( aLocalInterface, aLocalPort ); |
|
69 if(r != ITS_OK) |
|
70 return r; |
|
71 |
|
72 r = makeConnection(iLocal_Sock, iRemote_Sock, iRemote_Addr); |
|
73 return r; |
|
74 |
|
75 } |
|
76 |
|
77 |
|
78 /*************************************************************************************** |
|
79 * |
|
80 * SECTION: CUSTOMISATION METHODS |
|
81 * |
|
82 **************************************************************************************/ |
|
83 /*************************************************************************************** |
|
84 * |
|
85 * PRIVATE METHOD: ProcessBuffer |
|
86 * |
|
87 **************************************************************************************/ |
|
88 void CTcpServer::ProcessBuffer( char* aBuffer, int aLen ) |
|
89 { |
|
90 int i; |
|
91 for( i = 0; i < aLen; i++ ) { |
|
92 // fprintf( stderr, "%c (0x%x)\n", aBuffer[i], aBuffer[i] ); |
|
93 fprintf( stderr, "%c", aBuffer[i] ); |
|
94 } |
|
95 } |
|
96 |
|
97 /*************************************************************************************** |
|
98 * |
|
99 * PRIVATE METHOD: IsBufferComplete |
|
100 * |
|
101 **************************************************************************************/ |
|
102 bool CTcpServer::IsBufferComplete(char* aBuffer,int aLen) |
|
103 { |
|
104 return true; |
|
105 } |
|
106 |
|
107 |
|
108 /*************************************************************************************** |
|
109 * |
|
110 * SECTION: PRIVATE METHODS |
|
111 * |
|
112 **************************************************************************************/ |
|
113 // |
|
114 // Method binds the sock to the address. |
|
115 // |
|
116 int CTcpServer::connect(SOCKET &aSocket, SOCKADDR_IN &aAddr) |
|
117 { |
|
118 int err; |
|
119 |
|
120 //Bind the local address with a socket, so it listens to that port. |
|
121 if (bind(aSocket,(struct sockaddr*)&aAddr, sizeof(SOCKADDR_IN)) != 0) |
|
122 { |
|
123 //return, error has occured |
|
124 err = WSAGetLastError(); |
|
125 printf ("Error binding socket: %d", err); |
|
126 return E_SOCKETBIND; |
|
127 } |
|
128 |
|
129 return ITS_OK; |
|
130 } |
|
131 |
|
132 // |
|
133 // Disoconnect |
|
134 // |
|
135 int CTcpServer::disconnect() |
|
136 { |
|
137 shutdown(iLocal_Sock, SD_SEND); |
|
138 shutdown(iLocal_Sock, SD_RECEIVE); |
|
139 |
|
140 //do we close remote sock? |
|
141 |
|
142 if (closesocket(iLocal_Sock) == SOCKET_ERROR) |
|
143 return E_SOCKETCLOSE; |
|
144 |
|
145 return ITS_OK; |
|
146 } |
|
147 |
|
148 // |
|
149 // Method to check if we have IP adress or hostname, and return IP address |
|
150 // |
|
151 SOCKADDR_IN CTcpServer::getSockAddr( const char* aIp, const char* aPort) |
|
152 { |
|
153 SOCKADDR_IN sockAddr; |
|
154 |
|
155 // check params |
|
156 assert( aIp != NULL ); |
|
157 |
|
158 // check for null port |
|
159 if( aPort == NULL ) { |
|
160 aPort = "0"; |
|
161 } |
|
162 |
|
163 // set the socket |
|
164 sockAddr.sin_family = AF_INET; |
|
165 sockAddr.sin_port = htons( atoi(aPort) ); |
|
166 sockAddr.sin_addr.S_un.S_addr = inet_addr( aIp ); |
|
167 return sockAddr; |
|
168 } |
|
169 |
|
170 |
|
171 // |
|
172 // Method to check if the adress is IP format or is a hostname string. |
|
173 // |
|
174 bool CTcpServer::isIPAdress(const char* aAddr) |
|
175 { |
|
176 int c =0; |
|
177 |
|
178 char* q=(char *)aAddr; |
|
179 char* tokenPtr = strtok(q,"."); |
|
180 |
|
181 while(tokenPtr != NULL) |
|
182 { |
|
183 tokenPtr = strtok(NULL,"."); |
|
184 c++; |
|
185 } |
|
186 |
|
187 if (c==4) |
|
188 return true; //We have IP adrress, nothing to do |
|
189 else |
|
190 return false; |
|
191 } |
|
192 |
|
193 // |
|
194 // Makes a connection, listens, and prints any incoming data. |
|
195 // |
|
196 int CTcpServer::makeConnection(SOCKET &aLocalSocket, SOCKET &aRemoteSocket, SOCKADDR_IN & aRemoteAddr) |
|
197 { |
|
198 int remote_addr_len; |
|
199 |
|
200 int err = listen( aLocalSocket, 1 ); |
|
201 if( err == SOCKET_ERROR ) |
|
202 { |
|
203 err = WSAGetLastError (); |
|
204 printf ("Error listening to socket: %d", err); |
|
205 return E_LISTENING; |
|
206 } |
|
207 |
|
208 //wait for connection |
|
209 while( 1 ) |
|
210 { |
|
211 // Wait for the next connection |
|
212 printf( "\nWaiting for connection...\n" ); |
|
213 remote_addr_len = sizeof(aRemoteAddr); |
|
214 aRemoteSocket = accept( aLocalSocket, (struct sockaddr*)&aRemoteAddr, &remote_addr_len ); |
|
215 if( aRemoteSocket == INVALID_SOCKET ) |
|
216 { |
|
217 err = WSAGetLastError(); |
|
218 printf ("Accept failed. Error: %d",err); |
|
219 return E_ACCEPT; |
|
220 } |
|
221 |
|
222 // Connection received |
|
223 printf( "Connection received from %d.%d.%d.%d : %d\n", |
|
224 aRemoteAddr.sin_addr.S_un.S_un_b.s_b1, |
|
225 aRemoteAddr.sin_addr.S_un.S_un_b.s_b2, |
|
226 aRemoteAddr.sin_addr.S_un.S_un_b.s_b3, |
|
227 aRemoteAddr.sin_addr.S_un.S_un_b.s_b4, |
|
228 aRemoteAddr.sin_port ); |
|
229 |
|
230 // Read until the socket is closed and print out the info received. |
|
231 err = 1; |
|
232 while( err > 0 ) |
|
233 { |
|
234 err = recv(aRemoteSocket, iPacket, RECVBUFFSIZE, 0 ); |
|
235 if (err == SOCKET_ERROR) |
|
236 return E_RECEIVING; |
|
237 ProcessBuffer(iPacket, err); |
|
238 err = send(aRemoteSocket, iPacket, err, 0 ); |
|
239 if (err == SOCKET_ERROR) |
|
240 return E_SENDING; |
|
241 } |
|
242 |
|
243 // Close the socket and go again |
|
244 closesocket(aRemoteSocket); |
|
245 } |
|
246 return ITS_OK; |
|
247 } |
|
248 |
|
249 // |
|
250 // Returns a a TCP/IP socket |
|
251 // |
|
252 SOCKET CTcpServer::getSocket() |
|
253 { |
|
254 SOCKET sock; |
|
255 int err; |
|
256 |
|
257 // create a socket |
|
258 sock = socket( AF_INET, SOCK_STREAM, 0 ) ; |
|
259 if( sock == INVALID_SOCKET) |
|
260 { |
|
261 //return, error has occured |
|
262 err = WSAGetLastError (); |
|
263 printf ("Allocating socket failed. Error: %d",err); |
|
264 return NULL; |
|
265 } |
|
266 return sock; |
|
267 } |
|
268 |
|
269 // |
|
270 // Initialise use of the dll. |
|
271 // |
|
272 int CTcpServer::initialise() |
|
273 { |
|
274 WORD version; |
|
275 WSADATA wsaData; |
|
276 |
|
277 // 1. start the windows iSocket server |
|
278 version = MAKEWORD( 2, 2 ); |
|
279 if (WSAStartup( version, &wsaData )) |
|
280 return E_SOCKETSTARTUP; |
|
281 |
|
282 return ITS_OK; |
|
283 } |
|
284 |
|
285 |
|
286 // |
|
287 // Release. |
|
288 // |
|
289 int CTcpServer::release() |
|
290 { |
|
291 int err =WSACleanup(); |
|
292 |
|
293 if ( err == SOCKET_ERROR) |
|
294 return E_SOCKETSHUTDOWN; |
|
295 |
|
296 return ITS_OK; |
|
297 } |
|
298 |
|
299 // |
|
300 // Set the arguments |
|
301 // |
|
302 int CTcpServer::setArguments(char* li, char* lp) |
|
303 { |
|
304 if(!lp) |
|
305 { |
|
306 printf("Error: Missing argument - lp argument required.\n"); |
|
307 return E_INCORRECTARG; |
|
308 } |
|
309 |
|
310 iLocal_Sock = getSocket(); |
|
311 iLocal_Addr = getSockAddr(li,lp ); |
|
312 connect(iLocal_Sock,iLocal_Addr); //bind |
|
313 |
|
314 return ITS_OK; |
|
315 |
|
316 } |
|
317 |