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 | */ |