/* * * User: David RENE * Date: 25/04/2007 * Time: 11:01 * (c) Calexium * */ read tools/basis.anubis read system/convert.anubis read system/string.anubis read system/muscle.anubis read system/data_io.anubis read system/message_queue.anubis read system/message_transceiver.anubis read CXM_generic_protocol.anubis read calexium_lib/CXM_message_constants.anubis public type NetService: net_service( Int32 version, Int32 id, String name, (MessageQueue) -> One handler ). define One print_services ( List(NetService) net_services ) = map_forget((NetService net_s)|-> println(" id : 0x"+ to_hexa(net_s.id)); println(" version : " + to_String(net_s.version)); println(" name : "+ net_s.name ); println("----------------------------------------") ,net_services). /** Try to find the service_id in services_list. If the service is found in that list * the corresponding NetService object is return */ define Maybe(NetService) find_service ( List(NetService) services_list, Int32 service_id, Int32 service_version )= if services_list is { [] then failure, [h.t] then if h.id = service_id & h.version >= service_version then success(h) else find_service(t, service_id, service_version) }. /** Check if the muscle message msg has the correct fields for requesting a net_services * if we found "service" and "version" fields on the message, we try to find if the service * referenced in "service" is available in net_services list */ define Maybe(NetService) has_service ( MessageQueue queue, Message msg, List(NetService) net_services )= if find_int32(msg, "service") is { failure then send_ACK_error(queue, _CXM_REQUEST_FOR_SERVICE); failure, success(service_id) then if find_int32(msg, "version") is { failure then send_ACK_error(queue, _CXM_REQUEST_FOR_SERVICE);failure, success(service_version) then find_service(net_services, service_id, service_version) } }. /** This message_received function just handle the negociation process the available net_services. * In other words, it only recognize the _CXM_REQUEST_FOR_SERVICE message and try to launch the * corresponding servcice */ define One service_negociation ( MessageQueue queue, Message msg, List(NetService) net_services )= print("MESSAGE [" + to_ascii(*msg.what) + "] received\n"); if * msg.what = _CXM_REQUEST_FOR_SERVICE then if has_service(queue, msg, net_services) is { failure then unique, success(net_service) then send_ACK_ok(queue, _CXM_REQUEST_FOR_SERVICE); net_service.handler(queue) } else unique . /** this function unflatten muscle message and give the correct message to service_negociation function * */ //TODO At this time, the function is in infinite loop, we must change to provide a mechanism for quitting //TODO when shutdown_required is true define One message_receiver ( MessageQueue queue, List(NetService) net_services ) = if queue.get_next_received_Message(10) is { timeout then message_receiver(queue, net_services), closed then unique, msg(msg) then service_negociation(queue, msg, net_services); message_receiver(queue, net_services) }. define Server -> (RWStream) -> One net_services_handler ( List(NetService) net_services, ) = (Server server) |-> (RWStream conn) |-> if remote_IP_address_and_port(conn) is (num_peer,_) then //convert IP address of the client to string // with peer = ip_addr_to_string(num_peer), // print("NET SERVICES Accepting connection with "+peer+"\n"); //now managing the list of SERVICES with queue = create_MessageQueue, message_transceiver(conn, queue); message_receiver(queue, net_services). public define Maybe(Server) start_net_services ( List(NetService) net_services, Int32 network_port, Var(Bool) shutdown_required )= //TODO change the port number in the real world if start_server(0, network_port, net_services_handler(net_services), (One u) |-> unique) is { cannot_create_the_socket then println("Cannot create the listening socket."); failure, cannot_bind_to_port then println("Cannot bind to port " + network_port ); failure, cannot_listen_on_port then println("Cannot listen on port " + network_port); failure, ok(server) then println("Net services started on port " + network_port); println("------ Available services ------"); print_services(net_services); success(server) }.