Jump to content
IGNORED

TIPI - TI-99/4A to Raspberry PI interface development


Recommended Posts

Well, I found that doing a login to localhost:23, I could run the following command and the BBS / TI-Server capability was restored.  That answers the tipi.service needs to be restarted.

 

sudo systemctl restart tipi.service

 

So, that answers the first thing.

 

I then using Windows Notepad and created a file "tipireboot.sh" with the following contents:

 

ping -c4 www.google.com > /dev/null

if [ $? != 0 ] 

then

  sudo systemctl restart tipi.service

fi

 

I have a program, WinSCP that I was using both the pi and tipi credentials to login into with sFTP.  I then tried to drag the file to /usr/local/bin and I get a permission denied from server. I was going to setup a CRON job to run every minute the above "tipireboot.sh" script, however I can not get it copied to that path.  I've tried dragging the file with WinSCP to any of the paths at /usr/local/ when I login with the tipi credentials, but get a permission denied as well.  Not sure what I need to do to resolve this issue.

 

Anyways, that is where I am at the moment.

 

 

 

Link to comment
Share on other sites

14 minutes ago, BeeryMiller said:

Well, I found that doing a login to localhost:23, I could run the following command and the BBS / TI-Server capability was restored.  That answers the tipi.service needs to be restarted.

 

sudo systemctl restart tipi.service

 

So, that answers the first thing.

 

I then using Windows Notepad and created a file "tipireboot.sh" with the following contents:

 

ping -c4 www.google.com > /dev/null

if [ $? != 0 ] 

then

  sudo systemctl restart tipi.service

fi

 

I have a program, WinSCP that I was using both the pi and tipi credentials to login into with sFTP.  I then tried to drag the file to /usr/local/bin and I get a permission denied from server. I was going to setup a CRON job to run every minute the above "tipireboot.sh" script, however I can not get it copied to that path.  I've tried dragging the file with WinSCP to any of the paths at /usr/local/ when I login with the tipi credentials, but get a permission denied as well.  Not sure what I need to do to resolve this issue.

 

Anyways, that is where I am at the moment.

 

 

 

 

A TI TIPI client will lock up if that restart executes while it is mid-message. It would be better if I put that sort of test in a safe-block... between handling TI messages.

 

-M@

  • Like 1
Link to comment
Share on other sites

27 minutes ago, jedimatt42 said:

 

A TI TIPI client will lock up if that restart executes while it is mid-message. It would be better if I put that sort of test in a safe-block... between handling TI messages.

 

-M@

We should meet in the middle... 1, the sudo command is going to prompt for a password , or you would need to run the service script as root, and messiness.  

 

There isn't a good place in the tipi.service to check for the network... cause you could be polling for connected clients constantly.. 

 

I can have my idle code check for existance of /tmp/tipi_safepoint and exit, letting the machinery in place restart the service. 

 

Then your script just has to :

touch /tmp/tipi_safepoint 

instead of the sudo systemctl command. 

 

-M@

  • Like 1
Link to comment
Share on other sites

@BeeryMiller - here ya go: 

 

Your cron script would look like this now:

18 hours ago, jedimatt42 said:

ping -c4 www.google.com > /dev/null

if [ $? != 0 ] 

then

  touch /tmp/tipi_safepoint

fi

 

And make sure your TI side software takes a breath once in a while for a second, or 3/4 of a second to give this a chance to be detected. 

 

The tipi service will remove the /tmp/tipi_safepoint file when it sees it. then quit(). there will be an obvious log message. 

 

-M@

Link to comment
Share on other sites

I've got your script file setup as you mentioned.  I then setup a CRON job with the editor containing:

 

*/1 * * * * /usr/bin/sudo -H /usr/bin/tipireboot.sh >> /dev/null 2>&1

 

I also did a sudo chmod 775 /usr/bin/tipireboot.sh as the link back earlier in the message suggested it be done.

 

The server software is now in a loop where it decrements from >FFFF to 0, 5 times, before it sends a message to check for an incoming connection.  This loop is about 3.5 seconds, estimated.

 

