Where have I gone wrong

General FreeBASIC programming questions.
Post Reply
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Where have I gone wrong

Post by jj2007 »

Gablea wrote:Its just understanding that transition from CSV format to your format (and your format is a much better format anyway more forgiving then what csv is)
Well, it's not exactly "my" format - *.tab has been around for several decades. But if the translation step is difficult, just use my commandline tool zipped here. Drag the csv file over ConvertCsvToTab.exe, and immediately after you'll find the corresponding tab file in the same folder. For those who don't trust executables and want to build it from source, here it is:

Code: Select all

include \masm32\MasmBasic\MasmBasic.inc
  Init
  Let esi=CL$()
  Let edi=Left$(esi, Instr_(esi, ".csv", 1))+"tab"
  Recall esi, L$()
  Csv2Tab
  Store edi, L$()
  Print Str$("%i lines converted and saved to ", L$(?)), edi
EndOfCode
grindstone
Posts: 862
Joined: May 05, 2015 5:35
Location: Germany

Re: Where have I gone wrong

Post by grindstone »

Gablea wrote:still need to work out how I can talk to a IP/TCP Socket device from FreeBASIC
Have a look at libcurl. I use it and it works fine (at least for downloading playlists and mp3/4 - files). It shouldn't be too difficult to implement a peer-to-peer communication.
Gablea
Posts: 1104
Joined: Apr 06, 2010 0:05
Location: Northampton, United Kingdom
Contact:

Re: Where have I gone wrong

Post by Gablea »

@jj2007
I have converted the feed file to a tab deterred file (that was the easy bit) but I’m not sure where to start on the actual PoS program to convert that to work with the tab file.

I do like you code and I would like to keep the data files in memory. I know I would need to have each file in it’s own array (not a problem I can call them things like cashierArray or productArray etc)

It just knowing what to remove and what to add to get it to work (I hope you know what I mean)

@grindstone
Would that libcurl let me talk to a card machine that needs to have user name and password etc encrypted into the header file? (I have done it in a add on module written in VB.net)

Would it allow the PoS to talk to a separate exe that is running in the background I.E.

PoS <—> card addon <—> card machine

The card addon would be started with the Linux command

./algPoS/card/CardAddon & (to start as a background app)
grindstone
Posts: 862
Joined: May 05, 2015 5:35
Location: Germany

Re: Where have I gone wrong

Post by grindstone »

The answer to all questions is "yes".
The host part of the URL contains the address of the server that you want to connect to. This can be the fully qualified domain name of the server, the local network name of the machine on your network or the IP address of the server or machine represented by either an IPv4 or IPv6 address. For example:

http://www.example.com/

http://hostname/

http://192.168.0.1/

http://[2001:1890:1112:1::20]/

It is also possible to specify the user name, password and any supported login options as part of the host, for the following protocols, when connecting to servers that require authentication:

http://user:password@www.example.com

ftp://user:password@ftp.example.com

smb://domain%2fuser:password@server.example.com

imap://user:password;options@mail.example.com

pop3://user:password;options@mail.example.com

smtp://user:password;options@mail.example.com
...
With libcurl you can link all devices that are connected to the network and have an IP-address. It even supports SSL, and it works with both Windows and Linux.
Gablea
Posts: 1104
Joined: Apr 06, 2010 0:05
Location: Northampton, United Kingdom
Contact:

Re: Where have I gone wrong

Post by Gablea »

@grindstone

below is the code I use to get the status of the terminal

Code: Select all

