int main() { GREENTEA_SETUP(20, "udp_echo"); EthernetInterface eth; eth.connect(); printf("UDP client IP Address is %s\n", eth.get_ip_address()); greentea_send_kv("target_ip", eth.get_ip_address()); char recv_key[] = "host_port"; char ipbuf[60] = {0}; char portbuf[16] = {0}; unsigned int port = 0; UDPSocket sock; sock.open(ð); sock.set_timeout(MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT); greentea_send_kv("host_ip", " "); greentea_parse_kv(recv_key, ipbuf, sizeof(recv_key), sizeof(ipbuf)); greentea_send_kv("host_port", " "); greentea_parse_kv(recv_key, portbuf, sizeof(recv_key), sizeof(ipbuf)); sscanf(portbuf, "%u", &port); printf("MBED: UDP Server IP address received: %s:%d \n", ipbuf, port); SocketAddress udp_addr(ipbuf, port); int success = 0; for (int i=0; i < ECHO_LOOPS; ++i) { prep_buffer(tx_buffer, sizeof(tx_buffer)); const int ret = sock.sendto(udp_addr, tx_buffer, sizeof(tx_buffer)); printf("[%02d] sent...%d Bytes \n", i, ret); SocketAddress temp_addr; const int n = sock.recvfrom(&temp_addr, rx_buffer, sizeof(rx_buffer)); printf("[%02d] recv...%d Bytes \n", i, n); if ((temp_addr == udp_addr && n == sizeof(tx_buffer) && memcmp(rx_buffer, tx_buffer, sizeof(rx_buffer)) == 0)) { success += 1; } } bool result = (success > 3*ECHO_LOOPS/4); sock.close(); eth.disconnect(); GREENTEA_TESTSUITE_RESULT(result); }
int main() { GREENTEA_SETUP(20, "udp_shotgun"); EthernetInterface eth; int err = eth.connect(); TEST_ASSERT_EQUAL(0, err); printf("MBED: UDPClient IP address is '%s'\n", eth.get_ip_address()); printf("MBED: UDPClient waiting for server IP and port...\n"); greentea_send_kv("target_ip", eth.get_ip_address()); bool result = false; char recv_key[] = "host_port"; char ipbuf[60] = {0}; char portbuf[16] = {0}; unsigned int port = 0; greentea_send_kv("host_ip", " "); greentea_parse_kv(recv_key, ipbuf, sizeof(recv_key), sizeof(ipbuf)); greentea_send_kv("host_port", " "); greentea_parse_kv(recv_key, portbuf, sizeof(recv_key), sizeof(ipbuf)); sscanf(portbuf, "%u", &port); printf("MBED: UDP Server IP address received: %s:%d \n", ipbuf, port); // align each size to 4-bits for (int i = 0; i < udp_dtls_handshake_count; i++) { udp_dtls_handshake_pattern[i] = (~0xf & udp_dtls_handshake_pattern[i]) + 0x10; } printf("MBED: DTLS pattern ["); for (int i = 0; i < udp_dtls_handshake_count; i++) { printf("%d", udp_dtls_handshake_pattern[i]); if (i != udp_dtls_handshake_count-1) { printf(", "); } } printf("]\r\n"); UDPSocket sock; SocketAddress udp_addr(ipbuf, port); for (int attempt = 0; attempt < MBED_CFG_UDP_DTLS_HANDSHAKE_RETRIES; attempt++) { err = sock.open(ð); TEST_ASSERT_EQUAL(0, err); for (int i = 0; i < udp_dtls_handshake_count; i++) { buffer[i] = udp_dtls_handshake_pattern[i] >> 4; } err = sock.sendto(udp_addr, buffer, udp_dtls_handshake_count); printf("UDP: tx -> %d\r\n", err); TEST_ASSERT_EQUAL(udp_dtls_handshake_count, err); int step = 0; while (step < udp_dtls_handshake_count) { err = sock.recvfrom(NULL, buffer, sizeof(buffer)); printf("UDP: rx <- %d ", err); // check length if (err != udp_dtls_handshake_pattern[step]) { printf("x (expected %d)\r\n", udp_dtls_handshake_pattern[step]); break; } // check quick xor of packet uint8_t check = 0; for (int j = 0; j < udp_dtls_handshake_pattern[step]; j++) { check ^= buffer[j]; } if (check != 0) { printf("x (checksum 0x%02x)\r\n", check); break; } // successfully got a packet printf("\r\n"); step += 1; } err = sock.close(); TEST_ASSERT_EQUAL(0, err); // got through all steps, test passed if (step == udp_dtls_handshake_count) { result = true; break; } } eth.disconnect(); GREENTEA_TESTSUITE_RESULT(result); }
int ACE_TMAIN(int argc, ACE_TCHAR *argv[]) { // Register the default factory in the Service Configurator. // If your platform supports static constructors then you can // simply using the ACE_STATIC_SVC_DEFINE() macro, unfortunately TAO // must run on platforms where static constructors do not work well, // so we have to explicitly invoke this function. TAO_EC_Default_Factory::init_svcs (); // The exception macros are described in $ACE_ROOT/docs/exceptions.html // and defined in $ACE_ROOT/ace/CORBA_macros.h. // If your platform supports native exceptions, and TAO was compiled // with native exception support then you can simply use try/catch // and avoid the argument. // Unfortunately many embedded systems cannot use exceptions due to // the space and time overhead. // try { // **************** HERE STARTS THE ORB SETUP // Create the ORB, pass the argv list for parsing. CORBA::ORB_var orb = CORBA::ORB_init (argc, argv); // Parse the arguments, you usually want to do this after // invoking ORB_init() because ORB_init() will remove all the // -ORB options from the command line. if (parse_args (argc, argv) == -1) { ACE_ERROR ((LM_ERROR, "Usage: Service [-m udp_mcast_addr]\n")); return 1; } if (valuetype) { Hello::ValueTypeData_init *vb_factory = 0; ACE_NEW_RETURN (vb_factory, Hello::ValueTypeData_init, 1); // supplied by mapping orb->register_value_factory (vb_factory->tao_repository_id (), vb_factory); vb_factory->_remove_ref (); // release ownership } // This is the standard code to get access to the POA and // activate it. // The POA starts in the holding state, if it is not activated // it will not process any requests. CORBA::Object_var object = orb->resolve_initial_references ("RootPOA"); PortableServer::POA_var poa = PortableServer::POA::_narrow (object.in ()); PortableServer::POAManager_var poa_manager = poa->the_POAManager (); poa_manager->activate (); // **************** THAT COMPLETS THE ORB SETUP // **************** HERE START THE LOCAL EVENT CHANNEL SETUP // This structure is used to define the startup time event // channel configuration. // This structure is described in // // $TAO_ROOT/docs/ec_options.html // TAO_EC_Event_Channel_Attributes attributes (poa.in (), poa.in ()); // Create the Event Channel implementation class TAO_EC_Event_Channel ec_impl (attributes); // Activate the Event Channel, depending on the configuration // that may involve creating some threads. // But it should always be invoked because several internal data // structures are initialized at that point. ec_impl.activate (); // The event channel is activated as any other CORBA servant. // In this case we use the simple implicit activation with the // RootPOA RtecEventChannelAdmin::EventChannel_var event_channel = ec_impl._this (); // **************** THAT COMPLETES THE LOCAL EVENT CHANNEL SETUP // **************** HERE STARTS THE FEDERATION SETUP // The next step is to setup the multicast gateways. // There are two gateways involved, one sends the locally // generated events to the federated peers, the second gateway // receives multicast traffic and turns it into local events. // The sender requires a helper object to select what // multicast group will carry what traffic, this is the // so-called 'Address Server'. // The intention is that advanced applications can use different // multicast groups for different events, this can exploit // network interfaces that filter unwanted multicast traffic. // The helper object is accessed through an IDL interface, so it // can reside remotely. // In this example, and in many application, using a fixed // multicast group is enough, and a local address server is the // right approach. // First we convert the string into an INET address, then we // convert that into the right IDL structure: ACE_INET_Addr udp_addr (udp_mcast_address); ACE_DEBUG ((LM_DEBUG, "udp mcast address is: %s\n", udp_mcast_address)); // Now we create and activate the servant AddrServer as_impl (udp_addr); RtecUDPAdmin::AddrServer_var address_server = as_impl._this (); TAO_ECG_Refcounted_Endpoint endpoint(new TAO_ECG_UDP_Out_Endpoint); // Now we connect the sender as a consumer of events, it will // receive any event from any source and send it to the "right" // multicast group, as defined by the address server set above: RtecEventChannelAdmin::ConsumerQOS sub; sub.is_gateway = 1; sub.dependencies.length (1); sub.dependencies[0].event.header.type = ACE_ES_EVENT_ANY; // first free event type sub.dependencies[0].event.header.source = ACE_ES_EVENT_SOURCE_ANY; // Any source is OK // To receive events we need to setup an event handler: PortableServer::Servant_var<TAO_ECG_UDP_Receiver> receiver = TAO_ECG_UDP_Receiver::create(); TAO_ECG_Mcast_EH mcast_eh (&(*receiver)); // The event handler uses the ORB reactor to wait for multicast // traffic: mcast_eh.reactor (orb->orb_core ()->reactor ()); // The multicast Event Handler needs to know to what multicast // groups it should listen to. To do so it becomes an observer // with the event channel, to determine the list of events // required by all the local consumer. // Then it register for the multicast groups that carry those // events: mcast_eh.open (event_channel.in ()); // Again the receiver connects to the event channel as a // supplier of events, using the Observer features to detect // local consumers and their interests: receiver->init (event_channel.in (), endpoint, address_server.in ()); // The Receiver is also a supplier of events. The exact type of // events is only known to the application, because it depends // on the traffic carried by all the multicast groups that the // different event handlers subscribe to. // In this example we choose to simply describe our publications // using wilcards, any event from any source. More advanced // application could use the Observer features in the event // channel to update this information (and reduce the number of // multicast groups that each receive subscribes to). // In a future version the event channel could perform some of // those tasks automatically RtecEventChannelAdmin::SupplierQOS pub; pub.publications.length (1); pub.publications[0].event.header.type = ACE_ES_EVENT_ANY; pub.publications[0].event.header.source = ACE_ES_EVENT_SOURCE_ANY; pub.is_gateway = 1; receiver->connect (pub); // **************** THAT COMPLETES THE FEDERATION SETUP // **************** HERE STARTS THE CLIENT SETUP // First let us create a consumer and connect it to the event // channel Consumer consumer (valuetype); RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin = event_channel->for_consumers (); consumer.connect (consumer_admin.in ()); // **************** THAT COMPLETES THE CLIENT SETUP // **************** HERE STARTS THE EVENT LOOP // Wait for events, including incoming multicast data. // We could also use orb->run(), but that will not let us // terminate the application in a nice way. for (int i = 0; i != 100; ++i) { CORBA::Boolean there_is_work = orb->work_pending (); if (there_is_work) { // We use a TAO extension. The CORBA mechanism does not // provide any decent way to control the duration of // perform_work() or work_pending(), so just calling // them results in a spin loop. ACE_Time_Value tv (0, 50000); orb->perform_work (tv); } ACE_Time_Value tv (0, 100000); ACE_OS::sleep (tv); if (consumer.event_count () == 25) { break; } } // **************** THAT COMPLETES THE EVENT LOOP // **************** HERE STARTS THE CLEANUP CODE consumer.disconnect (); // Now let us close the Receiver receiver->shutdown (); int const r = mcast_eh.shutdown (); if (r == -1) { ACE_ERROR_RETURN ((LM_ERROR, "Closing MCast event handler\n"), 1); } // The event channel must be destroyed, so it can release its // resources, and inform all the clients that are still // connected that it is going away. event_channel->destroy (); // Deactivating the event channel implementation is not strictly // required, the POA will do it for us, but it is good manners: { // Using _this() activates with the default POA, we must gain // access to that POA to deactivate the object. // Notice that we 'know' that the default POA for this servant // is the root POA, but the code is more robust if we don't // rely on that. PortableServer::POA_var poa = ec_impl._default_POA (); // Get the Object Id used for the servant.. PortableServer::ObjectId_var oid = poa->servant_to_id (&ec_impl); // Deactivate the object poa->deactivate_object (oid.in ()); } // Now we can destroy the POA, the flags mean that we want to // wait until the POA is really destroyed poa->destroy (1, 1); // Finally destroy the ORB orb->destroy (); // **************** THAT COMPLETES THE CLEANUP CODE ACE_DEBUG ((LM_DEBUG, "UDP receiver ready\n")); } catch (const CORBA::Exception& ex) { ex._tao_print_exception ("Service"); return 1; } return 0; }