Author Topic: Automatic search for gsm-modem  (Read 431 times)

microtronx

  • Newbie
  • *
  • Posts: 10
    • View Profile
Automatic search for gsm-modem
« on: November 13, 2015, 08:19:13 am »
Hello nrCommLib Support,

we have created some funcs to find modem based on comport-ranges, everything works, but the modem / application hangs after finding the modem.
In example modem is found and i try to send a sms with
Code: [Select]
gsmport.SmsSendWaitRefID(testno.text,'Test SMS '+formatdatetime('dd.mm.yyyy hh:nn:ss',now),false );it hangs!

Can you have a look over our code?

Code: [Select]
unit ztools_gsmport;
interface
uses sysutils, classes, vcl.forms, nrclasses, nratcmd, nrgsm, nrcomm, nrlogfile, vcl.stdctrls;

type
    tmxgsmport_receivetext_onreceive = procedure(Com: TObject; Buffer: Pointer; Received: Cardinal) of object;
    tmxgsmport_receivetext = class(tObject)
    public
        fBuffer:string;
        procedure onAfterReceive(Com: TObject; Buffer: Pointer; Received: Cardinal);
    end;

function mxgsmport_FindGSMdevice(gModem: TnrGsm; gsm_comport:tnrcomm; vfromport:integer=1; vtoport:integer=15; vdoInit:boolean=true; vproducer:ansistring=''; vserial:ansistring=''):boolean;
function mxgsmport_Initialize_GSM_Modem(gModem: TnrGsm; gsm_comport:tnrcomm; vSimPin:string=''; vport_von:integer=1; vport_bis:integer=20; vKeepConnection:boolean=true; vlog:tMemo=nil; vproducer:ansistring=''; vserial:ansistring=''):boolean;

implementation
var
    vmxgsmportlog:tMemo=nil;

procedure tmxgsmport_receivetext.onAfterReceive(Com: TObject; Buffer: Pointer; Received: Cardinal);
var
    i:integer;
    ch:AnsiChar;
begin
    for i := 0 to Received - 1 do begin
        fBuffer := fBuffer + PAnsiChar(Buffer)[I];
        if pos('OK', uppercase(fBUFFER))>0 then exit;
    end;
end;

procedure mxgsmport_log(vtext:string);
var
    vt:boolean;
