Rev 4505 | Rev 4589 | 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 | */ |