+ case SILC_NOTIFY_TYPE_KILLED:
+ /** KILLED */
+ silc_fsm_next(fsm, silc_client_notify_killed);
+ break;
+
+ case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
+ /** SERVER_SIGNOFF */
+ silc_fsm_next(fsm, silc_client_notify_server_signoff);
+ break;
+
+ case SILC_NOTIFY_TYPE_ERROR:
+ /** ERROR */
+ silc_fsm_next(fsm, silc_client_notify_error);
+ break;
+
+ case SILC_NOTIFY_TYPE_WATCH:
+ /** WATCH */
+ silc_fsm_next(fsm, silc_client_notify_watch);
+ break;
+
+ default:
+ /** Unknown notify */
+ silc_notify_payload_free(payload);
+ silc_packet_free(packet);
+ silc_free(notify);
+ return SILC_FSM_FINISH;
+ break;
+ }
+
+ return SILC_FSM_CONTINUE;
+}
+
+/* Notify processed, finish the packet processing thread */
+
+SILC_FSM_STATE(silc_client_notify_processed)
+{
+ SilcClientNotify notify = state_context;
+ SilcPacket packet = notify->packet;
+ SilcNotifyPayload payload = notify->payload;
+
+ silc_notify_payload_free(payload);
+ silc_packet_free(packet);
+ silc_free(notify);
+ return SILC_FSM_FINISH;
+}
+
+/********************************** NONE ************************************/
+
+SILC_FSM_STATE(silc_client_notify_none)
+{
+ SilcClientConnection conn = fsm_context;
+ SilcClient client = conn->client;
+ SilcClientNotify notify = state_context;
+ SilcNotifyPayload payload = notify->payload;
+ SilcNotifyType type = silc_notify_get_type(payload);
+ SilcArgumentPayload args = silc_notify_get_args(payload);
+
+ SILC_LOG_DEBUG(("Notify: NONE"));
+
+ /* Notify application */
+ NOTIFY(client, conn, type, silc_argument_get_arg_type(args, 1, NULL));
+
+ /** Notify processed */
+ silc_fsm_next(fsm, silc_client_notify_processed);
+ return SILC_FSM_CONTINUE;
+}
+
+/********************************* INVITE ***********************************/
+
+/* Someone invite me to a channel */
+
+SILC_FSM_STATE(silc_client_notify_invite)
+{
+ SilcClientConnection conn = fsm_context;
+ SilcClient client = conn->client;
+ SilcClientNotify notify = state_context;
+ SilcNotifyPayload payload = notify->payload;
+ SilcNotifyType type = silc_notify_get_type(payload);
+ SilcArgumentPayload args = silc_notify_get_args(payload);
+ SilcClientEntry client_entry;
+ SilcChannelEntry channel = NULL;
+ unsigned char *tmp;
+ SilcUInt32 tmp_len;
+ SilcID id;
+
+ SILC_LOG_DEBUG(("Notify: INVITE"));
+
+ /* Get Channel ID */
+ if (!silc_argument_get_decoded(args, 1, SILC_ARGUMENT_ID, &id, NULL))
+ goto out;
+
+ /* Get the channel name */
+ tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
+ if (!tmp)
+ goto out;
+
+ /* Get the channel entry */
+ channel = silc_client_get_channel_by_id(client, conn, &id.u.channel_id);
+ if (!channel) {
+ /** Resolve channel */
+ SILC_FSM_CALL(silc_client_get_channel_by_id_resolve(
+ client, conn, &id.u.channel_id,
+ silc_client_notify_resolved,
+ notify));
+ /* NOT REACHED */
+ }
+
+ /* If channel is being resolved handle notify after resolving */
+ if (channel->internal.resolve_cmd_ident) {
+ silc_client_unref_channel(client, conn, channel);
+ SILC_FSM_CALL(silc_client_command_pending(
+ conn, SILC_COMMAND_NONE,
+ channel->internal.resolve_cmd_ident,
+ silc_client_notify_wait_continue,
+ notify));
+ /* NOT REACHED */
+ }
+
+ /* Get sender Client ID */
+ if (!silc_argument_get_decoded(args, 3, SILC_ARGUMENT_ID, &id, NULL))