begin
    vtext:=StringReplace(vtext, #10, '', [rfReplaceAll]);
    vtext:=StringReplace(vtext, #13, '', [rfReplaceAll]);
    vtext:=trim(vtext);

    vt:=false;
{    if tThread.CurrentThread<>nil then begin
        if tThread.CurrentThread.ThreadID<>MainThreadID then begin
            vt:=true;
            TThread.Synchronize(TThread.CurrentThread,
            procedure
            begin
                if (trim(vtext)<>'') then begin
                    vmxgsmportlog.lines.add(formatdatetime('yyyy.mm.dd hh:nn:ss',now)+' '+vtext);
                end;
            end);
        end;
    end;
}
    if vt=false then begin
        if trim(vtext)<>'' then begin
            vmxgsmportlog.Lines.add(formatdatetime('yyyy.mm.dd hh:nn:ss',now)+' '+vtext);
        end;
    end;

end;

function mxgsmport_FindComport(vfromport, vtoport:integer):integer;
var
    vTestData:tmxgsmport_receivetext;
    vport:tnrComm;
    cc, i:integer;
    vtmp:string;
begin
    result:=0;

    try
        vPort:=TnrComm.Create(nil);
        vTestData:=tmxgsmport_receivetext.create;
        vPort.OnAfterReceive:=vtestdata.onAfterReceive;

        for i:=vFromPort to vToPort do begin
            mxgsmport_log('Probe comport: '+inttostr(i));

            try
                vPort.ComPortNo:=i;
                vPort.InitDeviceConnect;
                if vPort.active=false then vPort.Active:=true;
                vTestData.fBuffer:='';

                vPort.SendString('AT'+#13);
                cc:=0;
                while cc<40 do begin
                    sleep(100);
                    application.processmessages;
                    if pos('OK', uppercase(vTestData.fBuffer))>0 then begin
                        vtmp:='OK';
                        cc:=100;
                    end;
                    inc(cc);
                end;

                if pos('OK', uppercase(trim(vtmp)))>0 then begin
                    // Modem answer with OK
                    result:=i;
                    break;
                end;

            except
                on e:Exception do begin
                    vPort.active:=false;
                    vPort.ClearDeviceBuffers;
                end;
            end;

        end;
    finally
        vPort.Active:=false;
        vPort.ClearDeviceBuffers;
        vPort.free;
        vPort:=nil;

        vTestData.free;
        vTestData:=nil;

    end;

end;

function mxgsmport_FindGSMdevice(gModem: TnrGsm; gsm_comport:tnrcomm; vfromport:integer=1; vtoport:integer=15; vdoInit:boolean=true; vproducer:ansistring=''; vserial:ansistring=''):boolean;
var
    vPortNo, cc, i, i2:integer;
begin
    result:=false;
    vproducer:=trim(lowercase(vproducer));
    vserial:=trim(lowercase(vserial));
    if vfromport<1 then vfromport:=1;
    if vtoport>32 then vtoport:=32;

    gsm_comport.Active:=false;
    gModem.Active:=true;
    gModem.Autodetect:=true;

    vPortNo:=mxgsmport_FindComport(vfromport, vtoport);
    if vPortNo>0 then begin
        mxgsmport_log('Modem found at port: '+inttostr(vPortNo));
        try
            gsm_comport.ComPortNo:=vPortNo;
            gsm_comport.active:=true;

            for i2:=0 to 3 do begin
                for i:=1 to 30 do begin
                    cc:=0;
                    while (gmodem.IsBusy) and (cc<=4) do begin
                        Sleep(250);
                        application.processmessages;
                        inc(cc);
                    end;
                    if gmodem.isbusy then begin
                        mxgsmport_log('Modem initializing for '+inttostr(i+(i2*30))+' sec.');
                    end else begin
                        if trim(gmodem.DeviceManufacturer)<>'' then continue;
                        if trim(gmodem.DeviceIMEI)<>'' then continue;
                    end;
                end;
                if gmodem.isbusy=false then break;
            end;

            if (ansisametext(gModem.DeviceManufacturer, vproducer)) or (trim(vproducer)='') then begin
                mxgsmport_log('Modem producer: '+gModem.DeviceManufacturer);
                result:=true;

                if (vdoInit) or (trim(vserial)<>'') then begin
                    if trim(vserial)<>'' then begin
                        if ansisametext(gModem.DeviceIMSI, vserial) then begin
                            mxgsmport_log('Modem serial: '+gModem.DeviceIMSI+': OK');
                            result:=true;
                        end else begin
                            mxgsmport_log('Need modem serial: '+vserial+', found: '+gModem.DeviceIMSI+': ERROR');
                            result:=false;
                        end;
                    end;
                end;
            end else begin
                mxgsmport_log('Modem producer: '+gModem.DeviceManufacturer+' found! Need: '+vproducer);
            end;

        except
            on e:Exception do begin
                mxgsmport_log('Exception after found modem: '+e.message);
            end;
        end;

    end;

    if result=false then mxgsmport_log('Modem not active');
end;

function mxgsmport_Initialize_GSM_Modem(gModem: TnrGsm; gsm_comport:tnrcomm; vSimPin:string=''; vport_von:integer=1; vport_bis:integer=20; vKeepConnection:boolean=true; vlog:tmemo=nil; vproducer:ansistring=''; vserial:ansistring=''):boolean;
var
    i:integer;
begin
    try
        vmxgsmportlog:=vlog;
        gsm_comport.KeepConnection:=vKeepConnection;
        gModem.PIN:=vSimPin;
        result:=false;

        if mxgsmport_FindGSMdevice(gModem, gsm_comport, vport_von, vport_bis)=true then begin
            mxgsmport_log('--');
            mxgsmport_log('--');
            mxgsmport_log('--');
            result:=true;
        end else begin
            mxgsmport_log('Modem NOT OK');
            mxgsmport_log('--');
            mxgsmport_log('--');
            mxgsmport_log('--');
            result:=false;
        end;
    finally
        vmxgsmportlog:=nil;
    end;
end;

end.

you can start this code by:

Code: [Select]
    if mxgsmport_Initialize_GSM_Modem(gsmport {tnrGSM}, gsm_comport {tnrCOMM}, '', 1, 32, true, vLogbuch {tMemo}, '' {gsm manufacturer}, '' {imei})=true then begin
        showmessage('Modem found');
    end else begin
        showmessage('Modem not found');
    end;
« Last Edit: November 13, 2015, 08:45:27 am by microtronx »

microtronx

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: Automatic search for gsm-modem
« Reply #1 on: November 13, 2015, 09:17:03 am »
We had a VisualOut connected to a tMemo in nrlog, after removing that VisualOut to a Memo the whole thing is working! Can someone confirm this bug with VisualOut?

Now we have a problem: Sending a SMS with SmsSendWaitRefID is not returning a ID but i see in the event onSMSSent that the ID is available. Is this another bug?

microtronx

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: Automatic search for gsm-modem
« Reply #2 on: November 13, 2015, 11:55:19 am »
Also there is a bug, fReplyLast is not cleared and that means

1. sending a SMS
2. disconnecting modem from computer
3. connecting modem again
4. sending a new sms throws no error and returns the SMS-ID from 1.

Can we clear fReplyLast somehow? or is this again a bug?