Esempio n. 1
0
static int codec_drv_control(
		ErlDrvData handle,
		unsigned int command,
		char *buf, int len,
		char **rbuf, int rlen)
{
	codec_data* d = (codec_data*)handle;

	int ret = 0;
	ErlDrvBinary *out;
	*rbuf = NULL;

	int n = 0; // Number of frames
	int i = 0; // Temporary counter

	switch(command) {
		case CMD_ENCODE:
			if (len % 160 != 0)
				break;

			n = len / 160; // Calculate a number of frames

			out = driver_alloc_binary(n*10); // n*80 bits
			ret = n*10;

			for(i = 0; i<n; i++)
				bcg729Encoder(d->estate, (int16_t*)buf+80*i, (uint8_t*)out->orig_bytes+10*i);

			*rbuf = (char *) out;
			break;
		 case CMD_DECODE:
			if (len % 10 != 0)
				break;

			n = len / 10; // Calculate a number of frames

			out = driver_alloc_binary(n*160); // n*160 bytes
			ret = n*160;

			for(i = 0; i<n; i++)
				bcg729Decoder(d->dstate, ((uint8_t*)buf)+10*i, 0, (int16_t*)out->orig_bytes+80*i);

			*rbuf = (char *) out;
			break;
		 default:
			break;
	}
	return ret;
}
Esempio n. 2
0
void es_peepEvents2(ErlDrvPort port, ErlDrvTermData caller, char *bp)
{  
    SDL_Event events[256];
    int numevents, res, i, sz;
    Uint32 mask;
    char *start;
    ErlDrvBinary * bin;
    ErlDrvTermData rt[8];
    
    mask = * (Uint32 *) bp; bp += sizeof(Uint32);
    numevents = *bp++;
    
    SDL_PumpEvents();
    res = SDL_PeepEvents(events, numevents, SDL_GETEVENT, mask);
    bin = driver_alloc_binary(res*MAX_EVENT_SIZE);
    bp = start = bin->orig_bytes;
    for (i = 0; i < res; i++) {
	bp = encode_event(&(events[i]), bp);
    }
    sz = bp-start;
    rt[0] = ERL_DRV_ATOM; rt[1]=driver_mk_atom((char *) "_esdl_result_");
    rt[2] = ERL_DRV_BINARY; rt[3] = (ErlDrvTermData) bin; rt[4] = sz; rt[5] = 0;
    rt[6] = ERL_DRV_TUPLE; rt[7] = 2;
    driver_send_term(port,caller,rt,8);
    driver_free_binary(bin);
}
Esempio n. 3
0
static void iv_open(t_iconvdrv *iv, char *tocode, char *fromcode)
{
    int len;
    iconv_t cd;
    ErlDrvBinary *bin;

    if ((cd = iconv_open(tocode, fromcode)) == (iconv_t) -1) {
        driver_send_error(iv, &am_einval);
    }
    else {
        len = sizeof(iconv_t);
        if (!(bin = driver_alloc_binary(len+1))) {
            iconv_close(cd);
            driver_send_error(iv, &am_enomem);
        }
        else {
            memcpy(bin->orig_bytes, &cd, len);
            if (!strcasecmp(tocode + strlen(tocode) -6, "IGNORE")) {
                /* GLIBC's iconv is annoying and will throw the failure code for
                 * invalid sequences even though we specify //IGNORE so we have to
                 * keep track if we initalized this conversion handle with //IGNORE
                 * or not so we can disregard the error. */
                bin->orig_bytes[len] = 1;
            } else {
                bin->orig_bytes[len] = 0;
            }
            driver_send_bin(iv, bin, len+1);
            driver_free_binary(bin);
        }
    }

    return;
}
ErlDrvSSizeT 
DriverController::control(
    ErlDrvData drv_data, 
    const unsigned int  command, 
    char*         buf, 
    ErlDrvSizeT   e_len, 
    char**        rbuf, 
    ErlDrvSizeT   e_rlen)
{
    const size_t len  = static_cast<int>(e_len);
    const size_t rlen = static_cast<int>(e_rlen);

    Driver& drv = * reinterpret_cast<Driver*>( drv_data );

    ParamDecoder params(buf, len); 
    ResultEncoder result(*gp_driverMemoryManager, *rbuf, rlen);
    drv.handleCommand(params, result, command);

    ErlDrvSSizeT result_len = result.finalSize();

    /* It is too long for rbuf, create new binary. */
    if (result.isExtended())
    {
        ErlDrvBinary* bin = driver_alloc_binary(result_len);
        if (bin == NULL)
            throw MemoryAllocationDriverError(POS, result_len);
        result.finalize(bin->orig_bytes);
        *rbuf = (char*) bin;
    }
    return result_len;
}
Esempio n. 5
0
static int iconv_erl_control(ErlDrvData drv_data,
			     unsigned int command,
			     char *buf, int len,
			     char **rbuf, int rlen)
{
   int i;
   int size;
   int index = 0;
   int avail;
   size_t inleft, outleft;
   ErlDrvBinary *b;
   char *from, *to, *string, *stmp, *rstring, *rtmp;
   iconv_t cd;

   ei_decode_version(buf, &index, &i);
   ei_decode_tuple_header(buf, &index, &i);
   ei_get_type(buf, &index, &i, &size);
   from = malloc(size + 1); 
   ei_decode_string(buf, &index, from);

   ei_get_type(buf, &index, &i, &size);
   to = malloc(size + 1); 
   ei_decode_string(buf, &index, to);
  
   ei_get_type(buf, &index, &i, &size);
   stmp = string = malloc(size + 1); 
   ei_decode_string(buf, &index, string);
  
   cd = iconv_open(to, from);

   if(cd == (iconv_t) -1)
   {
      cd = iconv_open("ascii", "ascii");
      if(cd == (iconv_t) -1)
	{
	  cd = iconv_open("ascii", "ascii");
	}
   }
   
   outleft = avail = 4*size;
   inleft = size;
   rtmp = rstring = malloc(avail);
   iconv(cd, &stmp, &inleft, &rtmp, &outleft);
   
   size = rtmp - rstring;

   //printf("size=%d, res=%s\r\n", size, rstring);
   
   *rbuf = (char*)(b = driver_alloc_binary(size));
   memcpy(b->orig_bytes, rstring, size);

   free(from);
   free(to);
   free(string);
   free(rstring);
   iconv_close(cd);
   
   return size;
}
Esempio n. 6
0
int erl_tess_impl(char* buff, ErlDrvPort port, ErlDrvTermData caller)
{
  ErlDrvBinary* bin;
  int i;
  int num_vertices;
  GLdouble *n;
  int AP;
  int a_max = 2;
  int i_max = 6;
  num_vertices = * (int *) buff; buff += 8; /* Align */
  n = (double *) buff; buff += 8*3;

  egl_tess.alloc_max = a_max*num_vertices*3;
  bin = driver_alloc_binary(egl_tess.alloc_max*sizeof(GLdouble));
  egl_tess.error = 0;
  egl_tess.tess_coords = (double *) bin->orig_bytes;
  memcpy(egl_tess.tess_coords,buff,num_vertices*3*sizeof(GLdouble));
  egl_tess.index_max = i_max*3*num_vertices;
  egl_tess.tess_index_list = (int *) driver_alloc(sizeof(int) * egl_tess.index_max);

  egl_tess.tess_coords = (double *) bin->orig_bytes;
  egl_tess.index_n = 0;
  egl_tess.alloc_n = num_vertices*3;

  gluTessNormal(tess, n[0], n[1], n[2]);
  gluTessBeginPolygon(tess, 0);
  gluTessBeginContour(tess);
  for (i = 0; i < num_vertices; i++) {
    gluTessVertex(tess, egl_tess.tess_coords+3*i, egl_tess.tess_coords+3*i);
  }
  gluTessEndContour(tess);
  gluTessEndPolygon(tess);

  AP = 0; ErlDrvTermData *rt;
  rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData) * (13+egl_tess.index_n*2));
  rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");

  for(i=0; i < egl_tess.index_n; i++) {
    rt[AP++] = ERL_DRV_INT; rt[AP++] = (int) egl_tess.tess_index_list[i];
  };
  rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = egl_tess.index_n+1;

  rt[AP++] = ERL_DRV_BINARY; rt[AP++] = (ErlDrvTermData) bin;
  rt[AP++] = egl_tess.alloc_n*sizeof(GLdouble); rt[AP++] = 0;

  rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; // Return tuple {list, Bin}
  rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; // Result tuple

  driver_send_term(port,caller,rt,AP);
  /* fprintf(stderr, "List %d: %d %d %d \r\n",  */
  /* 	  res, */
  /* 	  n_pos,  */
  /* 	  (tess_alloc_vertex-new_vertices)*sizeof(GLdouble),  */
  /* 	  num_vertices*6*sizeof(GLdouble)); */
  driver_free_binary(bin);
  driver_free(egl_tess.tess_index_list);
  driver_free(rt);
  return 0;
}
Esempio n. 7
0
static ErlDrvSSizeT sha_drv_control(ErlDrvData handle,
			   unsigned int command,
			   char *buf, ErlDrvSizeT len,
			   char **rbuf, ErlDrvSizeT rlen)
{
  ErlDrvBinary *b = NULL;

  switch (command) {
#ifdef HAVE_MD2
  case 2:
    rlen = MD2_DIGEST_LENGTH;
    b = driver_alloc_binary(rlen);
    if (b) MD2((unsigned char*)buf, len, (unsigned char*)b->orig_bytes);
    break;
#endif
  case 224:
    rlen = SHA224_DIGEST_LENGTH;
    b = driver_alloc_binary(rlen);
    if (b) SHA224((unsigned char*)buf, len, (unsigned char*)b->orig_bytes);
    break;
  case 256:
    rlen = SHA256_DIGEST_LENGTH;
    b = driver_alloc_binary(rlen);
    if (b) SHA256((unsigned char*)buf, len, (unsigned char*)b->orig_bytes);
    break;
  case 384:
    rlen = SHA384_DIGEST_LENGTH;
    b = driver_alloc_binary(rlen);
    if (b) SHA384((unsigned char*)buf, len, (unsigned char*)b->orig_bytes);
    break;
  case 512:
    rlen = SHA512_DIGEST_LENGTH;
    b = driver_alloc_binary(rlen);
    if (b) SHA512((unsigned char*)buf, len, (unsigned char*)b->orig_bytes);
    break;
  };

  if (b) {
    *rbuf = (char *)b;
  } else {
    *rbuf = NULL;
    rlen = 0;
  };

  return rlen;
}
Esempio n. 8
0
/* Put elements from vec at q head */
int erts_ioq_pushqv(ErtsIOQueue *q, ErtsIOVec* vec, Uint skipbytes)
{
    int n;
    Uint len;
    Uint size = vec->common.size - skipbytes;
    SysIOVec* iov;
    ErtsIOQBinary** binv;
    ErtsIOQBinary* b;

    if (q == NULL)
	return -1;

    ASSERT(vec->common.size >= skipbytes);
    if (vec->common.size <= skipbytes)
	return 0;

    n = skip(vec, skipbytes, &iov, &binv, &len);

    if (n < 0)
        return n;

    if (q->v_head - n < q->v_start)
	if (expandq(q, n, 0))
            return -1;

    /* Queue and reference all binaries (remove zero length items) */
    iov += (n-1);  /* move to end */
    binv += (n-1); /* move to end */
    while(n--) {
	if ((len = iov->iov_len) > 0) {
	    if ((b = *binv) == NULL) { /* special case create binary ! */
                if (q->driver) {
                    ErlDrvBinary *bin = driver_alloc_binary(len);
                    if (!bin) return -1;
                    sys_memcpy(bin->orig_bytes, iov->iov_base, len);
                    b = (ErtsIOQBinary *)bin;
                    q->v_head->iov_base = bin->orig_bytes;
                }
		*--q->b_head = b;
		q->v_head--;
		q->v_head->iov_len = len;
	    }
	    else {
                if (q->driver)
                    driver_binary_inc_refc(&b->driver);
                else
                    erts_refc_inc(&b->nif.intern.refc, 1);
		*--q->b_head = b;
		*--q->v_head = *iov;
	    }
	}
	iov--;
	binv--;
    }
    q->size += size;      /* update total size in queue */
    return 0;
}
Esempio n. 9
0
/*
** Yet another malloc wrapper
*/
static ErlDrvBinary *my_alloc_binary(int size)
{
    ErlDrvBinary *ret;
    if ((ret = driver_alloc_binary(size)) == NULL) {
	/* May or may not work... */
	fprintf(stderr, "Could not allocate a binary of %lu bytes in %s.",
		(unsigned long) size, __FILE__);
	exit(1);
    }
    return ret;
}
Esempio n. 10
0
static int return_control_result(void* pLocalResult, int localLen, char **ppRetBuf, int returnLen)
{
    if (*ppRetBuf == NULL || localLen > returnLen) {
        *ppRetBuf = (char*)driver_alloc_binary(localLen);
        if(*ppRetBuf == NULL) {
            return -1;
        }
    }
    memcpy(*ppRetBuf, pLocalResult, localLen);
    return localLen;
}
Esempio n. 11
0
static ErlDrvSSizeT control(ErlDrvData drvstate, unsigned int command,
			    char *args, ErlDrvSizeT argslen,
			    char **rbuf, ErlDrvSizeT rbuflen) {
  state *st = (state *)drvstate;
  init_state(st, args, argslen);

  switch (command) {
  case ENDWIN: do_endwin(st); break;
  case INITSCR: do_initscr(st); break;
  case REFRESH: do_refresh(st); break;
  case CBREAK: do_cbreak(st); break;
  case NOCBREAK: do_nocbreak(st); break;
  case ECHO: do_echo(st); break;
  case NOECHO: do_noecho(st); break;
  case ADDCH: do_addch(st); break;
  case ADDSTR: do_addstr(st); break;
  case MOVE: do_move(st); break;
  case GETYX: do_getyx(st); break;
  case GETMAXYX: do_getmaxyx(st); break;
  case CURS_SET: do_curs_set(st); break;
  case WERASE: do_werase(st); break;
  case HAS_COLORS: do_has_colors(st); break;
  case START_COLOR: do_start_color(st); break;
  case INIT_PAIR: do_init_pair(st); break;
  case WATTRON: do_wattron(st); break;
  case WATTROFF: do_wattroff(st); break;
  case NL: do_nl(st); break;
  case NONL: do_nonl(st); break;
  case SCROLLOK: do_scrollok(st); break;
  case MVADDCH: do_mvaddch(st); break;
  case MVADDSTR: do_mvaddstr(st); break;
  case NEWWIN: do_newwin(st); break;
  case DELWIN: do_delwin(st); break;
  case WMOVE: do_wmove(st); break;
  case WADDSTR: do_waddstr(st); break;
  case WADDCH: do_waddch(st); break;
  case MVWADDSTR: do_mvwaddstr(st); break;
  case MVWADDCH: do_mvwaddch(st); break;
  case WREFRESH: do_wrefresh(st); break;
  case WHLINE: do_whline(st); break;
  case WVLINE: do_wvline(st); break;
  case WBORDER: do_wborder(st); break;
  case BOX: do_box(st); break;
  case KEYPAD: do_keypad(st); break;
  default: break;
  }

  int rlen = st->eixb.index;
  ErlDrvBinary *response = driver_alloc_binary(rlen);
  memcpy(response->orig_bytes, st->eixb.buff, rlen);
  ei_x_free(&(st->eixb));
  *rbuf = (char *)response;
  return rlen;
}
Esempio n. 12
0
static int zlib_output_init(ZLibData* d)
{
    if (d->bin != NULL)
	driver_free_binary(d->bin);
    if ((d->bin = driver_alloc_binary(d->binsz_need)) == NULL)
	return -1;
    d->binsz = d->binsz_need;
    d->s.next_out = (unsigned char*)d->bin->orig_bytes;
    d->s.avail_out = d->binsz;
    return 0;
}
Esempio n. 13
0
void *
edtk_driver_alloc_wrapper(size_t size)
{
    ErlDrvBinary	*eb;

    edtk_debug("%s: top", __FUNCTION__);
    if ((eb = driver_alloc_binary(size)) != NULL) {
	edtk_debug("%s: size %lu eb = 0x%lx orig_bytes = 0x%lx", __FUNCTION__, size, eb, eb->orig_bytes);
	return eb->orig_bytes;
    } else {
	return NULL;
    }
}
Esempio n. 14
0
static int codec_drv_control(
		ErlDrvData handle,
		unsigned int command,
		char *buf, int len,
		char **rbuf, int rlen)
{
	codec_data* d = (codec_data*)handle;

	int i;
	int ret = 0;
	ErlDrvBinary *out;
	*rbuf = NULL;
	float frame[FRAME_SIZE];
	char cbits[200];

	switch(command) {
		case CMD_ENCODE:
			for (i=0; i < len / 2; i++){
				frame[i] = (buf[2*i] & 0xff) | (buf[2*i+1] << 8);
			}
			speex_bits_reset(&d->bits);
			speex_encode(d->estate, frame, &d->bits);
			ret = speex_bits_write(&d->bits, cbits, 200);
			out = driver_alloc_binary(ret);
			memcpy(out->orig_bytes, cbits, ret);
			*rbuf = (char *) out;
			break;
		 case CMD_DECODE:
			out = driver_alloc_binary(2*FRAME_SIZE);
			speex_bits_read_from(&d->bits, buf, len);
			speex_decode_int(d->dstate, &d->bits, (spx_int16_t *)out->orig_bytes);
			ret = 2*FRAME_SIZE;
			*rbuf = (char *) out;
			break;
		 default:
			break;
	}
	return ret;
}
Esempio n. 15
0
static ErlDrvSSizeT expat_erl_control(ErlDrvData drv_data,
			     unsigned int command,
			     char *buf, ErlDrvSizeT len,
			     char **rbuf, ErlDrvSizeT rlen)
{
   expat_data* d = (expat_data*)drv_data;
   int res, errcode;
   char *errstring;
   ErlDrvBinary *b;
   size_t size;

   switch (command)
   {
      case PARSE_COMMAND:
      case PARSE_FINAL_COMMAND:
	 ei_x_new_with_version(&event_buf);
	 ei_x_new(&xmlns_buf);
	 res = XML_Parse(d->parser, buf, len, command == PARSE_FINAL_COMMAND);

	 if(!res)
	 {
	    errcode = XML_GetErrorCode(d->parser);
	    errstring = (char *)XML_ErrorString(errcode);

	    ei_x_encode_list_header(&event_buf, 1);
	    ei_x_encode_tuple_header(&event_buf, 2);
	    ei_x_encode_long(&event_buf, XML_ERROR);
	    ei_x_encode_tuple_header(&event_buf, 2);
	    ei_x_encode_long(&event_buf, errcode);
	    ei_x_encode_binary(&event_buf, errstring, strlen(errstring));
	 }

	 ei_x_encode_empty_list(&event_buf);

	 size = event_buf.index;

	 b = driver_alloc_binary(size);
	 memcpy(b->orig_bytes, event_buf.buff, size);

	 ei_x_free(&event_buf);
	 ei_x_free(&xmlns_buf);
 
	 *rbuf = (char *)b;
	 return size;
      default:
	 return 0;
   }
}
Esempio n. 16
0
static void video_async_decode(void *async_data){
  H264Frame *frame = (H264Frame *)async_data;
  H264Decoder *handle = frame->decoder;
  AVCodecContext *avctx = handle->dec;
  AVCodec *codec = avctx->codec;
  AVPacket avpkt;
  av_init_packet(&avpkt);
  struct timeval tv1;
  struct timeval tv2;
  gettimeofday(&tv1, NULL);
  int frame_ready = 0, len,i;
  AVFrame *decoded;
  decoded = avcodec_alloc_frame();
  frame_ready = sizeof(AVFrame)*2;
  avpkt.data = (uint8_t *)frame->h264->orig_bytes;
  avpkt.size = frame->h264->orig_size;
  len = avcodec_decode_video2(handle->dec, decoded, &frame_ready, &avpkt);  
  //  av_log(avctx,AV_LOG_ERROR,"\nORIGSIZE: %i; LEN %i \n",avpkt.size,len);
  if(len == -1) {
    av_free(decoded);
    return;
  };
  if(frame_ready) {
    int width = handle->dec->width;
    int height = handle->dec->height;
      if(handle->scale_ctx==NULL) {
        fprintf(stderr, "Started stream from camera %dx%d\r\n", width, height);
        handle->scale_ctx = sws_getContext(
          width, height, avctx->pix_fmt,
          width, height, avctx->pix_fmt,
	  SWS_FAST_BILINEAR, 
          NULL, NULL, NULL
        );
      }        
    int stride_size = width*height;
    frame->yuv = driver_alloc_binary(stride_size*3/2);
    uint8_t *yuv_data = (uint8_t *)frame->yuv->orig_bytes;        
    uint8_t *plane[4] = {yuv_data, yuv_data+stride_size, yuv_data+stride_size+stride_size/4, NULL};
    int stride[4] = {width, width/2, width/2, 0};
    sws_scale(handle->scale_ctx, (const uint8_t **)decoded->data, decoded->linesize, 0, height, plane, stride);
  }
  gettimeofday(&tv2, NULL);
  handle->total_time += (tv2.tv_sec * 1000 + tv2.tv_usec / 1000) - (tv1.tv_sec * 1000 + tv1.tv_usec / 1000);
  av_free(decoded);
  driver_free_binary(frame->h264);
}
Esempio n. 17
0
/* general control reply function */
static ErlDrvSSizeT ctl_reply(int rep, char* buf, ErlDrvSizeT len,
			      char** rbuf, ErlDrvSizeT rsize)
{
    char* ptr;

    if ((len+1) > rsize) {
	ErlDrvBinary* bin = driver_alloc_binary(len+1);
	if (bin == NULL)
	    return -1;
	ptr = bin->orig_bytes;
	*rbuf = (char*)ptr;
    }
    else
	ptr = *rbuf;
    *ptr++ = rep;
    memcpy(ptr, buf, len);
    return len+1;
}
Esempio n. 18
0
static ErtsIOQBinary *alloc_binary(Uint size, char *source, void **iov_base, int driver)
{
    if (driver) {
        ErlDrvBinary *bin = driver_alloc_binary(size);
        if (!bin) return NULL;
        sys_memcpy(bin->orig_bytes, source, size);
        *iov_base = bin->orig_bytes;
        return (ErtsIOQBinary *)bin;
    } else {
        /* This clause can be triggered in enif_ioq_enq_binary is used */
        Binary *bin = erts_bin_nrml_alloc(size);
        if (!bin) return NULL;
        erts_refc_init(&bin->intern.refc, 1);
        sys_memcpy(bin->orig_bytes, source, size);
        *iov_base = bin->orig_bytes;
        return (ErtsIOQBinary *)bin;
    }
}
Esempio n. 19
0
static void get_blob(Cmd *cmd) {
  char *buff = cmd->data;
  int len = cmd->size;
  Gd *gd = cmd->gd;
  int index = 0;
  void *imgData = NULL;
  int size = 0;
  ErlDrvBinary * bin;
  long quality;
  
  ei_decode_version(buff, &index, NULL);
  ei_decode_long(buff, &index, &quality);
  
  if (NULL == gd->image) {
    driver_failure_atom(gd->port, "null_image");
    return;
  }
  
  imgData = gd->blob(gd->image, &size, quality);
  
  if (NULL == imgData) {
    driver_failure_posix(gd->port, ENOMEM);
    return;
  }
  
  bin = driver_alloc_binary(size);
  if (NULL == bin) {
    driver_failure_posix(gd->port, ENOMEM);
    return;
  }
  
  memcpy(bin->orig_bytes, imgData, size);
  gdFree(imgData);
  ErlDrvTermData spec[] = {
    ERL_DRV_PORT, driver_mk_port(gd->port),
    ERL_DRV_ATOM, driver_mk_atom("ok"),
    ERL_DRV_BINARY, bin, size, 0,
    ERL_DRV_TUPLE, 3};
  driver_output_term(gd->port, spec, sizeof(spec) / sizeof(ERL_DRV_PORT));
  driver_free_binary(bin);
}
Esempio n. 20
0
static void md4drv_from_erlang(ErlDrvData drv_data, char *buf, int len)
{
    MD4_CTX context;
    unsigned char digest[16];
    t_md4drv *md4 = (t_md4drv *) drv_data;
    ErlDrvBinary *bin = NULL;

    MD4Init(&context);
    MD4Update(&context, buf, len);
    MD4Final(digest, &context);

    if (!(bin = driver_alloc_binary(16))) {
	driver_send_error(md4, &am_enomem);
    }
    else {
	memcpy(bin->orig_bytes, digest, 16);
	driver_send_bin(md4, bin, 16);
	driver_free_binary(bin);
    }
    return;
}
Esempio n. 21
0
void es_waitEvent2(ErlDrvPort port, ErlDrvTermData caller) 
{
    SDL_Event event;
    ErlDrvBinary * bin;
    ErlDrvTermData rt[8];
    char *bp, *start;
    int sz;

    bin = driver_alloc_binary(MAX_EVENT_SIZE);
    bp = start = bin->orig_bytes;
    
    SDL_WaitEvent(&event);
    bp = encode_event(&event, bp);
    
    sz = bp-start;
    rt[0] = ERL_DRV_ATOM; rt[1]=driver_mk_atom((char *) "_esdl_result_");  
    rt[2] = ERL_DRV_BINARY; rt[3] = (ErlDrvTermData) bin; rt[4] = sz; rt[5] = 0;
    rt[6] = ERL_DRV_TUPLE; rt[7] = 2;
    driver_send_term(port,caller,rt,8);
    driver_free_binary(bin);
}
Esempio n. 22
0
static void audio_async_decode(void *async_data){
  H264Frame *frame = (H264Frame *)async_data;
  H264Decoder *handle = frame->decoder;
  int16_t *outbuf=NULL;
  int len;
  int size_out;
  outbuf=av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE*2);
  AVPacket avpkt;  
  avpkt.data = (uint8_t *)frame->h264->orig_bytes;
  avpkt.size = frame->h264->orig_size;
  size_out = AVCODEC_MAX_AUDIO_FRAME_SIZE*2;
  len = avcodec_decode_audio3(handle->dec, outbuf, &size_out,&avpkt);  
  if(len == -1) {
    av_free(outbuf);
    return;
  };
  frame->sample = driver_alloc_binary(size_out);    
  memcpy(frame->sample->orig_bytes,outbuf,size_out);
  frame->sample->orig_size = size_out; 
  av_free(outbuf);
  driver_free_binary(frame->h264);
}
Esempio n. 23
0
static void iv_open(t_iconvdrv *iv, char *tocode, char *fromcode)
{
    int len;
    iconv_t cd;
    ErlDrvBinary *bin;

    if ((cd = iconv_open(tocode, fromcode)) == (iconv_t) -1) {
	driver_send_error(iv, &am_einval);
    }
    else {
	len = sizeof(iconv_t);
	if (!(bin = driver_alloc_binary(len))) {
            iconv_close(cd);
	    driver_send_error(iv, &am_enomem);
	}
	else {
	    memcpy(bin->orig_bytes, &cd, len);
	    driver_send_bin(iv, bin, len);
	    driver_free_binary(bin);
	}
    }

    return;
}
Esempio n. 24
0
static void iv_conv(t_iconvdrv *iv, iconv_t cd, char *ip, int ileft)
{
    int oleft=OUTBUF_SZ;
    char *op;
    int len;
    ErlDrvBinary *bin;

    op = &outbuf[0];

    /* Reset cd to initial state */
    iconv(cd, NULL, NULL, NULL, NULL);

    if (iconv(cd, &ip, &ileft, &op, &oleft) == (size_t) -1) {
	if (errno == EILSEQ) 
	    driver_send_error(iv, &am_eilseq);
	else if (errno == EINVAL) 
	    driver_send_error(iv, &am_einval);
	else if (errno == E2BIG) 
	    driver_send_error(iv, &am_e2big);
	else 
	    driver_send_error(iv, &am_unknown);
    }
    else if (ileft == 0) {
	len = OUTBUF_SZ - oleft;
	if (!(bin = driver_alloc_binary(len))) {
	    driver_send_error(iv, &am_enomem);
	}
	else {
	    memcpy(bin->orig_bytes, &outbuf[0], len);
	    driver_send_bin(iv, bin, len);
	    driver_free_binary(bin);
	}
    }

    return;
}
Esempio n. 25
0
static ErlDrvSSizeT iconv_erl_control(ErlDrvData drv_data,
			     unsigned int command,
			     char *buf, ErlDrvSizeT len,
			     char **rbuf, ErlDrvSizeT rlen)
{
   int i;
   int size;
   int index = 0;
   int avail;
   size_t inleft, outleft;
   ErlDrvBinary *b;
   char *from, *to, *string, *stmp, *rstring, *rtmp;
   iconv_t cd;
   int invalid_utf8_as_latin1 = 0;

   ei_decode_version(buf, &index, &i);
   ei_decode_tuple_header(buf, &index, &i);
   ei_get_type(buf, &index, &i, &size);
   from = driver_alloc(size + 1); 
   ei_decode_string(buf, &index, from);

   ei_get_type(buf, &index, &i, &size);
   to = driver_alloc(size + 1); 
   ei_decode_string(buf, &index, to);
  
   ei_get_type(buf, &index, &i, &size);
   stmp = string = driver_alloc(size + 1); 
   ei_decode_string(buf, &index, string);

   /* Special mode: parse as UTF-8 if possible; otherwise assume it's
      Latin-1.  Makes no difference when encoding. */
   if (strcmp(from, "utf-8+latin-1") == 0) {
      from[5] = '\0';
      invalid_utf8_as_latin1 = 1;
   }
   if (strcmp(to, "utf-8+latin-1") == 0) {
      to[5] = '\0';
   }
   cd = iconv_open(to, from);

   if (cd == (iconv_t) -1) {
      cd = iconv_open("ascii", "ascii");
      if (cd == (iconv_t) -1) {
	 *rbuf = (char*)(b = driver_alloc_binary(size));
	 memcpy(b->orig_bytes, string, size);

	 driver_free(from);
	 driver_free(to);
	 driver_free(string);

	 return size;
      }
   }
   
   outleft = avail = 4*size;
   inleft = size;
   rtmp = rstring = driver_alloc(avail);
   while (inleft > 0) {
      if (iconv(cd, &stmp, &inleft, &rtmp, &outleft) == (size_t) -1) {
	 if (invalid_utf8_as_latin1 && (*stmp & 0x80) && outleft >= 2) {
	    /* Encode one byte of (assumed) Latin-1 into two bytes of UTF-8 */
	    *rtmp++ = 0xc0 | ((*stmp & 0xc0) >> 6);
	    *rtmp++ = 0x80 | (*stmp & 0x3f);
	    outleft -= 2;
	 }
	 stmp++;
	 inleft--;
      }
   }
Esempio n. 26
0
   while (inleft > 0) {
      if (iconv(cd, &stmp, &inleft, &rtmp, &outleft) == (size_t) -1) {
	 if (invalid_utf8_as_latin1 && (*stmp & 0x80) && outleft >= 2) {
	    /* Encode one byte of (assumed) Latin-1 into two bytes of UTF-8 */
	    *rtmp++ = 0xc0 | ((*stmp & 0xc0) >> 6);
	    *rtmp++ = 0x80 | (*stmp & 0x3f);
	    outleft -= 2;
	 }
	 stmp++;
	 inleft--;
      }
   }
   
   size = rtmp - rstring;

   *rbuf = (char*)(b = driver_alloc_binary(size));
   memcpy(b->orig_bytes, rstring, size);

   driver_free(from);
   driver_free(to);
   driver_free(string);
   driver_free(rstring);
   iconv_close(cd);
   
   return size;
}



