GAMMU and SQLServer

GAMMU merupakan software sms gateway yang cukup bagus dan terkenal . Selain mudah penggunaannya, perangkat modem gsm yang support cukup banyak mulai dari nokia, siemen dan Sonny ericsson. Untuk sony ericsson saya dah nyoba dan penggunaannya sangat mudah. Selain itu perangkat lain yang lebih cocok untuk dijadikan sms gateway dengan software gammu seperti modem gsm itegno. GAMMU bahkan sudah menyediakan service online untuk proses update data sms ke database. Database yang di support GAMMU adalah MySQL.

Ada beberapa pihak yang menginginkan program SMSgateway nya menggunakan database yang lain seperti SQLserver, Oracle dll. Apakah bisa?  Jawabnya bisa,  dengan menggunkan sediki program tambahan (delphi atau vb) kita bisa membuat service atau program yang memanfaatkan gammu dan sqlserver sebagai databasenya.

Sebenarnya kita bisa membuat software sms gateway sendiri tanpa harus menggunakan GAMMU, syaratnya kita harus mengetahui terlebih dahulu instruksi atau perintah yang dikirim dari pc ke perangkat modem gsm dan sebaliknya. Perintah itu diberi istilah AT-Command. Jika sudah memiliki AT-Command , kita bisa membuat aplikasinya dengan menggunakan bahasa pemrograman apapun yang penting program tersebut telah menyediakan fungsi untuk komunikasi baik ke port RS232 atau pun USB. Tapi jika terlalu pusing untuk membuatnya, gammu masih dapat dimanfaatkan untuk dipadukan dengan program khusus yang kita buat, sehingga kita dapat memanfaatkan database lain selain MySQL.

Algoritma pemrograman

Logic dari program ini adalah bagai mana kita mengeksekusi program gammu dengan parameter yang kita sediakan dan selanjutnya output dari program gammu tangkap dan ditrace. Hasil dari tracing selanjutnya dimasukan ke database yang kita inginkan.

Salah satu fungsi yang dibutuhkan adalah kita harus membuat fungsi atau procedure yang dapat mengeksekusi perintah dos dan outputnya kita simpan di objek teks misalkan untuk didelpi ke objek stringlist. Berikut ini adalah kode nya :

procedure GetConsoleLineOutput(const CommandLine:string;stoutput:TStringList);
var  SA: TSecurityAttributes;

  SI: TStartupInfo; 

  PI: TProcessInformation; 

  StdOutFile, AppProcess, AppThread : THandle; 

  RootDir, WorkDir, StdOutFileName:string; 

const 

  FUNC_NAME = 'GetConsoleOuput'; 

begin 

  try 

    StdOutFile:=0; 

    AppProcess:=0; 

    AppThread:=0;    
// Initialize dirs 

    RootDir:=ExtractFilePath(ParamStr(0)); 

    WorkDir:=ExtractFilePath(CommandLine); 

// Check WorkDir 

    if not (FileSearch(ExtractFileName(CommandLine),WorkDir)<>'') then 

WorkDir:=RootDir; 

