예제 #1
0
파일: bearerbox.c 프로젝트: markjeee/mbuni
/* helper function for queueing delivery reports. */
static int queue_dlr(MmscGrp *mmc, Octstr *from, Octstr *to, Octstr *msgid, Octstr *status, char *interf, List *errl)
{
     Octstr *mmc_id = NULL, *qdir;
     MmsMsg *m = mms_deliveryreport(msgid, from, to, time(NULL), status);
     List *lto = gwlist_create();
     int ret;
     Octstr *qf, *rr_uri = NULL;
     List *rqh = http_create_empty_headers(); 

     
     if (errl) 
	  http_header_combine(rqh, errl); /* add status stuff. */

     
     gwlist_append(lto, octstr_duplicate(to));

     
     qdir = get_mmsbox_queue_dir(from, lto, mmc, &mmc_id); /* get routing info. */

     rr_uri = mmsbox_get_report_info(m, mmc, mmc_id, "delivery-report", status, rqh, NULL, 0, msgid);     

     qf = qfs->mms_queue_add(from, lto, NULL, 
			     mmc ? mmc->id : NULL, mmc_id,
			     0, time(NULL) + default_msgexpiry, m, NULL, 
			     NULL, NULL,
			     rr_uri, NULL,
			     rqh,
			     0,
			     octstr_get_cstr(qdir), 				  
			     interf,
			     NULL);
     if (qf)  {
	  /* Log to access log */
	  mms_log("Received DLR", from, lto, -1, msgid, status, mmc ? mmc->id : NULL, "MMSBox", NULL, NULL);
	  ret = 0;
     }  else 
	  ret = -1;

     octstr_destroy(qf);
     http_destroy_headers(rqh);     
     octstr_destroy(rr_uri);
     
     gwlist_destroy(lto, (void *)octstr_destroy);
     octstr_destroy(mmc_id);
     mms_destroy(m);

     return ret;
}
예제 #2
0
static int sendNotify(MmsEnvelope *e)
{
     Octstr *to;
     MmsMsg *msg, *smsg = NULL;
     MmsEnvelopeTo *xto = gwlist_get(e->to, 0);
     Octstr *err = NULL;
     time_t tnow = time(NULL);
     int j, k, len;
     Octstr *phonenum = NULL, *rcpt_ip = NULL, *msgId, *from, *fromproxy;
     int mtype, msize;
     int res = MMS_SEND_OK, dlr;
     time_t expiryt;
     char *prov_notify_event = NULL;
     char *rtype = NULL;

          
     if (e->lastaccess != 0) { /* This message has been fetched at least once, no more signals. */	  
	  e->sendt = e->expiryt + 3600*24*30*12;
	  info(0, "MM1: Message [ID: %s] fetched/touched at least once. Skipping",
	       e->xqfname);
	  return settings->qfs->mms_queue_update(e);
     }

     if (!xto) {
	  error(0, "mobilesender: Queue entry %s with no recipients!", 
		e->xqfname);
	  return 0;
     }

     msg = settings->qfs->mms_queue_getdata(e);
     to = octstr_duplicate(xto->rcpt);
     expiryt = e->expiryt;
     msgId = e->msgId ? octstr_duplicate(e->msgId) : NULL;
     from = octstr_duplicate(e->from);
     fromproxy = e->fromproxy ? octstr_duplicate(e->fromproxy) : NULL;
     msize = e->msize;
     dlr = e->dlr;

     if (e->expiryt != 0 &&  /* Handle message expiry. */
	 e->expiryt < tnow) {
	  err = octstr_format("MMSC error: Message expired while sending to %S!", to);
	  res = MMS_SEND_ERROR_FATAL;
	  prov_notify_event = "failedfetch";
	  rtype = "Expired";	  
	  goto done;
     } else if (e->attempts >= settings->maxsendattempts) {
	  err = octstr_format("MMSC error: Failed to deliver to %S after %ld attempts!", 
			      to, e->attempts);
	  res = MMS_SEND_ERROR_FATAL;

	  prov_notify_event = "failedfetch";
	  rtype = "Expired";	  
	  goto done;
     }
     
     j = octstr_case_search(to, octstr_imm("/TYPE=PLMN"), 0);
     k = octstr_case_search(to, octstr_imm("/TYPE=IPv"), 0);
     len = octstr_len(to);
     
     if (j > 0 && j - 1 +  sizeof "/TYPE=PLMN" == len) { /* A proper number. */
	  phonenum = octstr_copy(to, 0, j);
#if 0
	  normalize_number(octstr_get_cstr(settings->unified_prefix), &phonenum);
#else
	  mms_normalize_phonenum(&phonenum, 
				 octstr_get_cstr(settings->unified_prefix), 
				 settings->strip_prefixes);	  
#endif
     }     else if (k > 0 && k + sizeof "/TYPE=IPv" == len) 
	  rcpt_ip = octstr_copy(to, 0, k);
     else {
	  /* We only handle phone numbers here. */
	  err = octstr_format("Unexpected recipient %s in MT queue!", octstr_get_cstr(to));	  
	  res = MMS_SEND_ERROR_FATAL;	  
	  goto done;
     }
     
     mtype = mms_messagetype(msg);     
     
     /* For phone, getting here means the message can be delivered. So: 
      * - Check whether the recipient is provisioned, if not, wait (script called will queue creation req)
      * - If the recipient can't take MMS, then send SMS.
      */
     
     /* We handle two types of requests: send and delivery/read notifications. 
      * other types of messages cannot possibly be in this queue!
      */
     
     if (mtype == MMS_MSGTYPE_SEND_REQ ||
	 mtype == MMS_MSGTYPE_RETRIEVE_CONF) {
	  Octstr *url, *transid;
	  
	  if (phonenum) {
	       int send_ind = mms_ind_send(settings->prov_getstatus, phonenum);
	       
	       if (send_ind < 0 && 
		   settings->notify_unprovisioned)
		    send_ind = 0;

	       if (send_ind < 0) { /* That is, recipient is not (yet) provisioned. */
		    res = MMS_SEND_ERROR_TRANSIENT;
		    err = octstr_format("%S is not provisioned for MMS reception, delivery deferred!", 
					phonenum);
		    
		    /* Do not increase delivery attempts counter. */
		    e->lasttry = tnow;		    
		    e->sendt = e->lasttry + settings->send_back_off * (1 + e->attempts);
		    
		    if (settings->qfs->mms_queue_update(e) == 1) 
			 e = NULL; /* Queue entry gone. */	
		    else 	  
			 settings->qfs->mms_queue_free_env(e);		    		    
		    goto done;
	       } else if (send_ind == 0) { /*  provisioned but does not support */		    
		    Octstr *s = octstr_format(octstr_get_cstr(settings->mms_notify_txt),
					      from);
		    if (settings->notify_unprovisioned && s && octstr_len(s) > 0) { /* Only send if the string was set. */
			 List *pheaders;					    
			 Octstr *sto = octstr_duplicate(phonenum);
			 
			 octstr_url_encode(s);
			 octstr_url_encode(sto);
			 
			 url = octstr_format("%S&text=%S&to=%S",settings->sendsms_url,s, sto);
			 pheaders = http_create_empty_headers();
			 http_header_add(pheaders, "Connection", "close");
			 http_header_add(pheaders, "User-Agent", MM_NAME "/" VERSION);      
			 
			 http_start_request(httpcaller, HTTP_METHOD_GET, url, 
					    pheaders, NULL, 0, &edummy, NULL);			 			 
			 http_destroy_headers(pheaders);
			 octstr_destroy(url);
			 octstr_destroy(sto);		   		 
		    } else if (s)
			 octstr_destroy(s);	
		    res = MMS_SEND_OK;
		    err = octstr_imm("No MMS Ind support, sent SMS instead");
		    
		    xto->process = 0; /* No more processing. */
		    if (settings->qfs->mms_queue_update(e) == 1) 
			 e = NULL; 
		    else 	  
			 settings->qfs->mms_queue_free_env(e);		    
		    goto done;

	       }	       
	  }
	  
	  /* To get here means we can send Ind. */
	  url = mms_makefetchurl(e->xqfname, e->token, MMS_LOC_MQUEUE,
				 phonenum ? phonenum : to,
				 settings);
	  info(0, "Preparing to notify client to fetch message at URL: %s",
	       octstr_get_cstr(url));
	  transid = mms_maketransid(e->xqfname, settings->host_alias);	  
	  
	  smsg = mms_notification(msg, e->msize, url, transid, 
				  e->expiryt ? e->expiryt :
				  tnow + settings->default_msgexpiry,
				  settings->optimize_notification_size);
	  octstr_destroy(transid);
	  octstr_destroy(url);
     } else if (mtype == MMS_MSGTYPE_DELIVERY_IND ||
		mtype == MMS_MSGTYPE_READ_ORIG_IND) 
	  smsg = msg;
     else {
	  error(0, "Unexpected message type %s for %s found in MT queue!", 
		mms_message_type_to_cstr(mtype), octstr_get_cstr(to));
	  res = MMS_SEND_ERROR_FATAL;
	  goto done;
     }
     
     if (smsg)
	  start_push(phonenum ? phonenum : rcpt_ip, 
		     phonenum ? 1 : 0, 
		     e, smsg); /* Send the message. 
				* Don't touch 'e' after this point!
				* It may be freed by receive thread. 
				*/
     
     if (smsg != msg && smsg)
	  mms_destroy(smsg);
    
 done:
     if (err != NULL && 
	 res != MMS_SEND_ERROR_TRANSIENT) { /* If there was a report request and this is a legit error
					     *  queue it. 
					     */
	  
	  if (dlr) {	       
	       MmsMsg *m = mms_deliveryreport(msgId, to, tnow, 
					      rtype ? octstr_imm(rtype) : 
					      octstr_imm("Indeterminate"));
	       
	       List *l = gwlist_create();
	       Octstr *res;
	       gwlist_append(l, from);
	       
	       /* Add to queue, switch via proxy to be from proxy. */
	       res = settings->qfs->mms_queue_add(to ? to : settings->system_user, l,  err, 
						  NULL, fromproxy,  
						  tnow, tnow+settings->default_msgexpiry, m, NULL, 
						  NULL, NULL,
						  NULL, NULL,
						  NULL,
						  0,
						  octstr_get_cstr(settings->mm1_queuedir), 
						  "MM2",
						  settings->host_alias);
	       gwlist_destroy(l, NULL);
	       mms_destroy(m);
	       octstr_destroy(res);
	  }
	  
     }
     
     /* Write to log */
     info(0, "%s Mobile Queue MMS Send Notify: From=%s, to=%s, msgsize=%d, reason=%s", 
	  SEND_ERROR_STR(res),
	  octstr_get_cstr(from), octstr_get_cstr(to), msize,
	  err ? octstr_get_cstr(err) : "");
     
     
     if (res == MMS_SEND_ERROR_FATAL) {
	  xto->process = 0;  /* No more attempts to deliver, delete this. */	       
	  if (settings->qfs->mms_queue_update(e) == 1) 
	       e = NULL; /* Queue entry gone. */	
	  else 	  
	       settings->qfs->mms_queue_free_env(e);
     }    /* Else queue will be updated/freed elsewhere. */
     
     
     if (prov_notify_event)
	  notify_prov_server(octstr_get_cstr(settings->prov_notify), 
			     to ? octstr_get_cstr(to) : "unknown", 
			     prov_notify_event, 
			     rtype ? rtype : "",
			     e ? e->msgId : NULL, NULL, NULL);

     if (msg) mms_destroy(msg);       

     octstr_destroy(phonenum);
     
     octstr_destroy(rcpt_ip);
     octstr_destroy(to);
     octstr_destroy(msgId);
     octstr_destroy(fromproxy);
     octstr_destroy(from);
     octstr_destroy(err);

     return 1;
}