Dim Request As HttpWebRequest = HttpWebRequest.Create(PS_URL & "/terminals/" & terminalIDNumber)
        Dim credentials As String = Convert.ToBase64String(Encoding.ASCII.GetBytes(PS_USER & ":" & PS_PASS))
        txtResults.Text = vbNullString

        With Request
            .Proxy = Nothing
            .Headers(HttpRequestHeader.Authorization) = String.Format("Basic {0}", credentials)
            .UserAgent = PS_USER
        End With

        Dim response As HttpWebResponse = Request.GetResponse()
        Dim dataStream As Stream = response.GetResponseStream
        Dim reader As New StreamReader(dataStream)
        Dim responseFromServer As String = reader.ReadToEnd()

        txtResults.Text = responseFromServer


        If responseFromServer = "0" Then
            MsgBox("Retreal of Status Failed")
        Else
            Dim json As String = responseFromServer
            Dim ser As JObject = JObject.Parse(json)
            Dim data As List(Of JToken) = ser.Children().ToList
            For Each item As JProperty In data
                item.CreateReader()
                Select Case item.Name
                    Case "status"
                        Select Case item.Value
                            Case "AVAILABLE"
                                SendToPoSterminal("TerminalOnLine|")
                                Label1.Text = "Terminal Ready"

                            Case "BUSY"
                                SendToPoSterminal("TerminalBusy|")
                                Label1.Text = "Terminal busy please wait 10 seconds and try again"

                            Case "Offline", "OFFLINE", "offline"
                                SendToPoSterminal("offline|")
                                Label1.Text = "Terminal OFFLINE NO Card processing Possible"
                        End Select
                End Select
            Next
        End If

        reader.Close()
        dataStream.Close()
        response.Close()