The first call in, no problem establishing a connection. When a connection is established, pretty much there is either a send or receive message going constantly.  Now, I disconnect.  Any subsequent connection attempt, nothing is passed back to the software.  As I am using my other Geneve/TIPI to call in, the two PI's appear to have connected as the Geneve/TIPI holds things as it waits on the other system before one PI drops the attempted connection.  The TIPI on the sidecar continues to flash every 3.5 seconds, just does not see anything.  I can do a manual login from the TI keyboard, so the system isn't hung up.

 

I've tried from a SSH connection with a keyboard/monitor as user tipi into the PI with various combinations of the following commands without the BBS server being able to establish another connection:

 

touch /tmp/tipi_safepoint

sudo -H /usr/bin/tipireboot.sh >> /dev/null 2>&1

sudo systemctl restart tipi.service

 

Nothing thus far allows the link to happen.  Next, I exit the BBS program and return to the TI title screen, go back into EA option #5, and reload the program.  Now, I have access for one inbound telnet connection before I am forced to return to the TITLE screen again.  I'm thinking the tipi powerup routine may be doing something here????

 

Beery

 

Link to comment
Share on other sites

The tipi power-up routine ( 4A side ) looks like this:

 

https://github.com/jedimatt42/tipi/blob/master/hardware/dsr/powerup.a99

 

Pretty trivial assembly... the only extra thing is those 2 CLR instructions that zero out the outbound registers that the PI can read. But really, that shouldn't matter.. or I've never seen it matter. The sidecar TIPI is your BBS? If it continues to flash, then it isn't hung, so that indicates it doesn't matter in this case either.

 

When the powerup routine on the 4A runs, the significant thing is the cru bit set that the PI gets to observe... That triggers this code: 

 

https://github.com/jedimatt42/tipi/blob/master/services/TipiWatchDogService.py

 

