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]; }
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"); }
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; }