예제 #1
0
파일: cs_util.c 프로젝트: Anatolis/naev
/* change the max # of entries sparse matrix */
int cs_sprealloc (cs *A, int nzmax)
{
    int ok, oki, okj = 1, okx = 1 ;
    if (!A) return (0) ;
    if (nzmax <= 0) nzmax = (CS_CSC (A)) ? (A->p [A->n]) : A->nz ;
    A->i = cs_realloc (A->i, nzmax, sizeof (int), &oki) ;
    if (CS_TRIPLET (A)) A->p = cs_realloc (A->p, nzmax, sizeof (int), &okj) ;
    if (A->x) A->x = cs_realloc (A->x, nzmax, sizeof (double), &okx) ;
    ok = (oki && okj && okx) ;
    if (ok) A->nzmax = nzmax ;
    return (ok) ;
}
예제 #2
0
파일: win32.cpp 프로젝트: garinh/cs
void Win32Assistant::DisableConsole ()
{
  if (!console_window) return;
  console_window = false;

  DWORD lasterr;
  csString outName;
  {
    char apppath[MAX_PATH];
    GetModuleFileName (0, apppath, sizeof(apppath));
    lasterr = GetLastError ();
    if (lasterr != ERROR_INSUFFICIENT_BUFFER)
      outName = apppath;
  }
  if (lasterr == ERROR_INSUFFICIENT_BUFFER)
  {
    DWORD bufSize = 2*MAX_PATH;
    char* buf = 0;
    while (lasterr == ERROR_INSUFFICIENT_BUFFER)
    {
      buf = (char*)cs_realloc (buf, bufSize);
      GetModuleFileName (0, buf, bufSize);
      bufSize += MAX_PATH;
      lasterr = GetLastError ();
    }
    outName = buf;
    cs_free (buf);
  }

  {
    size_t basePos = outName.FindLast ('\\');
    if (basePos != (size_t)-1) outName.DeleteAt (0, basePos+1);
  }
  {
    size_t dot = outName.FindLast ('.');
    if (dot != (size_t)-1)
      outName.Overwrite (dot, ".txt");
    else
      outName.Append (".txt");
  }
  {
    char tmp[MAX_PATH];
    if (GetTempPath (sizeof (tmp), tmp) != 0)
      outName.Insert (0, tmp);
  }

  /* Redirect only those handles that were not initially redirected by
   * the user */
  if (!IsStdHandleRedirected (STD_ERROR_HANDLE)) 
    freopen (outName, "w", stderr);
  if (!IsStdHandleRedirected (STD_OUTPUT_HANDLE)) 
    freopen (outName, "w", stdout);
  FreeConsole();

  struct tm *now;
  time_t aclock;
  time( &aclock );
  now = localtime( &aclock );
  csPrintf("====== %s", asctime(now));
}
예제 #3
0
bool array_add(void **arr_data, int32_t *arr_num_entries, uint32_t entry_size, void *new_entry)
{
	if (!cs_realloc(arr_data, (*arr_num_entries + 1) * entry_size))
		return false;
	memcpy(*arr_data + (*arr_num_entries * entry_size), new_entry, entry_size);
	*arr_num_entries += 1;
	return true;
}
예제 #4
0
파일: meshobj.cpp 프로젝트: garinh/cs
void csMeshWrapper::InstancingData::RenderMeshesSet::CopyOriginalMeshes (int n,
  csRenderMesh** origMeshes)
{
  /* This _deliberately_ does not do proper C++ construction/destruction/
     copying.
     csRenderMesh contains a number of csRef<>s and such, but we're really
     only interested in the bbox members, and neither care about nor want to
     pay for the others. Also, the meshes only have to be valid for one
     frame - and if the original meshes are the simple copies are, too. */
  if (n != this->n)
  {
    meshes = (csRenderMesh*)cs_realloc (meshes, n * sizeof (csRenderMesh));
    meshArray = (csRenderMesh**)cs_realloc (meshArray, n * sizeof (csRenderMesh*));
    for (int i = 0; i < n; i++)
      meshArray[i] = meshes+i;
    
    this->n = n;
  }
  for (int i = 0; i < n; i++)
    memcpy (meshes+i, origMeshes[i], sizeof (csRenderMesh));
}
예제 #5
0
static void term_destination (j_compress_ptr cinfo)
{
  my_dst_mgr *dest = (my_dst_mgr*)cinfo->dest;
  size_t len = my_dst_mgr::buf_len - dest->pub.free_in_buffer;

  if (len > 0)
  {
    dest->ds->data = (unsigned char*)cs_realloc (dest->ds->data,
      dest->ds->len + sizeof(JOCTET) * len);
    if (!dest->ds->data)
      ERREXITS(cinfo,JERR_OUT_OF_MEMORY, "Could not reallocate enough memory");
    memcpy(dest->ds->data + dest->ds->len, dest->buffer, sizeof(JOCTET) * len);
    dest->ds->len += sizeof(JOCTET) * len;
  }
}
예제 #6
0
static jpeg_boolean empty_output_buffer (j_compress_ptr cinfo)
{
  my_dst_mgr *dest = (my_dst_mgr*)cinfo->dest;

  dest->ds->data = (unsigned char*)cs_realloc (dest->ds->data,
    dest->ds->len + sizeof(JOCTET) * my_dst_mgr::buf_len);
  if (!dest->ds->data)
    ERREXITS(cinfo,JERR_OUT_OF_MEMORY, "Could not reallocate enough memory");
  memcpy (dest->ds->data + dest->ds->len, dest->buffer,
    sizeof(JOCTET) * my_dst_mgr::buf_len);
  dest->pub.next_output_byte = dest->buffer;
  dest->pub.free_in_buffer = my_dst_mgr::buf_len;
  dest->ds->len += sizeof(JOCTET) * my_dst_mgr::buf_len;
  return true;
}
예제 #7
0
void cs_ri_log(struct s_reader * reader, char *fmt,...)
{
	char txt[256];

	va_list params;
	va_start(params, fmt);
	vsnprintf(txt, sizeof(txt), fmt, params);
	va_end(params);
	cs_log("%s", txt);

	if (cfg.saveinithistory) {
		int32_t size = reader->init_history_pos+strlen(txt)+2;

		cs_realloc(&reader->init_history, size, -1);

		if (!reader->init_history)
			return;

		snprintf(reader->init_history+reader->init_history_pos, strlen(txt)+2, "%s\n", txt);
		reader->init_history_pos+=strlen(txt)+1;
	}
}
예제 #8
0
 /**
  * Reallocate a block of memory with a new size, with the start address 
  * being aligned to a multiple of \p align bytes.
  * \remarks The returned block of memory must be freed with AlignedFree.
  * \warning The alignment must be the same as initially passed to 
  *   AlignedMalloc.
  */
 void* AlignedRealloc (void* ptr, size_t size, 
   size_t align)
 {
 #if !defined(CS_NO_PTMALLOC)
   void* newPtr = ptmalloc_::ptrealloc (ptr, size);
   if ((newPtr != ptr)
     && ((((uintptr_t)newPtr) / align * align) != (uintptr_t)newPtr))
   {
     // Bah, alignment borked. Need to alloc again :(
     void* newPtrAligned = ptmalloc_::ptmemalign (align, size);
     memcpy (newPtrAligned, newPtr, size);
     ptfree (newPtr);
     newPtr = newPtrAligned;
   }
   return newPtr;
 #elif defined(CS_HAVE__ALIGNED_MALLOC)
   return _aligned_realloc (ptr, size, align);
 #else
   void* orgPtr = *(((void**)ptr) - 1);
   uintptr_t offsetToData = (uintptr_t)ptr - (uintptr_t)orgPtr;
   void* newPtr = cs_realloc (orgPtr, size + align + sizeof(void*));
   
   uintptr_t ptrInt = (intptr_t)newPtr;
   ptrInt = (ptrInt + align + sizeof(void*)) / align * align;
   uintptr_t newOffsetToData = ptrInt - (uintptr_t)newPtr;
   if (newOffsetToData != offsetToData)
   {
     // Ensure realloced data is aligned again
     memmove ((void*)(ptrInt), (void*)((uintptr_t)newPtr + offsetToData),
       size);
   }
   
   *(((void**)ptrInt) - 1) = newPtr;
   return (void*)ptrInt;
 #endif
 }
