svg_status_t
_svg_android_set_font_size (void *closure, double size)
{
	svg_android_t *svg_android = closure;

	DEBUG_ENTRY("set_font_size");
	svg_android->state->font_size = size;
	svg_android->state->font_dirty = 1;
	DEBUG_EXIT("set_font_size");

	return SVG_ANDROID_STATUS_SUCCESS;
}
/**********************************************************
Required procedure of NDIS
NDIS wants to cancel sending of each list which has specified CancelID
Can be tested only under NDIS Test
***********************************************************/
VOID ParaNdis6_CancelSendNetBufferLists(
    NDIS_HANDLE  miniportAdapterContext,
    PVOID pCancelId)
{
    PARANDIS_ADAPTER *pContext = (PARANDIS_ADAPTER *)miniportAdapterContext;

    DEBUG_ENTRY(0);
    for (UINT i = 0; i < pContext->nPathBundles; i++)
    {
        pContext->pPathBundles[i].txPath.CancelNBLs(pCancelId);
    }
}
svg_status_t
_svg_android_set_font_style (void *closure, svg_font_style_t font_style)
{
	svg_android_t *svg_android = closure;

	DEBUG_ENTRY("set_font_style");
	svg_android->state->font_style = font_style;
	svg_android->state->font_dirty = 1;
	DEBUG_EXIT("set_font_style");

	return SVG_ANDROID_STATUS_SUCCESS;
}
svg_status_t
_svg_android_set_font_weight (void *closure, unsigned int font_weight)
{
	svg_android_t *svg_android = closure;

	DEBUG_ENTRY("set_font_weight");
	svg_android->state->font_weight = font_weight;
	svg_android->state->font_dirty = 1;
	DEBUG_EXIT("set_font_weight");

	return SVG_ANDROID_STATUS_SUCCESS;
}
/**********************************************************
    callback from asynchronous SEND PAUSE
***********************************************************/
static void OnSendPauseComplete(PARANDIS_ADAPTER *pContext)
{
    NDIS_STATUS  status;
    DEBUG_ENTRY(0);
    status = ParaNdis6_ReceivePauseRestart(pContext, TRUE, OnReceivePauseComplete);
    if (status != NDIS_STATUS_PENDING)
    {
        // pause exit
        ParaNdis_DebugHistory(pContext, hopSysPause, NULL, 0, 0, 0);
        NdisMPauseComplete(pContext->MiniportHandle);
    }
}
svg_status_t
_svg_android_render_rect (void *closure,
			  svg_length_t *x_len,
			  svg_length_t *y_len,
			  svg_length_t *width_len,
			  svg_length_t *height_len,
			  svg_length_t *rx_len,
			  svg_length_t *ry_len)
{
	svg_android_t *svg_android = closure;

	double x, y, width, height, rx, ry;
 
	DEBUG_ENTRY("render_rect");
	_svg_android_length_to_pixel (svg_android, x_len, &x);
	_svg_android_length_to_pixel (svg_android, y_len, &y);
	_svg_android_length_to_pixel (svg_android, width_len, &width);
	_svg_android_length_to_pixel (svg_android, height_len, &height);
	_svg_android_length_to_pixel (svg_android, rx_len, &rx);
	_svg_android_length_to_pixel (svg_android, ry_len, &ry);
 
	if (rx > width / 2.0)
		rx = width / 2.0;
	if (ry > height / 2.0)
		ry = height / 2.0;

	if (rx > 0 || ry > 0)
	{
		_svg_android_move_to (svg_android, x + rx, y);
		_svg_android_line_to (svg_android, x + width - rx, y);
		_svg_android_arc_to  (svg_android, rx, ry, 0, 0, 1, x + width, y + ry);
		_svg_android_line_to (svg_android, x + width, y + height - ry);
		_svg_android_arc_to  (svg_android, rx, ry, 0, 0, 1, x + width - rx, y + height);
		_svg_android_line_to (svg_android, x + rx, y + height);
		_svg_android_arc_to  (svg_android, rx, ry, 0, 0, 1, x, y + height - ry);
		_svg_android_line_to (svg_android, x, y + ry);
		_svg_android_arc_to  (svg_android, rx, ry, 0, 0, 1, x + rx, y);
	}
	else
	{
		_svg_android_move_to (svg_android, x, y);
		_svg_android_line_to (svg_android, x + width, y);
		_svg_android_line_to (svg_android, x + width, y + height);
		_svg_android_line_to (svg_android, x, y + height);
	}
	_svg_android_close_path (svg_android);

	_svg_android_render_path (svg_android);

	DEBUG_EXIT("render_rect");
	return SVG_ANDROID_STATUS_SUCCESS;
}
Example #7
0
//
// Creates a TCP/IP server by binding to a socket and listening. The 
// returned data structure can be used to 'tcp_accept' incoming
// connections.
//
tcp_server *tcp_server_create( unsigned int port, unsigned int backlog )
{
    int n;
    tcp_server *s;

    DEBUG_ENTRY( "tcp_server_create()" )

        s = malloc( sizeof( tcp_server ) );
    if ( s == NULL ) {
        perror( "malloc" );
        DEBUG_EXIT( "tcp_server_create()" )
            return NULL;
    }
Example #8
0
void make_measurements(u8 num_double_diffs, const sdiff_t *sdiffs, double *raw_measurements)
{
  DEBUG_ENTRY();

  double phase0 = sdiffs[0].carrier_phase;
  double code0 = sdiffs[0].pseudorange;
  for (u8 i=0; i<num_double_diffs; i++) {
    raw_measurements[i] = sdiffs[i+1].carrier_phase - phase0;
    raw_measurements[i+num_double_diffs] = sdiffs[i+1].pseudorange - code0;
  }

  DEBUG_EXIT();
}
svg_status_t
_svg_android_end_element (void *closure)
{
	svg_android_t *svg_android = closure;

	DEBUG_ENTRY("end_element");
	_svg_android_pop_state (svg_android);

	ANDROID_RESTORE(svg_android);

	DEBUG_EXIT("end_element");
	return SVG_ANDROID_STATUS_SUCCESS;
}
svg_status_t
_svg_android_set_stroke_miter_limit (void *closure, double limit)
{
	svg_android_t *svg_android = closure;

	DEBUG_ENTRY("set_stroke_miter_limit");
	ANDROID_PAINT_SET_MITER_LIMIT(svg_android, limit);

	svg_android->state->miter_limit = limit;
	DEBUG_EXIT("set_stroke_miter_limit");
	
	return SVG_ANDROID_STATUS_SUCCESS;
}
svg_status_t
_svg_android_close_path (void *closure)
{
	svg_android_t *svg_android = closure;

	DEBUG_ENTRY("close_path");
	ANDROID_PATH_CLOSE(svg_android);
	svg_android->state->last_x = 0.0; // don't know if this is right, really... 
	svg_android->state->last_y = 0.0;
	DEBUG_EXIT("close_path");

	return SVG_ANDROID_STATUS_SUCCESS;
}
svg_status_t
_svg_android_line_to (void *closure, double x, double y)
{
	svg_android_t *svg_android = closure;

	DEBUG_ENTRY("line_to");
	ANDROID_PATH_LINE_TO(svg_android, x, y);
	svg_android->state->last_x = x;
	svg_android->state->last_y = y;
	DEBUG_EXIT("line_to");

	return SVG_ANDROID_STATUS_SUCCESS;
}
/* XXX: begin_element could be made more efficient in that no extra
   group is needed if there is only one element in a group */
svg_status_t
_svg_android_begin_element (void *closure)
{
	svg_android_t *svg_android = closure;

	DEBUG_ENTRY("begin_element");
	ANDROID_SAVE(svg_android);

	_svg_android_push_state (svg_android, NULL);

	DEBUG_EXIT("begin_element");
	return SVG_ANDROID_STATUS_SUCCESS;
}
svg_status_t
_svg_android_pop_state (svg_android_t *svg_android)
{
	DEBUG_ENTRY("pop_state");
	svg_android->state = _svg_android_state_pop (svg_android->state);

	if (svg_android->state && svg_android->state->saved_canvas) {
		svg_android->canvas = svg_android->state->saved_canvas;
		svg_android->state->saved_canvas = NULL;
	}
	DEBUG_EXIT("pop_state");

	return SVG_STATUS_SUCCESS;
}
/* TODO use the set abstraction fnoble is working on. */
static void set_reference_sat(const u8 ref_prn, sats_management_t *sats_management,
                              const u8 num_sdiffs, const sdiff_t *sdiffs, sdiff_t *sdiffs_with_ref_first)
{
  DEBUG_ENTRY();

  u8 old_ref = sats_management->prns[0];
  log_debug("ref_prn = %u", ref_prn);
  log_debug("old_ref = %u", old_ref);
  u8 j;
  if (old_ref != ref_prn) {
    j = 1;
    u8 old_prns[sats_management->num_sats];
    memcpy(old_prns, sats_management->prns, sats_management->num_sats * sizeof(u8));
    u8 set_old_yet = 0;
    sats_management->prns[0] = ref_prn;
    for (u8 i=1; i<sats_management->num_sats; i++) {
      if (old_prns[i] != ref_prn) {
        if (old_prns[i]>old_ref && set_old_yet == 0) {
          sats_management->prns[j] = old_ref;
          j++;
          i--;
          set_old_yet++;
        }
        else {
          sats_management->prns[j] = old_prns[i];
          j++;
        }
      }
    }
    if (set_old_yet == 0) {
      sats_management->prns[j] = old_ref;
      set_old_yet++;
    }
    assert(set_old_yet == 1);
  }

  j=1;
  for (u8 i=0; i<num_sdiffs; i++) {
    if (sdiffs[i].prn != ref_prn) {
      log_debug("prn[%u] = %u", j, sdiffs[i].prn);
      memcpy(&sdiffs_with_ref_first[j], &sdiffs[i], sizeof(sdiff_t));
      j++;
    } else {
      log_debug("prn[0] = %u", sdiffs[i].prn);
      memcpy(&sdiffs_with_ref_first[0], &sdiffs[i], sizeof(sdiff_t));
    }
  }

  DEBUG_EXIT();
}
svg_status_t
_svg_android_render_text (void *closure,
			  svg_length_t *x_len,
			  svg_length_t *y_len,
			  const char *utf8)
{
	svg_android_t *svg_android = closure;
	double x, y;
	svg_status_t status;
	svg_paint_t *fill_paint, *stroke_paint;

	DEBUG_ENTRY("render_text");
	fill_paint = &svg_android->state->fill_paint;
	stroke_paint = &svg_android->state->stroke_paint;

	_svg_android_select_font (svg_android);

	_svg_android_length_to_pixel (svg_android, x_len, &x);
	_svg_android_length_to_pixel (svg_android, y_len, &y);
	
	status = _svg_android_move_to (svg_android, x, y);
	if (status)
		return status;

	ANDROID_TEXT_PATH(svg_android, utf8, x, y);
	_svg_android_render_path (svg_android);
	
#if 0 // this code doesn't work with renderToArea
	if (fill_paint->type) {
		_svg_android_set_paint_and_opacity (svg_android, fill_paint,
						    svg_android->state->fill_opacity,
						    SVG_ANDROID_RENDER_TYPE_FILL);

//		ANDROID_DRAW_TEXT(svg_android, utf8, 0.0, 0.0);
		ANDROID_DRAW_TEXT(svg_android, utf8, x, y);
	}

	if (stroke_paint->type) {
		_svg_android_set_paint_and_opacity (svg_android, stroke_paint,
						    svg_android->state->stroke_opacity,
						    SVG_ANDROID_RENDER_TYPE_STROKE);

		ANDROID_DRAW_TEXT(svg_android, utf8, x, y);
	}

#endif
	DEBUG_EXIT("render_text");
	return SVG_ANDROID_STATUS_SUCCESS;
}
/**********************************************************
NDIS-required procedure for hardware interrupt registration
Parameters:
    IN PVOID MiniportInterruptContext (actually Adapter context)
***********************************************************/
static VOID MiniportEnableInterruptEx(IN PVOID MiniportInterruptContext)
{
    DEBUG_ENTRY(0);
    PARANDIS_ADAPTER *pContext = (PARANDIS_ADAPTER *)MiniportInterruptContext;

    for (UINT i = 0; i < pContext->nPathBundles; i++)
    {
        pContext->pPathBundles[i].txPath.EnableInterrupts();
        pContext->pPathBundles[i].rxPath.EnableInterrupts();
    }
    if (pContext->bCXPathCreated)
    {
        pContext->CXPath.EnableInterrupts();
    }
}
/**********************************************************
NDIS-required procedure for DPC handling
Parameters:
    PVOID  MiniportInterruptContext (Adapter context)
***********************************************************/
static VOID MiniportInterruptDPC(
    IN NDIS_HANDLE  MiniportInterruptContext,
    IN PVOID  MiniportDpcContext,
    IN PVOID                   ReceiveThrottleParameters,
    IN PVOID                   NdisReserved2
    )
{
    PARANDIS_ADAPTER *pContext = (PARANDIS_ADAPTER *)MiniportInterruptContext;
    bool requiresDPCRescheduling;

#if NDIS_SUPPORT_NDIS620
    PNDIS_RECEIVE_THROTTLE_PARAMETERS RxThrottleParameters = (PNDIS_RECEIVE_THROTTLE_PARAMETERS)ReceiveThrottleParameters;
    DEBUG_ENTRY(5);
    RxThrottleParameters->MoreNblsPending = 0;
    requiresDPCRescheduling = ParaNdis_DPCWorkBody(pContext, RxThrottleParameters->MaxNblsToIndicate);
    if (requiresDPCRescheduling)
        {
            GROUP_AFFINITY Affinity;
            GetAffinityForCurrentCpu(&Affinity);

            NdisMQueueDpcEx(pContext->InterruptHandle, 0, &Affinity, MiniportDpcContext);
        }
#else /* NDIS 6.0*/
    DEBUG_ENTRY(5);
    UNREFERENCED_PARAMETER(ReceiveThrottleParameters);

    requiresDPCRescheduling = ParaNdis_DPCWorkBody(pContext, PARANDIS_UNLIMITED_PACKETS_TO_INDICATE);
    if (requiresDPCRescheduling)
    {
        DPrintf(4, ("[%s] Queued additional DPC for %d\n", __FUNCTION__,  requiresDPCRescheduling));
        NdisMQueueDpc(pContext->InterruptHandle, 0, 1 << KeGetCurrentProcessorNumber(), MiniportDpcContext);
    }
#endif /* NDIS_SUPPORT_NDIS620 */

    UNREFERENCED_PARAMETER(NdisReserved2);
}
static void OnResetWorkItem(NDIS_WORK_ITEM * pWorkItem, PVOID  Context)
{
	tGeneralWorkItem *pwi = (tGeneralWorkItem *)pWorkItem;
	PARANDIS_ADAPTER *pContext = pwi->pContext;
	DEBUG_ENTRY(0);

	ParaNdis_IndicateConnect(pContext, FALSE, FALSE);
	ParaNdis_Suspend(pContext);
	ParaNdis_Resume(pContext);
	ParaNdis_ReportLinkStatus(pContext);

	NdisFreeMemory(pwi, 0, 0);
	ParaNdis_DebugHistory(pContext, hopSysReset, NULL, 0, NDIS_STATUS_SUCCESS, 0);
	NdisMResetComplete(pContext->MiniportHandle, NDIS_STATUS_SUCCESS, TRUE);
}
svg_status_t
_svg_android_set_font_family (void *closure, const char *family)
{
	svg_android_t *svg_android = closure;

	DEBUG_ENTRY("set_font_family");
	if (svg_android->state->font_family)
		free (svg_android->state->font_family);

	svg_android->state->font_family = strdup (family);
	svg_android->state->font_dirty = 1;
	DEBUG_EXIT("set_font_family");

	return SVG_ANDROID_STATUS_SUCCESS;
}
void measure_b_with_external_ambs(u8 state_dim, const double *state_mean,
                                  u8 num_sdiffs, sdiff_t *sdiffs,
                                  const double receiver_ecef[3], double *b)
{
  DEBUG_ENTRY();

  sdiff_t sdiffs_with_ref_first[num_sdiffs];
  /* We require the sats updating has already been done with these sdiffs */
  u8 ref_prn = sats_management.prns[0];
  copy_sdiffs_put_ref_first(ref_prn, num_sdiffs, sdiffs, sdiffs_with_ref_first);

  measure_b(state_dim, state_mean, num_sdiffs, sdiffs_with_ref_first, receiver_ecef, b);

  DEBUG_EXIT();
}
svg_status_t
_svg_android_quadratic_curve_to (void *closure,
				 double x1, double y1,
				 double x2, double y2)
{
	svg_android_t *svg_android = closure;

	DEBUG_ENTRY("quadratic_curve_to");
	ANDROID_PATH_QUADRATIC_CURVE_TO(svg_android, x1, y1, x2, y2);
	svg_android->state->last_x = x2;
	svg_android->state->last_y = y2;
	DEBUG_EXIT("quadratic_curve_to");

	return SVG_ANDROID_STATUS_SUCCESS;
}
Example #23
0
void measure_iar_b_with_external_ambs(double *state_mean,
                                      u8 num_sdiffs, sdiff_t *sdiffs,
                                      double receiver_ecef[3],
                                      double *b)
{
  DEBUG_ENTRY();

  sdiff_t sdiffs_with_ref_first[num_sdiffs];
  match_sdiffs_to_sats_man(&ambiguity_test.sats, num_sdiffs, sdiffs, sdiffs_with_ref_first);

  measure_b(CLAMP_DIFF(ambiguity_test.sats.num_sats, 1), state_mean,
      num_sdiffs, sdiffs_with_ref_first, receiver_ecef, b);

  DEBUG_EXIT();
}
Example #24
0
void measure_amb_kf_b(u8 num_sdiffs, sdiff_t *sdiffs,
                      const double receiver_ecef[3], double *b)
{
  DEBUG_ENTRY();

  sdiff_t sdiffs_with_ref_first[num_sdiffs];
  /* We require the sats updating has already been done with these sdiffs */
  gnss_signal_t ref_sid = sats_management.sids[0];
  copy_sdiffs_put_ref_first(ref_sid, num_sdiffs, sdiffs, sdiffs_with_ref_first);

  measure_b( nkf.state_dim, nkf.state_mean,
      num_sdiffs, sdiffs_with_ref_first, receiver_ecef, b);

  DEBUG_EXIT();
}
Example #25
0
/** A least squares solution for baseline from phases using the KF state.
 * This uses the current state of the KF and a set of phase observations to
 * solve for the current baseline.
 *
 * \param num_dds_u8            State dimension
 * \param state_mean            KF estimated state mean
 * \param sdiffs_with_ref_first A list of sdiffs. The first in the list must be
 *                              the reference sat of the KF, and the rest must
 *                              correspond to the KF's DD amb estimates' sats,
 *                              sorted in ascending PRN order.
 * \param dd_measurements       A vector of carrier phases. They must be double
 *                              differenced and ordered according to the sdiffs
 *                              and KF's sats (which must match each other).
 * \param ref_ecef              The reference position in ECEF frame, for
 *                              computing the sat direction vectors.
 * \param b                     The output baseline in meters.
 * \param disable_raim          True disables raim check/repair
 * \param raim_threshold        Threshold for raim checks.
 * \return                      See lesq_solve_raim()
 */
s8 least_squares_solve_b_external_ambs(u8 num_dds_u8, const double *state_mean,
         const sdiff_t *sdiffs_with_ref_first, const double *dd_measurements,
         const double ref_ecef[3], double b[3],
         bool disable_raim, double raim_threshold)
{
  DEBUG_ENTRY();

  integer num_dds = num_dds_u8;
  double DE[num_dds * 3];
  assign_de_mtx(num_dds+1, sdiffs_with_ref_first, ref_ecef, DE);

  s8 code = lesq_solve_raim(num_dds_u8, dd_measurements, state_mean, DE, b,
                            disable_raim, raim_threshold, 0, 0, 0);
  DEBUG_EXIT();
  return code;
}
/**********************************************************
NDIS-required procedure for hardware interrupt registration
Parameters:
    IN PVOID MiniportInterruptContext (actually Adapter context)
***********************************************************/
static VOID MiniportDisableInterruptEx(IN PVOID MiniportInterruptContext)
{
    DEBUG_ENTRY(0);
    PARANDIS_ADAPTER *pContext = (PARANDIS_ADAPTER *)MiniportInterruptContext;

    /* TODO - make sure that interrups are not reenabled by the DPC callback*/
    for (UINT i = 0; i < pContext->nPathBundles; i++)
    {
        pContext->pPathBundles[i].txPath.DisableInterrupts();
        pContext->pPathBundles[i].rxPath.DisableInterrupts();
    }
    if (pContext->bCXPathCreated)
    {
        pContext->CXPath.DisableInterrupts();
    }
}
void init_sats_management(sats_management_t *sats_management,
                          const u8 num_sdiffs, const sdiff_t *sdiffs, sdiff_t *sdiffs_with_ref_first)
{
  DEBUG_ENTRY();

  if (num_sdiffs == 0) {
    sats_management->num_sats = 0;
    DEBUG_EXIT();
    return;
  }

  u8 ref_prn = choose_reference_sat(num_sdiffs, sdiffs);
  set_reference_sat_and_prns(ref_prn, sats_management,
                             num_sdiffs, sdiffs, sdiffs_with_ref_first);
  DEBUG_EXIT();
}
static NDIS_STATUS  ParaNdis6_AddDevice(IN NDIS_HANDLE  MiniportAdapterHandle, IN NDIS_HANDLE  MiniportDriverContext)
{
    NDIS_MINIPORT_ADAPTER_ATTRIBUTES  MiniportAttributes;
    NDIS_STATUS status;

    UNREFERENCED_PARAMETER(MiniportDriverContext);

    DEBUG_ENTRY(0);
    MiniportAttributes.AddDeviceRegistrationAttributes.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADD_DEVICE_REGISTRATION_ATTRIBUTES;
    MiniportAttributes.AddDeviceRegistrationAttributes.Header.Revision = NDIS_MINIPORT_ADD_DEVICE_REGISTRATION_ATTRIBUTES_REVISION_1;
    MiniportAttributes.AddDeviceRegistrationAttributes.Header.Size = NDIS_SIZEOF_MINIPORT_ADD_DEVICE_REGISTRATION_ATTRIBUTES_REVISION_1;
    MiniportAttributes.AddDeviceRegistrationAttributes.MiniportAddDeviceContext = MiniportAdapterHandle;
    MiniportAttributes.AddDeviceRegistrationAttributes.Flags = 0;
    status = NdisMSetMiniportAttributes(MiniportAdapterHandle, &MiniportAttributes);
    return status;
}
svg_status_t
_svg_android_curve_to (void *closure,
		       double x1, double y1,
		       double x2, double y2,
		       double x3, double y3)
{
	svg_android_t *svg_android = closure;

	DEBUG_ENTRY("curve_to");
	ANDROID_PATH_CURVE_TO(svg_android, x1, y1, x2, y2, x3, y3);
	svg_android->state->last_x = x3;
	svg_android->state->last_y = y3;
	DEBUG_EXIT("curve_to");

	return SVG_ANDROID_STATUS_SUCCESS;
}
//assumes both sets are ordered
static u8 intersect_sats(const u8 num_sats1, const u8 num_sdiffs, const u8 *sats1,
                         const sdiff_t *sdiffs, sdiff_t *intersection_sats)
{
  DEBUG_ENTRY();

  u8 i, j, n = 0;
  if(DEBUG) {
    printf("sdiff prns= {");
    for (u8 k=0; k< num_sdiffs; k++) {
      printf("%u, ", sdiffs[k].prn);
    }
    printf("}\n");
    printf("sats= {");
    for (u8 k=0; k< num_sats1; k++) {
      printf("%u, ", sats1[k]);
    }
    printf("}\n");
    printf("(n, i, prn1[i],\t j, prn2[j])\n");
  }
  /* Loop over sats1 and sdffs and check if a PRN is present in both. */
  for (i=0, j=0; i<num_sats1 && j<num_sdiffs; i++, j++) {
    if (sats1[i] < sdiffs[j].prn) {
      log_debug("(%u, %u, prn1=%u,\t %u, prn2=%u)\t\t prn1 < prn2  i++", n, i, sats1[i], j, sdiffs[j].prn);
      j--;
    }
    else if (sats1[i] > sdiffs[j].prn) {
      log_debug("(%u, %u, prn1=%u,\t %u, prn2=%u)\t\t prn1 > prn2  j++", n, i, sats1[i], j, sdiffs[j].prn);
      i--;
    }
    else {
      log_debug("(%u, %u, prn1=%u,\t %u, prn2=%u)\t\t prn1 = prn2  i,j,n++", n, i, sats1[i], j, sdiffs[j].prn);
      memcpy(&intersection_sats[n], &sdiffs[j], sizeof(sdiff_t));
      n++;
    }
  }
  if (DEBUG) {
    printf("intersection_sats= {");
    for (u8 k=0; k< n; k++) {
      printf("%u, ", intersection_sats[k].prn);
    }
    printf("}\n");
  }

  DEBUG_EXIT();
  return n;
}