Subversion Repositories HelenOS

Rev

Rev 4505 | Rev 4603 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4505 Rev 4579
Line 32... Line 32...
32
 
32
 
33
/** @file
33
/** @file
34
 */
34
 */
35
 
35
 
36
#include <async.h>
36
#include <async.h>
-
 
37
#include <malloc.h>
37
#include <stdio.h>
38
#include <stdio.h>
38
 
39
 
39
#include <ipc/ipc.h>
40
#include <ipc/ipc.h>
40
#include <ipc/services.h>
41
#include <ipc/services.h>
41
 
42
 
42
#include "../../err.h"
43
#include "../../err.h"
43
#include "../../messages.h"
44
#include "../../messages.h"
44
#include "../../modules.h"
45
#include "../../modules.h"
45
#include "../../structures/packet/packet_client.h"
46
#include "../../structures/packet/packet_client.h"
46
 
47
 
-
 
48
#include "../../include/in.h"
-
 
49
#include "../../include/inet.h"
47
#include "../../include/ip_client.h"
50
#include "../../include/ip_client.h"
48
#include "../../include/ip_interface.h"
51
#include "../../include/ip_interface.h"
49
#include "../../include/ip_protocols.h"
52
#include "../../include/ip_protocols.h"
-
 
53
#include "../../include/socket.h"
-
 
54
#include "../../include/socket_errno.h"
50
//#include "../../include/udp_interface.h"
55
//#include "../../include/udp_interface.h"
51
 
56
 
-
 
57
#include "../../socket/socket_core.h"
-
 
58
#include "../../socket/socket_messages.h"
-
 
59
 
52
#include "../tl_messages.h"
60
#include "../tl_messages.h"
53
 
61
 
54
#include "udp.h"
62
#include "udp.h"
-
 
63
#include "udp_header.h"
55
#include "udp_module.h"
64
#include "udp_module.h"
56
 
65
 
57
int udp_received_msg( device_id_t device_id, packet_t packet, services_t receiver );
66
int udp_received_msg( device_id_t device_id, packet_t packet, services_t receiver );
-
 
67
int process_client_messages( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count );
-
 
68
int udp_sendto_message( socket_cores_ref local_sockets, int socket_id, void * addr, size_t addrlen, void * data, size_t length, int flags );
-
 
69
int socket_get_data( void ** data, size_t * length );
58
 
70
 
59
udp_globals_t   udp_globals;
71
udp_globals_t   udp_globals;
60
 
72
 
61
/** Initializes the module.
73
/** Initializes the module.
62
 */
74
 */
63
int udp_initialize( async_client_conn_t client_connection ){
75
int udp_initialize( async_client_conn_t client_connection ){
64
//  ERROR_DECLARE;
76
    ERROR_DECLARE;
65
 
-
 
66
//  ipcarg_t    arg1, arg2;
-
 
67
//  packet_t    packet;
-
 
68
 
77
 
69
/*  printf( "UDP - testing to send to IP:\n" );
78
    udp_globals.port_search_start = 1025;
70
    ERROR_PROPAGATE( ip_echo( udp_globals.ip_phone, 12, 34, 0, 0, 0, & arg1, & arg2, NULL, NULL, NULL ));
-
 
71
    if(( arg1 != 12 ) || ( arg2 != 34 )) return EINVAL;
-
 
72
    printf( "OK\n" );
-
 
73
*/
-
 
74
    udp_globals.ip_phone = ip_bind_service( SERVICE_IP, IPPROTO_UDP, SERVICE_UDP, client_connection, udp_received_msg );
79
    udp_globals.ip_phone = ip_bind_service( SERVICE_IP, IPPROTO_UDP, SERVICE_UDP, client_connection, udp_received_msg );
75
 
-
 
76
/*  printf( "UDP - testing to send packet to IP:\n" );
80
    if( udp_globals.ip_phone < 0 ){
77
    packet = packet_get_4( udp_globals.net_phone, 6, 20, 30, 20 );
81
        return udp_globals.ip_phone;
-
 
82
    }
78
    if( ! packet ) return ENOMEM;
83
    ERROR_PROPAGATE( ip_packet_size_req( udp_globals.ip_phone, -1, & udp_globals.addr_len, & udp_globals.prefix, & udp_globals.content, & udp_globals.suffix ));
79
    packet_copy_data( packet, "Hi, this is UDP", 16 );
84
    ERROR_PROPAGATE( socket_ports_initialize( & udp_globals.sockets ));
80
    ip_send_msg( udp_globals.ip_phone, -1, packet, SERVICE_UDP );
85
    udp_globals.prefix += sizeof( udp_header_t );
81
    printf( "OK\n" );
86
    udp_globals.content -= sizeof( udp_header_t );
82
*/  return EOK;
87
    return EOK;
83
}
88
}
84
 
