From 2444ac841fad00133f231e9667ab427c4ce4d39e Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 5 Oct 2010 01:44:25 +0200 Subject: Receiving messages works again (kinda) --- src/core/CMakeLists.txt | 2 ++ src/core/ephraim_account.erl | 2 ++ src/core/ephraim_conn.erl | 2 -- src/core/ephraim_conv.erl | 51 +++++++++++++++++++++++----- src/core/ephraim_conv_handler.erl | 71 +++++++++++++++++++++++++++++++++++++++ src/core/ephraim_conv_man.erl | 12 +++++++ src/core/ephraim_gui.erl | 2 +- src/core/ephraim_roster.erl | 2 ++ 8 files changed, 132 insertions(+), 12 deletions(-) create mode 100644 src/core/ephraim_conv_handler.erl create mode 100644 src/core/ephraim_conv_man.erl (limited to 'src/core') diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 9baaeee..97c7d4e 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -6,6 +6,8 @@ erl_target(ephraim-core ephraim_config.erl ephraim_conn.erl ephraim_conv.erl + ephraim_conv_handler.erl + ephraim_conv_man.erl ephraim_gui.erl ephraim_roster.erl ephraim_roster_handler.erl diff --git a/src/core/ephraim_account.erl b/src/core/ephraim_account.erl index d79e118..8024d68 100644 --- a/src/core/ephraim_account.erl +++ b/src/core/ephraim_account.erl @@ -9,6 +9,8 @@ start_link() -> {ok, EventManager} = supervisor:start_child(Pid, {event_man, {gen_event, start_link, []}, permanent, 1000, worker, [gen_event]}), ephraim_account_event_proxy:start(EventManager), + {ok, _} = supervisor:start_child(Pid, {conv_man, {ephraim_conv_man, start_link, [EventManager]}, permanent, 1000, supervisor, [ephraim_conv_man]}), + {ok, Connection} = supervisor:start_child(Pid, {connection, {ephraim_conn, start_link, [EventManager]}, permanent, 10000, worker, [ephraim_conn]}), {ok, _} = supervisor:start_child(Pid, {roster, {ephraim_roster, start_link, [EventManager, Connection]}, permanent, 1000, worker, [ephraim_roster]}), {ok, Pid}. diff --git a/src/core/ephraim_conn.erl b/src/core/ephraim_conn.erl index f4e14e0..fa9344d 100644 --- a/src/core/ephraim_conn.erl +++ b/src/core/ephraim_conn.erl @@ -37,8 +37,6 @@ session(Session) -> exmpp_session:login(Session), io:format("Getting profile...~n"), exmpp_session:send_packet(Session, exmpp_iq:get('jabber:client', #xmlel{ns='vcard-temp',name='vCard'})), - io:format("Getting roster...~n"), - exmpp_session:send_packet(Session, exmpp_client_roster:get_roster("foo")), io:format("Setting presence...~n"), exmpp_session:send_packet(Session, exmpp_presence:set_status(exmpp_presence:available(), "Foo/Test\\Bar")), io:format("Ok.~n"). diff --git a/src/core/ephraim_conv.erl b/src/core/ephraim_conv.erl index 3342bc9..d9431b2 100644 --- a/src/core/ephraim_conv.erl +++ b/src/core/ephraim_conv.erl @@ -1,18 +1,51 @@ -module(ephraim_conv). --compile([debug_info, export_all]). +-behaviour(gen_server). + +-export([start_link/2]). +-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). +-export([received_message/4]). -record(conv_state, { - my_jid :: binary(), - jid :: binary() + conv_ref :: reference(), + event_manager :: pid(), + my_jid :: binary(), + jid :: binary() }). --spec init(binary()) -> ok. -init(JID) -> - io:format("Starting a conversation with ~p~n", [JID]), - +-spec start_link(pid(), binary()) -> ok. +start_link(EventManager, JID) -> + ConvRef = make_ref(), + io:format("Starting conversation ~p with ~p~n", [ConvRef, JID]), + + gen_event:notify(EventManager, {view_update, {conversation, ConvRef, {new, JID}}}), + {jid,MyJID} = ephraim_config:get(jid), - loop(#conv_state{my_jid=list_to_binary(MyJID),jid=JID}), - io:format("Stopping a conversation with ~p~n", [JID]). + gen_server:start_link(?MODULE, #conv_state{conv_ref=ConvRef,event_manager=EventManager,my_jid=list_to_binary(MyJID),jid=JID}, []). + +init(State) -> + process_flag(trap_exit, true), + {ok, State}. + +received_message(Conv, From, Type, Body) -> + gen_server:cast(Conv, {received_message, From, Type, Body}). + +handle_call(_Msg, _From, State) -> + {noreply, State}. + +handle_cast({received_message, From, Type, Body}, State) -> + gen_event:notify(State#conv_state.event_manager, {view_update, {conversation, State#conv_state.conv_ref, {message, From, Type, Body}}}), + {noreply, State}; +handle_cast(_Msg, State) -> + {noreply, State}. + +handle_info(_Msg, State) -> + {ok, State}. +terminate(_Reason, State) -> + io:format("Stopping conversation ~p with ~p~n", [State#conv_state.conv_ref, State#conv_state.jid]), + ok. +code_change(_OldVersion, State, _Extra) -> + {ok, State}. + -spec loop(#conv_state{}) -> ok. loop(State) -> diff --git a/src/core/ephraim_conv_handler.erl b/src/core/ephraim_conv_handler.erl new file mode 100644 index 0000000..e525d99 --- /dev/null +++ b/src/core/ephraim_conv_handler.erl @@ -0,0 +1,71 @@ +-module(ephraim_conv_handler). +-include_lib("exmpp/include/exmpp_client.hrl"). +-behaviour(gen_event). +-export([start/2]). +-export([init/1, handle_event/2, handle_call/2, handle_info/2, terminate/2, code_change/3]). + +-record(conv_handler_state, { + supervisor :: pid(), + event_manager :: pid(), + convs = dict:new() :: dict() + }). + +start(Supervisor, EventManager) -> + gen_event:add_handler(EventManager, ?MODULE, {Supervisor, EventManager}). + +init({Supervisor, EventManager}) -> + State = #conv_handler_state{supervisor=Supervisor,event_manager=EventManager}, + {ok, State}. + +-spec get_conv(#conv_handler_state{},exmpp_jid:jid()) -> {#conv_handler_state{},pid()|undefined}. +get_conv(State, JID) -> + {Node, Domain, Resource} = exmpp_jid:to_lower(exmpp_jid:parse(JID)), + + case Resource of + undefined -> + {State, undefined}; + _ -> + Key = list_to_binary([Node, <<"@">>, Domain, <<"/">>, Resource]), + + case dict:find(Key, State#conv_handler_state.convs) of + {ok, Conv} -> + {State, Conv}; + error -> + {ok, Conv} = supervisor:start_child(State#conv_handler_state.supervisor, + {Key, {ephraim_conv, start_link, [State#conv_handler_state.event_manager, JID]}, transient, 1000, worker, [ephraim_conv]}), + Dict = dict:store(Key, Conv, State#conv_handler_state.convs), + {State#conv_handler_state{convs=Dict}, Conv} + end + end. + +handle_event({received_packet, #received_packet{packet_type=message, raw_packet=Packet}}, State) -> + From = exmpp_xml:get_attribute(Packet, from, <<"unknown">>), + Type = exmpp_message:get_type(Packet), + Body = exmpp_message:get_body(Packet), + NewState = if + Body =/= undefined -> + {State2, Conv} = get_conv(State, From), + if + Conv =/= undefined -> + ephraim_conv:received_message(Conv, From, Type, Body); + true -> + ok + end, + State2; + true -> + io:format("Received strange message from ~p:~n~p~n", [From, Packet]), + State + end, + {ok, NewState}; + +handle_event(_Event, State) -> + {ok, State}. + +handle_call(_Msg, State) -> + {noreply, State}. +handle_info(_Msg, State) -> + {ok, State}. +terminate(_Reason, _State) -> + ok. +code_change(_OldVersion, State, _Extra) -> + {ok, State}. diff --git a/src/core/ephraim_conv_man.erl b/src/core/ephraim_conv_man.erl new file mode 100644 index 0000000..617ccc4 --- /dev/null +++ b/src/core/ephraim_conv_man.erl @@ -0,0 +1,12 @@ +-module(ephraim_conv_man). +-behaviour(supervisor). +-export([start_link/1]). +-export([init/1]). + +start_link(EventManager) -> + {ok, Pid} = supervisor:start_link(?MODULE, []), + ephraim_conv_handler:start(Pid, EventManager), + {ok, Pid}. + +init(_Args) -> + {ok, {{one_for_one, 0, 1}, []}}. diff --git a/src/core/ephraim_gui.erl b/src/core/ephraim_gui.erl index 92ab521..7bf4b74 100644 --- a/src/core/ephraim_gui.erl +++ b/src/core/ephraim_gui.erl @@ -30,7 +30,7 @@ handle_info({Port, {data, Data}}, Port) -> init:stop(), remove_handler; _ -> - ephraim:notify({view_event, Msg}), + ephraim:notify({view_request, Msg}), {ok, Port} end; diff --git a/src/core/ephraim_roster.erl b/src/core/ephraim_roster.erl index f111f38..605d019 100644 --- a/src/core/ephraim_roster.erl +++ b/src/core/ephraim_roster.erl @@ -40,6 +40,8 @@ init({EventManager, Connection}) -> process_flag(trap_exit, true), ephraim_roster_handler:start(EventManager, self()), + io:format("Getting roster...~n"), + ephraim_conn:send_packet(Connection, exmpp_client_roster:get_roster("foo")), {ok, #roster_state{event_manager=EventManager,connection=Connection,entries=dict:new()}}. -spec updateResource(#roster_state{}, binary(), integer(), atom(), atom(), binary()) -> #roster_state{}. -- cgit v1.2.3