示例#1
0
unsigned char *overlay_get_my_sid()
{

  /* Make sure we can find our SID */
  int zero=0;
  if (!findHlr(hlr,&zero,NULL,NULL)) { WHY("Could not find first entry in HLR"); return NULL; }
  return &hlr[zero+4];
}
示例#2
0
int createHlr(char *did,char *sid) {
  int i;
  int record_offset=0;

  /* Generate random SID */
  for(i=0;i<64;i++) sid[i]=hexdigit[random()&0xf]; sid[64]=0;
  if (debug>1) fprintf(stderr,"Creating new HLR entry with sid %s\n",sid);
  
  /* Find first free byte of HLR */
  findHlr(hlr,&record_offset,NULL,NULL);

  if (record_offset>=hlr_size)
    {
      /* No space */
      return setReason("No space in HLR for a new record");
    }
  else
    {
      /* We have found space, but is it enough? */
      int bytes=hlr_size-record_offset;
      if (bytes<1024) return setReason("<1KB space in HLR");
      
      /* Write shiny fresh new record.
	 32bit - record length 
	 32 bytes - SID
	 Total length = 4+32=36 bytes.
      */
      if (stowSid(hlr,record_offset+4,sid)) return setReason("Could not store SID in new HLR entry");
	
      /* Write length last of all to make entry valid */
      hlr[record_offset]=0;
      hlr[record_offset+1]=0;
      hlr[record_offset+2]=0;
      hlr[record_offset+3]=36;

      /* Store the DID */
      {
	unsigned char packeddid[DID_MAXSIZE];
	int pdidlen=0;
	stowDid(packeddid,&pdidlen,did);
	/* Work out reduced length of DID */
	for(pdidlen=1;pdidlen<DID_MAXSIZE;pdidlen++) if (packeddid[pdidlen-1]==0xff) break;
	hlrSetVariable(hlr,record_offset,VAR_DIDS,0x00,packeddid,pdidlen);
      }

      if (debug) fprintf(stderr,"Created new 36 byte HLR record for DID=[%s] @ 0x%x with SID=[%s]\n",
			 did,record_offset,sid);
      if (debug>2) dump("after HLR create",&hlr[0],256);
      return 0;
    }

  return setReason("Unreachable code turned out not to be");
}
示例#3
0
int processRequest(unsigned char *packet,int len,
		   struct sockaddr *sender,int sender_len,
		   unsigned char *transaction_id,char *did,char *sid)
{
  /* Find HLR entry by DID or SID, unless creating */
  int ofs,rofs=0;
  int records_searched=0;
  
  int prev_pofs=0;
  int pofs=OFS_PAYLOAD;

  while(pofs<len)
    {
      if (debug>1) fprintf(stderr,"  processRequest: len=%d, pofs=%d, pofs_prev=%d\n",len,pofs,prev_pofs);
      /* Avoid infinite loops */
      if (pofs<=prev_pofs) break;
      prev_pofs=pofs;

      if (packet[pofs]==ACTION_CREATEHLR)
	{
	  /* Creating an HLR requires an initial DID number and definately no SID -
	     you can't choose a SID. */
	  if (debug>1) fprintf(stderr,"Creating a new HLR record. did='%s', sid='%s'\n",did,sid);
	  if (!did[0]) return respondSimple(NULL,ACTION_DECLINED,NULL,0,transaction_id);
	  if (sid[0])  return respondSimple(sid,ACTION_DECLINED,NULL,0,transaction_id);
	  if (debug>1) fprintf(stderr,"Verified that create request supplies DID but not SID\n");
	  
	  {
	    char sid[128];
	    /* make HLR with new random SID and initial DID */
	    if (!createHlr(did,sid))
	      return respondSimple(sid,ACTION_OKAY,NULL,0,transaction_id);
	    else
	      return respondSimple(NULL,ACTION_DECLINED,NULL,0,transaction_id);
	  }
	  pofs+=1;
	  pofs+=1+SID_SIZE;
	}
      else
	{
	  switch(packet[pofs])
	    {
	    case ACTION_PAD: /* Skip padding */
	      pofs++;
	      pofs+=1+packet[pofs];
	      break;
	    case ACTION_EOT:  /* EOT */
	      pofs=len;
	      break;
	    case ACTION_STATS:
	      /* short16 variable id,
		 int32 value */
	      {
		pofs++;
		short field=packet[pofs+1]+(packet[pofs]<<8);
		int value=packet[pofs+5]+(packet[pofs+4]<<8)+(packet[pofs+3]<<16)+(packet[pofs+2]<<24);
		pofs+=6;
		if (instrumentation_file)
		  {
		    if (!i_f) { if (strcmp(instrumentation_file,"-")) i_f=fopen(instrumentation_file,"a"); else i_f=stdout; }
		    if (i_f) fprintf(i_f,"%ld:%08x:%d:%d\n",time(0),*(unsigned int *)&sender->sa_data[0],field,value);
		    if (i_f) fflush(i_f);
		  }
	      }
	      break;
	    case ACTION_DIGITALTELEGRAM:
	      // Unpack SMS message.
	      {
		char emitterPhoneNumber[256];
		char message[256];
		pofs++;
		char messageType = packet[pofs];
		pofs++;
		char emitterPhoneNumberLen = packet[pofs];
		pofs++;
		char messageLen = packet[pofs];
		pofs++;
		strncpy(emitterPhoneNumber, (const char*)packet+pofs, emitterPhoneNumberLen);
		pofs+=emitterPhoneNumberLen;
		strncpy(message, (const char*)packet+pofs, messageLen); 
		pofs+=messageLen;
	      
		// Check if I'm the recipient

		// Send SMS to android
		char amCommand[576]; // 64 char + 2*256(max) char = 576
		sprintf(amCommand, "am broadcast -a org.servalproject.DT -e number \"%s\"  -e content \"%s\"", emitterPhoneNumber, message);
		int exitcode = printf(amCommand);
		//int exitcode = system(amCommand); 
	      }
	      break;
	    case ACTION_SET:
	      ofs=0;
	      if (debug>1) fprintf(stderr,"Looking for hlr entries with sid='%s' / did='%s'\n",sid,did);

	      if ((!sid)||(!sid[0])) {
		setReason("You can only set variables by SID");
		return respondSimple(NULL,ACTION_ERROR,(unsigned char *)"SET requires authentication by SID",0,transaction_id);
	      }

	      while(findHlr(hlr,&ofs,sid,did))
		{
		  int itemId,instance,start_offset,bytes,flags;
		  unsigned char value[9000],oldvalue[65536];
		  int oldr,oldl;
		  
		  if (debug>1) fprintf(stderr,"findHlr found a match for writing at 0x%x\n",ofs);
		  if (debug>2) hlrDump(hlr,ofs);
		  
		  /* XXX consider taking action on this HLR
		     (check PIN first depending on the action requested) */
	      
		  /* XXX Doesn't verify PIN authentication */
		  
		  /* Get write request */
		    
		  pofs++; rofs=pofs;
		  if (extractRequest(packet,&pofs,len,
				     &itemId,&instance,value,
				     &start_offset,&bytes,&flags))
		    {
		      setReason("Could not extract ACTION_SET request");
		      return 
			respondSimple(NULL,ACTION_ERROR,(unsigned char *)"Mal-formed SET request",0,transaction_id);
		    }
		  
		  /* Get the stored value */
		  oldl=65536;
		  oldr=hlrGetVariable(hlr,ofs,itemId,instance,oldvalue,&oldl);
		  if (oldr) {
		    if (flags==SET_NOREPLACE) {
		      oldl=0;
		    } else {
		      setReason("Tried to SET_NOCREATE/SET_REPLACE a non-existing value");
		      return 
			  respondSimple(NULL,ACTION_ERROR,
					(unsigned char *)"Cannot SET NOCREATE/REPLACE a value that does not exist",
					0,transaction_id);
		    }
		  } else {
		    if (flags==SET_NOREPLACE) {
		      setReason("Tried to SET_NOREPLACE an existing value");
		      if (debug>1) dump("Existing value",oldvalue,oldl);
		      return 
			respondSimple(NULL,ACTION_ERROR,
				      (unsigned char *)"Cannot SET NOREPLACE; a value exists",
				      0,transaction_id);
		      }
		  }
		  /* Replace the changed portion of the stored value */
		  if ((start_offset+bytes)>oldl) {
		    bzero(&oldvalue[oldl],start_offset+bytes-oldl);
		    oldl=start_offset+bytes;
		  }
		  bcopy(&value[0],&oldvalue[start_offset],bytes);
		    
		  /* Write new value back */
		  if (hlrSetVariable(hlr,ofs,itemId,instance,oldvalue,oldl))
		    {
		      setReason("Failed to write variable");
		      return 
			respondSimple(NULL,ACTION_ERROR,(unsigned char *)"Failed to SET variable",0,transaction_id);
		    }
		  if (debug>2) { fprintf(stderr,"HLR after writing:\n"); hlrDump(hlr,ofs); }
		  
		  /* Reply that we wrote the fragment */
		  respondSimple(sid,ACTION_WROTE,&packet[rofs],6,
				transaction_id);
		  /* Advance to next record and keep searching */
		  if (nextHlr(hlr,&ofs)) break;
		}
	      break;
	    case ACTION_GET:
	      {
		/* Limit transfer size to MAX_DATA_BYTES, plus an allowance for variable packing. */
		unsigned char data[MAX_DATA_BYTES+16];
		int dlen=0;
		int sendDone=0;
		int var_id=packet[pofs+1];
		int instance=packet[pofs+2];
		int offset=(packet[pofs+3]<<8)+packet[pofs+4];
		char *hlr_sid=NULL;

		pofs+=7;
		if (debug>2) dump("Request bytes",&packet[pofs],8);
		if (debug>1) fprintf(stderr,"Processing ACTION_GET (var_id=%02x, instance=%02x, pofs=0x%x, len=%d)\n",var_id,instance,pofs,len);

		ofs=0;
		if (debug>1) fprintf(stderr,"Looking for hlr entries with sid='%s' / did='%s'\n",sid?sid:"null",did?did:"null");

		while(1)
		  {
		    struct hlrentry_handle *h;

		    // if an empty did was passed in, get results from all hlr records
		    if (*sid || *did){
 		      if (!findHlr(hlr,&ofs,sid,did)) break;
		      if (debug>1) fprintf(stderr,"findHlr found a match @ 0x%x\n",ofs);
		    }
		    if (debug>2) hlrDump(hlr,ofs);
  		  
		    /* XXX consider taking action on this HLR
		       (check PIN first depending on the action requested) */

		    /* Form a reply packet containing the requested data */
  		  
		    if (instance==0xff) instance=-1;
  		  
		    /* Step through HLR to find any matching instances of the requested variable */
		    h=openhlrentry(hlr,ofs);
		    if (debug>1) fprintf(stderr,"openhlrentry(hlr,%d) returned %p\n",ofs,h);
		    while(h)
		      {
			/* Is this the variable? */
			if (debug>2) fprintf(stderr,"  considering var_id=%02x, instance=%02x\n",
					     h->var_id,h->var_instance);
			if (h->var_id==var_id)
			  {
			    if (h->var_instance==instance||instance==-1)
			      {
				if (debug>1) fprintf(stderr,"Sending matching variable value instance (instance #%d), value offset %d.\n",
						     h->var_instance,offset);
  			      
				// only send each value when the *next* record is found, that way we can easily stamp the last response with DONE
				if (sendDone>0)
				  respondSimple(hlr_sid,ACTION_DATA,data,dlen,transaction_id);

				dlen=0;
	    
				if (packageVariableSegment(data,&dlen,h,offset,MAX_DATA_BYTES+16))
				  return setReason("packageVariableSegment() failed.");
				hlr_sid=hlrSid(hlr,ofs);

				sendDone++;
			      }
			    else
			      if (debug>2) fprintf(stderr,"Ignoring variable instance %d (not %d)\n",
						   h->var_instance,instance);
			  }
			else
			  if (debug>2) fprintf(stderr,"Ignoring variable ID %d (not %d)\n",
					       h->var_id,var_id);
			h=hlrentrygetent(h);
		      }
  		  
		    /* Advance to next record and keep searching */
		    if (nextHlr(hlr,&ofs)) break;
		  }
		  if (sendDone)
		    {
		      data[dlen++]=ACTION_DONE;
		      data[dlen++]=sendDone&0xff;
		      respondSimple(hlr_sid,ACTION_DATA,data,dlen,transaction_id);
		    }
		  if (gatewayuri&&(var_id==VAR_LOCATIONS)&&did&&strlen(did))
		    {
		      /* We are a gateway, so offer connection via the gateway as well */
		      unsigned char data[MAX_DATA_BYTES+16];
		      int dlen=0;
		      struct hlrentry_handle fake;
		      unsigned char uri[1024];
		      
		      /* Turn gateway into full URI including extension */
		      snprintf((char *)uri,1024,"4101*%s@%s",did,gatewayuri);
		      
		      fake.value_len=strlen((char *)uri);
		      fake.var_id=var_id;
		      fake.value=uri;
		      
		      if (packageVariableSegment(data,&dlen,&fake,offset,MAX_DATA_BYTES+16))
			return setReason("packageVariableSegment() of gateway URI failed.");
		      
		      respondSimple(hlrSid(hlr,0),ACTION_DATA,data,dlen,transaction_id);
		    }
	      
	      }
	      break;
	    default:
	      setReason("Asked to perform unsupported action");
	      if (debug) fprintf(stderr,"Packet offset = 0x%x\n",pofs);
	      if (debug) dump("Packet",packet,len);
	      return -1;
	    }	   
	}
    }
  
  if (debug>1) fprintf(stderr,"Searched %d HLR entries.\n",records_searched);

  return 0;
}