ErlDrvEntry iconv_driver_entry = {
   NULL,                       /* F_PTR init, N/A */
Esempio n. 27
0
static int
exmpp_xml_control(ErlDrvData drv_data, unsigned int command,
    char *buf, int len, char **rbuf, int rlen)
{
	struct exmpp_xml_data *edd;
	ei_x_buff *to_return;
	ErlDrvBinary *bin;
	int size, ret;

	edd = (struct exmpp_xml_data *)drv_data;
	size = 0;
	bin = NULL;
	to_return = NULL;

	switch (command) {
	/*
	 * Parsing.
	 */

	case COMMAND_PARSE:
	case COMMAND_PARSE_FINAL:
		if (edd->parser == NULL) {
			/* Start a parser. */
			if (create_parser(edd) != 0) {
				to_return = exmpp_new_xbuf();
				if (to_return == NULL)
					return (-1);

				ret = RET_ERROR;
				ei_x_encode_atom(to_return,
				    "parser_setup_failed");

				break;
			}
		}

		/* Control the total size of data to parse. */
		if (!is_data_size_under_limit(&edd->ctx, len)) {
			to_return = exmpp_new_xbuf();
			if (to_return == NULL)
				return (-1);

			ret = RET_ERROR;
			ei_x_encode_atom(to_return, "stanza_too_big");

			break;
		}

		/* Run XML document parsing. */
		ret = XML_Parse(edd->parser, buf, len,
		    command == COMMAND_PARSE_FINAL);

		if (!ret) {
			enum XML_Error errcode;
			const char *errmsg;

			/* An error occured during parsing; most probably,
			 * XML wasn't well-formed. */
			errcode = XML_GetErrorCode(edd->parser);
			errmsg = XML_ErrorString(errcode);

			to_return = exmpp_new_xbuf();
			if (to_return == NULL)
				return (-1);

			ret = RET_ERROR;
			ei_x_encode_tuple_header(to_return, 2);
			ei_x_encode_atom(to_return, "parsing_failed");
			ei_x_encode_tuple_header(to_return, 2);
			ei_x_encode_long(to_return, errcode);
			ei_x_encode_string(to_return, errmsg);

			break;
		}

		/* Return the complete tree(s). */
		ret = RET_OK;
		if (edd->ctx.complete_trees_ready) {
			/* Terminate the complete trees list. */
			ei_x_encode_empty_list(edd->ctx.complete_trees);

			to_return = edd->ctx.complete_trees;
			size = 1 + to_return->index;
			bin = driver_alloc_binary(size);
			if (bin == NULL)
				return (-1);
			bin->orig_bytes[0] = (char)ret;
			memcpy(bin->orig_bytes + 1,
			    to_return->buff, to_return->index);
		} else {
			/* We need more data to produce a tree. */
			to_return = exmpp_new_xbuf();
			if (to_return == NULL)
				return (-1);

			ei_x_encode_atom(to_return,
			    command == COMMAND_PARSE ? "continue" : "done");
		}

		if (command == COMMAND_PARSE) {
			/* Update the size of processed data. */
			add_data_size(&edd->ctx, len);

			/* Reset the complete trees list. */
			reset_complete_trees(&edd->ctx);
		} else {
			/* We're done with the parser. */
			destroy_parser(edd);
		}

		break;

	case COMMAND_RESET_PARSER:
		if (edd->parser != NULL) {
			reset_context(&edd->ctx);
			XML_ParserReset(edd->parser, "UTF-8");
			init_parser(edd);
		}

		ret = RET_OK;

		break;

	/*
	 * Misc.
	 */

	case COMMAND_PORT_REVISION:
		/* Store the revision in the buffer. */
		to_return = exmpp_new_xbuf();
		if (to_return == NULL)
			return (-1);

		ret = RET_OK;
		ei_x_encode_string(to_return, "$Revision$");

		break;

	default:
		/* Other commands are handled in 'exmpp_xml.c' */
		to_return = exmpp_new_xbuf();
		if (to_return == NULL)
			return (-1);

		ret = control(&edd->ctx, command, buf, to_return);
		if (ret < 0)
			return (-1);
	}

	if (bin == NULL) {
		if (to_return != NULL) {
			size = 1 + to_return->index;
			bin = driver_alloc_binary(size);
			if (bin == NULL)
				return (-1);
			bin->orig_bytes[0] = (char)ret;
			if (to_return->index > 0)
				memcpy(bin->orig_bytes + 1,
				    to_return->buff, to_return->index);
			exmpp_free_xbuf(to_return);
		} else {
			/* The command called doesn't return anything. */
			size = 1;
			bin = driver_alloc_binary(size);
			bin->orig_bytes[0] = RET_OK;
		}
	}

	/* Set the returned buffer. */
	*rbuf = (char *)bin;

	/* Return the size of this buffer. */
	return (size);
}
Esempio n. 28
0
static int tls_drv_control(ErlDrvData handle,
			   unsigned int command,
			   char *buf, int len,
			   char **rbuf, int rlen)
{
   tls_data *d = (tls_data *)handle;
   int res;
   int size;
   ErlDrvBinary *b;
   X509 *cert;
   unsigned int flags = command;

   command &= 0xffff;

   ERR_clear_error();
   switch (command)
   {
      case SET_CERTIFICATE_FILE_ACCEPT:
      case SET_CERTIFICATE_FILE_CONNECT: {
	 time_t mtime = 0;
	 SSL_CTX *ssl_ctx = hash_table_lookup(buf, &mtime);
	 if (is_key_file_modified(buf, &mtime) || ssl_ctx == NULL)
	 {
	    SSL_CTX *ctx;

	    hash_table_insert(buf, mtime, NULL);

	    ctx = SSL_CTX_new(SSLv23_method());
	    die_unless(ctx, "SSL_CTX_new failed");

	    res = SSL_CTX_use_certificate_chain_file(ctx, buf);
	    die_unless(res > 0, "SSL_CTX_use_certificate_file failed");

	    res = SSL_CTX_use_PrivateKey_file(ctx, buf, SSL_FILETYPE_PEM);
	    die_unless(res > 0, "SSL_CTX_use_PrivateKey_file failed");

	    res = SSL_CTX_check_private_key(ctx);
	    die_unless(res > 0, "SSL_CTX_check_private_key failed");

	    SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
	    SSL_CTX_set_default_verify_paths(ctx);
#ifdef SSL_MODE_RELEASE_BUFFERS
	    SSL_CTX_set_mode(ctx, SSL_MODE_RELEASE_BUFFERS);
#endif

	    if (command == SET_CERTIFICATE_FILE_ACCEPT)
	    {
	       SSL_CTX_set_verify(ctx,
				  SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,
				  verify_callback);
	    }

	    ssl_ctx = ctx;
	    hash_table_insert(buf, mtime, ssl_ctx);
	 }

	 d->ssl = SSL_new(ssl_ctx);
	 die_unless(d->ssl, "SSL_new failed");

	 if (flags & VERIFY_NONE)
	    SSL_set_verify(d->ssl, SSL_VERIFY_NONE, verify_callback);

	 d->bio_read = BIO_new(BIO_s_mem());
	 d->bio_write = BIO_new(BIO_s_mem());

	 SSL_set_bio(d->ssl, d->bio_read, d->bio_write);

	 if (command == SET_CERTIFICATE_FILE_ACCEPT) {
	    SSL_set_options(d->ssl, SSL_OP_NO_TICKET);
	    SSL_set_accept_state(d->ssl);
	 } else {
	    SSL_set_options(d->ssl, SSL_OP_NO_SSLv2|SSL_OP_NO_TICKET);
	    SSL_set_connect_state(d->ssl);
	 }
	 break;
      }
      case SET_ENCRYPTED_INPUT:
	 die_unless(d->ssl, "SSL not initialized");
	 BIO_write(d->bio_read, buf, len);
	 break;
      case SET_DECRYPTED_OUTPUT:
	 die_unless(d->ssl, "SSL not initialized");
	 res = SSL_write(d->ssl, buf, len);
	 if (res <= 0) 
	 {
	    res = SSL_get_error(d->ssl, res);
	    if (res == SSL_ERROR_WANT_READ || res == SSL_ERROR_WANT_WRITE) 
	    {
	       b = driver_alloc_binary(1);
	       b->orig_bytes[0] = 2;
	       *rbuf = (char *)b;
	       return 1;
	    } else {
	       die_unless(0, "SSL_write failed");
	    }
	 }
	 break;
      case GET_ENCRYPTED_OUTPUT:
	 die_unless(d->ssl, "SSL not initialized");
	 size = BUF_SIZE + 1;
	 rlen = 1;
	 b = driver_alloc_binary(size);
	 b->orig_bytes[0] = 0;
	 while ((res = BIO_read(d->bio_write,
				b->orig_bytes + rlen, BUF_SIZE)) > 0)
	 {
	    //printf("%d bytes of encrypted data read from state machine\r\n", res);

	    rlen += res;
	    size += BUF_SIZE;
	    b = driver_realloc_binary(b, size);
	 }
	 b = driver_realloc_binary(b, rlen);
	 *rbuf = (char *)b;
	 return rlen;
      case GET_DECRYPTED_INPUT:
	 if (!SSL_is_init_finished(d->ssl))
	 {
	    res = SSL_do_handshake(d->ssl);
	    if (res <= 0)
	       die_unless(SSL_get_error(d->ssl, res) == SSL_ERROR_WANT_READ,
			  "SSL_do_handshake failed");
	 } else {
	    size = BUF_SIZE + 1;
	    rlen = 1;
	    b = driver_alloc_binary(size);
	    b->orig_bytes[0] = 0;

	    while ((res = SSL_read(d->ssl,
				   b->orig_bytes + rlen, BUF_SIZE)) > 0)
	    {
	       //printf("%d bytes of decrypted data read from state machine\r\n",res);
	       rlen += res;
	       size += BUF_SIZE;
	       b = driver_realloc_binary(b, size);
	    }

	    if (res < 0)
	    {
	       int err = SSL_get_error(d->ssl, res);

	       if (err == SSL_ERROR_WANT_READ)
	       {
		  //printf("SSL_read wants more data\r\n");
		  //return 0;
	       }
	       // TODO
	    }
	    b = driver_realloc_binary(b, rlen);
	    *rbuf = (char *)b;
	    return rlen;
	 }
	 break;
      case GET_PEER_CERTIFICATE:
	 cert = SSL_get_peer_certificate(d->ssl);
	 if (cert == NULL)
	 {
	    b = driver_alloc_binary(1);
	    b->orig_bytes[0] = 1;
	    *rbuf = (char *)b;
	    return 1;
	 } else {
	    unsigned char *tmp_buf;
	    rlen = i2d_X509(cert, NULL);
	    if (rlen >= 0)
	    {
	       rlen++;
	       b = driver_alloc_binary(rlen);
	       b->orig_bytes[0] = 0;
	       tmp_buf = (unsigned char *)&b->orig_bytes[1];
	       i2d_X509(cert, &tmp_buf);
	       X509_free(cert);
	       *rbuf = (char *)b;
	       return rlen;
	    } else
	       X509_free(cert);
	 }
	 break;
      case GET_VERIFY_RESULT:
	 b = driver_alloc_binary(1);
	 b->orig_bytes[0] = SSL_get_verify_result(d->ssl);
	 *rbuf = (char *)b;
	 return 1;
	 break;
   }

   b = driver_alloc_binary(1);
   b->orig_bytes[0] = 0;
   *rbuf = (char *)b;
   return 1;
}
Esempio n. 29
0
static int ejabberd_zlib_drv_control(ErlDrvData handle,
				     unsigned int command,
				     char *buf, int len,
				     char **rbuf, int rlen)
{
   ejabberd_zlib_data *d = (ejabberd_zlib_data *)handle;
   int err;
   int size;
   ErlDrvBinary *b;

   switch (command)
   {
      case DEFLATE:
	 size = BUF_SIZE + 1;
	 rlen = 1;
	 b = driver_alloc_binary(size);
	 b->orig_bytes[0] = 0;

	 d->d_stream->next_in = (unsigned char *)buf;
	 d->d_stream->avail_in = len;
	 d->d_stream->avail_out = 0;
	 err = Z_OK;

	 while (err == Z_OK && d->d_stream->avail_out == 0)
	 {
	    d->d_stream->next_out = (unsigned char *)b->orig_bytes + rlen;
	    d->d_stream->avail_out = BUF_SIZE;

	    err = deflate(d->d_stream, Z_SYNC_FLUSH);
	    die_unless((err == Z_OK) || (err == Z_STREAM_END),
		       "Deflate error");

	    rlen += (BUF_SIZE - d->d_stream->avail_out);
	    size += (BUF_SIZE - d->d_stream->avail_out);
	    b = driver_realloc_binary(b, size);
	 }
	 b = driver_realloc_binary(b, rlen);
	 *rbuf = (char *)b;
	 return rlen;
      case INFLATE:
	 size = BUF_SIZE + 1;
	 rlen = 1;
	 b = driver_alloc_binary(size);
	 b->orig_bytes[0] = 0;

	 if (len > 0) {
	    d->i_stream->next_in = (unsigned char *)buf;
	    d->i_stream->avail_in = len;
	    d->i_stream->avail_out = 0;
	    err = Z_OK;

	    while (err == Z_OK && d->i_stream->avail_out == 0)
	    {
	       d->i_stream->next_out = (unsigned char *)b->orig_bytes + rlen;
	       d->i_stream->avail_out = BUF_SIZE;

	       err = inflate(d->i_stream, Z_SYNC_FLUSH);
	       die_unless((err == Z_OK) || (err == Z_STREAM_END),
			  "Inflate error");

	       rlen += (BUF_SIZE - d->i_stream->avail_out);
	       size += (BUF_SIZE - d->i_stream->avail_out);
	       b = driver_realloc_binary(b, size);
	    }
	 }
	 b = driver_realloc_binary(b, rlen);
	 *rbuf = (char *)b;
	 return rlen;
   }

   b = driver_alloc_binary(1);
   b->orig_bytes[0] = 0;
   *rbuf = (char *)b;
   return 1;
}
Esempio n. 30
0
static void uvc_drv_input(ErlDrvData handle, ErlDrvEvent io_event)
{
  Uvc* d = (Uvc*) handle;
  struct v4l2_buffer buf;
	
  memset(&buf, 0, sizeof buf);
	buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	buf.memory = V4L2_MEMORY_MMAP;
	int ret = ioctl(d->fd, VIDIOC_DQBUF, &buf);
	if(ret < 0) {
    driver_failure_posix(d->port, errno);
    return;
	}
	
  ErlDrvBinary* bin;
  size_t len;
  if(d->pixelformat == V4L2_PIX_FMT_YUYV) {
    len = d->width*d->height*3/2;
    bin = driver_alloc_binary(len);
    
    if(!d->scale_ctx) d->scale_ctx = sws_getContext(
      d->width, d->height, PIX_FMT_YUYV422, 
      d->width, d->height, PIX_FMT_YUV420P, 
      SWS_FAST_BILINEAR, NULL, NULL, NULL
    );

    int linesize[4] = {d->width*2, 0, 0, 0};
    uint8_t *src[4] = {(uint8_t *)d->buffers[buf.index].mem, 0, 0, 0};

    int stride_size = d->width*d->height;
    uint8_t *plane[4] = {(uint8_t *)bin->orig_bytes, (uint8_t *)bin->orig_bytes+stride_size, (uint8_t *)bin->orig_bytes+stride_size+stride_size/4, NULL};
    int stride[4] = {d->width, d->width/2, d->width/2, 0};
    
    sws_scale(d->scale_ctx, (const uint8_t * const*)src, linesize, 0, d->height, plane, stride);
  } else {
    bin = driver_alloc_binary(buf.bytesused + 1024);
    len = add_huffman((uint8_t *)bin->orig_bytes, (uint8_t *)d->buffers[buf.index].mem, buf.bytesused);
  }
  
  
  ErlDrvUInt64 pts = buf.timestamp.tv_sec * 1000 + buf.timestamp.tv_usec / 1000;
  
  ErlDrvTermData reply[] = {
    ERL_DRV_ATOM, driver_mk_atom("uvc"),
    ERL_DRV_PORT, driver_mk_port(d->port),
    ERL_DRV_ATOM, driver_mk_atom(d->pixelformat == V4L2_PIX_FMT_YUYV ? "yuv" : "jpeg"),
    ERL_DRV_UINT64, &pts,
    ERL_DRV_BINARY, (ErlDrvTermData)bin, (ErlDrvTermData)len, 0,
    ERL_DRV_TUPLE, 5
  };


  // fprintf(stderr, "Event in uvc: %lu %u %u\r\n", len, (unsigned)buf.timestamp.tv_sec, (unsigned)buf.timestamp.tv_usec);
  driver_output_term(d->port, reply, sizeof(reply) / sizeof(reply[0]));
  driver_free_binary(bin);
  
  ret = video_queue_buffer(d, buf.index);
  if(ret < 0) {
      driver_failure_posix(d->port, errno);
      return;
  }
}