89
 
85
int udp_received_msg( device_id_t device_id, packet_t packet, services_t receiver ){
90
int udp_received_msg( device_id_t device_id, packet_t packet, services_t receiver ){
86
    // TODO received
91
    // TODO received
87
    //  TODO remove debug dump:
92
    //  TODO remove debug dump:
Line 98... Line 103...
98
 
103
 
99
    packet_t    packet;
104
    packet_t    packet;
100
 
105
 
101
    * answer_count = 0;
106
    * answer_count = 0;
102
    switch( IPC_GET_METHOD( * call )){
107
    switch( IPC_GET_METHOD( * call )){
103
        case IPC_M_PHONE_HUNGUP:
-
 
104
            return EOK;
-
 
105
        case NET_TL_RECEIVED:
108
        case NET_TL_RECEIVED:
106
            ERROR_PROPAGATE( packet_translate( udp_globals.net_phone, & packet, IPC_GET_PACKET( call )));
109
            ERROR_PROPAGATE( packet_translate( udp_globals.net_phone, & packet, IPC_GET_PACKET( call )));
107
            return udp_received_msg( IPC_GET_DEVICE( call ), packet, 0 );
110
            return udp_received_msg( IPC_GET_DEVICE( call ), packet, 0 );
-
 
111
        case IPC_M_CONNECT_TO_ME:
-
 
112
            return process_client_messages( callid, call, answer, answer_count );
108
    }
113
    }
109
    return ENOTSUP;
114
    return ENOTSUP;
110
}
115
}
111
 
116
 
-
 