예제 #9
0
int32_t init_srvid(void)
{
	int8_t new_syntax = 1;
	FILE *fp = open_config_file("oscam.srvid2");
	if(!fp)
	{ 
		fp = open_config_file(cs_srid);
		if(fp)
		{
			new_syntax = 0;
		}
	}

	if(!fp)
	{ 
		fp = create_config_file("oscam.srvid2");
		if(fp)
		{
			flush_config_file(fp, "oscam.srvid2");
		}
		
		return 0;
	}

	int32_t nr = 0, i, j;
	char *payload, *saveptr1 = NULL, *saveptr2 = NULL, *token;
	const char *tmp;
	if(!cs_malloc(&token, MAXLINESIZE))
		{ return 0; }
	struct s_srvid *srvid = NULL, *new_cfg_srvid[16], *last_srvid[16];
	// A cache for strings within srvids. A checksum is calculated which is the start point in the array (some kind of primitive hash algo).
	// From this point, a sequential search is done. This greatly reduces the amount of string comparisons.
	const char **stringcache[1024];
	int32_t allocated[1024] = { 0 };
	int32_t used[1024] = { 0 };
	struct timeb ts, te;
	cs_ftime(&ts);

	memset(last_srvid, 0, sizeof(last_srvid));
	memset(new_cfg_srvid, 0, sizeof(new_cfg_srvid));

	while(fgets(token, MAXLINESIZE, fp))
	{
		int32_t l, len = 0, len2, srvidtmp;
		uint32_t k;
		uint32_t pos;
		char *srvidasc, *prov;
		tmp = trim(token);

		if(tmp[0] == '#') { continue; }
		if((l = strlen(tmp)) < 6) { continue; }
		if(!(srvidasc = strchr(token, ':'))) { continue; }
		if(!(payload = strchr(token, '|'))) { continue; }
		*payload++ = '\0';
		
		if(!cs_malloc(&srvid, sizeof(struct s_srvid)))
		{
			NULLFREE(token);
			fclose(fp);
			return (1);
		}

		char tmptxt[128];

		int32_t offset[4] = { -1, -1, -1, -1 };
		char *ptr1 = NULL, *ptr2 = NULL;
		const char *searchptr[4] = { NULL, NULL, NULL, NULL };
		const char **ptrs[4] = { &srvid->prov, &srvid->name, &srvid->type, &srvid->desc };
		uint32_t max_payload_length = MAXLINESIZE - (payload - token);
		
		if(new_syntax)
		{
			ptrs[0] = &srvid->name;
			ptrs[1] = &srvid->type;
			ptrs[2] = &srvid->desc;
			ptrs[3] = &srvid->prov;
		}
		
		// allow empty strings as "||"
		if(payload[0] == '|' && (strlen(payload)+2 < max_payload_length))
		{
			memmove(payload+1, payload, strlen(payload)+1);
			payload[0] = ' ';
		}
		
		for(k=1; ((k < max_payload_length) && (payload[k] != '\0')); k++)
		{
			if(payload[k-1] == '|' && payload[k] == '|')
			{
				if(strlen(payload+k)+2 < max_payload_length-k)
				{
					memmove(payload+k+1, payload+k, strlen(payload+k)+1);
					payload[k] = ' ';
				}
				else
				{
					break;
				}	
			}
		}
	
		for(i = 0, ptr1 = strtok_r(payload, "|", &saveptr1); ptr1 && (i < 4) ; ptr1 = strtok_r(NULL, "|", &saveptr1), ++i)
		{
			// check if string is in cache
			len2 = strlen(ptr1);
			pos = 0;
			for(j = 0; j < len2; ++j) { pos += (uint8_t)ptr1[j]; }
			pos = pos % 1024;
			for(j = 0; j < used[pos]; ++j)
			{
				if(!strcmp(stringcache[pos][j], ptr1))
				{
					searchptr[i] = stringcache[pos][j];
					break;
				}
			}
			if(searchptr[i]) { continue; }

			offset[i] = len;
			cs_strncpy(tmptxt + len, trim(ptr1), sizeof(tmptxt) - len);
			len += strlen(ptr1) + 1;
		}

		char *tmpptr = NULL;
		if(len > 0 && !cs_malloc(&tmpptr, len))
			{ continue; }

		srvid->data = tmpptr;
		if(len > 0) { memcpy(tmpptr, tmptxt, len); }

		for(i = 0; i < 4; i++)
		{
			if(searchptr[i])
			{
				*ptrs[i] = searchptr[i];
				continue;
			}
			if(offset[i] > -1)
			{
				*ptrs[i] = tmpptr + offset[i];
				// store string in stringcache
				tmp = *ptrs[i];
				len2 = strlen(tmp);
				pos = 0;
				for(j = 0; j < len2; ++j) { pos += (uint8_t)tmp[j]; }
				pos = pos % 1024;
				if(used[pos] >= allocated[pos])
				{
					if(allocated[pos] == 0)
					{
						if(!cs_malloc(&stringcache[pos], 16 * sizeof(char *)))
							{ break; }
					}
					else
					{
						if(!cs_realloc(&stringcache[pos], (allocated[pos] + 16) * sizeof(char *)))
							{ break; }
					}
					allocated[pos] += 16;
				}
				stringcache[pos][used[pos]] = tmp;
				used[pos] += 1;
			}
		}

		*srvidasc++ = '\0';
		if(new_syntax)
			{ srvidtmp = dyn_word_atob(token) & 0xFFFF; }
		else
			{ srvidtmp = dyn_word_atob(srvidasc) & 0xFFFF; }
			
		if(srvidtmp < 0)
		{
			NULLFREE(tmpptr);
			NULLFREE(srvid);
			continue;
		}
		else
		{
			srvid->srvid = srvidtmp;
		}		
		
		srvid->ncaid = 0;
		for(i = 0, ptr1 = strtok_r(new_syntax ? srvidasc : token, ",", &saveptr1); (ptr1); ptr1 = strtok_r(NULL, ",", &saveptr1), i++)
		{
			srvid->ncaid++;
		}
		
		if(!cs_malloc(&srvid->caid, sizeof(struct s_srvid_caid) * srvid->ncaid))
		{
			NULLFREE(tmpptr);
			NULLFREE(srvid);
			return 0;
		}
		
		ptr1 = new_syntax ? srvidasc : token;
		for(i = 0; i < srvid->ncaid; i++)
		{
			prov = strchr(ptr1,'@');
						
			srvid->caid[i].nprovid = 0;
			
			if(prov)
			{
				if(prov[1] != '\0')
				{
					for(j = 0, ptr2 = strtok_r(prov+1, "@", &saveptr2); (ptr2); ptr2 = strtok_r(NULL, "@", &saveptr2), j++)
					{
						srvid->caid[i].nprovid++;
					}
		    		
					if(!cs_malloc(&srvid->caid[i].provid, sizeof(uint32_t) * srvid->caid[i].nprovid))
					{
						for(j = 0; j < i; j++)
							{ NULLFREE(srvid->caid[j].provid); } 
						NULLFREE(srvid->caid);
						NULLFREE(tmpptr);
						NULLFREE(srvid);
						return 0;
					}
					
					ptr2 = prov+1;
					for(j = 0;  j < srvid->caid[i].nprovid; j++)
					{
						srvid->caid[i].provid[j] = dyn_word_atob(ptr2) & 0xFFFFFF;
						ptr2 = ptr2 + strlen(ptr2) + 1;
					}
				}
				else
				{
					ptr2 = prov+2;
				}
				
				prov[0] = '\0';
			}

			srvid->caid[i].caid = dyn_word_atob(ptr1) & 0xFFFF;
			if(prov)
				{ ptr1 = ptr2; }
			else 
				{ ptr1 = ptr1 + strlen(ptr1) + 1; }
		}
			
		nr++;

		if(new_cfg_srvid[srvid->srvid >> 12])
			{ last_srvid[srvid->srvid >> 12]->next = srvid; }
		else
			{ new_cfg_srvid[srvid->srvid >> 12] = srvid; }

		last_srvid[srvid->srvid >> 12] = srvid;
	}
예제 #10
0
int32_t init_srvid(void)
{
	FILE *fp = open_config_file(cs_srid);
	if (!fp)
		return 0;

	int32_t nr = 0, i;
	char *payload, *tmp, *saveptr1 = NULL, *token;
	if (!cs_malloc(&token, MAXLINESIZE))
		return 0;
	struct s_srvid *srvid=NULL, *new_cfg_srvid[16], *last_srvid[16];
	// A cache for strings within srvids. A checksum is calculated which is the start point in the array (some kind of primitive hash algo).
	// From this point, a sequential search is done. This greatly reduces the amount of string comparisons.
	char **stringcache[1024];
	int32_t allocated[1024] = { 0 };
	int32_t used[1024] = { 0 };
	struct timeb ts, te;
  cs_ftime(&ts);

	memset(last_srvid, 0, sizeof(last_srvid));
	memset(new_cfg_srvid, 0, sizeof(new_cfg_srvid));

	while (fgets(token, MAXLINESIZE, fp)) {
		int32_t l, j, len=0, len2, srvidtmp;
		uint32_t pos;
		char *srvidasc;
		tmp = trim(token);

		if (tmp[0] == '#') continue;
		if ((l=strlen(tmp)) < 6) continue;
		if (!(srvidasc = strchr(token, ':'))) continue;
		if (!(payload=strchr(token, '|'))) continue;
		*payload++ = '\0';

		if (!cs_malloc(&srvid, sizeof(struct s_srvid))) {
			free(token);
			fclose(fp);
			return(1);
		}

		char tmptxt[128];

		int32_t offset[4] = { -1, -1, -1, -1 };
		char *ptr1, *searchptr[4] = { NULL, NULL, NULL, NULL };
		char **ptrs[4] = { &srvid->prov, &srvid->name, &srvid->type, &srvid->desc };

		for (i = 0, ptr1 = strtok_r(payload, "|", &saveptr1); ptr1 && (i < 4) ; ptr1 = strtok_r(NULL, "|", &saveptr1), ++i){
			// check if string is in cache
			len2 = strlen(ptr1);
			pos = 0;
			for(j = 0; j < len2; ++j) pos += (uint8_t)ptr1[j];
			pos = pos%1024;
			for(j = 0; j < used[pos]; ++j){
				if (!strcmp(stringcache[pos][j], ptr1)){
					searchptr[i]=stringcache[pos][j];
					break;
				}
			}
			if (searchptr[i]) continue;

			offset[i]=len;
			cs_strncpy(tmptxt+len, trim(ptr1), sizeof(tmptxt)-len);
			len+=strlen(ptr1)+1;
		}

		char *tmpptr = NULL;
		if (len > 0 && !cs_malloc(&tmpptr, len))
			continue;

		srvid->data=tmpptr;
		if(len > 0) memcpy(tmpptr, tmptxt, len);

		for (i=0;i<4;i++) {
			if (searchptr[i]) {
				*ptrs[i] = searchptr[i];
				continue;
			}
			if (offset[i]>-1){
				*ptrs[i] = tmpptr + offset[i];
				// store string in stringcache
				tmp = *ptrs[i];
				len2 = strlen(tmp);
				pos = 0;
				for(j = 0; j < len2; ++j) pos += (uint8_t)tmp[j];
				pos = pos%1024;
				if(used[pos] >= allocated[pos]){
					if (allocated[pos] == 0) {
						if (!cs_malloc(&stringcache[pos], 16 * sizeof(char *)))
							break;
					} else {
						if (!cs_realloc(&stringcache[pos], (allocated[pos] + 16) * sizeof(char *)))
							break;
					}
					allocated[pos] += 16;
				}
				stringcache[pos][used[pos]] = tmp;
				used[pos] += 1;
			}
		}

		*srvidasc++ = '\0';
		srvidtmp = dyn_word_atob(srvidasc) & 0xFFFF;
		//printf("srvid %s - %d\n",srvidasc,srvid->srvid );

		if (srvidtmp<0) {
			free(tmpptr);
			free(srvid);
			continue;
		} else srvid->srvid = srvidtmp;

		srvid->ncaid = 0;
		for (i = 0, ptr1 = strtok_r(token, ",", &saveptr1); (ptr1) && (i < 10) ; ptr1 = strtok_r(NULL, ",", &saveptr1), i++){
			srvid->caid[i] = dyn_word_atob(ptr1);
			srvid->ncaid = i+1;
			//cs_debug_mask(D_CLIENT, "ld caid: %04X srvid: %04X Prov: %s Chan: %s",srvid->caid[i],srvid->srvid,srvid->prov,srvid->name);
		}
		nr++;

		if (new_cfg_srvid[srvid->srvid>>12])
			last_srvid[srvid->srvid>>12]->next = srvid;
		else
			new_cfg_srvid[srvid->srvid>>12] = srvid;

		last_srvid[srvid->srvid>>12] = srvid;
	}
예제 #11
0
 void* Realloc (void* p, size_t size) { return cs_realloc (p, size); }
예제 #12
0
int32_t Protocol_T1_Command (struct s_reader *reader, unsigned char * command, uint16_t command_len, unsigned char * rsp, uint16_t * lr)
{
  T1_Block *block;
  BYTE *buffer, rsp_type, bytes, nr, wtx;
  uint16_t counter;
  int32_t ret;
  bool more;
  if (command[1] == T1_BLOCK_S_IFS_REQ)
  {
    BYTE inf = command[3];

    /* Create an IFS request S-Block */
    block = T1_Block_NewSBlock (T1_BLOCK_S_IFS_REQ, 1, &inf);
    rdr_debug_mask(reader, D_IFD, "Protocol: Sending block S(IFS request, %d)", inf);

    /* Send IFSD request */
    ret = Protocol_T1_SendBlock (reader, block);
	
	/* Delete block */
	T1_Block_Delete (block);
	
    /* Receive a block */
    ret = Protocol_T1_ReceiveBlock (reader, &block);

    if (ret == OK)
      {
        rsp_type = T1_Block_GetType (block);

        /* Positive IFS Response S-Block received */
        if (rsp_type == T1_BLOCK_S_IFS_RES)
          {
            /* Update IFSD value */
            inf = (*T1_Block_GetInf (block));
            rdr_debug_mask(reader, D_IFD, "Protocol: Received block S(IFS response, %d)", inf);
          }
        T1_Block_Delete (block);
      }

    return ret;
  }

  if (command[1] == T1_BLOCK_S_RESYNCH_REQ)
  {
    /* Create an Resynch request S-Block */
    block = T1_Block_NewSBlock (T1_BLOCK_S_RESYNCH_REQ, 0, NULL);
    rdr_debug_mask(reader, D_IFD, "Protocol: Sending block S(RESYNCH request)");

    /* Send request */
    ret = Protocol_T1_SendBlock (reader, block);
	
	/* Delete I-block */
	T1_Block_Delete (block);

    /* Receive a block */
    ret = Protocol_T1_ReceiveBlock (reader, &block);

    if (ret == OK)
      {
        rsp_type = T1_Block_GetType (block);

        /* Positive IFS Response S-Block received */
        if (rsp_type == T1_BLOCK_S_RESYNCH_RES) {
            rdr_debug_mask(reader, D_IFD, "Protocol: Received block S(RESYNCH response)");
						reader->ns = 0;
				}
		T1_Block_Delete (block);
      }

    return ret;
  }

  /* Calculate the number of bytes to send */
  counter = 0;
  bytes = MIN (command_len, reader->ifsc);

  /* See if chaining is needed */
  more = (command_len > reader->ifsc);

  /* Increment ns */
  reader->ns = (reader->ns == 1) ? 0:1; //toggle from 0 to 1 and back

  /* Create an I-Block */
  block = T1_Block_NewIBlock (bytes, command, reader->ns, more);
  rdr_debug_mask(reader, D_IFD, "Sending block I(%d,%d)", reader->ns, more);

  /* Send a block */
  ret = Protocol_T1_SendBlock (reader, block);
  
  /* Delete I-block */
  T1_Block_Delete (block);

  while ((ret == OK) && more) {
  
				/* Receive a block */
				ret = Protocol_T1_ReceiveBlock (reader, &block);
				
				if (ret == OK){
					rsp_type = T1_Block_GetType (block);

					/* Positive ACK R-Block received */
					if (rsp_type == T1_BLOCK_R_OK) {
						rdr_debug_mask(reader, D_IFD, "Protocol: Received block R(%d)", T1_Block_GetNR (block));
						/* Delete block */
						T1_Block_Delete (block);
 
						/* Increment ns  */
						reader->ns = (reader->ns == 1) ? 0:1; //toggle from 0 to 1 and back

						/* Calculate the number of bytes to send */
						counter += bytes;
						bytes = MIN (command_len - counter, reader->ifsc);

						/* See if chaining is needed */
						more = (command_len - counter > reader->ifsc);

						/* Create an I-Block */
						block = T1_Block_NewIBlock (bytes, command + counter, reader->ns, more);
						rdr_debug_mask(reader, D_IFD, "Protocol: Sending block I(%d,%d)", reader->ns, more);

						/* Send a block */
						ret = Protocol_T1_SendBlock (reader, block);
		  
						/* Delete I-block */
						T1_Block_Delete (block);
					}
					else {
						/* Delete block */
						T1_Block_Delete (block);
						rdr_debug_mask(reader, D_TRACE, "ERROR: T1 Command %02X not implemented in SendBlock", rsp_type);
						return ERROR;
					}
				}
				else {
					rdr_debug_mask(reader, D_TRACE, "ERROR: T1 Command returned error");
					return ERROR;
				}
  }

  /* Reset counter */
  buffer = NULL;
  counter = 0;      
  more = TRUE;
  wtx = 0;
      
  while ((ret == OK) && more)
    {
      if (wtx > 1)
        ICC_Async_SetTimings (reader, wtx * reader->BWT);

      /* Receive a block */
      ret = Protocol_T1_ReceiveBlock (reader, &block);

      if (wtx > 1)
        {
          ICC_Async_SetTimings (reader, reader->BWT);          
          wtx = 0;
        }

      if (ret == OK)
        {
          rsp_type = T1_Block_GetType (block);

          if (rsp_type == T1_BLOCK_I)
            {
              rdr_debug_mask (reader, D_IFD, "Protocol: Received block I(%d,%d)", 
              T1_Block_GetNS(block), T1_Block_GetMore (block));
              /* Calculate nr */
              nr = (T1_Block_GetNS (block) + 1) % 2;
                               
              /* Save inf field */
              bytes = T1_Block_GetLen (block);
      	      if(!cs_realloc(&buffer, counter + bytes, -1)) return -1; 
	          memcpy (buffer + counter, T1_Block_GetInf (block), bytes);
              counter += bytes;

              /* See if chaining is requested */
              more = T1_Block_GetMore (block);

              /* Delete block */
              T1_Block_Delete (block);

              if (more)
                {
                  /* Create an R-Block */
                  block = T1_Block_NewRBlock (T1_BLOCK_R_OK, nr);
                  rdr_debug_mask(reader, D_IFD, "Protocol: Sending block R(%d)", nr);

                  /* Send R-Block */
                  ret = Protocol_T1_SendBlock (reader, block);
				  
				  /* Delete I-block */
				  T1_Block_Delete (block);
                }
            }

          /* WTX Request S-Block received */ 
          else if (rsp_type == T1_BLOCK_S_WTX_REQ)
            {
              /* Get wtx multiplier */
              wtx = (*T1_Block_GetInf (block));
              rdr_debug_mask(reader, D_IFD, "Protocol: Received block S(WTX request, %d)", wtx);

              /* Delete block */
              T1_Block_Delete (block);
             
              /* Create an WTX response S-Block */
              block = T1_Block_NewSBlock (T1_BLOCK_S_WTX_RES, 1, &wtx);
              rdr_debug_mask(reader, D_IFD, "Protocol: Sending block S(WTX response, %d)", wtx);

              /* Send WTX response */
              ret = Protocol_T1_SendBlock (reader, block);
			  
			  /* Delete block */
              T1_Block_Delete (block);
            }

          else
            {
              rdr_debug_mask(reader, D_TRACE, "ERROR: T1 Command %02X not implemented in Receive Block", rsp_type);
              ret = ERROR;//not implemented
            }
        }
    }

  if (ret == OK) {
		memcpy(rsp, buffer, counter);
		*lr = counter;
	}

  if (buffer != NULL)
    free (buffer);
  
  return ret;
}