comms[$key] ?? 0; case 'ls_rxAttnStr': return $this->comms[$key] ?? ''; default: throw new Exception('Unknown key: '.$key); } } /** * @throws Exception */ public function __set($key,$value) { switch ($key) { case 'ls_rxAttnStr': case 'ls_SkipGuard': case 'rxOptions': $this->comms[$key] = $value; break; default: throw new Exception('Unknown key: '.$key); } } /** * We got an error, close anything we are have open * * @throws Exception */ protected function error_close(): void { if ($this->send->fd) $this->send->close(FALSE); if ($this->recv->fd) $this->recv->close(); } /** * Incoming Protocol session * * @param SocketClient $client * @return int|null * @throws SocketException */ public function onConnect(SocketClient $client): ?int { $pid = pcntl_fork(); if ($pid == -1) throw new SocketException(SocketException::CANT_ACCEPT,'Could not fork process'); Log::debug(sprintf('%s: = End [%d]',__METHOD__,$pid)); // Parent return ready for next connection return $pid; } protected function optionClear(int $key): void { $this->options &= ~$key; } protected function optionGet(int $key): int { return ($this->options & $key); } protected function optionSet(int $key): void { $this->options |= $key; } /** * Initialise our Session * * @param int $type * @param SocketClient $client * @param NodeModel|null $o * @return int * @throws Exception */ public function session(int $type,SocketClient $client,NodeModel $o=NULL): int { Log::debug(sprintf('%s: + Start [%d]',__METHOD__,$type)); // This sessions options $this->options = 0; $this->session = 0; // Our files that we are sending/receive $this->send = new Send; $this->recv = new Receive; if ($o) { // Our configuration and initialise values $this->setup = Setup::findOrFail(self::setup); // The node we are communicating with $this->node = new Node; $this->originate = $o->exists; // If we are connecting to a node if ($o->exists) { $this->node->originate($o); } else { $this->optionSet(self::O_INB); } } // We are an IP node $this->optionSet(self::O_TCP); $this->setClient($client); switch ($type) { /** @noinspection PhpMissingBreakStatementInspection */ case self::SESSION_AUTO: Log::debug(sprintf('%s: - Trying EMSI',__METHOD__)); $rc = $this->protocol_init(); if ($rc < 0) { Log::error(sprintf('%s: ! Unable to start EMSI [%d]',__METHOD__,$rc)); return self::S_REDIAL | self::S_ADDTRY; } case self::SESSION_EMSI: Log::debug(sprintf('%s: - Starting EMSI',__METHOD__)); $rc = $this->protocol_session(); break; case self::SESSION_BINKP: Log::debug(sprintf('%s: - Starting BINKP',__METHOD__)); $rc = $this->protocol_session(); break; case self::SESSION_ZMODEM: Log::debug(sprintf('%s: - Starting ZMODEM',__METHOD__)); $this->client->speed = SocketClient::TCP_SPEED; $this->originate = FALSE; // @todo While Debugging $this->send->add('/tmp/aa'); return $this->protocol_session(); default: Log::error(sprintf('%s: ! Unsupported session type [%d]',__METHOD__,$type)); return self::S_REDIAL | self::S_ADDTRY; } // @todo Unlock outbounds // @todo These flags determine when we connect to the remote. // If the remote indicated that they dont support file requests (NRQ) or temporarily hold them (HRQ) if (($this->node->optionGet(self::O_NRQ) && (! $this->setup->ignore_nrq)) || $this->node->optionGet(self::O_HRQ)) $rc |= self::S_HOLDR; if ($this->optionGet(self::O_HXT)) $rc |= self::S_HOLDX; if ($this->optionGet(self::O_HAT)) $rc |= self::S_HOLDA; Log::info(sprintf('%s: Total: %s - %d:%02d:%02d online, (%d) %lu%s sent, (%d) %lu%s received - %s', __METHOD__, $this->node->ftn, $this->node->session_time/3600, $this->node->session_time%3600/60, $this->node->session_time%60, $this->send->total_sent,$this->send->total_sent_bytes,'b', $this->recv->total_recv,$this->recv->total_recv_bytes,'b', (($rc & self::S_MASK) == self::S_OK) ? 'Successful' : 'Failed', )); // @todo Log to history log in the DB. //if ($this->node->start_time && $this->setup->cfg('CFG_HISTORY')) {} // @todo Optional after session execution event // if ($this->node->start_time && $this->setup->cfg('CFG_AFTERSESSION')) {} // @todo Optional after session includes mail event // if ($this->node->start_time && $this->setup->cfg('CFG_AFTERMAIL')) {} return ($rc & ~self::S_ADDTRY); } /** * Clear a session bit * * @param int $key */ protected function sessionClear(int $key): void { $this->session &= ~$key; } /** * Get a session bit * @param int $key * @return bool */ protected function sessionGet(int $key): bool { return ($this->session & $key); } /** * Set a session bit (with SE_*) * * @param int $key */ protected function sessionSet(int $key): void { $this->session |= $key; } /** * Set our client that we are communicating with * * @param SocketClient $client */ private function setClient(SocketClient $client): void { $this->client = $client; } }