117
int process_client_messages( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count ){
-
 
118
    ERROR_DECLARE;
-
 
119
 
-
 
120
    int                     res;
-
 
121
    bool                    keep_on_going = true;
-
 
122
    socket_cores_t          local_sockets;
-
 
123
    int                     app_phone = IPC_GET_PHONE( call );
-
 
124
    void *                  addr;
-
 
125
    size_t                  addrlen;
-
 
126
    void *                  data;
-
 
127
    size_t                  length;
-
 
128
 
-
 
129
    /*
-
 
130
     * Accept the connection
-
 
131
     *  - Answer the first IPC_M_CONNECT_ME_TO call.
-
 
132
     */
-
 
133
    ipc_answer_0( callid, EOK );
-
 
134
 
-
 
135
    socket_cores_initialize( & local_sockets );
-
 
136
 
-
 
137
    while( keep_on_going ){
-
 
138
        // refresh data
-
 
139
        * answer_count = 0;
-
 
140
        IPC_SET_RETVAL( * answer, 0 );
-
 
141
        // just to be precize
-
 
142
        IPC_SET_METHOD( * answer, 0 );
-
 
143
        IPC_SET_ARG1( * answer, 0 );
-
 
144
        IPC_SET_ARG2( * answer, 0 );
-
 
145
        IPC_SET_ARG3( * answer, 0 );
-
 
146
        IPC_SET_ARG4( * answer, 0 );
-
 
147
        IPC_SET_ARG5( * answer, 0 );
-
 
148
 
-
 
149
        callid = async_get_call( call );
-
 
150
        printf( "message %d\n", IPC_GET_METHOD( * call ));
-
 
151
 
-
 
152
        switch( IPC_GET_METHOD( * call )){
-
 
153
            case IPC_M_PHONE_HUNGUP:
-
 
154
                keep_on_going = false;
-
 
155
                res = EOK;
-
 
156
                break;
-
 
157
            case NET_SOCKET:
-
 
158
                res = socket_create( & local_sockets, app_phone );
-
 
159
                break;
-
 
160
            case NET_SOCKET_BIND:
-
 
161
                if( ERROR_OCCURRED( socket_get_data( & addr, & addrlen ))){
-
 
162
                    res = ERROR_CODE;
-
 
163
                    break;
-
 
164
                }
-
 
165
                res = socket_bind( & local_sockets, & udp_globals.sockets, SOCKET_GET_SOCKET_ID( call ), addr, addrlen );
-
 
166
                free( addr );
-
 
167
                break;
-
 
168
            case NET_SOCKET_SENDTO:
-
 
169
                if( ERROR_OCCURRED( socket_get_data( & addr, & addrlen ))){
-
 
170
                    res = ERROR_CODE;
-
 
171
                    break;
-
 
172
                }
-
 
173
                if( ERROR_OCCURRED( socket_get_data( & data, & length ))){
-
 
174
                    free( addr );
-
 
175
                    res = ERROR_CODE;
-
 
176
                    break;
-
 
177
                }
-
 
178
                res = udp_sendto_message( & local_sockets, SOCKET_GET_SOCKET_ID( call ), addr, addrlen, data, length, SOCKET_GET_FLAGS( call ));
-
 
179
                free( addr );
-
 
180
                free( data );
-
 
181
                break;
-
 
182
            case NET_SOCKET_RECVFROM:
-
 
183
                // TODO read first received packet queue data continuesly
-
 
184
                res = ENOTSUP;
-
 
185
                break;
-
 
186
            case NET_SOCKET_CLOSE:
-
 
187
                res = socket_destroy( udp_globals.net_phone, SOCKET_GET_SOCKET_ID( call ), & local_sockets, & udp_globals.sockets );
-
 
188
                break;
-
 
189
            case NET_SOCKET_GETSOCKOPT:
-
 
190
            case NET_SOCKET_SETSOCKOPT:
-
 
191
            default:
-
 
192
                res = ENOTSUP;
-
 
193
                break;
-
 
194
        }
-
 
195
 
-
 
196
        // TODO debug
-
 
197
        printf( "res = %d\n", res );
-
 
198
 
-
 
199
        switch( * answer_count ){
-
 
200
            case 0:     ipc_answer_0( callid, res );
-
 
201
                    continue;
-
 
202
            case 1:     ipc_answer_1( callid, res, IPC_GET_ARG1( * answer ));
-
 
203
                    continue;
-
 
204
            case 2:     ipc_answer_2( callid, res, IPC_GET_ARG1( * answer ), IPC_GET_ARG2( * answer ));
-
 
205
                    continue;
-
 
206
            case 3:     ipc_answer_3( callid, res, IPC_GET_ARG1( * answer ), IPC_GET_ARG2( * answer ), IPC_GET_ARG3( * answer ));
-
 
207
                    continue;
-
 
208
            case 4:     ipc_answer_4( callid, res, IPC_GET_ARG1( * answer ), IPC_GET_ARG2( * answer ), IPC_GET_ARG3( * answer ), IPC_GET_ARG4( * answer ));
-
 
209
                    continue;
-
 
210
            default:    ipc_answer_5( callid, res, IPC_GET_ARG1( * answer ), IPC_GET_ARG2( * answer ), IPC_GET_ARG3( * answer ), IPC_GET_ARG4( * answer ), IPC_GET_ARG5( * answer ));
-
 
211
                    continue;
-
 
212
        }
-
 
213
    }
-
 
214
 
-
 
215
    socket_cores_destroy( & local_sockets );
-
 
216
 
-
 
217
    return EOK;
-
 
218
}
-
 
219
 
-
 
