ftl_status_t _ingest_connect()

in libftl/handshake.c [137:262]


ftl_status_t _ingest_connect(ftl_stream_configuration_private_t *ftl) {
  ftl_response_code_t response_code = FTL_INGEST_RESP_UNKNOWN;
  char response[MAX_INGEST_COMMAND_LEN];

  if (ftl_get_state(ftl, FTL_CONNECTED)) {
    return FTL_ALREADY_CONNECTED;
  }

  if (ftl->ingest_socket <= 0) {
    return FTL_SOCKET_NOT_CONNECTED;
  }

  do {

    if (!ftl_get_hmac(ftl->ingest_socket, ftl->key, ftl->hmacBuffer)) {
      FTL_LOG(ftl, FTL_LOG_ERROR, "could not get a signed HMAC!");
      response_code = FTL_INGEST_NO_RESPONSE;
      break;
    }

    if ((response_code = _ftl_send_command(ftl, TRUE, response, sizeof(response), "CONNECT %d $%s", ftl->channel_id, ftl->hmacBuffer)) != FTL_INGEST_RESP_OK) {
      break;
    }

    /* We always send our version component first */
    if ((response_code = _ftl_send_command(ftl, FALSE, response, sizeof(response), "ProtocolVersion: %d.%d", FTL_VERSION_MAJOR, FTL_VERSION_MINOR)) != FTL_INGEST_RESP_OK) {
      break;
    }

    /* Cool. Now ingest wants our stream meta-data, which we send as key-value pairs, followed by a "." */
    if ((response_code = _ftl_send_command(ftl, FALSE, response, sizeof(response), "VendorName: %s", ftl->vendor_name)) != FTL_INGEST_RESP_OK) {
      break;
    }

    if ((response_code = _ftl_send_command(ftl, FALSE, response, sizeof(response), "VendorVersion: %s", ftl->vendor_version)) != FTL_INGEST_RESP_OK) {
      break;
    }

    ftl_video_component_t *video = &ftl->video;
    /* We're sending video */
    if ((response_code = _ftl_send_command(ftl, FALSE, response, sizeof(response), "Video: true")) != FTL_INGEST_RESP_OK) {
      break;
    }

    if ((response_code = _ftl_send_command(ftl, FALSE, response, sizeof(response), "VideoCodec: %s", ftl_video_codec_to_string(video->codec))) != FTL_INGEST_RESP_OK) {
      break;
    }

    if ((response_code = _ftl_send_command(ftl, FALSE, response, sizeof(response), "VideoHeight: %d", video->height)) != FTL_INGEST_RESP_OK) {
      break;
    }

    if ((response_code = _ftl_send_command(ftl, FALSE, response, sizeof(response), "VideoWidth: %d", video->width)) != FTL_INGEST_RESP_OK) {
      break;
    }

    if ((response_code = _ftl_send_command(ftl, FALSE, response, sizeof(response), "VideoPayloadType: %d", video->media_component.payload_type)) != FTL_INGEST_RESP_OK) {
      break;
    }

    if ((response_code = _ftl_send_command(ftl, FALSE, response, sizeof(response), "VideoIngestSSRC: %d", video->media_component.ssrc)) != FTL_INGEST_RESP_OK) {
      break;
    }

    ftl_audio_component_t *audio = &ftl->audio;

    if ((response_code = _ftl_send_command(ftl, FALSE, response, sizeof(response), "Audio: true")) != FTL_INGEST_RESP_OK) {
      break;
    }

    if ((response_code = _ftl_send_command(ftl, FALSE, response, sizeof(response), "AudioCodec: %s", ftl_audio_codec_to_string(audio->codec))) != FTL_INGEST_RESP_OK) {
      break;
    }

    if ((response_code = _ftl_send_command(ftl, FALSE, response, sizeof(response), "AudioPayloadType: %d", audio->media_component.payload_type)) != FTL_INGEST_RESP_OK) {
      break;
    }

    if ((response_code = _ftl_send_command(ftl, FALSE, response, sizeof(response), "AudioIngestSSRC: %d", audio->media_component.ssrc)) != FTL_INGEST_RESP_OK) {
      break;
    }

    if ((response_code = _ftl_send_command(ftl, TRUE, response, sizeof(response), ".")) != FTL_INGEST_RESP_OK) {
      break;
    }

    /*see if there is a port specified otherwise use default*/
    int port = ftl_read_media_port(response);

    ftl->media.assigned_port = port;

    ftl_set_state(ftl, FTL_CONNECTED);

    if (os_semaphore_create(&ftl->connection_thread_shutdown, "/ConnectionThreadShutdown", O_CREAT, 0) < 0) {
        response_code = FTL_MALLOC_FAILURE;
        break;
    }

    if (os_semaphore_create(&ftl->keepalive_thread_shutdown, "/KeepAliveThreadShutdown", O_CREAT, 0) < 0) {
        response_code = FTL_MALLOC_FAILURE;
        break;
    }

    ftl_set_state(ftl, FTL_CXN_STATUS_THRD);
    if ((os_create_thread(&ftl->connection_thread, NULL, connection_status_thread, ftl)) != 0) {
      ftl_clear_state(ftl, FTL_CXN_STATUS_THRD);
      response_code = FTL_MALLOC_FAILURE;
      break;
    }

    ftl_set_state(ftl, FTL_KEEPALIVE_THRD);
    if ((os_create_thread(&ftl->keepalive_thread, NULL, control_keepalive_thread, ftl)) != 0) {
      ftl_clear_state(ftl, FTL_KEEPALIVE_THRD);\
      response_code = FTL_MALLOC_FAILURE;
      break;
    }

    FTL_LOG(ftl, FTL_LOG_INFO, "Successfully connected to ingest.  Media will be sent to port %d\n", ftl->media.assigned_port);
  
    return FTL_SUCCESS;
  } while (0);

  _ingest_disconnect(ftl);

  return _log_response(ftl, response_code);;
}