That sets up a trigger on the electrical signal that controlled by the cru bit. It is electrically the inverse of the cru_bit state, cause pull-up resisters make life better. So when the cru_bit is set to 1, the wire goes LOW and ( I just spilled water on my keyboard -> :(  )  .... and the python code receives an interrupt that triggers the service reset behavior... which just runs systemctl restart tipi.service

 

---

 

After some dinner, I'll try and write an XB program that does some of this, and maybe I'll see the problem... If not, I'll have a more robust example... 

 

-M@

Link to comment
Share on other sites

3 hours ago, jedimatt42 said:

The tipi power-up routine ( 4A side ) looks like this:

 

https://github.com/jedimatt42/tipi/blob/master/hardware/dsr/powerup.a99

 

Pretty trivial assembly... the only extra thing is those 2 CLR instructions that zero out the outbound registers that the PI can read. But really, that shouldn't matter.. or I've never seen it matter. The sidecar TIPI is your BBS? If it continues to flash, then it isn't hung, so that indicates it doesn't matter in this case either.

 

When the powerup routine on the 4A runs, the significant thing is the cru bit set that the PI gets to observe... That triggers this code: 

 

https://github.com/jedimatt42/tipi/blob/master/services/TipiWatchDogService.py

 

That sets up a trigger on the electrical signal that controlled by the cru bit. It is electrically the inverse of the cru_bit state, cause pull-up resisters make life better. So when the cru_bit is set to 1, the wire goes LOW and ( I just spilled water on my keyboard -> :(  )  .... and the python code receives an interrupt that triggers the service reset behavior... which just runs systemctl restart tipi.service

 

---

 

After some dinner, I'll try and write an XB program that does some of this, and maybe I'll see the problem... If not, I'll have a more robust example... 

 

-M@

I did just realize one thing at 3:30 am while in bed thinking of the issue.  When the tipi.service was restarted, I would need to rebind the port.  I will need to add another call into my loop to bind the port again in the event the tipi.service is restarted.  

 

From what you wrote about the trigger for the systemctl restart tipi.service routine by running the powerup routine, that sounds like that may be another way to accomplish the same behavior as the CRON job??? I'm just not sure that trigger would need to be restarted every 3.5 seconds and the CRON job is the better route.

 

What puzzles me is the fact that even though the internet connection was not lost during that initial session, I would have thought nothing should have happened for the subsequent session to lead the tipi to touch the /tmp/safe_point file when the tipi messaging system went to access only every 3.5 seconds.  I'm wondering if another BIND in that loop would solve that issue even though v 1.55 and before, that was not a factor.  That's something for me to try after I get back up again later in the morning.

 

Beery

 

 

Link to comment
Share on other sites

I spotted a bug in the error handling code too.. making it hard to detect if the bound socket no longer exists... 

 

I'm working on that, cause yes, you'll need to detect that the port isn't bound ( should be a failure mode of the accept message ) , and then rebind. 

 

Still working on fixing this, and keeping to the documented API... 

 

--

 

If you poke the cru-bit from the 4A , that will restart the service. And you'll be at a safe-point cause the 4A won't be in the middle of a message handling routine. 

 

  • Like 1
Link to comment
Share on other sites

OK, wanted to make a note/observation on what I am seeing with the BIND with 1.59

 

I am running a Windows 10, 64 bit Microsoft Telnet client.  I call into the BBS.  The connection is picked up, no issue.  I log off.  The telnet connection says two things:

 

Connection to host lost.

 

Press any key to continue...

 

If I do not press a key, the BBS server thinks there is a connection to Bind and restarts the BBS program.  I just repeated this 3 times in a row while the Microsoft Telnet Client sat there as I DID NOT "Press any key to continue...".  I subsequently hit <ENTER> to return to the Telnet client prompt while logged in (but using local sysop keyboard control) to type on the BBS TI-99/4A computer.  This time the BIND thinks there is nothing there.

 

Same thing looks to happen on my Geneve MyTerm client connecting to the BBS where it is PI talking to another PI.  I had something with a less than 1 minute interval between logging off, the loop returning to signon prompt again, logging in, logging off, and then it was back to the signon again.  The next time, it did not repeat.  This was without a CRON job active.

 

Seems as though there is something unique that perhaps the CLOSE is not fully breaking the connection???  Just a guess here.

 

About to see what happens when I turn on the CRON job.


Beery

 

 

Link to comment
Share on other sites

If I followed the chronology correctly, this is something you are still resolving as I believe the 1.59 update came out prior to the time of this posting?  Want to make sure as I noted above in an earlier post, when I disconnect from a Telnet client, the BBS Server code thinks the connection is still present.  It has the appearance of a time issue before complete disconnect.  I extended the loop to counting down from >FFFF to 0 for 8 times, and still wasn't enough yet.  The originating client doesn't see the connection, but the server side responds as though a connection does exist.

 

I wish my rural internet connection was better, but unfortunately that is not the case, so I guess I am getting some good debugging in.  I'm not going to rule out my services could be just too poor until AT&T fixes things for the better to run a server setup on the TI.

 

If I am in the middle of a BIND message, if the PI loses internet, and the CRON job hits the "touch /tmp/tipi_safepoint" file, when does the restart of the tipi.service take place?  As I am waiting on a RECVMSG message back from the BIND message, will that cause things to hang if the timing hits just right?

 

If I am following your last statement in the line below, should I do a reset from the powerup routine to restart the service before a new BIND call so I am not in the middle of a message handling routine?  Again, sorta goes back to how quickly the tipi_safepoint file gets written and how fast the PI processes that request.

 

Beery

 

On 4/19/2020 at 2:33 PM, jedimatt42 said:

I spotted a bug in the error handling code too.. making it hard to detect if the bound socket no longer exists... 

 

I'm working on that, cause yes, you'll need to detect that the port isn't bound ( should be a failure mode of the accept message ) , and then rebind. 

 

Still working on fixing this, and keeping to the documented API... 

 

--

 

If you poke the cru-bit from the 4A , that will restart the service. And you'll be at a safe-point cause the 4A won't be in the middle of a message handling routine. 

 

 

 

Link to comment
Share on other sites

The message handler on the PI in tipi.service looks for the safepoint file before taking a message from the 4A. 

So if you have begun sending, it won't process the file until that operation is complete... which is not until the 4A has finished receiving the response. Then 500ms has to pass without the 4A initiating another send.  When a safepoint does restart the service, it will be safe. If the 4A tries to send, it will block until the restart completes, and then the PI will take the pending message from the 4A.  I have tested this. 

 

You'll get a failure to 'accept' now, if the bound port is lost due to a restart. You then have to retry binding until it succeeds. That might take as long as 2 minutes... Not awesome, but it does clear. 

 

64k decremented 8 times over is something like 3 seconds? Or am I a few orders of magnitude off?

Link to comment
Share on other sites

I am estimating the time from flashing the light, but you are in the right ballpark.  

 

As far as the tipi_safepoint file handling, sounds great.

 

This morning, working from home and going through the morning ritual where the connection drops out every 5 minutes or so.

 

Beery

4 hours ago, jedimatt42 said:

64k decremented 8 times over is something like 3 seconds? Or am I a few orders of magnitude off?

 

Edited by BeeryMiller
Link to comment
Share on other sites

Just a note on an observation I made yesterday.  I had a monitor and a USB keyboard connected to the PI.  Twice yesterday, I bumped the PI.  When I did, the board responded as though there was a connection.  I pulled the cover to the case on the PI and had one pin from the TIPI to the PI that was not connected as tight as it could be on the PI.  I unplugged my monitor and keyboard from the PI, and put the top cover back onto the PI.  No more spurious issues have occurred.

 

Beery

 

  • Like 1
Link to comment
Share on other sites

Matt,

 

Back when I was writing the XOP code to access the TIPI from MDOS mode, I discovered I had to copy your code for the SENDMSG and RECVMSG into my code rather than running from the DSR itself.  I suspected some kind of speed issue trying to run the TIPI DSR code within the Geneve memory map.  I thought at the time as long as I just accessed the ports, all would be well and it was with the telnet client and the code modifications I made for Mass Transfer.

 

Anyways, now, I am working with the BBS/Server code.  I'm running the same code on both the Geneve and the TI-99/4A.  I am finding intermittent lockups on the Geneve/PI3+ (or B, whatever the better one was) while I am not seeing locksups on the TI-99/4A/PI4 (4MB) setup.

 

After the initialization, I go into a loop of code where I BIND, ACCEPT, if nothing, KSCAN (for local access), or loop back to BIND.  On the 4A, the loop between BIND and ACCEPT is a countdown from >FFFF loop 5 times.  On the Geneve, I have increased  to a loop of 32 times as I was watching the TIPI light which is about 50% longer (6 seconds Geneve vs 4 seconds on the 4A with 5 loops). 

 

After either a keypress or a successful ACCEPT from an incoming connection, I send a string out.  

 

I'm getting a lockup in my loops which has me a bit suspicious of the SENDMSG and RECVMSG routines that may be tied to something in the ACCEPT.  I can't see how it would be in the RECVMSG from the ACCEPT SENDMSG, so it has me a bit suspicious something could be slower in the SENDMSG when making an ACCEPT call.

 

Anyways, it is just a theory.  If you think there may be something with timing or the PI taking longer to respond, etc. with a BIND call with the Geneve's faster speed, please let me know.

 

Right now, just trying to find the differences, and I do realize the TIPI was developed for the 4A and wanted to bring the subject up if you think of something.

 

Beery

 

 

 

 

 

  • Like 1
Link to comment
Share on other sites

I put a lot of energy into creating a communication model between the TI and PI so that the speed of each side is non-consequential. 

 

This is how I ended up with the 'mailbox' approach. Each side has their own mailbox. And each side polls it checking for data... 

 

The PI is in total control of data transfer rate across the wires... So Geneve vs 4A should not matter there. 

 

There should be no required delay between bind and accept.  

Link to comment
Share on other sites

8 hours ago, jedimatt42 said:

I put a lot of energy into creating a communication model between the TI and PI so that the speed of each side is non-consequential. 

 

This is how I ended up with the 'mailbox' approach. Each side has their own mailbox. And each side polls it checking for data... 

 

The PI is in total control of data transfer rate across the wires... So Geneve vs 4A should not matter there. 

 

There should be no required delay between bind and accept.  

That loop is where I am giving the PI enough time to look for the tipi_safepoint file suggested in an earlier note to restart the tipi services should I lose connection.

 

Beery

 

Link to comment
Share on other sites

8 hours ago, BeeryMiller said:

That loop is where I am giving the PI enough time to look for the tipi_safepoint file suggested in an earlier note to restart the tipi services should I lose connection.

 

Beery

 

 

I suspect your code is 'over-medicated' now, after many attempted work-arounds... it might be worth re-assessing / removing any that did not pay dividends.

 

I would have imagined the delay for the safepoint detection would go between each accept... and that there isn't the need to bind for every accept...  If you haven't received input from a user in a while while you suspect they are connected, backing off to poll less aggressively and allow the safepoint could be useful as well, if the reason you haven't seen anything from them is the PI's loss of network connectivity...

 

I saw good disconnect and reconnect with this code flow ( BASIC with Labels Tidbit style ) :

 

 

BEGIN:
    ON ERROR BINDERR
    OPEN #1:"PI.TCP=*:8080.BIND"
    PRINT "Bound server port 8080"
POLCON:
    ON ERROR SOCERR
    INPUT #1:HANDLE
    IF HANDLE=255 THEN ACCERR
    IF HANDLE<>0 THEN GETCON
    CALL SOUND(1000,40000,30)
    GOTO POLCON
GETCON:
    OPEN #2:"PI.TCP=*:8080."&STR$(HANDLE)
    PRINT #2:"Hello, I am a TI-99/4A"&CHR$(13)&CHR$(10)
    PRINT #2:"Who are you? "
GETNAME:
    LINPUT #2:LINE$
    IF LINE$="" THEN GETNAME
    PRINT "Login from: "&LINE$
    PRINT #2:"Hello "&LINE$&CHR$(13)&CHR$(10)
    CLOSE #2
    GOTO POLCON
ACCERR:
    PRINT "Accept Error"
SOCERR:
    PRINT "Closing port"
    ON ERROR SOCE2
    CLOSE #1
SOCE2:
    CALL SOUND(1000,40000,30)
    GOTO BEGIN
BINDERR:
    CALL SOUND(3000,40000,30)
    GOTO BEGIN

The only reason the delay ( call sound ) in the BINDERR is 3 seconds instead of 1, is cause if there is a bind error it is likely to take many seconds or a couple minutes to clear up... 3 is the magic human patience number when waiting for computer feedback, such as watching a log...

Link to comment
Share on other sites

14 hours ago, jedimatt42 said:

 

I suspect your code is 'over-medicated' now, after many attempted work-arounds... it might be worth re-assessing / removing any that did not pay dividends.

 

I would have imagined the delay for the safepoint detection would go between each accept... and that there isn't the need to bind for every accept...  If you haven't received input from a user in a while while you suspect they are connected, backing off to poll less aggressively and allow the safepoint could be useful as well, if the reason you haven't seen anything from them is the PI's loss of network connectivity...

 

I saw good disconnect and reconnect with this code flow ( BASIC with Labels Tidbit style ) :

 

The only reason the delay ( call sound ) in the BINDERR is 3 seconds instead of 1, is cause if there is a bind error it is likely to take many seconds or a couple minutes to clear up... 3 is the magic human patience number when waiting for computer feedback, such as watching a log...

Well, after I think it was 1.59 that was released, I did pull some code out and did some cleanup.  I've managed to keep the TI system up and running for 3 days now through quite a few drops in internet.  The CRON job and the safepoint file seems to be doing its thing correctly on the TI-99/4A.  There is still a 4A bug I am chasing, but I do not think it is a TIPI issue.

 

I am hoping I have the Geneve issue worked out as there may be an interrupt issue in the interrupt timer routine that is behaving differently on the 4A versus the Geneve.

 

Beery

 

 

 

 

 

  • Like 1
Link to comment
Share on other sites

  • 3 weeks later...

Matt,

 

The BBS code I have been working with has been stable and up and running without hiccup for the past week now.  So, it looks like the stability issue between the PI and TIPI and my code has been resolved, or I have been really lucky.

 

The last update to the code that is running, I added some screen feedback to the "BBS waiting code" so I would know which tipi call (bind/accept/unbind/close, etc) routine it was in should a lockup occur.  I did this as just prior to the change, I had a lockup, but I didn't know which routine had the issue.  For now, I am not sure, but I suspect something with the  extra time writing to the screen may have masked the issue.  I can't say for 100% certainty, but I just know things are working as I thought they should be.

 

Beery

  • Like 3
Link to comment
Share on other sites

Matt,

 

Trying to understand how smart and capable the URL potential is within the TIPI DSR.

 

If I open a file at 9640news.ddns.net:port\FILENAME that is a DIS/FIX 80 file with a TIFiles header, assuming the file has full permissions on the server, can the file be READ/WRITE/etc?

 

Beery

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...