// Initialize output file security attributes 

    FillChar(SA,SizeOf(SA),#0); 

    SA.nLength:=SizeOf(SA); 

    SA.lpSecurityDescriptor:=nil; 

    SA.bInheritHandle:=True; 

// Create Output File 

    StdOutFileName:=RootDir+'output.tmp'; 

    StdOutFile:=CreateFile(PChar(StdOutFileName), 

                   GENERIC_READ or GENERIC_WRITE, 

                   FILE_SHARE_READ or FILE_SHARE_WRITE, 

                   @SA, 

                   CREATE_ALWAYS, // Always create it 

                   FILE_ATTRIBUTE_TEMPORARY or // Will cache in memory 

                                               // if possible 

                   FILE_FLAG_WRITE_THROUGH, 

                   0); 

// Check Output Handle 

    if StdOutFile = INVALID_HANDLE_VALUE then 

      raise Exception.CreateFmt('Function %s() failed!' + #10#13 + 

        'Command line = %s',[FUNC_NAME,CommandLine]); 

// Initialize Startup Info 

    FillChar(SI,SizeOf(SI),#0);

    with SI do begin 

      cb:=SizeOf(SI); 

      dwFlags:=STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES; 

      wShowWindow:=SW_HIDE; 

      hStdInput:=GetStdHandle(STD_INPUT_HANDLE); 

      hStdError:=StdOutFile; 

      hStdOutput:=StdOutFile; 

    end; 

// Create the process 

    if CreateProcess(nil, PChar(CommandLine), nil, nil, 

                     True, 0, nil, 

                     PChar(WorkDir), SI, PI) then begin 

      WaitForSingleObject(PI.hProcess,INFINITE); 

      AppProcess:=PI.hProcess; 

      AppThread:=PI.hThread;  

    end 

   else 

      raise Exception.CreateFmt('CreateProcess() in function %s() failed!' 

                   + #10#13 + 'Command line = %s',[FUNC_NAME,CommandLine]); 

CloseHandle(StdOutFile); 

    StdOutFile:=0; 

finally 

    // Close handles 

    if StdOutFile <> 0 then CloseHandle(StdOutFile); 

    if AppProcess <> 0 then CloseHandle(AppProcess);

    if AppThread <> 0 then CloseHandle(AppThread); 
// Delete Output file
    if FileExists(StdOutFileName) then DeleteFile(StdOutFileName); 
  end; 
end; 

 

Prosedure pembacaan SMS

untuk membaca SMS  dari Modem GSM atau Handphone , dengan memanfaatkan prosedur di atas menggunakan GAMMU adalah sebagai berikut :

var st:string; 
i,k:integer; 
stlines:tstringlist; 
begin 
{ 
try 
  stlines:= tstringlist.Create; 
  GetConsoleLineOutput('gammu --geteachsms',stlines); 
  if stlines.count>0 then 
  begin 
    k:=stlines.IndexOf('SMS message'); 
    if k>1 then 
    begin 
    dec(k); 
    for i:=k to stlines.count-5 do 
    begin 
      lblog.Items.Add(stlines[i]); 
    end; 
    end; 
  end; 
finally 
stlines.Free; 
end; 
readsmssavetoinbox; 
end;

Selanjutnya untuk penyimpanan data ke database disediakan procedure readsmssavetoinbox :

procedure Tfmmain.readsmssavetoinbox; 
var strsql,sender,msg:string; 
smslines : tstringlist; 
tgl:string; 
i,beginpos,k:integer; 
begin 
try 
  smslines:= tstringlist.Create; 
  GetConsoleLineOutput('gammu --geteachsms',smslines); 
  if smslines.Count>0  then 
  begin 
    beginpos:=smslines.IndexOf('SMS message'); 
    if beginpos>1 then 
    begin 
      dec(beginpos); 
      //for i:=beginpos to smslines.count-1 do 
      i:=beginpos; 
      while not i<=smslines.count-5 do 
      begin 
            if i>=smslines.count-5 then break; 
            if pos('"Inbox"',smslines[i])>0 then 
            begin 
            sender:= copy(smslines[i+5],20,length(smslines[i+5])); 
            if sender<>'' then sender:= StringReplace(sender,'"','',[rfReplaceAll, rfIgnoreCase]); 
            sender:= StringReplace(sender,'''','''''',[rfReplaceAll, rfIgnoreCase]); 
            msg:=smslines[i+8]; 
            tgl:= trim(copy(smslines[i+3],pos(',',smslines[i+3])+1,pos('+',smslines[i+3])-2-(pos(',',smslines[i+3])))); 
            strsql:='insert into inbox(inbox_sender,inbox_message,inbox_date) values (''' + sender + ''',''' + msg + ''','''+ tgl + ''')'; 
            execsql(strsql); 
            end; 
            i:=i+10; 
      end; 
      delsms; 
    end; 

  end; 
finally 
  smslines.Free; 
end; 
end;

Execsql adalah procedure untuk mengeksekusi sql yang ada.

Simpan prosedure diatas diprogram looping dengan memanfaatkan timer atau mebuat program services.
Selamat mencoba.