220
int udp_sendto_message( socket_cores_ref local_sockets, int socket_id, void * addr, size_t addrlen, void * data, size_t length, int flags ){
-
 
221
    ERROR_DECLARE;
-
 
222
 
-
 
223
    socket_core_ref         socket;
-
 
224
    struct sockaddr *       address;
-
 
225
    struct sockaddr_in *    address_in;
-
 
226
    packet_t                packet;
-
 
227
    udp_header_ref          header;
-
 
228
 
-
 
229
    if( addrlen < sizeof( struct sockaddr )) return EINVAL;
-
 
230
    address = ( struct sockaddr * ) addr;
-
 
231
    switch( address->sa_family ){
-
 
232
        case AF_INET:
-
 
233
            if( addrlen != sizeof( struct sockaddr_in )) return EINVAL;
-
 
234
            address_in = ( struct sockaddr_in * ) addr;
-
 
235
            socket = socket_cores_find( local_sockets, socket_id );
-
 
236
            if( ! socket ) return ENOTSOCK;
-
 
237
/*          if( socket->port < 0 ){
-
 
238
                return ENOTCONN;
-
 
239
                socket->port = udp_globals.port_search_start;
-
 
240
                while( socket_ports_find( global_sockets, socket->port ) >= 0 ){
-
 
241
                    socket_port = ( socket->port + 1 ) % ( 65535 - 1025 ) + 1025;
-
 
242
                }
-
 
243
                ERROR_PROPAGATE( socket_ports_add( global_sockets, socket->port );
-
 
244
                udp_globals.port_search_start = socket->port + 1;
-
 
245
            }
-
 
246
*/          // TODO create and send fragmented packets
-
 
247
            // TODO do not ask all the time
-
 
248
            ERROR_PROPAGATE( ip_packet_size_req( udp_globals.ip_phone, -1, & udp_globals.addr_len, & udp_globals.prefix, & udp_globals.content, & udp_globals.suffix ));
-
 
249
            packet = packet_get_4( udp_globals.net_phone, length, udp_globals.addr_len, udp_globals.prefix, udp_globals.suffix );
-
 
250
            if( ! packet ) return ENOMEM;
-
 
251
            if( ERROR_OCCURRED( packet_copy_data( packet, data, length ))
-
 
252
            || ERROR_OCCURRED( packet_set_addr( packet, NULL, ( uint8_t * ) & address_in->sin_addr.s_addr, sizeof( address_in->sin_addr.s_addr )))){
-
 
253
                pq_release( udp_globals.net_phone, packet_get_id( packet ));
-
 
254
                return ERROR_CODE;
-
 
255
            }
-
 
256
            header = PACKET_PREFIX( packet, udp_header_t );
-
 
257
            if( ! header ){
-
 
258
                pq_release( udp_globals.net_phone, packet_get_id( packet ));
-
 
259
                return ENOMEM;
-
 
260
            }
-
 
261
            header->source = ( socket->port < 0 ) ? 0 : htons( socket->port );
-
 
262
            header->dest = htons( address_in->sin_port );
-
 
263
            header->len = htons( length );
-
 
264
            // TODO my ip address for the pseudo header checksum
-
 
265
            header->check = 0;
-
 
266
            if( ERROR_OCCURRED( ip_client_prepare_packet( packet, IPPROTO_UDP, 0, 0, 0, 0 ))){
-
 
267
                pq_release( udp_globals.net_phone, packet_get_id( packet ));
-
 
268
                return ERROR_CODE;
-
 
269
            }
-
 
270
            return ip_send_msg( udp_globals.ip_phone, socket->device_id, packet, SERVICE_UDP );
-
 
271
            break;
-
 
272
        // TODO IPv6
-
 
273
        default:
-
 
274
            return EAFNOSUPPORT;
-
 
275
    }
-
 
276
    return EOK;
-
 
277
}
-
 
278
 
-
 
279
int socket_get_data( void ** data, size_t * length ){
-
 
280
    ERROR_DECLARE;
-
 
281
 
-
 
282
    ipc_callid_t    callid;
-
 
283
 
-
 
284
    if( !( data && length )) return EBADMEM;
-
 
285
    if( ! ipc_data_write_receive( & callid, length )) return EINVAL;
-
 
286
    * data = malloc( * length );
-
 
287
    if( ! data ) return ENOMEM;
-
 
288
    if( ERROR_OCCURRED( ipc_data_write_finalize( callid, * data, * length ))){
-
 
289
        free( data );
-
 
290
        return ERROR_CODE;
-
 
291
    }
-
 
292
    return EOK;
-
 
293
}
-
 
294
 
112
/** @}
295
/** @}
113
 */
296
 */