+ * send data to the remote socket join instance
+ */
+int admin_message_to_join(struct admin_msg *msg, char *remote)
+{
+ class Join *join;
+ struct admin_list *admin;
+
+ /* hello message */
+ if (msg->type == MESSAGE_HELLO)
+ {
+ if (remote[0])
+ {
+ PERROR("Remote application repeats hello message.\n");
+ return(-1);
+ }
+ /* look for second application */
+ admin = admin_first;
+ while(admin)
+ {
+ if (!strcmp(admin->remote, msg->param.hello.application))
+ break;
+ admin = admin->next;
+ }
+ if (admin)
+ {
+ PERROR("Remote application connects twice??? (ignoring)\n");
+ return(-1);
+ }
+ /* set asterisk socket instance */
+ SCPY(remote, msg->param.hello.application);
+ return(0);
+ }
+
+ /* check we already have no application name */
+ if (!remote[0])
+ {
+ PERROR("Remote application did not send us a hello message.\n");
+ return(-1);
+ }
+
+ /* new join */
+ if (msg->type == MESSAGE_NEWREF)
+ {
+ /* create new join instance */
+ join = new JoinRemote(0, remote); // must have no serial, because no endpoint is connected
+ if (!join)
+ FATAL("No memory for remote join instance\n");
+ return(0);
+ }
+
+ /* check for ref */
+ if (!msg->ref)
+ {
+ PERROR("Remote application did not send us a valid ref with a message.\n");
+ return(-1);
+ }
+
+ /* find join instance */
+ join = join_first;
+ while(join)
+ {
+ if (join->j_serial == msg->ref)
+ break;
+ join = join->next;
+ }
+
+ /* check application */
+ if (join->j_type != JOIN_TYPE_REMOTE)
+ {
+ PERROR("Ref %d does not belong to a remote join instance.\n", msg->ref);
+ return(-1);
+ }
+ if (!!strcmp(remote, ((class JoinRemote *)join)->j_remote))
+ {
+ PERROR("Ref %d belongs to remote application %s, but not to sending application %s.\n", msg->ref, ((class JoinRemote *)join)->j_remote, remote);
+ return(-1);
+ }
+
+ /* send message */
+ ((class JoinRemote *)join)->message_remote(msg->ref, msg->type, &msg->param);
+
+ return(0);
+}
+
+
+/*
+ * this function is called for every message to remote socket
+ */
+int admin_message_from_join(char *remote, unsigned long ref, int message_type, union parameter *param)
+{
+ struct admin_list *admin;
+ struct admin_queue *response, **responsep; /* response pointer */
+
+ /* searching for admin id
+ * maybe there is no given remote application
+ */
+ admin = admin_first;
+ while(admin)
+ {
+ if (admin->remote[0] && !strcmp(admin->remote, remote))
+ break;
+ admin = admin->next;
+ }
+ /* no given remote application connected */
+ if (!admin)
+ return(-1);
+
+ /* seek to end of response list */
+ response = admin->response;
+ responsep = &admin->response;
+ while(response)
+ {
+ responsep = &response->next;
+ response = response->next;
+ }
+
+ /* create state response */
+ response = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message));
+ memuse++;
+ response->num = 1;
+
+ /* message */
+ response->am[0].u.msg.type = message_type;
+ response->am[0].u.msg.ref = ref;
+ memcpy(&response->am[0].u.msg.param, param, sizeof(union parameter));
+
+ /* attach to response chain */
+ *responsep = response;
+ responsep = &response->next;
+
+ return(0);
+}
+
+
+/*