This code starts a sale (data is sent to the Module from the PoS terminal on a given Port number that is always being polled by a timer

Code: Select all

Dim Request As String = PS_URL & "/terminals/" & terminalIDNumber & "/transactions"
        Dim credentials As String = Convert.ToBase64String(Encoding.ASCII.GetBytes(PS_USER & ":" & PS_PASS))
        Dim jsonString As String = "{""transactionType"":""SALE"",""amount"":""" & transAmount & """,""currency"":""GBP""}"
        txtResults.Text = vbNullString

        Try
            Dim data = Encoding.UTF8.GetBytes(jsonString)
            Dim result_post = SendRequest(Request, data, "application/json", "POST", credentials)
            Dim responseFromServer As String = result_post

            txtResults.Text = result_post

            If responseFromServer = "0" Then
                MsgBox("Retreal of Status Failed")
            Else
                Dim json As String = responseFromServer
                Dim ser As JObject = JObject.Parse(json)
                Dim DataList As List(Of JToken) = ser.Children().ToList

                For Each item As JProperty In DataList
                    item.CreateReader()
                    Select Case item.Name
                        Case "requestId"
                            TransRequest = item.Value

                            getTransStatus(TransRequest, 0)
                    End Select
                Next
            End If
        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try
This is Visual basic.net code so if i am understanding you correctly i could convert this to run in a FreeBASIC formless Module
Gablea
Posts: 1104
Joined: Apr 06, 2010 0:05
Location: Northampton, United Kingdom
Contact:

Re: Where have I gone wrong

Post by Gablea »

hi jj2007

I have uploaded to my server the current project KPoS that I want to use the new tab format / Array with (download from here http://www.algpos.co.uk/freebasic/kpos.7z)

KPoS runs on a 2x20 line PoS keyboard. the plan for this app is to be a bridge between old MS-DOS systems and my full Graphical interface. A few of my customers are still using old MS-DOS hardware with just keyboard interface and the machines are getting REALLY OLD (I am surprised i have managed to keep them going as long as I have) even the back office applications are running in Windows 3.11 / 95 / 98 (and I know I like my old OS like DOS on a Till but the hardware is that old even the Drivers are no longer online) that is why i was looking at Linux (run on oldish hardware I have access to machines that have 512mb ram and 600MHz CPU)

Would 512MB RAM be enough for the PoS to load the full data files into memory (max number of products would be about 10,000)

Could you have a look at the Database.bi and if possible just convert over the function for the find cashier (source data file can be downloaded from http://www.algpos.co.uk/freebasic/dosdata.7z) I would really appreciate it if you could just do that one for me that way i can see what you did and why you did it and then i can understand how it work and then I can update the other functions as I need them (like the scanned coupon data mutilsavers (buy one get one free etc)

You could explain it all to me on here but I learn better with a simple example and as the find cashier is the simple function I have in the application
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Where have I gone wrong

Post by jj2007 »

Gablea wrote:Would 512MB RAM be enough for the PoS to load the full data files into memory (max number of products would be about 10,000)
Yes, 10,000 is about 0.8MB, so IMHO that should be possible.
Gablea wrote:I have uploaded to my server the current project KPoS that I want to use the new tab format / Array with (download from here http://www.algpos.co.uk/freebasic/kpos.7z)
I've downloaded the data. How did you produce them? I hope it wasn't my converter, because it's not in a good format, see hexdump full of char(1):

Code: Select all

02560020  30 30 30 30 31 32 39 33 20 20 20 20 20 56 41 43 00001293     VAC
02560030  55 55 4D 20 43 4C 45 41 4E 45 52 53 20 20 20 20 UUM CLEANERS
02560040  20 20 20 20 20 20 20 20 20 20 20 30 30 30 33 01            0003.
02560050  01 01 01 30 20 53 31 32 39 39 20 20 20 20 20 20 ...0 S1299
02560060  41 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 A...............
02560070  01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................
02560080  01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................
02560090  01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................
025600A0  01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................
025600B0  01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................
025600C0  01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................
025600D0  01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................
025600E0  01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................
025600F0  01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................
02560100  01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................
02560110  01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................
02560120  01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................
02560130  01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................
02560140  01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................
02560150  01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................
02560160  01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................
02560170  01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................
02560180  01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................
02560190  01 01 01 01 01 01 01 01 30 30 30 30 31 33 30 31 ........00001301
025601A0  30 20 20 20 20 46 49 4C 54 45 52 53 20 20 20 20 0    FILTERS
025601B0  20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
025601C0  20 20 20 30 30 30 34 01 01 01 01 30 20 4C 30 37    0004....0 L07
025601D0  30 20 20 20 20 20 20 20 41 01 01 01 01 01 01 01 0       A.......
025601E0  01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................
025601F0  01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................
02560200  01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................
02560210  01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................
Gablea
Posts: 1104
Joined: Apr 06, 2010 0:05
Location: Northampton, United Kingdom
Contact:

Re: Where have I gone wrong

Post by Gablea »

They was produced by my Visual Basic back office application.

What is the 01 char then?
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Where have I gone wrong

Post by jj2007 »

Gablea wrote:They was produced by my Visual Basic back office application.

What is the 01 char then?
An invalid character, neither tab nor zero nor anything usable. Which lines of the VB app produces it?

Once you have fixed that problem, you can use the Recall(filename, stringarray) and Cell(row, col, stringarray) functions posted below, using Recall.fbi: (simple example: Print "The description of product #5: "; Cell(5, posdescription, Products()))

Code: Select all

' Recall.fbi, 14.10.2018, jj2007
#include "Windows.bi"	' needed for lstrcpyn
#ifndef maxCell
	#Define maxCell 100	' whatever you consider enough for a single cell
#endif
Dim shared retstr As string * maxCell+1	

Function Recall(fname As String, locArray() As String) As Integer
  Dim As Integer ct=0, cursize=100	' locArray is a local representation of a dynamic array
  If Open(fname For Input As #1) = 0 Then
	Do While Not Eof(1)
		if ct=0 or ct>cursize then
			cursize+=cursize shr 1
			ReDim Preserve locArray(cursize)
		endif
		Line Input #1, locArray(ct)
		ct+=1
	Loop
	Close #1
	ReDim Preserve locArray(ct)
  Else
	Print "Error opening file"
  End If
  Return ct
End Function

Function Cell(row As integer, col As integer, locArray() As String) As string
  Dim As integer ct=0, ctTabs=0, posLeft=-1, posRight=0
  Dim As ubyte ptr pString
  Dim c As ubyte
  pString=StrPtr(locArray(row))
  if pString then
	Do
		c=pString[ct]
		if pString[ct]=9 then
			ctTabs=ctTabs+1
			if col=0 then
				posLeft=0
				if ctTabs>col then posRight=ct+1
			else
				if posLeft=-1 and ctTabs>=col then
				    posLeft=ct+1
				elseif ctTabs>col then
				    posRight=ct+1
				endif
			endif
		endif
		ct=ct+1
	Loop Until c=0 or posRight
  endif
  if posRight=0 then
	retstr[0]=0
  else
	lstrcpyn(StrPtr(retstr), pString+posLeft, Min(maxCell, posRight-posLeft))
  endif
  return retstr
end function
Usage:

Code: Select all

#include "..\Recall.fbi"
Enum product
  BarcodeNumber, posdescription, salelocation, agerestricted, agelimit, pricetype, retailprice, vatcode,_
  print_guarantee_message, print_guarantee_code, displaymessage, messagenumber, sendtoppr,_
  requestserial, itemnotallowed, itemnotallowed_reason, restrict_product_qty, product_qty_allowed,_
  discount_not_allowed, no_refund_allowed, ask_for_qty_before_selling, healthy_start_voucher_ok
End Enum

Dim shared Products() As string
Print "Arg1: ";Command$(1)
if Recall(Command$(1), Products()) then
  Print "records loaded:";ubound(Products)
  For i As Integer=0 To ubound(Products)-1		' print the first and last Cells
	If i<10 Or i>=ubound(Products)-5 Then
		Print i,
		For j As Integer=0 To 5
			Print Cell(i, j, Products()),
		Next
		print
	ElseIf i=10 Then
		Print " ..."
	EndIf
  Next
  Print "OK"
endif
Sleep
Gablea
Posts: 1104
Joined: Apr 06, 2010 0:05
Location: Northampton, United Kingdom
Contact:

Re: Where have I gone wrong

Post by Gablea »

The problem is JJ your code will not complie on a Linux machine or will it compile for DOS as it uses the windows.bi (I’ve found that out in the past)

This is becoming harder to do as some solutions require files that are not present on a Linux machine

Once I’m at the computer I shall post the code that makes the vb file.
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Where have I gone wrong

Post by jj2007 »

Gablea wrote:The problem is JJ your code will not complie on a Linux machine
I am confident that you will be able to find a replacement for lstrcpyn on Linux. Maybe the CRT has something portable, such as "memcopy" or so.

Code: Select all

#include "Windows.bi"	' needed for lstrcpyn
Gablea
Posts: 1104
Joined: Apr 06, 2010 0:05
Location: Northampton, United Kingdom
Contact:

Re: Where have I gone wrong

Post by Gablea »

ok I will look into it

what would be the same DOS?


Also as promised here is one of the VB.NEt code functions that makes the data file (in this case it is the cashier data file)

Code: Select all

    Private Sub ExportCashierFile(ByVal FileType As String)
        Dim fileFucntion As System.IO.StreamWriter
        Dim FileData As String = vbNullString
        Dim FileName As String = My.Settings.DOSDB_Location & "\users.dat"

        If File.Exists(FileName) = True Then Kill(FileName)

        DisplayMessage(" Exporting Cashier Table", "Export")

        SQLCommand = vbNullString
        SQLCommand += "Select "
        SQLCommand += "userid, "
        SQLCommand += "userpassword, "
        SQLCommand += "username, "
        SQLCommand += "usernameposrecipit, "
        SQLCommand += "changepassword, "

        If FileType = "Simple" Then
            SQLCommand += "useraccesslevel "
        Else
            SQLCommand += "restricrefundvalue, "
            SQLCommand += "refundvalue, "
            SQLCommand += "usercanoverridelockout, "
            SQLCommand += "useraccesslevel "
        End If

        SQLCommand += "from usertable "

        SQLCommand += "Where usertype='P';"


        With Me
            ProgressBar1.Value = 0
            .ProgressBar1.Maximum = RecordCount("select count(userid) from usertable where usertype='P'")
        End With

        Try
            ConnecttoDatabase()

            Dim dr As MySqlDataReader

            MySQLCmd = New MySqlCommand(SQLCommand, dbCon)

            'Connect to the Database and find the SQLCommand
            If dbCon.State = ConnectionState.Open Then
                dbCon.Close()
            End If

            dbCon.Open()

            dr = MySQLCmd.ExecuteReader

            If dr.HasRows Then
                While dr.Read
                    FileData = vbNullString
                    Me.ProgressBar1.Value += 1
                    DisplayPercentage(ProgressBar1.Value, ProgressBar1.Maximum)

                    'This is where the POS File is created
                    If FileType = "Simple" Then
                        FileData += dr.Item("userid") & Chr(9)
                        FileData += dr.Item("userpassword") & Chr(9)
                        FileData += Trim(dr.Item("username")) & Chr(9)
                        FileData += Trim(dr.Item("usernameposrecipit")) & Chr(9)
                        FileData += dr.Item("changepassword")
                    Else
                        FileData += dr.Item("userid") & Chr(9)
                        FileData += dr.Item("userpassword") & Chr(9)
                        FileData += Trim(dr.Item("username")) & Chr(9)
                        FileData += Trim(dr.Item("usernameposrecipit")) & Chr(9)
                        FileData += dr.Item("changepassword") & Chr(9)
                        FileData += dr.Item("restricrefundvalue") & Chr(9)
                        FileData += dr.Item("refundvalue") & Chr(9)
                        FileData += dr.Item("usercanoverridelockout") & Chr(9)
                        FileData += dr.Item("useraccesslevel")
                    End If

                    DisplayPercentage(ProgressBar1.Value, ProgressBar1.Maximum)


                    'Save Data to File
                    fileFucntion = My.Computer.FileSystem.OpenTextFileWriter(FileName, True)
                    fileFucntion.WriteLine(Trim(FileData))
                    fileFucntion.Close()

                End While
                dr.Close()
            Else
                'Save Data to File
                fileFucntion = My.Computer.FileSystem.OpenTextFileWriter(FileName, True)
                fileFucntion.WriteLine(Trim(FileData))
                fileFucntion.Close()
            End If

            With dbCon
                .Dispose()
                .Close()
            End With

        Catch ex As Exception
            MsgBox(ex.Message)
            MySQLDR.Close()
            If dbCon.State = ConnectionState.Open Then
                dbCon.Close()
            End If
        Finally
            dbCon.Close()
            DisplayMessage(" DONE", "Export_Done")
        End Try
badidea
Posts: 2591
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Where have I gone wrong

Post by badidea »

jj2007 wrote:
Gablea wrote:The problem is JJ your code will not complie on a Linux machine
I am confident that you will be able to find a replacement for lstrcpyn on Linux. Maybe the CRT has something portable, such as "memcopy" or so.

Code: Select all

#include "Windows.bi"	' needed for lstrcpyn
Something like will probably works as well:

Code: Select all

retstr = mid(locArray(row), posLeft + 1, Min(maxCell, posRight-posLeft))
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Where have I gone wrong

Post by jj2007 »

I have posted a new version that does not need Windows.bi in the spreadsheet thread.
grindstone
Posts: 862
Joined: May 05, 2015 5:35
Location: Germany

Re: Where have I gone wrong

Post by grindstone »

Gablea wrote:Would it allow the PoS to talk to a separate exe that is running in the background I.E.
I guess this .exe is your file server, isn't it?
Post Reply