- CALCnet2.2 Preliminary Writeup
- 20 Jul 2006 01:20:00 pm
- Last edited by KermMartian on 08 Aug 2010 12:55:34 pm; edited 1 time in total
[This is a Work in Progress]
CALCnet2 Ideas
---------------
Collisions: In order for collision detection to work properly, we should poll the link port a few times after setting it to check that it doesn't change state on its own. If it does, we'll know that for some reason another calc is trying to send at the same time. If this happens, any sending calc that notices this anomaly should do something to inhibit all communication on the line for several (u)s, then wait a random amount of time before trying again.
Ideas for what to do to inhibit communication: perhaps pull and hold the clock line? Then we could have any calc pulsing the clock line as it's sending check if the clock line is still high after it releases it. If it's still low, then someone else is holding it low. Also, the one inhibiting communication is going to have to _actively_ keep setting clock to low, since other ones might be trying to pull it high in the meantime. Ideally, all sending calcs will recognize that there was a collision even before the inhibit, but the inhibit is necessary if for some reason one calc notices and stops before the other one(s). If even one calc failed to notice the collision and kept transmitting, the integrity of the data being sent would be compromised. Also, the receiving calc needs to notice the inhibit as well (or at least notice that the clock line hasn't flipped) and discard any data in the current frame.
Ideas for acknowledgement of received frame: one idea would be to have the receiving calc do something to the clock line to acknowledge each bit, but that sounds kinda hard to synchronize. Instead, it might be good to have the pause time per bit sufficiently large that the read loop on the receiving calc could do several (3-4) iterations in the pause time to prevent missed bits. Then, when the frame is finished, the receiving calc should perhaps immediately send back a 32-bit checksum. If the sending calc believes it to be correct, it does nothing. Otherwise, it needs to send a discard frame/resending frame frame.
I believe at this point one of the hardest things is going to be making the receiving calculator realize it's being sent data. If the check for data method is an interrupt, as planned, then there is the problem of the relatively large amount of time between successive calls of the interrupt (roughly once every 46500 clock cycles). One way to do it would be to just make the sending calc hold the clock line low for about 100,000 clock cycles. That would almost guarantee that every other calculator's attention would be gotten, and it could then proceed with the address and the frame itself. The problem there is that a calc that notices the clock low pull near the beginning may have to wait outside of regular execution up to 1/60th of a second (0.167s) before the sending calc starts sending the address and the calc can safely ignore the data or recognize that it is the intended recipient. Possible workarounds or solutions for this?
Addresses: I was originally going to make CALCnet2 utilize a cascading checkin system that would have each calc in a network have a 1-byte identifier that determined both its position in the cascade check and its target address for transmissions from other calculators. However, it seems to me that the cascading checks would take a good deal of time and unnecessarily tie up network resources. I have been taking an informal networking class at my college, and as I was listening to some of the networking theory we are learning, I realized that whereas every single piece of computer networking equipment manufactured has a unique Media Access Control (MAC) address that identifies it, the calc does as well - the SID number! This 14-character (7-byte) string could be used as the CALCnet2 equivalent of the MAC address. The followup I am still considering, however, is whether I will also need to have a local CALCnet2 network (LCN) address, equivalent to a LAN IP address. At the moment I am inclined to think that I do not, and I'm trying to see if there's any reason that I would need such an address in addition to the SID.
Other Devices: Those non-calculator devices on a network necessarily do not have an inherint SID. Because of this, they must be given an artificial one. I pick A5A5A5A5A5A5A5 as the SID, since that has enough state changes to avoid any random problems, and is unlikely to be an actual SID of a calculator (too high of a number). This will make it extremely easy for a non-calculator host device to check if there is already such a service on the network. Simply send a ping frame to A5A5A5A5A5A5A5 and wait for a response. If there is no ping-response frame within one second, the device can safely assume it is the only such device on the network and begin to serve out ping, HTTP, gCn, and other services to calculators present.
gCn: By using the SID as the network identifier, it's easy to remove several layers of complexity from gCn. In order to send data to another calculator, the sending calculator might first send a ping frame to that SID. If there's no response, it may decide the calculator is not on the network. Next it pings A5A5A5A5A5A5A5. If there's no response, it returns an error to the program or user. Otherwise, if there is a ping response frame, it sends a gCn frame to the non-calc device with its full frame (recipient, sender, frame). The device can then send a messsage to all of the python servers via its own python server that goes something like: "hey, I'm looking for calculator so-and-so from so-and-so". The python servers notice the requesting calc and cache its non-calc device host's IP address, then ask each other where the receiving calc is. They may know where it is from previous where-is... requests, in which case the python serv can respond, "oh, it's an NN.NN.NN.NN". If not, they ask each of the connected hosts for that device. Each host pings its network; if no response, they send back a failed search message. The python servers give an address (if found) to the requesting host, which then contacts the reciving host directly. That host pings its network, and if it gets a response, it sends along the message to the calc as well as a confirmation message to the requesting host. If, however, the receiving host does not receive a ping response or at any time fails to receive an acknowledgement frame from the receiving calc, all it needs to do is tell the requesting host that the transfer failed, which the host will act upon by sending a "terminate send - connection to recipient lost" frame to the sending calc, and also by alerting the python server network that it no longer has a certain calc responding on its network. To summarize:
--the python server network attempts to cache IPs that each calc can be found at based on requests from hosts
--hosts alert the python servers when a calculator is no longer found on its network
--it seems that a ping service layered over Cn2 but lower than gCn is essential
--by doing things like this, gCn becomes effectively COMPLETELY transparent to the calculators themselves
This allows such things as seamless sharing of programs or files the same way between two friends or coworkers whether they are next to each other or on opposite sides of the world. In addition, it seems likely that Doors CS will contain some kind of fileservice. Calculators should be identified by their SID in any application, but by giving the host an option to search the PHP server for SID<-->username via the python servers, it may be possible to reference any calculator by its username in addition to its SID. Also, usernames should also be registerable to hosts, via IP and port, to allow them to act as file-, game-, or even (!) web-servers for globalCALCnet2.
CALCnet2 Ideas
---------------
Collisions: In order for collision detection to work properly, we should poll the link port a few times after setting it to check that it doesn't change state on its own. If it does, we'll know that for some reason another calc is trying to send at the same time. If this happens, any sending calc that notices this anomaly should do something to inhibit all communication on the line for several (u)s, then wait a random amount of time before trying again.
Ideas for what to do to inhibit communication: perhaps pull and hold the clock line? Then we could have any calc pulsing the clock line as it's sending check if the clock line is still high after it releases it. If it's still low, then someone else is holding it low. Also, the one inhibiting communication is going to have to _actively_ keep setting clock to low, since other ones might be trying to pull it high in the meantime. Ideally, all sending calcs will recognize that there was a collision even before the inhibit, but the inhibit is necessary if for some reason one calc notices and stops before the other one(s). If even one calc failed to notice the collision and kept transmitting, the integrity of the data being sent would be compromised. Also, the receiving calc needs to notice the inhibit as well (or at least notice that the clock line hasn't flipped) and discard any data in the current frame.
Ideas for acknowledgement of received frame: one idea would be to have the receiving calc do something to the clock line to acknowledge each bit, but that sounds kinda hard to synchronize. Instead, it might be good to have the pause time per bit sufficiently large that the read loop on the receiving calc could do several (3-4) iterations in the pause time to prevent missed bits. Then, when the frame is finished, the receiving calc should perhaps immediately send back a 32-bit checksum. If the sending calc believes it to be correct, it does nothing. Otherwise, it needs to send a discard frame/resending frame frame.
I believe at this point one of the hardest things is going to be making the receiving calculator realize it's being sent data. If the check for data method is an interrupt, as planned, then there is the problem of the relatively large amount of time between successive calls of the interrupt (roughly once every 46500 clock cycles). One way to do it would be to just make the sending calc hold the clock line low for about 100,000 clock cycles. That would almost guarantee that every other calculator's attention would be gotten, and it could then proceed with the address and the frame itself. The problem there is that a calc that notices the clock low pull near the beginning may have to wait outside of regular execution up to 1/60th of a second (0.167s) before the sending calc starts sending the address and the calc can safely ignore the data or recognize that it is the intended recipient. Possible workarounds or solutions for this?
Addresses: I was originally going to make CALCnet2 utilize a cascading checkin system that would have each calc in a network have a 1-byte identifier that determined both its position in the cascade check and its target address for transmissions from other calculators. However, it seems to me that the cascading checks would take a good deal of time and unnecessarily tie up network resources. I have been taking an informal networking class at my college, and as I was listening to some of the networking theory we are learning, I realized that whereas every single piece of computer networking equipment manufactured has a unique Media Access Control (MAC) address that identifies it, the calc does as well - the SID number! This 14-character (7-byte) string could be used as the CALCnet2 equivalent of the MAC address. The followup I am still considering, however, is whether I will also need to have a local CALCnet2 network (LCN) address, equivalent to a LAN IP address. At the moment I am inclined to think that I do not, and I'm trying to see if there's any reason that I would need such an address in addition to the SID.
Other Devices: Those non-calculator devices on a network necessarily do not have an inherint SID. Because of this, they must be given an artificial one. I pick A5A5A5A5A5A5A5 as the SID, since that has enough state changes to avoid any random problems, and is unlikely to be an actual SID of a calculator (too high of a number). This will make it extremely easy for a non-calculator host device to check if there is already such a service on the network. Simply send a ping frame to A5A5A5A5A5A5A5 and wait for a response. If there is no ping-response frame within one second, the device can safely assume it is the only such device on the network and begin to serve out ping, HTTP, gCn, and other services to calculators present.
gCn: By using the SID as the network identifier, it's easy to remove several layers of complexity from gCn. In order to send data to another calculator, the sending calculator might first send a ping frame to that SID. If there's no response, it may decide the calculator is not on the network. Next it pings A5A5A5A5A5A5A5. If there's no response, it returns an error to the program or user. Otherwise, if there is a ping response frame, it sends a gCn frame to the non-calc device with its full frame (recipient, sender, frame). The device can then send a messsage to all of the python servers via its own python server that goes something like: "hey, I'm looking for calculator so-and-so from so-and-so". The python servers notice the requesting calc and cache its non-calc device host's IP address, then ask each other where the receiving calc is. They may know where it is from previous where-is... requests, in which case the python serv can respond, "oh, it's an NN.NN.NN.NN". If not, they ask each of the connected hosts for that device. Each host pings its network; if no response, they send back a failed search message. The python servers give an address (if found) to the requesting host, which then contacts the reciving host directly. That host pings its network, and if it gets a response, it sends along the message to the calc as well as a confirmation message to the requesting host. If, however, the receiving host does not receive a ping response or at any time fails to receive an acknowledgement frame from the receiving calc, all it needs to do is tell the requesting host that the transfer failed, which the host will act upon by sending a "terminate send - connection to recipient lost" frame to the sending calc, and also by alerting the python server network that it no longer has a certain calc responding on its network. To summarize:
--the python server network attempts to cache IPs that each calc can be found at based on requests from hosts
--hosts alert the python servers when a calculator is no longer found on its network
--it seems that a ping service layered over Cn2 but lower than gCn is essential
--by doing things like this, gCn becomes effectively COMPLETELY transparent to the calculators themselves
This allows such things as seamless sharing of programs or files the same way between two friends or coworkers whether they are next to each other or on opposite sides of the world. In addition, it seems likely that Doors CS will contain some kind of fileservice. Calculators should be identified by their SID in any application, but by giving the host an option to search the PHP server for SID<-->username via the python servers, it may be possible to reference any calculator by its username in addition to its SID. Also, usernames should also be registerable to hosts, via IP and port, to allow them to act as file-, game-, or even (!) web-servers for globalCALCnet2.