⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 asn1_erl_driver.c

📁 OTP是开放电信平台的简称
💻 C
📖 第 1 页 / 共 4 页
字号:
    ret = CEIL(desired_no,8);/*     printf("ret = %d\n\r",ret); */  }/*   printf("*unused = %d\n\r",*unused); */  *input_ptr = in_ptr;  return ret;}/* insert_octets_as_bits_exact_len */intinsert_octets_as_bits_exact_len(int desired_len,				int in_buff_len,				unsigned char **in_ptr,				unsigned char **ptr,				int *unused){  int ret = 0;  int ret2 = 0;  if (desired_len == in_buff_len) {    if ((ret = insert_octets_as_bits(in_buff_len,in_ptr,ptr,unused)) == ASN1_ERROR)      return ASN1_ERROR;  }  else if(desired_len > in_buff_len) {    if((ret = insert_octets_as_bits(in_buff_len,in_ptr,ptr,unused)) == ASN1_ERROR)      return ASN1_ERROR;    /* now pad with zero bits *//*     printf("~npad_bits: called with %d bits padding~n~n~r",desired_len - in_buff_len); */    if ((ret2=pad_bits(desired_len - in_buff_len,ptr,unused)) == ASN1_ERROR)      return ASN1_ERROR;  }  else {/* desired_len < no_bits */    if ((ret=insert_octets_as_bits(desired_len,in_ptr,ptr,unused)) == ASN1_ERROR)      return ASN1_ERROR;    /* now remove no_bits - desired_len bytes from in buffer */    *in_ptr += (in_buff_len - desired_len);  }  return (ret+ret2);}/* insert_octets_as_bits takes no_bytes bytes from the buffer that input_ptr   points at and inserts the least significant bit of it in the buffer that   output_ptr points at. Each byte in the input buffer must be 1 or 0   otherwise the function returns ASN1_ERROR. The output buffer is concatenated   without alignment. */int insert_octets_as_bits(int no_bytes,			  unsigned char **input_ptr,			  unsigned char **output_ptr,			  int *unused){  unsigned char *in_ptr = *input_ptr;  unsigned char *ptr = *output_ptr;  int used_bits = 8 - *unused;  while (no_bytes > 0) {    switch (*++in_ptr) {    case 0:      if(*unused == 1){	*unused = 8;	*++ptr = 0x00;      } else 	(*unused)--;      break;    case 1:      if(*unused == 1){	*ptr = *ptr | 1;	*unused = 8;	*++ptr = 0x00;      } else {	*ptr = *ptr | (1 << (*unused - 1));	(*unused)--;      }      break;    default:      return ASN1_ERROR;    }    no_bytes--;  }  *input_ptr = in_ptr;  *output_ptr = ptr;  return ((used_bits+no_bytes) / 8); /*return number of new bytes				      in completed buffer */}/* insert_octets inserts bytes from the input buffer, *input_ptr,   into the output buffer, *output_ptr. Before the first byte is   inserted the input buffer is aligned. */int insert_octets(int no_bytes,		  unsigned char **input_ptr,		  unsigned char **output_ptr,		  int *unused){    unsigned char *in_ptr = *input_ptr;    unsigned char *ptr = *output_ptr;    int ret = 0;          if (*unused != 8) {/* must align before octets are added */      *++ptr = 0x00;      ret++;      *unused = 8;    }    while(no_bytes > 0) {      *ptr = *(++in_ptr);      *++ptr = 0x00;      /*      *unused = *unused - 1; */      no_bytes--;    }  *input_ptr = in_ptr;  *output_ptr = ptr;  return (ret + no_bytes);}/* insert_octets_unaligned inserts bytes from the input buffer, *input_ptr,   into the output buffer, *output_ptr.No alignment is done. */int insert_octets_unaligned(int no_bytes,			    unsigned char **input_ptr,			    unsigned char **output_ptr,			    int unused){  unsigned char *in_ptr = *input_ptr;  unsigned char *ptr = *output_ptr;  int n = no_bytes;  unsigned char val;    while (n > 0) {    if (unused == 8) {      *ptr = *++in_ptr;      *++ptr = 0x00;    }else {      val = *++in_ptr;      *ptr =  *ptr | val >> (8 - unused);      *++ptr = 0x00;      *ptr = val << unused;    }    n--;  }  *input_ptr = in_ptr;  *output_ptr = ptr;  return no_bytes;}int insert_octets_except_unused(int no_bytes,				unsigned char **input_ptr,				unsigned char **output_ptr,				int *unused,				int in_unused){  unsigned char *in_ptr = *input_ptr;  unsigned char *ptr = *output_ptr;  int val, no_bits;  int ret = 0;    if (in_unused == 0){/*      printf("%d: insert_octets_except_unused: if\n\r",__LINE__); */    if ((ret = insert_octets_unaligned(no_bytes,&in_ptr,&ptr,				       *unused)) == ASN1_ERROR)      return ASN1_ERROR;  }    else {/*        printf("%d: insert_octets_except_unused: else\n\r",__LINE__); */      if ((ret=insert_octets_unaligned(no_bytes - 1,&in_ptr,&ptr,*unused)) != ASN1_ERROR) {	val = (int) *(++in_ptr);	no_bits = 8 - in_unused;	/* no_bits is always less than *unused since the buffer is	   octet aligned after insert:octets call, so the following	   if clasuse is obsolete I think */	if(no_bits < *unused){	  *ptr = *ptr | (val >> (8 - *unused));	  *unused = *unused - no_bits;	} else if (no_bits == *unused) {	  *ptr = *ptr | (val >> (8 - *unused));	  *++ptr = 0x00;	  ret++;	  *unused = 8;	} else {	  *ptr = *ptr | (val >> (8 - *unused));	  *++ptr = 0x00;	  ret++;	  *ptr = *ptr | (val << *unused);	  *unused = 8 - (no_bits - *unused);	}      } else	return ASN1_ERROR;    }  *input_ptr = in_ptr;  *output_ptr = ptr;/*    printf("%d: insert_octets_except_unused: ret=%d\n\r",__LINE__,ret); */  return ret;}/* *  * This section defines functionality for the partial decode of a * BER encoded message * *//* * int decode(ErlDrvBinary **drv_binary,unsigned char *decode_buf, *            unsigned char *in_buf, int in_buf_len)  * drv_binary is a pointer to a pointer to an allocated driver binary. * in_buf is a pointer into the buffer of incoming bytes. * in_buf_len is the length of the incoming buffer. * The function reads the bytes in the incoming buffer and structures * it in a nested way as Erlang terms. The buffer contains data in the * order tag - length - value. Tag, length and value has the following * format: * A tag is normally one byte but may be of any length, if the tag number * is greater than 30. +----------+ *		       |CL|C|NNNNN| * 		       +----------+ * If NNNNN is 31 then will the 7 l.s.b of each of the following tag number * bytes contain the tag number. Each tag number byte that is not the last one * has the m.s.b. set to 1. * The length can be short definite length (sdl), long definite length (ldl) * or indefinite length (il). * sdl: +---------+ the L bits is the length *	|0|LLLLLLL| *	+---------+ * ldl:	+---------+ +---------+ +---------+     +-----------+ *	|1|lllllll| |first len| |	  |     |the Nth len| *	+---------+ +---------+ +---------+ ... +-----------+ *    	The first byte tells how many len octets will follow, max 127 * il:  +---------+ +----------------------+ +--------+ +--------+ *	|1|0000000| |content octets (Value)| |00000000| |00000000| *	+---------+ +----------------------+ +--------+ +--------+ *	The value octets are preceded by one octet and followed by two  *	exactly as above. The value must be some tag-length-value encoding. * * The function returns a value in Erlnag term format: * {{TagNo,Value},Rest} * TagNo is an integer ((CL bsl 16) + tag number) which limits the tag number  * to 65535. * Value is a binary if the C bit in tag was unset, otherwise (if tag was * constructed) Value is a list, List. * List is like: [{TagNo,Value},{TagNo,Value},...] * Rest is a binary, i.e. the undecoded part of the buffer. Most often Rest * is the empty binary. * If some error occured during the decoding of the in_buf an error is returned. */int decode_begin(ErlDrvBinary **drv_binary,unsigned char *in_buf, int in_buf_len, unsigned int *err_pos){  int maybe_ret;  char *decode_buf = (*drv_binary)->orig_bytes;  int ei_index = 0;  int ib_index = 0;  /* ei_index is the index used by the ei functions to encode an     Erlang term into the buffer decode_buf */  /* ib_index is the index were to read the next byte from in_buf */#ifdef ASN1_DEBUG    printf("decode_begin1: ei_index=%d, ib_index=%d\n\r",ei_index,ib_index);#endif  /* the first byte must be a "version magic" */  if(ei_encode_version(decode_buf,&ei_index) == ASN1_ERROR)    return ASN1_ERROR;		/* 1 byte */#ifdef ASN1_DEBUG    printf("decode_begin2: ei_index=%d, ib_index=%d\n\r",ei_index,ib_index);#endif  if (ei_encode_tuple_header(decode_buf,&ei_index,2) == ASN1_ERROR)    return ASN1_ERROR;		/* 2 bytes */#ifdef ASN1_DEBUG    printf("decode_begin3: ei_index=%d, ib_index=%d\n\r",ei_index,ib_index);#endif  if((maybe_ret=decode(drv_binary,&ei_index,in_buf,&ib_index,in_buf_len)) <= ASN1_ERROR)     {      *err_pos = ib_index;#ifdef ASN1_DEBUG       printf("err_pos=%d,ib_index=%d\r\n",*err_pos,ib_index);#endif      return maybe_ret;    };    decode_buf = (*drv_binary)->orig_bytes; /* maybe a realloc during decode_value */#ifdef ASN1_DEBUG    printf("decode_begin4: in_buf_len=%d, ei_index=%d, ib_index=%d\n\r",  	 in_buf_len,ei_index,ib_index);#endif  /* "{{TagNo,Value},Rest}" */  if (ei_encode_binary(decode_buf,&ei_index,&(in_buf[ib_index]),in_buf_len-ib_index)      == ASN1_ERROR)		/* at least 5 bytes */    return ASN1_ERROR;#ifdef ASN1_DEBUG    printf("decode_begin5: ei_index=%d, ib_index=%d\n\r",ei_index,ib_index);#endif  return ei_index;}int decode(ErlDrvBinary **drv_binary,int *ei_index,unsigned char *in_buf,	   int *ib_index, int in_buf_len){  int maybe_ret;  char *decode_buf = (*drv_binary)->orig_bytes;  int form;#ifdef ASN1_DEBUG    printf("decode 1\n\r");#endif  if (((*drv_binary)->orig_size - *ei_index) < 19) {/* minimum amount of bytes */    /* allocate more memory */    if (realloc_decode_buf(drv_binary,(*drv_binary)->orig_size * 2) == 	ASN1_ERROR)      return ASN1_ERROR;    decode_buf = (*drv_binary)->orig_bytes;  }/*    printf("decode 2\n\r"); */    /* "{" */    if (ei_encode_tuple_header(decode_buf,ei_index,2) == ASN1_ERROR)    return ASN1_ERROR;		/* 2 bytes */#ifdef ASN1_DEBUG    printf("decode 3:orig_size=%d, ei_index=%d, ib_index=%d\n\r",(*drv_binary)->orig_size,*ei_index,*ib_index);#endif    /*buffer must hold at least two bytes*/	    if ((*ib_index +2) > in_buf_len)      return ASN1_VALUE_ERROR;    /* "{{TagNo," */    if ((form = decode_tag(decode_buf,ei_index,in_buf,in_buf_len,ib_index)) <= ASN1_ERROR)      return form;		/* 5 bytes */#ifdef ASN1_DEBUG    printf("i_i=%d,in_buf_len=%d\r\n",*ei_index,in_buf_len);#endif    if (*ib_index >= in_buf_len){      return ASN1_TAG_ERROR;    }#ifdef ASN1_DEBUG    printf("decode 5 ib_index=%d\n\r",*ib_index);#endif    /* buffer must hold at least one byte (0 as length and nothing as       value) */    /* "{{TagNo,Value}," */    if ((maybe_ret=decode_value(ei_index,in_buf,ib_index,drv_binary,form,				in_buf_len)) <= ASN1_ERROR)      return maybe_ret;		/* at least 5 bytes */#ifdef ASN1_DEBUG     printf("decode 7\n\r");#endif    return *ei_index;}/*  * decode_tag decodes the BER encoded tag in in_buf and puts it in the * decode_buf encoded by the Erlang extern format as an Erlang term. */int decode_tag(char *decode_buf,int *db_index,unsigned char *in_buf,	       int in_buf_len, int *ib_index){  int tag_no, tmp_tag, form;    /* first get the class of tag and bit shift left 16*/  tag_no = ((MASK(in_buf[*ib_index],ASN1_CLASS)) << 10);  form = (MASK(in_buf[*ib_index],ASN1_FORM));#ifdef ASN1_DEBUG     printf("decode_tag0:ii=%d, tag_no=%d, form=%d.\r\n",	    *ib_index,tag_no,form);#endif  /* then get the tag number */  if((tmp_tag = (int) INVMASK(in_buf[*ib_index],ASN1_CLASSFORM)) < 31) {    ei_encode_ulong(decode_buf,db_index,tag_no+tmp_tag); /* usual case */    (*ib_index)++;#ifdef ASN1_DEBUG     printf("decode_tag1:ii=%d.\r\n",*ib_index);#endif  }  else    {      int n = 0; /* n is used to check that the 64K limit is not		    exceeded*/#ifdef ASN1_DEBUG     printf("decode_tag1:ii=%d, in_buf_len=%d.\r\n",*ib_index,in_buf_len);#endif      /* should check that at least three bytes are left in	 in-buffer,at least two tag byte and at least one length byte */      if ((*ib_index +3) > in_buf_len)	return ASN1_VALUE_ERROR;      (*ib_index)++;#ifdef ASN1_DEBUG       printf("decode_tag2:ii=%d.\r\n",*ib_index);#endif      /* The tag is in the following bytes in in_buf as 	 1ttttttt 1ttttttt ... 0ttttttt, where the t-bits	 is the tag number*/      /* In practice is the tag size limited to 64K, i.e. 16 bits. If	 the tag is greater then 64K return an error */      while (((tmp_tag = (int)in_buf[*ib_index]) >= 128) && n < 2){	/* m.s.b. = 1 */	tag_no = tag_no + (MASK(tmp_tag,ASN1_LONG_TAG) << 7);	(*ib_index)++;#ifdef ASN1_DEBUG 	printf("decode_tag3:ii=%d.\r\n",*ib_index);#endif	n++;      };      if ((n==2) && in_buf[*ib_index] > 3)	return ASN1_TAG_ERROR; /* tag number > 64K */      tag_no = tag_no + in_buf[*ib_index];      (*ib_index)++;#ifdef ASN1_DEBUG       printf("decode_tag4:ii=%d.\r\n",*ib_index);#endif      ei_encode_ulong(decode_buf,db_index,tag_no);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -