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

📄 mms_msg.c

📁 手机端彩信的编解码、以及接收和发送。非常有用。
💻 C
📖 第 1 页 / 共 5 页
字号:
     
     case MMS_HEADER_ATTRIBUTES:
	  ch = mms_string_to_header(value);
	  pack_short_integer(os, ch);
	  break;
	  	  
     case MMS_HEADER_MBOX_TOTALS:
     case MMS_HEADER_MBOX_QUOTAS:
     {
	  long i, l;
	  
	  i = octstr_parse_long(&l, value, 0, 10);
	  if (i <0) {
	       warning(0, "Bad quota value  for field %s!", mms_header_to_cstr(field_type));
	       i = 0;
	  }
	  
	  if (octstr_case_search(value, octstr_imm("bytes"), i) < 0)
	       ch = 0x80;
	  else
	       ch = 0x81;
	  pack_short_integer(encoded, ch);	  
	  wsp_pack_integer_value(encoded, l);
	  
	  wsp_pack_value(os, encoded);
     }
     break;
     
     case MMS_HEADER_ELEMENT_DESCRIPTOR:
     {
	  Octstr *cv, *cpar;
	  List *params;
	  int i, n;
	  
	  split_header_value(value, &cv, &cpar);
	  params = get_value_parameters(cpar);

	  wsp_pack_text(encoded, cv);
	  n = gwlist_len(params);

	  for (i = 0; i<n; i++) {
	       Octstr *h, *v;
	       int ch;
	       http_header_get(params, i, &h, &v);
	       ch = mms_string_to_descriptor_params(h);
	       if (ch < 0)
		    wsp_pack_text(encoded, h);
	       else
		    pack_short_integer(encoded, ch);

	       ch = wsp_string_to_content_type(v);
	       if (ch < 0)
		    wsp_pack_text(encoded, v);
	       else 
		    pack_short_integer(encoded, ch);

	       octstr_destroy(h);
	       octstr_destroy(v);
	  }
	  	  
	  octstr_destroy(cv);
	  octstr_destroy(cpar);
	  http_destroy_headers(params);

	  wsp_pack_value(os, encoded);
     }
     break;
     default:
	  warning(0, "MMS: Unknown header with code 0x%02x!", field_type);
     }

     if (encoded) octstr_destroy(encoded);
     return;
}

static int encode_msgheaders(Octstr *os, List *hdrs)
{
     int fcont = 1;
     int i, l = gwlist_len(hdrs), mtype;
     
     Octstr *msgtype = NULL, *transid = NULL, *version = NULL, *ctype;

     strip_boundary_element(hdrs,NULL);
     /* First ensure that top headers are in place. */

     version = http_header_value(hdrs, 
				 octstr_imm("X-Mms-MMS-Version"));
     
     transid = http_header_value(hdrs, 
				 octstr_imm("X-Mms-Transaction-Id"));
     msgtype = http_header_value(hdrs, 
				 octstr_imm("X-Mms-Message-Type"));
     
     ctype = http_header_value(hdrs, 
				 octstr_imm("Content-Type"));
     
     mtype = mms_string_to_message_type(msgtype);
     
     pack_short_integer(os, MMS_HEADER_MESSAGE_TYPE);
     pack_short_integer(os, mtype);
     octstr_destroy(msgtype);
     
     if (transid) {
	  pack_short_integer(os, MMS_HEADER_TRANSACTION_ID);
	  wsp_pack_text(os, transid);
	  octstr_destroy(transid);
     }
     pack_short_integer(os, MMS_HEADER_MMS_VERSION);
     wsp_pack_version_value(os, version);
     octstr_destroy(version);
     
     /* Now pack the rest. */
     for (i = 0; fcont && i < l; i++) {
	  Octstr *field = NULL, *value = NULL;	  
	  int htype;
	  
	  http_header_get(hdrs, i, &field, &value);

	  htype = mms_string_to_header(field);

	  if (htype == MMS_HEADER_MMS_VERSION ||
	      htype == MMS_HEADER_MESSAGE_TYPE ||
	      htype == MMS_HEADER_TRANSACTION_ID ||
	      htype == MMS_HEADER_CONTENT_TYPE)
	       goto loop1;

	  if (htype < 0)
	       wsp_pack_application_header(os, field, value);
	  else {
	       pack_short_integer(os, htype);
	       mms_pack_well_known_field(os, htype, value);	       
	  }
     loop1:
	  if (field) octstr_destroy(field);
	  if (value) octstr_destroy(value);
     }
     
     if (ctype) {
	  pack_short_integer(os, MMS_HEADER_CONTENT_TYPE);
	  wsp_pack_content_type(os, ctype);
	  octstr_destroy(ctype);
     } else if (mtype == MMS_MSGTYPE_SEND_REQ || 
		mtype == MMS_MSGTYPE_RETRIEVE_CONF)
	  warning(0, "MMS: Content type missing in encode_headers!");
     
     return 0;

}

/* Does basic fixups on a message. */
static int fixup_msg(MmsMsg *m, Octstr *from)
{
     Octstr *ver;
     Octstr *s = NULL;
     if (!m)
	  return -1;

     ver = http_header_value(m->headers, octstr_imm("X-Mms-MMS-Version"));
     if (!ver || octstr_str_compare(ver, "1.1") <= 0) {
	  m->enc = MS_1_1;
	  if (!ver)
	       http_header_add(m->headers, "X-Mms-MMS-Version", MMS_DEFAULT_VERSION);
     } else if (octstr_str_compare(ver, "1.2") <= 0)
	  m->enc = MS_1_2;
     http_header_remove_all(m->headers, "MIME-Version");
     switch (m->message_type) {
     case MMS_MSGTYPE_SEND_REQ:
     case MMS_MSGTYPE_RETRIEVE_CONF:
     case MMS_MSGTYPE_FORWARD_REQ:
	  
	  /* Check for from. */
	  if (from && (s = http_header_value(m->headers, octstr_imm("From"))) == NULL) 
	       http_header_add(m->headers, "From", octstr_get_cstr(from));
	  else if (s)
	       octstr_destroy(s);
	  
	  /* Check for date. */
	  
	  if ((s = http_header_value(m->headers, octstr_imm("Date"))) == NULL) {
	       Octstr *t = date_format_http(time(NULL));
	       http_header_add(m->headers, "Date", octstr_get_cstr(t));
	       octstr_destroy(t);
	  } else
	       octstr_destroy(s);
	  
#if 0    /* This will be done elsewhere. */
	  /* Check for msgid, put in if missing. */
	  if ((s = http_header_value(m->headers, octstr_imm("Message-ID"))) == NULL) 
	       http_header_add(m->headers, "Message-ID", "00000");
	  else
	       octstr_destroy(s);
#endif 
	  /* check for content-type. */
	  if ((s = http_header_value(m->headers, octstr_imm("Content-Type"))) == NULL) {
	       char *ctype;
	       if (m->body.s == NULL || 
		   (!m->ismultipart && 
		    octstr_check_range(m->body.s, 0, 
				       octstr_len(m->body.s), _mms_gw_isprint) == 0))
		    ctype = "application/octet-stream";
	       else if (m->ismultipart)
		    ctype = "application/vnd.wap.multipart.mixed";
	       else
		    ctype = "text/plain";
	       http_header_add(m->headers, "Content-Type", ctype);
	  }  else
	       octstr_destroy(s);
	  strip_boundary_element(m->headers, NULL); /* remove top-level boundary element if any. */     
	  break;
     case MMS_MSGTYPE_SEND_CONF:
     case MMS_MSGTYPE_NOTIFICATION_IND:
     case MMS_MSGTYPE_DELIVERY_IND:
     case MMS_MSGTYPE_READ_REC_IND:
     case MMS_MSGTYPE_READ_ORIG_IND:
	  http_header_remove_all(m->headers, "Content-Type"); /* Just in case, particularly from mime! */
	  break;
     }
     return 0;
}

mms_encoding mms_message_enc(MmsMsg *msg)
{
     gw_assert(msg);
     return msg->enc;
}

MmsMsg *mms_frombinary(Octstr *msg, Octstr *from)
{
     int res = 0;
     MmsMsg _m = {0}, *m = NULL;
     ParseContext *p;
     Octstr *s;
     
     if (!msg)
	  return NULL;
     
     p = parse_context_create(msg);     
     mms_strings_init(); /* Just in case. */
     
     _m.headers = gwlist_create();
     decode_msgheaders(p, _m.headers, from, 1);

     if (_m.headers == NULL || 
	 gwlist_len(_m.headers) == 0) 
	  goto done;        

     /* Get the message type and also set flag for whether multipart.*/
     
     s = http_header_value(_m.headers, octstr_imm("Content-Type"));     
     if (s && 
	 octstr_search(s, octstr_imm("application/vnd.wap.multipart"), 0) == 0)
	  _m.ismultipart = 1;
     if (s) 
	  octstr_destroy(s);

     s = http_header_value(_m.headers, octstr_imm("X-Mms-Message-Type"));     
     if (s) {
	  _m.message_type = mms_string_to_message_type(s); 
	  octstr_destroy(s);
     } else 
	  goto done;	  
     
     s = http_header_value(_m.headers, octstr_imm("Message-ID"));          
     _m.msgId = s;
 
     if ((res = decode_msgbody(p, &_m)) < 0)  /* A body decode error occured. */
	  goto done;
     
	 
     m = gw_malloc(sizeof m[0]); /* all ok, copy. */
     *m = _m;     
     
     fixup_msg(m, from);

 done:
     parse_context_destroy(p);
     if (!m) { /* This means an error occurred. Delete the interim stuff. */
	  MmsMsg *msg = &_m;
	
	  if (msg->ismultipart && msg->body.l)
	       gwlist_destroy(msg->body.l, (gwlist_item_destructor_t *)mime_entity_destroy);     
	  else if (msg->body.s)
	       octstr_destroy(msg->body.s);

	  if (msg->headers) 
	       http_destroy_headers(msg->headers);
	  if (msg->msgId)
	       octstr_destroy(msg->msgId);
     }
     return m;
}

static void _x_mime_entity_dump(MIMEEntity *x, int level, int headers_only)
{
     int i,m, ism;
     List *h;
     Octstr *body;

     ism = ((m = mime_entity_num_parts(x)) > 0);
     debug("part.dump", 0, "%sMultipart -> ", ism ? "" : "Not ");
     
     h = mime_entity_headers(x);
     strip_boundary_element(h,NULL);
     http_header_dump(h);
     http_destroy_headers(h);
     
     if (ism) 
	  for (i = 0; i<m; i++) {
	       MIMEEntity *xm = mime_entity_get_part(x, i);
	       _x_mime_entity_dump(xm, level+1, headers_only);
	       mime_entity_destroy(xm);
	  }
     else if ((body = mime_entity_body(x)) != NULL) {
	  if (!headers_only)
	       octstr_dump(body, level);	       
	  octstr_destroy(body);
     }
}

void mms_msgdump(MmsMsg *m, int headers_only)
{
     int i, n;

     gw_assert(m);

     http_header_dump(m->headers);

     debug("mms.dump", 0, "Dumping MMS message body (%s) [%ld parts] --> ", 
	   m->ismultipart ? "mulitpart" : "not multipart", 
	   m->ismultipart ? gwlist_len(m->body.l) : 0);

     if (m->ismultipart)        
	  for (i = 0, n = gwlist_len(m->body.l); i< n; i++) {
	       MIMEEntity *x = gwlist_get(m->body.l, i);
	       debug("mms.dump", 0, "--->Message part: %d --->", i);
	       
	       _x_mime_entity_dump(x,0,headers_only);
	  }
     else if (!headers_only) 
	  octstr_dump(m->body.s, 0);
     
}

Octstr *mms_tobinary(MmsMsg *msg)
{
     Octstr *s;

     if (!msg)
	  return NULL;
     s = octstr_create("");
     encode_msgheaders(s, msg->headers);
     
     if (msg->body.s)
	  encode_msgbody(s, msg);
     return s;
}

int mms_messagetype(MmsMsg *msg)
{
     gw_assert(msg);
     return msg->message_type;
}


static void convert_mime_msg(MIMEEntity *m)
{
     int i, n;
     Octstr *content_type = NULL, *params;
     char *s = NULL;
     List *h = mime_entity_headers(m);

     n = get_content_type(h, &content_type, &params);
     
     if (n == 0 && content_type) {
	  if (octstr_str_compare(content_type, 
				 "application/vnd.wap.multipart.related") == 0)
	       s = "multipart/related";
	  else if (octstr_str_compare(content_type, 
				      "application/vnd.wap.multipart.alternative") == 0)
	       s = "multipart/alternative";
	  else if (octstr_str_compare(content_type, 
				      "application/vnd.wap.multipart.mixed") == 0)
	       s = "multipart/mixed";
	  octstr_destroy(content_type);
     }
     if (s) {
	  Octstr *value;
	 
	  if (params && octstr_len(params) > 0) {
	       List   *ph = get_value_parameters(params); /* unpack then re-pack them with proper quoting for mime.*/
	       Octstr *ps = make_value_parameters(ph);	       
	       value = octstr_format("%s; %S", s, params);
	       octstr_destroy(ps);
	       http_destroy_headers(ph);
	  } else 
	       value = octstr_create(s);
	  
	  http_header_remove_all(h, "Content-Type");
	  http_header_add(h, "Content-Type", octstr_get_cstr(value));
	  mime_replace_headers(m,h);

	  octstr_destroy(value);
     }
     if (h)
	  http_destroy_headers(h);
     octstr_destroy(params);
     if ((n = mime_entity_num_parts(m)) > 0)
	  for (i = 0; i < n; i++) {
	       MIMEEntity *x = mime_entity_get_part(m, i);
	       convert_mime_msg(x);	       
	       mime_entity_replace_part(m, i, x);
	  }
}

static void unconvert_mime_msg(MIMEEntity *m)
{
     int i, n;
     Octstr *content_type, *params; 
     char *s = NULL;
     List *h = mime_entity_headers(m);

     n = get_content_type(h, &content_type, &params);
     if (n == 0 && content_type) {
	  if (octstr_case_compare(content_type, 
				 octstr_imm("multipart/related")) == 0)
	       s = "application/vnd.wap.multipart.related";
	  else if (octstr_case_compare(content_type, 
				      octstr_imm("multipart/alternative")) == 0)

⌨️ 快捷键说明

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