text:
Trainz/Content Manager

 * Releases earlier than Trainz: A New Era (TANE) are covered in the main page:  Trainz/Content Manager 2.0--CM3.7
 * Early versions coverage: Content Manager Plus,  AM&C/Content Manager

Introduction To CM/CMP
Predecessors to CM or CMP were a stand alone utilities from Trainz 1.0 through TRS2004-SP4 (also named ContentManager.exe,. hence the 'Plus' of TRS2006's CMP) with which users could install new modeling assets. There weren't many options but installing assets. Other utilities performed some of the tasks (e.g. uploading) but Data Management was mainly manual by moving folders about. In essence the early simple ContentManager.exe programs did some simple file management and unpacked files and tucked their contents away in a scheme using open folders,  folder locations, and a data system that had no real data base to it. They could also create cdp files, allowing the early growing Trainz community to feast on shared creations. Eventually, the early Download Station was hosted by Auran and users could browse without much search capability much as one can on today's less sophisticated 3rd party Trainz fan-sites. Most of these are operated by an individual or a small group of Content Creators. Prior to TRS2004, the cloud services we know as the DLS was more list presenting access to a disorganized collection of zip and cdp files than an organized database with a built in search engine, FTP manager. It was a central repository but a chaotic one, and the chaos was converted into today's order when DLS was established during UTC's hey days (v1.5), a little before the time TRS2004 (v2.0) came about.
 * Background to the Content Manager and the DLS

The need for CMP
The early local Trainz 's database was more organized as groups of open files as well, and data corruption was thus more likely until TRS2004 evolved a better file structure and compressed data formats, which was best exploited with the advent of TRS2006 and its Content Manager Plus became a data base manager and search and access tool. With a database manager on the servers to handshake with on the DLS end, the more sophisticated user-end software became feasible and it arrived with trainz-build v2.5 (TRS2006 Content Manager—then retitled as Content Manager Plus (or CMP).

The powers of CMP
CMP had capabilities unknown in the earlier Trainz 'Content Manager' which relied on a primitive and  tags classification system for it's limited capabilities of asset grouping and searching. The earlier module was mostly a listing/cataloging utility allowing a user to examine her own inventory of assets, with no information from the DLS. and generally became the center-point for asset operations not involving actually building a route.
 * CMP took on a whole host of additional capabilities formerly performed by several separate *.exe utility programs, including those of 3rd party providers, and incorporated a ton of new powerful search, classification, and asset management features such as:
 * 1) the ability to directly communicate with the Download Station (DLS) during searching
 * 2) could import content from installation to installation by direct file importing/parsing
 * 3) or via cdp importation,
 * 4) export a route or asset or
 * 5) upload it to share with others on the DLS
 * 6) manage asset editing
 * 7) manage and use archives and archiving
 * 8) search by combining criteria and classification

Launching CM/CMP
CM/CMP (Content Manager Plus) is accessible via the Trainz Launcher screens or by directly launching the ContentManager.exe file from the Trainz installation's root directory \bin sub-folder (recommended, or by shortcut thereto). Many users with multiple Trainz installations will bundle shortcuts to launch the CM or Trainz launcher programs from a common Trainz folder. CM's primary purpose is to manage the data flow to and from the DLS and manage the local assets on your hard drive (located in your ..\UserData folder) and the sub-folders therein (such as the ..\local, ..\settings, ..\screenshots, ..\editing folders) as well as the Trainz release's special data base of built-in items. (See  and .)

Mainly Trainzer's use it to communicate and manage downloading from the DLS, and to select and filter assets for surveyor. TS2009 introduced enhanced filtering (selectable savable criteria were part of the T'06 CMP, but the way they could be combined was limited. In T'09, the new power was in the addition of new search-refining Boolean logic operators: OR, AND NOT, and AND [the latter of which is somewhat redundant in most uses]) so power users will often define a search criteria, called a search filter, save that and then use that to trim down the list of assets one must look through to find a desired asset when route building. CM/CMP has a sophisticated search facility and automatically identifies and downloads associated with each asset. CM/CMP is closely integrated to and is also used to open assets for editing and committing them for use in Trainz. In TRS2006 and above, new assets and asset clones (copies with new kuids) are created via CM/CMP, though a route or session may be cloned using a Save As option in Surveyor.

Getting around in CM
CMP through CM-3.7 looks much like a spreadsheet with relocatable columns (from CM-2.0 of TS2009) meaning columns selected for viewing in the 'main view' (the right hand part of the screen) using can later be slide left or right and rearranged to suit the user preferences, or the type of task you might be about. For example, one day you might want to locate all the assets that were installed with the download of XYZ route and sessions, so want to see install date... an otherwise uninformative data column. Some days you want modification date, and on others perhaps, the regions, era or the trainz-build values are your primary sorting and searching interests. The check box in the menu allow hiding columns or turning their display on, whilst dragging them allows you to rearrange them left to right. The notations CM-X.Y appears in the CM/CMP title bar after TC3 and after TS2009-SP3 the X.Y (initially just CM-2.0) was incremented with each and so displayed as a suffix to give a visual reminder of the  or 'version' of the Trainz software. It now signifies the trainz-build code an asset created or updated using Content Creator Plus (CCP) editing will be given. CM supports asset editing in two forms: CCP, which is a table-like fill in the blanks rigid form for getting the proper parts assigned to a new asset, or by free form editing using Windows utilities. For asset repairs, virtually everyone avoids CCP and uses a Windows Explorer editing folder with direct access to the files making up the asset. This folder and files can be opened in several ways:
 * title bar notations
 * Editing modes
 * 1) Hotkeys  directly opens a Windows Explorer folder with no processing, and it pops up immediately on top of other screen windows.
 * 2)  accesses one of the PEVtools or other batch utility that has been installed in the \bin\...\Tools sub-folder. Thusly, for example, if a repair requires accessing textures (say in the error message you see an alphamask and it's base texture don't match in size, so one needs re-sized) one can open the asset with PEV's images2TGA utility and be ready to fix the problem immediately. In this case the window will often be behind or other another Windows application window depending upon your video set up and the biases built-in to Windows. If running a dual or three monitor system, often these can be biased to open in the other screen(s) from CM, so will open where it can be seen immediately.

Left hand panes
For the moment, notice the default tabs along CM's top of the main view each load a search criteria in the Search pane when pressed; and also that by using (Toggles) one can hide or open the left panes. The tutorial & reference will allow us to cover tips and tricks in depth outside this survey topic. (You didn't want to read that here, now anyway, did you?)

As can be seen in the image below and left, each left hand pane has a little click icon to open it or close it, and in normal operations, one will be the DLH (Download Helper) pane, another the Asset Details pane, and as needed, the Search pane, or other combinations (uploads, archive, and pick list) based on what you are doing that give you the desired flexibility. Each can be closed when set up and still have effect, or the whole set of panes can be toggled open or closed with commensurate widening or narrowing by alternate presses of the key. Other panes shown are for uploading, archiving, and so forth, but like the DLH pane, these are used primarily by dragging and dropping from the Main View into the pane, so must be open to be in actual use. Play a bit and read the manual, whether printed or in pdf format, then re-read it. Wait a month and read it again. Each time will give you the power of additional knowledge and insights as to the capabilities shedding further light on what we present here.

Download Helper (DLH)
To pick something for download, one sets up a search criteria (see image left) then clicks on one or more assets to select them (Highlighted, colors of CM and highlighting are as you set them in your Windows theme) then drag them into the DLH pane. As you add more you'll likely note some activity going on, part of which is CM and the DLS are filling in dependencies—sub-assets the asset you selected depend upon as parts, for example the bogeys, wheels, or couplings of that railcar type, or textures, etc. which are parts of the assets you selected. As you add more by drag and drop, the list will grow a scroll bar and grow longer as dependencies are identified and added.

Search pane
Buttons are straight forward,, , , and / to add/delete a new 'filter-line' (API data window). With nothing in the pane, it's already cleared.

Perils of Downloading
New Trainzer's need be aware of the perils of downloading too much too soon. There is a smart way to proceed, and ones less effective. The Table at right illustrates this point. Six assets were listed as downloads in the DLH pane. When the were added by CM, the download was 36! A sixfold increase, and this is a mild example. Downloading a session will bring in a route, the route (and since Layers were introduced in TS10) and sessions might both have several thousand or several hundred asset dependencies respectively.

Search Pane
Perhaps even more than the DLH the Search Pane will likely receive your most frequent attentions.

Notes, Footnotes & References
{{#if:||

title: Trainz/Content Manager


text:
User talk:Sué González Hauck

Welcome!
Welcome to Wikibooks, Sué González Hauck!

 First steps tutorial Wikibooks is for collaborative development of free textbooks.

You do not need technical skills to contribute. You can easily change most books. Please introduce yourself, and let us know what interests you.

If you already contribute at other Wikimedia projects, our Wikimedia Orientation should quickly get you started. (Would you like to provide feedback on this message?)

  Getting help   Made a mistake?   Goodies, tips and tricks
 * Read the Using Wikibooks book for a friendly introduction to the project, or our help pages for more information.
 * You can get friendly help from the community in the user assistance room or our IRC channel.
 * Upload freely licensed files to Wikimedia Commons. You may request permission to upload fair use files locally. Please include author and source information and a non-free use rationale for non-free files.
 * You can restore a previously saved version.
 * Pages should follow the  naming convention.
 * Need to rename a page? Use the move tab (is available once your account is 4 days old - until then, ask for help).
 * To request a page be deleted, add to the top of the page.
 * Was a page you made deleted? Please read the deletion policy, and check the deletion log to find out why. Also check the RFD archives if applicable. You can request undeletion at WB:RFU, or ask the administrator who deleted the page.
 * Please fill in the edit summary and preview your edits before saving.
 * Sign your name on discussion pages by typing ~~~~
 * User scripts can make many tasks easier. Look at the Gadgets tab of my preferences; check off the boxes for the scripts you want, and hit save!

-- Jules (Mrjulesd) 23:20, 25 March 2021 (UTC)

Moved to OpenRewi
We don't use the Wikibooks namespace for books; books are kept in the main namespace. Leaderboard (discuss • contribs) 13:20, 8 April 2021 (UTC)

 * Thank you. Maybe I should have clarified that I was not trying to create a page for a specific book but a WikiProject page, following the instructions @Mrjulesd gave us replying to this introductory post in the Reading Room. The idea is to have the OpenRewi page as a page where we can gather information on the project in general, styleguides, instructions for authors etc.  Sué González Hauck (discuss • contribs) 13:38, 8 April 2021 (UTC)
 * Ah I see. I'll wait for clarification from Jules then, since I forgot about that conversation. It's not a big deal anyway. Leaderboard (discuss • contribs) 13:39, 8 April 2021 (UTC)

 * yes that was actually my suggestion that they form a wikiproject. The reason is that on de.wb they have b:de:Benutzer:OpenRewi which is a user page. I though maybe a Wikiproject page may be a good place to put it? Their actual books are kept at OpenRewi, and any books they produce would have to be in the mainspace obviously. Any views on this? -- Jules (Mrjulesd) 13:55, 8 April 2021 (UTC)
 * Hmm I see your point, but perhaps we should use an English equivalent? Leaderboard (discuss • contribs) 14:26, 8 April 2021 (UTC)
 * Maybe we could keep the original German name with an addition in English. Something like "OpenRewi - Open Legal Science". That way it would still be possible to identify both the German and the international projects as part of the same initiative. @Maximilian.Petras, do you want to weigh in on this? Sué González Hauck (discuss • contribs) 14:45, 8 April 2021 (UTC)
 * The suggested name addition sounds great. In the long run we could think about an umbrella organisation for international puposes with a different name. As long as we are mainly centered in the German speaking countries I would like to stick with "OpenRewi" at the beginning. Maybe your project moves us to other countries - let's hope for the best :) Maximilian.Petras (discuss • contribs) 18:41, 9 April 2021 (UTC)

Hi, I have moved the page to WikiProject OpenRewi - Open Legal Science. I hope that is acceptable. -- Jules (Mrjulesd) 13:23, 14 April 2021 (UTC)

 * Perfect, thank you! Sué González Hauck (discuss • contribs) 13:49, 14 April 2021 (UTC)

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

title: User talk:Sué González Hauck


text:
Transportation Deployment Casebook/2021/Arkansas

Overview
Prior to the 1880s city transport consisted of the modes walking, running and by horseback. Streetcars found themselves conveniently in the transitional period between the horse riding and automobile era having a short but fruitful lifespan. The rail component of the trolley is the most important as it allowed for strict direction control and in combination with its double flanged wheel required less force to move due to decreased friction. In 1883 Arkansas, streetcars were introduced in the form of a trolley being pulled by mules over rail however within 10 years electric streetcars quickly overtook the mule-pulled trolleys and were heavily used in Arkansas. The main hub for trams in Arkansas was Fort Smith which got major benefits such as new roads.

As the 20th century dawned on Arkansas the usage of the trams reached its peak when they enabled access to theme parks such as the Electric Park and go for baseball games. Baseball was prohibited on Sundays in Arkansas, so when a tram line that went to a ballpark in Arkoma first opened an estimated 10,000 people used to Streetcar that day. The streetcar steadily declined from there as the main provider Fort Smith Light & Traction Company ran into legal issues and finally the Great Depression left the streetcar in ruin. In November of 1933 the last streetcar had its final run in Fort Smith which was once known as the main hub of streetcars in Arkansas. Although a few lines still ran in Arkansas by 1947 there were no streetcars within the state.

Past Transport Systems
Previously within urban cities in Arkansas the horse and buggy were predominantly used on roads. This system however was not a public system and was mostly only available for families who were wealthy. Even a horse with no carriage would be reserved for the upper classes as land is required for a horse. The streetcar was the first major transport system for the public produced from the industrial revolution.

Horse Powered Trams
The first horse pulled tram introduced into the US in 1832. It was an early form of transport that allowed for public use and didn't require it to be booked out. It combined steel wheels and rail to allow for extremely low friction allowing horses to pull more then what they could in normal carriages. Arkansas saw the use of horse drawn carriages from 1876 to 1926. The main disadvantage for this system is the need for horses.

Horses can only pull a tram for so many hours before they are exhausted. To maintain one network a lot of horses need to be used. On top of this costs for feeding them and stabling them are extremely high as are other factors in its general upkeep. Electric powered trams quickly overtook horses as they were much cheaper and required less logistical management.

Technological Advancements
The rapid urbanisation of cities due to the industrial revolution was a key factor as the demand for transport increased. As these cities started getting larger in size people needed a transport mechanism to get from place to place. Streetcars provided this transport in bulk and was able to utilise the already in-place infrastructure such as roads which were initially constructed for horses and carriages. The Although mule powered streetcars were used at the start, electric streetcars were quickly adopted and were far more efficient.

Steam Powered Trams
Steam powered trams made a very brief appearance in Arkansas in 1888 but only lasted one year due to their many limitations. Steam powered trams simply weren't efficient in power usage and due to the burning of coal required to create steam its produced many pollutants which reduced the air-quality of cities. Its thick smoke emissions that were produced made the city look generally worse and since electricity power advanced quickly the Arkansas steam powered line only lasted one year.

Electricity Powered Trams
Although electric trams existed in the 1880s there wasn't any infrastructure and the technology didn't exist to make them a possible better alternative to the current trams at the time. As the use of electricity soared and was seen as something extremely versatile adoption was a no brainer. The Ground-level power supply system allowed electric trams to be powered by the rail they were on. In some areas this was a safety hazard as people or pets would walk over the rail and get an electric shock. An alternative technology was Overhead Lines which provided power through electricity lines above the ground.

The first electric tram in Arkansas appeared in 1896. As soon as it arrived all previous forms of energy used to move trams started to be phased out rapidly. Electricity which was becoming a source of power for a variety of different appliances and as its availability increased as did its convenience to be used. The companies that owned the first electric trams in

Market Development
As there was a large void for intra-city transport the street-cars caught on very quickly. Transport systems allow a population to be more efficient as a group. Street-cars turned job opportunities from walking range to much further as they could be used to travel to and from work. Baseball was prohibited in Arkansas  on Sundays due to it being the  day of the week to go to church. When a tram line to Arkoma ballpark which is located in Oklahoma. On the first Sunday of its opening 10,000 people left the state to go to the ball park. The world becomes much smaller when transport becomes available. The Electric Park also received many visitors who came by tram. Businesses began using street-cars as a distribution system and some of these trams were refrigerated moving meats and other foods.

Policy Development
Arkansas replicated the main policies of heavy rail with minor amendments. The policies present at the time allowed tram lines to be privately run but must be done to government standards. This meant that fees for this transport system were fixed and unable to change to ensure no economic inequality. This however would be removed when tram companies were struggling against automobiles. This policy could be argued as being the main killer of the tram system as by the time the fixed fare policy was removed it was too late and trams were rendered obsolete shorty after. The fixed rate of 5c did not account for inflation and therefore

The Americans with Disabilities Act (ADA) was a policy which ensured that people with disabilities that were unable to travel by tram could still have a transport system. This transport system was separate to the tram line and if they were unable to use the tram they could use a custom system that the private company in-charge of that rail network would have to by policy provide. This system would usually run parallel along the line.

In 1903 the Arkansas General Assembly wanted to pass the Streetcar Segregation act which forced African-American and white passengers to be segregated to “separate but equal” streetcar sections. Jim Crow was the individual behind this act however since there were no black law makers the Arkansas General Assembly. This lead to a large boycott of trams and African-American leaders. It was not only black people who were angered by this but also white people. The protests went on for weeks however this policy would still define the way in which transport would work in Arkansas for decades.

Quantitative Investigation
The following data has been extracted from the McGraw Railway Directory. It contains in the miles of track in each municipality in Arkansas that had trams organised by year. Using this data and a 3 parameter logistics function the birthing, growth and maturity stages can be identified. An estimate for the decline can also be done. Municipalities that only had one or two entries of data were removed from the table as they would impact the data negatively being an outlier. Years prior to 1897 had limited numbers and were not kept well as many of the suburbs were missing. It is important to note that streetcars were around before this time. The data was not included due to it scenarios seeming impossible where there was high growth followed by miles of track missing.

S-Curve Estimation
In order to estimate the birthing, growth and maturity of the street-car in Arkansas the following model was used:

$$S(t)=\frac{S_{\max}}{1+e^{-b(t - t_0)}}$$

Where:

 * $$S(t)$$ - Predicted miles of track

 * $$S_{\max}$$ - Maximum Saturation
 * $$t$$ - Year to be estimated
 * $$t_0$$ - Inflection time
 * $$b$$ - Coefficient estimated

The data from McGraw Railway Directory was used in these estimates and the following parameters were found: The parameter $$b$$ was found by using Solver in excel to change b until the average for the delta between predicted miles of track and miles of track was at a minimum. This produced the following table.

Miles of Track & Predicted Miles of Track
Using this data both sets of data were plotted and the following was produced:

Conclusion
Although there was plenty of data missing as Arkansas the overall outcome seems to fit the curve quite well.

Using the S-curve it can be predicted that Arkansas' tram network grew steadily starting from 1880 and had a period of rapid growth starting in 1900 and reaching maturity in 1909. This growth would start to level out in the early 1920's and it can be estimated that it would start to decline in 1925. Although there was data missing the model seems to be quite accurate and it aligns with real events that occurred.


text:
User talk:Ardenter

Welcome!
Welcome to Wikibooks, Ardenter!

 First steps tutorial Wikibooks is for collaborative development of free textbooks.

You do not need technical skills to contribute. You can easily change most books. Please introduce yourself, and let us know what interests you.

If you already contribute at other Wikimedia projects, our Wikimedia Orientation should quickly get you started. (Would you like to provide feedback on this message?)

  Getting help   Made a mistake?   Goodies, tips and tricks
 * Read the Using Wikibooks book for a friendly introduction to the project, or our help pages for more information.
 * You can get friendly help from the community in the user assistance room or our IRC channel.
 * Upload freely licensed files to Wikimedia Commons. You may request permission to upload fair use files locally. Please include author and source information and a non-free use rationale for non-free files.
 * You can restore a previously saved version.
 * Pages should follow the  naming convention.
 * Need to rename a page? Use the move tab (is available once your account is 4 days old - until then, ask for help).
 * To request a page be deleted, add to the top of the page.
 * Was a page you made deleted? Please read the deletion policy, and check the deletion log to find out why. Also check the RFD archives if applicable. You can request undeletion at WB:RFU, or ask the administrator who deleted the page.
 * Please fill in the edit summary and preview your edits before saving.
 * Sign your name on discussion pages by typing ~~~~
 * User scripts can make many tasks easier. Look at the Gadgets tab of my preferences; check off the boxes for the scripts you want, and hit save!

-- Jules (Mrjulesd) 09:20, 26 March 2021 (UTC)

title: User talk:Ardenter


text:
User talk:Enazaa

Welcome!
Welcome to Wikibooks, Enazaa!

 First steps tutorial Wikibooks is for collaborative development of free textbooks.

You do not need technical skills to contribute. You can easily change most books. Please introduce yourself, and let us know what interests you.

If you already contribute at other Wikimedia projects, our Wikimedia Orientation should quickly get you started. (Would you like to provide feedback on this message?)

  Getting help   Made a mistake?   Goodies, tips and tricks
 * Read the Using Wikibooks book for a friendly introduction to the project, or our help pages for more information.
 * You can get friendly help from the community in the user assistance room or our IRC channel.
 * Upload freely licensed files to Wikimedia Commons. You may request permission to upload fair use files locally. Please include author and source information and a non-free use rationale for non-free files.
 * You can restore a previously saved version.
 * Pages should follow the  naming convention.
 * Need to rename a page? Use the move tab (is available once your account is 4 days old - until then, ask for help).
 * To request a page be deleted, add to the top of the page.
 * Was a page you made deleted? Please read the deletion policy, and check the deletion log to find out why. Also check the RFD archives if applicable. You can request undeletion at WB:RFU, or ask the administrator who deleted the page.
 * Please fill in the edit summary and preview your edits before saving.
 * Sign your name on discussion pages by typing ~~~~
 * User scripts can make many tasks easier. Look at the Gadgets tab of my preferences; check off the boxes for the scripts you want, and hit save!

-- Jules (Mrjulesd) 09:21, 26 March 2021 (UTC)

title: User talk:Enazaa


text:
User talk:Benjamin Shepard

Welcome!
Welcome to Wikibooks, Benjamin Shepard!

 First steps tutorial Wikibooks is for collaborative development of free textbooks.

You do not need technical skills to contribute. You can easily change most books. Please introduce yourself, and let us know what interests you.

If you already contribute at other Wikimedia projects, our Wikimedia Orientation should quickly get you started. (Would you like to provide feedback on this message?)

  Getting help   Made a mistake?   Goodies, tips and tricks
 * Read the Using Wikibooks book for a friendly introduction to the project, or our help pages for more information.
 * You can get friendly help from the community in the user assistance room or our IRC channel.
 * Upload freely licensed files to Wikimedia Commons. You may request permission to upload fair use files locally. Please include author and source information and a non-free use rationale for non-free files.
 * You can restore a previously saved version.
 * Pages should follow the  naming convention.
 * Need to rename a page? Use the move tab (is available once your account is 4 days old - until then, ask for help).
 * To request a page be deleted, add to the top of the page.
 * Was a page you made deleted? Please read the deletion policy, and check the deletion log to find out why. Also check the RFD archives if applicable. You can request undeletion at WB:RFU, or ask the administrator who deleted the page.
 * Please fill in the edit summary and preview your edits before saving.
 * Sign your name on discussion pages by typing ~~~~
 * User scripts can make many tasks easier. Look at the Gadgets tab of my preferences; check off the boxes for the scripts you want, and hit save!

-- Jules (Mrjulesd) 09:21, 26 March 2021 (UTC)

title: User talk:Benjamin Shepard


text: Template:Editnotices/Group/Transportation Deployment Casebook


text:
User:Bored Pencil

Hello, I'm bored pencil. I have an interest in American history and french.

title: User:Bored Pencil


text:
User:Salonimishraaz/sandbox

ROLE OF TECHNOLOGY IN CLINICAL TRIALS

Clinical trials studies are conducted for research purpose and are performed on volunteers. Clinical trials are focused on studying different diseases and their effect on human body mentally and physically. Clinical trials are primary methods used by clinical researchers to test new drug, new medical device or new diet is effective and safe for people. All the research is done for developing diagnostic methods, new treatments to safeguard the better patient care.

For the better clinical research, highly professional and trained researchers are needed to ensure seamless research as it can be dangerous to some people if proper care is not taken during research. For highly professional researcher, Clinical Research Certification is necessary to ensure the professionalism of the candidate. For the need of the moment, Fusion Technology Solutions is offering clinical research certificate program for students who are willing to join clinical trials as a career opportunity. Keeping in mind the impact of Covid pandemic, Fusion Technology solutions is also offering online clinical research courses.

Clinical trials are believed to be still pen and paper type of research; but in reality technology is centralizing in all the organizations around the globe and clinical research is not an exception in it. Technological advancements are need for the future and that applies for clinical trials too. Suppose, we have to track heart rates of the volunteers in clinical trial; so we have to organize it in proper manner to ensure proper data management for further use. This data cannot be organized properly with pen and paper and we have to use heart rate measurement device for it. This gives us a slight insight that technological penetration is at the highest level in clinicalresearch. Hence, technological knowledge is more important in clinical research.

Fusion Technology solution is the Best Clinical Research Training Institute

for it. Here candidates are trained on dummy projects for experience purpose from experts in the respective fields. In handling of data for future use, data management is the key segment to focus on. Data management involves proper segregation of data and analyzing reports on the basis of studies performed in clinical trials. For this purpose, candidate has to submit data management certification to the respective organization. Fusion Technology Solution is offering clinical data management course for the purpose with hands on project work. Clinical data management team members are involved in clinical research from the beginning of trials. Adequate process knowledge is very important in clinical data management process. Case report form designing, data designing, data validation, medical coding, data extraction are various procedures involved in data management. All the above mentioned data management courses are involved in the clinical research courses especially because CDM standards have to meet the regulatory requirements. CDM team has to meet high standards of data quality as it is mandatory to all clinical research institutes to submit the data electronically in specific period of time.

Furthermore, analyzing the side effects on the patients and calculating whether these effects are harmful for the patients or not is the most challenging task in clinical trials. In pharmacovigilance courses, candidates are trained for using different medical devices like heart mapping devices, ultrasound and MRI machines, CT scanners, X ray machines and LASIK machines. Also, clinical trials are also carried on these machines in order to check their accuracy and identifying malfunction occurrences if any. Classification of medical devices is given by US Federal Health government. Medical devices are classified into class 1, class 2 and class 3 type of devices in which class 1 devices denotes low risk of patient health while class 3 devices denotes high risk of patient health. Pharmacovigilance courses in Fusion Technology Solutions are especially set in the manner that clinical researchers will get full study and hands on practical on medical devices. Clinical research course syllabus is set by experts in such a way that candidates will get full experience of clinical trials even before starting actual clinical research projects. The entry level of pharmacovigilance course completion is job of Drug Safety Associate (DSA). The role of DSA’s are checking minimum safety information and data reconciliation.

Required skillset for pharmacovigilance course professionals are-

1.   Knowledge of medical coding

2.   Basic knowledge of rules and regulations

3.   Understanding of medical terms and processes

4.   Good knowledge of scientific writing

5.   Good communication and interpretive skills.

Use of CT scanners in clinical trials are detailed cross section and internal images of internal organs and blood vessels, soft tissues and bones, etc. This information is collected for further studies of drugs and medicines on different organs of body. LASIK machines are used for collecting data on eye and internal parts of eye for further studies on color blindness, color configuration and retinal imaging of volunteers.

Imaging is very crucial part in Online Clinical Research Courses  as cost is rapidly increasing for drug development and characterization of drug efficacy and safety are on the prime position for clinical trials institutes. Study of molecular medicines and genomics is ever growing and expanding array in clinical trials as more discoveries are made every day in medical sciences. Multi- center imaging is standardizing and becoming a crucial part in imaging technology. Image analysis and data acquisition are the key skills required for the purpose. This data is used for post approval stage of medicines/drugs in order to analyze effects of medicines on human body after ingestion. Go or no go method is carried out after process completion as reconciliation of data is made according to the clinical trials done. Clinical trials should be done in phases given as-

Phase 1: Giving dose to healthy volunteers for safety.

Phase 2: Testing of medicine on volunteers to test the drug efficacy

Phase 3: testing medicine and asses effectiveness of medicine.

Phase 4: post marketing survey in public.

Conclusion:

Role of technology is playing a very crucial part in clinical trials as all the methods are being data centric in every organization for research and development purpose. Technological advancements in big data, pharmacovigilance methods and medical device efficacy are on the rise as there is increasing competition in institutes involved in clinical trials.

title: User:Salonimishraaz/sandbox


text:
User talk:PeishiPeng

You need to name pages properly. Please follow the instructions on the page you are editing. Create a link on the page in this form /Alabama/. Then save the page and click on the red link to create your page. Do NOT name the page "Alabama", without the "/" or it will be deleted. QuiteUnusual (discuss • contribs) 15:57, 26 March 2021 (UTC)

title: User talk:PeishiPeng


text:
User talk:GrandTurion

Welcome!
Welcome to Wikibooks, GrandTurion!

 First steps tutorial Wikibooks is for collaborative development of free textbooks.

You do not need technical skills to contribute. You can easily change most books. Please introduce yourself, and let us know what interests you.

If you already contribute at other Wikimedia projects, our Wikimedia Orientation should quickly get you started. (Would you like to provide feedback on this message?)

  Getting help   Made a mistake?   Goodies, tips and tricks
 * Read the Using Wikibooks book for a friendly introduction to the project, or our help pages for more information.
 * You can get friendly help from the community in the user assistance room or our IRC channel.
 * Upload freely licensed files to Wikimedia Commons. You may request permission to upload fair use files locally. Please include author and source information and a non-free use rationale for non-free files.
 * You can restore a previously saved version.
 * Pages should follow the  naming convention.
 * Need to rename a page? Use the move tab (is available once your account is 4 days old - until then, ask for help).
 * To request a page be deleted, add to the top of the page.
 * Was a page you made deleted? Please read the deletion policy, and check the deletion log to find out why. Also check the RFD archives if applicable. You can request undeletion at WB:RFU, or ask the administrator who deleted the page.
 * Please fill in the edit summary and preview your edits before saving.
 * Sign your name on discussion pages by typing ~~~~
 * User scripts can make many tasks easier. Look at the Gadgets tab of my preferences; check off the boxes for the scripts you want, and hit save!

-- Jules (Mrjulesd) 19:54, 26 March 2021 (UTC)

title: User talk:GrandTurion


text:
Oberon/ETH Oberon/2.3.7/PPPDebug.Mod

(* ETH Oberon, Copyright 1990-2003 Computer Systems Institute, ETH Zurich, CH-8092 Zurich. Refer to the license.txt file provided with this distribution. *) MODULE PPPDebug;	(** non-portable *)	(* rb, 1996 *) (* $VCS  4, Edgar@EdgarSchwarz.de, 25 Apr :0, 10:31:10 $ Logging to kernel log. Interactive display with System.OpenKernelLog     $Log$ $   4, Edgar@EdgarSchwarz.de, 25 Apr :0, 10:31:10 now writing to a Text: PPPDebug.Log $   3, Edgar@EdgarSchwarz.de, 24 Apr :0, 12:3:18 problem with Kernel.WriteHex fixed $   2, Edgar.Schwarz@z.zgs.de, 18 Aug 99, 21:31:56 using Kernel log stuff instead of own log buffer $   1, Edgar.Schwarz@z.zgs.de, 28 Feb 99, 22:11:59 version for PPP 1.0.0 *) IMPORT SYSTEM, Texts; VAR HexChar: ARRAY 17 OF CHAR; W: Texts.Writer; Log*: Texts.Text; PROCEDURE String*(s: ARRAY OF CHAR); BEGIN Texts.WriteString(W, s); END String; PROCEDURE Int*(x, n:LONGINT); BEGIN Texts.WriteInt(W, x, n); END Int; PROCEDURE IntBin* (n:INTEGER); BEGIN String(" "); Int(n, 1);  String(" ") END IntBin; PROCEDURE LIntBin* (n:LONGINT); BEGIN String(" "); Int(n, 1);  String(" ") END LIntBin; PROCEDURE Hex*(n:LONGINT); BEGIN Texts.WriteHex(W, n); END Hex; PROCEDURE HexByte*(b: SYSTEM.BYTE); BEGIN Texts.Write(W, HexChar[(ORD(b) MOD 256) DIV 16]); Texts.Write(W, HexChar[(ORD(b) MOD 256) MOD 16]); END HexByte; PROCEDURE Char*(ch: CHAR); BEGIN Texts.Write(W, ch) END Char; PROCEDURE Ln*; BEGIN Texts.WriteLn(W); Texts.Append(Log, W.buf); END Ln; PROCEDURE LHex* (label: ARRAY OF CHAR; val: LONGINT); BEGIN String(label); String(": "); Hex(val); Ln END LHex; PROCEDURE Init * ; BEGIN HexChar := "0123456789ABCDEF"; NEW(Log); Texts.Open(Log, ""); Texts.OpenWriter(W); Texts.WriteString(W, "2.1/es/25.04.2000"); Texts.WriteLn(W); Texts.Append(Log, W.buf); END Init; BEGIN Init; END PPPDebug.

title: Oberon/ETH Oberon/2.3.7/PPPDebug.Mod


text:
Oberon/ETH Oberon/2.3.7/PPPFSM.Mod

(* ETH Oberon, Copyright 1990-2003 Computer Systems Institute, ETH Zurich, CH-8092 Zurich. Refer to the license.txt file provided with this distribution. *) MODULE PPPFSM;	(** non-portable *) (* $VCS  2, Edgar.Schwarz@z.zgs.de, 5 Sep 99, 13:46:21 $     $Log$ $   2, Edgar.Schwarz@z.zgs.de, 5 Sep 99, 13:46:21 log message for echo reply addes $   1, Edgar.Schwarz@z.zgs.de, 28 Feb 99, 22:15:39 version for PPP 1.0.0 *) IMPORT HDLC := PPPHDLC, Debug := PPPDebug, Tools := PPPTools; CONST (** CP (LCP, IPCP, etc.) codes *) ConfReq* = 1;	(* configuration request *) ConfAck* = 2;	(* configuration ack *) ConfNak* = 3;	(* configuration nak *) ConfRej* = 4;	(* configuration reject *) TermReq = 5;	(* termination request *) TermAck = 6;	(* termination ack *) CodeRej = 7;	(* code reject *) ProtRej = 8; 	(* protocol reject *) EchoReq = 9; EchoReply = 10; (** Link states *) Initial* = 0;	(* down, hasn't been opened *) Starting* = 1;	(* down, been opened *) Closed* = 2;	(* up, hasn't been opened *) Stopped* = 3;	(* open, waiting for down event *) Closing* = 4;	(* Terminating the connection, not open *) Stopping* = 5;	(* terminating, but open *) ReqSent* = 6;	(* we've sent a config request *) AckRcvd* = 7;	(* we've received a config ack *) AckSent* = 8;	(* we've sent a config ack *) Opened* = 9;	(* connection available *) (** Flags *) Passive* = 0;	(* don't die if we don't get a response *) Restart* = 1;	(* treat second Open as Down, Up *) Silent* = 2;	(* wait for peer to speak first *) (** Timeouts *) DefTimeout* = 30000;	(* timeout time in milliseconds *) DefMaxTermReqs* = 2;	(* maximum terminate-request transmissions *) DefMaxConfReqs* = 10;	(* maximum configure-request transmissions *) DefMaxNakLoops* = 10;	(* maximum # of nak loops *) HeaderLen = 4;	(* code(1) + id(1) + len(2) = HeaderLen of a CP-Packet *) StartPos = HDLC.StartPos + HDLC.HDLCHeaderLen + HeaderLen; newtransmit = TRUE; retransmit = FALSE; StrLen* = 33; TYPE Params = POINTER TO ParamsDesc; FSM* = POINTER TO FSMDesc; FSMDesc* = RECORD Protocol*: INTEGER;	ProtoName*: ARRAY 32 OF CHAR; State*: SHORTINT; Flags*: SET; ID*, reqID*: SHORTINT;	(* unsigned char *) TimeoutTime: LONGINT; MaxConfReqTransmits*, Retransmits*, MaxTermTransmits*, NakLoops*, MaxNakLoops*: INTEGER; (* Callback Procedures *) ResetCI*: PROCEDURE (f: FSM); CILen*: PROCEDURE (f: FSM): INTEGER; AddCI*: PROCEDURE (f: FSM; VAR p: ARRAY OF CHAR; pos: INTEGER; VAR len: INTEGER); AckCI*: PROCEDURE (f: FSM; VAR p: ARRAY OF CHAR; pos, len: INTEGER): BOOLEAN; NakCI*: PROCEDURE (f: FSM; VAR p: ARRAY OF CHAR; pos, len: INTEGER): BOOLEAN; RejCI*: PROCEDURE (f: FSM; VAR p: ARRAY OF CHAR; pos, len: INTEGER): BOOLEAN; ReqCI*: PROCEDURE (f: FSM; VAR p: ARRAY OF CHAR; VAR pos, len: INTEGER; mode: BOOLEAN): SHORTINT; Up*: PROCEDURE (f: FSM); Down*: PROCEDURE (f: FSM); (*		Starting*: PROCEDURE (f: FSM); *) (*		Finished*: PROCEDURE (f: FSM); *) ExtCode*: PROCEDURE (f: FSM; code, id:SHORTINT; VAR inp: ARRAY OF CHAR; pos, len: INTEGER): BOOLEAN; HDLCConfig*: HDLC.PPPUnit; params: Params; END; ParamsDesc = RECORD (HDLC.ParamsDesc) f:FSM END; String* = ARRAY StrLen OF CHAR; VAR ActTimeout*:LONGINT; ActMaxConfReqs*:INTEGER; PROCEDURE ^ Init* (f: FSM); PROCEDURE ^ LowerUp* (f: FSM); PROCEDURE ^ LowerDown* (f: FSM); PROCEDURE ^ Open* (f: FSM); PROCEDURE ^ Close* (f: FSM); PROCEDURE ^ Timeout (params: HDLC.Params); PROCEDURE ^ Input* (f: FSM; VAR p: ARRAY OF CHAR; pos, len: INTEGER); PROCEDURE ^ ReceiveConfReq* (f: FSM; id: SHORTINT; 						VAR p: ARRAY OF CHAR; pos, len: INTEGER); PROCEDURE ^ ReceiveConfAck* (f: FSM; id: SHORTINT; 						VAR p:  ARRAY OF CHAR; pos, len: INTEGER); PROCEDURE ^ ReceiveConfNakRej* (f: FSM; code, id: SHORTINT; 						VAR p: ARRAY OF CHAR; pos, len: INTEGER); PROCEDURE ^ ReceiveTermReq* (f: FSM; id: SHORTINT); PROCEDURE ^ ReceiveTermAck* (f: FSM); PROCEDURE ^ ReceiveCodeRej* (f: FSM; VAR p: ARRAY OF CHAR; 						pos, len: INTEGER); PROCEDURE ^ ProtReject* (f: FSM); PROCEDURE ^ SendConfReq* (f: FSM; retransmit: BOOLEAN); PROCEDURE ^ SendData* (f: FSM; code, id: SHORTINT; 						VAR p: ARRAY OF CHAR; pos, len: INTEGER); PROCEDURE OutLog* (text1, text2:ARRAY OF CHAR; f:FSM) ; BEGIN Debug.String(text1); Debug.Ln; IF text2 # "" THEN Debug.String(text2); Debug.Ln; END; Debug.String("protocol: "); Debug.String(f.ProtoName); Debug.String(" -  channel: "); Debug.String(f.HDLCConfig.cname); Debug.Ln; END OutLog; PROCEDURE OutCode* (code: SHORTINT); BEGIN Debug.String("code: "); CASE code OF 		  ConfReq:	Debug.String("ConfReq") | ConfAck:	Debug.String("ConfAck") | ConfNak:	Debug.String("ConfNak") | ConfRej:	Debug.String("ConfRej") | TermReq:	Debug.String("TermReq") | TermAck:	Debug.String("TermAck") | CodeRej:	Debug.String("CodeRej") | ProtRej:	Debug.String("ProtocolRej") | EchoReply: Debug.String("EchoReply") ELSE	Debug.String("*** illegal code ***"); Debug.Int(code, 4); END; Debug.Ln END OutCode; PROCEDURE GiveState*(state: SHORTINT; VAR s: String); BEGIN CASE state OF 		  Initial:		s:="Initial";	| Starting:	s:="Starting"; | Closed:		s:="Closed";	| Stopped:	s:="Stopped"; | Closing:		s:="Closing"; | Stopping:	s:="Stopping"; | ReqSent:	s:="ReqSent";	| AckRcvd:	s:="AckRcvd"; | AckSent:	s:="AckSent"; | Opened:	s:="Opened"; ELSE	s:=" *** unknown state ***"; END; END GiveState; PROCEDURE OutState* (state: SHORTINT); VAR s: String; BEGIN Debug.String("state: "); GiveState(state, s); Debug.String(s); Debug.Ln END OutState; (* Init FSM *) PROCEDURE Init* (f: FSM); BEGIN f.State := Initial;	f.Flags := {};	f.ID := 0;	(* f.reqID set later *) f.TimeoutTime := ActTimeout; f.MaxConfReqTransmits := ActMaxConfReqs; f.MaxTermTransmits := DefMaxTermReqs; f.MaxNakLoops := DefMaxNakLoops; NEW(f.params); f.params.f:=f; END Init; (* The lower layer is up *) PROCEDURE LowerUp* (f: FSM); BEGIN IF HDLC.debug THEN OutLog("FSM.LowerUp","",f); OutState(f.State); Debug.Ln; END; CASE f.State OF 		  Initial:	f.State := Closed | Starting: IF Silent IN f.Flags THEN f.State := Stopped ELSE SendConfReq(f, newtransmit); f.State := ReqSent	(* send an initial configure-request *) END ELSE OutLog("FSM.LowerUp","ERROR: in wrong state",f); OutState(f.State); Debug.Ln; END END LowerUp; (* The lower layer is down - cancel all timeouts and inform upper layers *) PROCEDURE LowerDown* (f: FSM); BEGIN IF HDLC.debug THEN OutLog("FSM.LowerDown","",f); OutState(f.State); Debug.Ln; END; CASE f.State OF 		  Closed:	f.State := Initial | Stopped:	f.State := Starting (* ; f.Starting (f) *) | Closing:	f.State := Initial; HDLC.UNTIMEOUT(f.HDLCConfig, Timeout)	(* cancel timeout *) | Stopping, ReqSent, AckRcvd, AckSent:	f.State := Starting; HDLC.UNTIMEOUT(f.HDLCConfig, Timeout)	(* cancel timeout *) | Opened:	f.Down(f); f.State := Starting ELSE OutLog("FSM.LowerDown", "ERROR: in wrong state", f); OutState(f.State); Debug.Ln 	END END LowerDown; (* Link is allowed to come up *) PROCEDURE Open* (f: FSM); BEGIN IF HDLC.debug THEN OutLog("FSM.Open","",f); OutState(f.State); Debug.Ln; END; CASE f.State OF 		  Initial:	f.State := Starting; (* f.Starting(f) *) | Closed: IF Silent IN f.Flags THEN f.State := Stopped ELSE SendConfReq(f, newtransmit); f.State := ReqSent;	(* send an initial configure-request *) END | Closing:	f.State := Stopping; IF Restart IN f.Flags THEN LowerDown(f); LowerUp(f) END | Stopped, Opened:	IF Restart IN f.Flags THEN LowerDown(f); LowerUp(f) END ELSE END END Open; (* Start closing connection *) PROCEDURE Close* (f: FSM); VAR p: ARRAY HDLC.ArrayLength OF CHAR; BEGIN IF HDLC.debug THEN OutLog("FSM.Close","",f); OutState(f.State); Debug.Ln; END; CASE f.State OF 		  Starting:	f.State := Initial | Stopped:	f.State := Closed | Stopping:	f.State := Closing | ReqSent, AckRcvd, AckSent, Opened: IF f.State # Opened THEN HDLC.UNTIMEOUT(f.HDLCConfig, Timeout)	(* cancel timeout *) ELSE f.Down(f)	(* inform upper layers we're down *) END; f.Retransmits := f.MaxTermTransmits; INC(f.ID); f.reqID := f.ID; SendData(f, TermReq, f.reqID, p, StartPos, 4); HDLC.TIMEOUT(f.HDLCConfig, Timeout, f.params, f.TimeoutTime); DEC(f.Retransmits); f.State := Closing ELSE END END Close; (* Timeout expired *) PROCEDURE Timeout (params: HDLC.Params); VAR f: FSM; BEGIN f := params(Params).f; 	IF HDLC.debug THEN OutLog("FSM.TimeOut","TimeOut-Handler called",f); OutState(f.State); Debug.Ln; END; CASE f.State OF 		  Closing, Stopping: IF f.Retransmits <= 0 THEN	(* we've waited for an ack long enough, peer probably heard us *) IF f.State = Closing THEN f.State := Closed ELSE f.State := Stopped END; (* f.Finished(f) *) ELSE	(* send terminate-request *) INC(f.ID); f.reqID := f.ID; SendData(f, TermReq, f.reqID, f.HDLCConfig.data2, StartPos, 0); HDLC.TIMEOUT(f.HDLCConfig, Timeout, params, f.TimeoutTime); DEC(f.Retransmits) END | ReqSent, AckRcvd, AckSent: IF f.Retransmits <= 0 THEN OutLog("LOG: FSM.Timeout", "Stop: sended all TimeOuts, no answer", f); Debug.Ln; f.State := Stopped; (* IF ~(Passive IN f.Flags) THEN f.Finished(f) END *) ELSE	(* retransmit the configure-request *) SendConfReq(f, retransmit); IF f.State = AckRcvd THEN f.State := ReqSent END END ELSE IF HDLC.debug THEN OutLog("FSM.Timeout", "ERROR:in wrong state", f); OutState(f.State); Debug.Ln; END END END Timeout; (* Input packet *) PROCEDURE Input* (f: FSM; VAR p: ARRAY OF CHAR; pos, len: INTEGER); VAR code, id: SHORTINT; size: INTEGER; BEGIN (* parse header (code, id and length). if packet too short, drop it. *) IF HDLC.debug THEN OutLog("FSM.Input","new Input",f); OutState(f.State); Debug.Ln; Tools.OutPacket(p, pos, len); Debug.Ln; END; IF len < HeaderLen THEN IF HDLC.debug THEN OutLog("FSM.Input", "ERROR: Received short header", f); END; RETURN END; code := SHORT(ORD(p[pos])); id := SHORT(ORD(p[pos + 1])); size := Tools.GetInt(p, pos + 2); IF size < HeaderLen THEN IF HDLC.debug THEN OutLog("FSM.Input", "ERROR: Received illegal length", f); END; RETURN END; IF size < len THEN IF HDLC.debug THEN OutLog("FSM.Input", "ERROR: Received short packet", f); END; RETURN END; DEC(size, HeaderLen); INC(pos, HeaderLen); IF (f.State = Initial) OR (f.State = Starting) THEN IF HDLC.debug THEN OutLog("FSM.Input", "ERROR: Received packet in wrong state", f); OutState(f.State); Debug.Ln; END; RETURN END; (* action depends on code *) CASE code OF 		  ConfReq:	ReceiveConfReq(f, id, p, pos, size) | ConfAck:	ReceiveConfAck(f, id, p, pos, size) | ConfNak, ConfRej:	ReceiveConfNakRej(f, code, id, p, pos, size) | TermReq:	ReceiveTermReq(f, id) | TermAck:	ReceiveTermAck(f) | CodeRej:	ReceiveCodeRej(f, p, pos, size) ELSE IF ~f.ExtCode(f, code, id, p, pos, size) THEN INC(f.ID); SendData(f, CodeRej, f.ID, p, pos - HeaderLen, size + HeaderLen) END END END Input; (* Receive Configure-Request *) PROCEDURE ReceiveConfReq* (f: FSM; id: SHORTINT; 						VAR p: ARRAY OF CHAR; pos, len: INTEGER); VAR code: SHORTINT; RejectIfDisagree: BOOLEAN; BEGIN IF HDLC.debug THEN OutLog("FSM.ReceiveConfigureRequest", "", f); Debug.String("id: "); Debug.Int(id, 4); Debug.Ln; Debug.Ln 	END; CASE f.State OF 		  Closed:	SendData(f, TermAck, id, p, StartPos, 0); RETURN	(* go away, we're closed *) | Closing, Stopping:	RETURN | Opened:	f.Down(f); SendConfReq(f, newtransmit) (* go down and restart negotiation, inform upper layers, 					send initial configure-request *) | Stopped:	SendConfReq(f, newtransmit); f.State := ReqSent; (* send initial configure-request *) ELSE END; (* pass the requested configuration options to protocol-specific code for checking *) RejectIfDisagree := f.NakLoops >= f.MaxNakLoops; code := f.ReqCI(f, p, pos, len, RejectIfDisagree); (* send the Ack, Nak or Rej to the peer *) SendData(f, code, id, p, pos, len); IF code = ConfAck THEN IF f.State = AckRcvd THEN HDLC.UNTIMEOUT(f.HDLCConfig, Timeout); f.State := Opened; f.Up(f) ELSE f.State := AckSent; f.NakLoops := 0 END ELSE	(* we sent ConfAck or ConfRej *) IF f.State # AckRcvd THEN f.State := ReqSent END; IF code = ConfNak THEN INC(f.NakLoops) END; END END ReceiveConfReq; (* Receive Configure-Ack *) PROCEDURE ReceiveConfAck* (f: FSM; id: SHORTINT; VAR p: ARRAY OF CHAR; pos, len: INTEGER); BEGIN IF HDLC.debug THEN OutLog("FSM.ReceiveConfAck", "", f); Debug.String("id: "); Debug.Int(id, 4); Debug.Ln; Debug.Ln END; IF (id=f.reqID) & f.AckCI(f, p, pos, len) THEN f.reqID := -1; CASE f.State OF 			  Closed, Stopped:	SendData(f, TermAck, id, p, StartPos, 0) | ReqSent:	f.State := AckRcvd; f.Retransmits := f.MaxConfReqTransmits | AckRcvd:	SendConfReq(f, newtransmit); f.State := ReqSent	(* huh?, an extra Ack? oh well... *) | AckSent:	HDLC.UNTIMEOUT(f.HDLCConfig, Timeout);	(* cancel timeout *) f.State := Opened; f.Retransmits := f.MaxConfReqTransmits; f.Up(f) | Opened:	(* go down and restart negotiation *) f.Down(f); SendConfReq(f, newtransmit); f.State := ReqSent ELSE END END END ReceiveConfAck; (* Receive Configure-Nak or Configure-Reject *) PROCEDURE ReceiveConfNakRej* (f: FSM; code, id: SHORTINT; VAR p: ARRAY OF CHAR; pos, len: INTEGER); BEGIN IF HDLC.debug THEN OutLog("FSM.ReceiveConfigureNak/Reject", "", f); Debug.String("id: "); Debug.Int(id, 4); Debug.Ln; Debug.Ln 	END; IF id # f.reqID THEN RETURN END;	(* expected ID? nope -> toss... *) IF ((code = ConfNak) & ~f.NakCI(f, p, pos, len)) OR ((code=ConfRej) & ~f.RejCI(f, p, pos, len)) THEN	(* Nak/Reject is bad - ignore it *) IF HDLC.debug THEN OutLog("FSM.ReceiveConfNakRej", "ERROR: Received bad Nak/Rej", f); Debug.String("id: "); Debug.Int(f.ID, 4); Debug.Ln; OutCode(code); Debug.Ln; RETURN END END; f.reqID := -1; CASE f.State OF 		  Closed, Stopped:	SendData(f, TermAck, id, p, StartPos, 0) | ReqSent, AckSent:	HDLC.UNTIMEOUT(f.HDLCConfig, Timeout); SendConfReq(f, newtransmit)	(* They didn't agree to what we wanted - try another request *) | AckRcvd:	SendConfReq(f, newtransmit); f.State := ReqSent	(* got a Nak/Reject when we had already had an Ack?? oh well... *) | Opened:	(* go down and restart negotiation *) f.Down(f); SendConfReq(f, newtransmit); f.State := ReqSent ELSE END END ReceiveConfNakRej; (* Receive Terminate-Request *) PROCEDURE ReceiveTermReq* (f: FSM; id: SHORTINT); VAR p: ARRAY HDLC.ArrayLength OF CHAR; BEGIN IF HDLC.debug THEN OutLog("FSM.ReceiveTermReq", "", f); Debug.String("id: "); Debug.Int(id, 4); Debug.Ln; Debug.Ln END; CASE f.State OF 		  AckRcvd, AckSent:	f.State := ReqSent | Opened: OutLog("FSM.ReceiveTermReq", "Terminated at peer's request", f); f.Down(f); f.Retransmits := 0; f.State := Stopping; HDLC.TIMEOUT(f.HDLCConfig, Timeout, f.params, f.TimeoutTime) ELSE END; SendData(f, TermAck, id, p, StartPos, 0) END ReceiveTermReq; (* Receive Terminate-Ack *) PROCEDURE ReceiveTermAck* (f: FSM); BEGIN IF HDLC.debug THEN OutLog("FSM.ReceiveTermAck", "", f); Debug.Ln; END; CASE f.State OF 		  Closing:	f.State := Closed (* ; IF f.Finished # NIL THEN f.Finished(f) END *) | Stopping:	f.State := Stopped (* ; IF f.Finished # NIL THEN f.Finished(f) END *) | AckRcvd:	f.State := ReqSent | Opened:	f.Down(f); SendConfReq(f, newtransmit) ELSE END END ReceiveTermAck; (* Receive a Code-Reject *) PROCEDURE ReceiveCodeRej* (f: FSM; VAR p: ARRAY OF CHAR; pos, len: INTEGER); VAR code, id: SHORTINT; BEGIN IF len < HeaderLen THEN IF HDLC.debug THEN OutLog("FSM.ReceiveCodeRej", "ERROR: too short", f); Debug.Ln; END; RETURN END; code := SHORT(ORD(p[pos])); id := SHORT(ORD(p[pos + 1]));	(* syslog *) IF HDLC.debug THEN OutLog("FSM.ReceiveCodeRej", "Received Code-Reject", f); OutCode(code); Debug.String("id: "); Debug.Int(id, 4); Debug.Ln; Debug.Ln; END; IF f.State = AckRcvd THEN f.State := ReqSent END END ReceiveCodeRej; (* Peer doesn't speak this protocol - Treat this as a catastrophic error (RXJ-)*) PROCEDURE ProtReject* (f: FSM); VAR p: ARRAY HDLC.ArrayLength OF CHAR; BEGIN IF HDLC.debug THEN OutLog("FSM.ProtReject", "", f); Debug.Ln; END; CASE f.State OF 		  Closing:	HDLC.UNTIMEOUT(f.HDLCConfig, Timeout); f.State := Closed; (* IF f.Finished # NIL THEN f.Finished(f) END *) | Closed:	f.State := Closed; (* IF f.Finished # NIL THEN f.Finished(f) END *) | Stopping, ReqSent, AckRcvd, AckSent:	HDLC.UNTIMEOUT(f.HDLCConfig, Timeout); f.State := Stopped (* ; IF f.Finished # NIL THEN f.Finished(f) END *) | Stopped:	f.State := Stopped (* IF f.Finished # NIL THEN f.Finished(f) END *) | Opened:	f.Down(f); (* init restart counter, send terminate-request *) f.Retransmits := f.MaxTermTransmits; INC(f.ID); f.reqID := f.ID; SendData(f, TermReq, f.reqID, p, StartPos, 0); HDLC.TIMEOUT(f.HDLCConfig, Timeout, f.params, f.TimeoutTime); DEC(f.Retransmits); f.State := Stopping ELSE IF HDLC.debug THEN OutLog("FSM.ProtReject", "ERROR: in wrong state", f); OutState(f.State); Debug.Ln END END END ProtReject; (* Send a Configure-Request *) PROCEDURE SendConfReq* (f: FSM; retransmit: BOOLEAN); VAR pos: INTEGER; CILen: INTEGER; p: ARRAY HDLC.ArrayLength OF CHAR; BEGIN IF (f.State # ReqSent) & (f.State # AckRcvd) & (f.State # AckSent) THEN (* not currently negotiating - reset options *) f.ResetCI(f); f.NakLoops := 0 END; IF retransmit THEN (* new request - reset transmission counter, use new ID *) f.Retransmits := f.MaxConfReqTransmits; INC(f.ID); f.reqID := f.ID 	END; IF HDLC.debug THEN OutLog("FSM.SendConfReq", "", f); Debug.String("id: "); Debug.Int(f.reqID, 4); Debug.String("   "); OutState(f.State); Debug.Ln; Debug.Ln END; (* make up a request packet *) pos := StartPos; IF f.CILen(f) < f.HDLCConfig.MTU - HeaderLen THEN f.AddCI(f, p, pos, CILen) ELSE OutLog("FSM.SendConfReq", "ERROR: Configure Request too big", f); RETURN END; (* send the request to our peer *) SendData(f, ConfReq, f.reqID, p, pos, CILen); (* start the retransmit timer *) DEC(f.Retransmits); HDLC.TIMEOUT(f.HDLCConfig, Timeout, f.params, f.TimeoutTime); END SendConfReq; (* SendData - Create a packet with code, id and data, 	data is in p[pos .. pos+len] *) PROCEDURE SendData* (f: FSM; code, id: SHORTINT; 												VAR p: ARRAY OF CHAR; pos, len: INTEGER); VAR minpos, maxlen: INTEGER; BEGIN maxlen:=f.HDLCConfig.MTU - HeaderLen; IF len > maxlen THEN len := maxlen; END; (* adjust length (of information + padding) to be smaller than MTU *) minpos:=HDLC.HDLCHeaderLen+HeaderLen; IF pos<minpos THEN Tools.CopyString(p, pos, minpos, len); pos:=minpos; END; DEC(pos, HeaderLen); INC(len, HeaderLen); p[pos]:=CHR(code); p[pos+1]:=CHR(id); Tools.PutInt(len, p, pos+2); IF HDLC.debug THEN OutLog("FSM.SendData", "", f); OutCode(code); OutState(f.State); Debug.String("id: "); Debug.Int(id, 4); Debug.Ln; Tools.OutPacket(p, pos, len); Debug.Ln; END; HDLC.SendPacket(f.HDLCConfig, f.Protocol, p, pos, len); END SendData; BEGIN ActTimeout:=DefTimeout; ActMaxConfReqs:=DefMaxConfReqs END PPPFSM.

title: Oberon/ETH Oberon/2.3.7/PPPFSM.Mod


text:
Oberon/ETH Oberon/2.3.7/PPPHDLC.Mod

(* ETH Oberon, Copyright 1990-2003 Computer Systems Institute, ETH Zurich, CH-8092 Zurich. Refer to the license.txt file provided with this distribution. *) (* $VCS  1, Edgar.Schwarz@z.zgs.de, 28 Feb 99, 22:13:54 $ *) MODULE PPPHDLC;	(** non-portable *) (* $Log$ $  1, Edgar.Schwarz@z.zgs.de, 28 Feb 99, 22:13:54 version for PPP 1.0.0 *) IMPORT Debug := PPPDebug, SYSTEM, T:=PPPTools, (*es*) Oberon, Ker:=Kernel, V24, PT := NetBase, Input, Out, Strings; (* Ker:=PPCXOKernel, P:=Peripherals; *) CONST HDLCAddress=0FFX; HDLCControl=03X; HDLCHeaderLen* = 4;	(* Flag + Address, Protocol (2 Byte) *) EscSymbol = 7DX; FlagSymbol = 7EX; MTU*=1500; StartPos*=4;	(* even if we received a packed Packet, we can send back an unpacked one, using the same array *) ArrayLength* = MTU+100;	(* some bytes more needed *) TYPE Params* = POINTER TO ParamsDesc; ParamsDesc* = RECORD END; CallbackProc*=PROCEDURE (p:Params); TimeOut = POINTER TO TimeOutDesc; TimeOutDesc = RECORD time: LONGINT; callback: CallbackProc;	params: Params; next: TimeOut; END; PPPUnit* = POINTER TO PPPUnitDesc; MyTask* = POINTER TO MyTaskDesc; MyTaskDesc = RECORD (*es*) (Oberon.TaskDesc) (* (Ker.MainEventDesc) (* Oberon.TaskDesc *) *) Config*:PPPUnit; END; PPPUnitDesc* = RECORD MTU*, MRU*:INTEGER;		(* Maximum Transmit Unit, how big our packets are; M Receive U, how big he may send*) SendAsyncMap*:SET;		(* Transmit AsyncMap; What characters have to be stuffed *) (*es*) c*: LONGINT; (* c*: P.SerialChannel; *) cname*:ARRAY 32 OF CHAR; task*: MyTask; data, data2*: ARRAY ArrayLength OF CHAR; TOqueue: TimeOut; TOempty: BOOLEAN; END; VAR (*es*) debug*: BOOLEAN; TOtask: Oberon.Task; (* check for timeout *) TOunit: PPPUnit; (* instead of extending task *) (*TOrecycle: TimeOut;*) (*es*) (* save uncomplete frames between calls to Reveive *) receiveFrame: RECORD active: BOOLEAN; (* ready to receive data *) (*deadline: LONGINT; (* until we want to receive the end *)*) i: INTEGER; (* index of last received byte in receive buffer *) esc: BOOLEAN; (* last byte received was EscSymbol *) END; (**)PPPHandleReceive*: PROCEDURE (U:PPPUnit; prot:INTEGER; VAR p: ARRAY OF CHAR; 			pos, len:INTEGER; VAR prno: INTEGER; VAR item: PT.Item); PROCEDURE SendString(c: (*es*)LONGINT(*P.SerialChannel*); 												VAR s: ARRAY OF CHAR); VAR l0, l1, start: LONGINT; (*es*)res: LONGINT;(**) BEGIN l0 := 0; WHILE s[l0] # 0X DO INC(l0) END; l1 := l0; start := 0; (*es*) WHILE l0 > 0 DO 			V24.SendBytes(c, s, l1, res); DEC(l0, l1); END (*	WHILE l0 > 0 DO 			c.Write(s, start, l1); 			DEC(l0, l1); INC(start, l1) 		END *) END SendString; (* Init *) PROCEDURE Init* (Config:PPPUnit; 									c:(*es*)LONGINT(* P.SerialChannel*);  						VAR cname, sstr, loginname, loginpasswd: ARRAY OF CHAR); VAR to:TimeOut; l: LONGINT; temp: ARRAY 4 OF CHAR; cr: ARRAY 2 OF CHAR; (*es*)res: LONGINT;(**) BEGIN Config.c := c; COPY(cname, Config.cname); (*es??? die V24 und Loginsachen macht doch der Dialer. Oder ? 		(* clear input-buffer *) 		WHILE V24.Available(c) > 0 DO V24.Receive(c, temp[0],res); END; 		(* WHILE c.Available > 0 DO l := 1; c.Read(temp, 0, l) END; *) 		(* send start string *) 		IF sstr[0] # 0X THEN 			SendString(c, sstr); 			(* consume some bytes (they contain the reply string from server) *) 			REPEAT 				WHILE c.Available > 0 DO l := 1; c.Read(temp, 0, l) END; 				Ker.Sleep(1, Ker.ONEsec) 			UNTIL c.Available = 0 		END; 		IF loginname[0] # 0X THEN	(* start normal unix-login procedure *) 			cr[0] := 0DX; cr[1] := 0X; 			(* send two CR *) 			SendString(c, cr); Ker.Sleep(1, Ker.ONEsec); 			SendString(c, cr); Ker.Sleep(5,Ker.ONEsec); 			(* send loginname *) 			SendString(c, loginname); SendString(c, cr); 			Ker.Sleep(1, Ker.ONEsec); 			(* send loginpasswd *) 			SendString(c, loginpasswd); SendString(c, cr); 			Ker.Sleep(1, Ker.ONEsec); END; REPEAT WHILE c.Available > 0 DO 				l := 1; c.Read(temp, 0, l); Debug.Int(ORD(temp[0]),4); IF (temp[0] >= 20X) & (temp[0] <= 7FX) THEN Debug.Char(9X); Debug.Char(temp[0]) END; Debug.Ln; END; Ker.Sleep(5,Ker.ONEsec); Debug.Ln; UNTIL c.Available = 0; es*) 		Debug.String(" Starting receiving-loop"); Debug.Ln; 		NEW(Config.task); Config.task.Config:=Config;	 		(*es???*) Debug.String("Pustekuchen, macht Devicepolling"); Debug.Ln; 		(*Ker.InitMain(Config.task);*) 		NEW(to); Config.TOqueue:=to; to.next:=to; 		to.time:=MAX(LONGINT); Config.TOempty:=TRUE;	(* sentinel *) 	END Init; 	PROCEDURE CheckTimer((*es*)me: Oberon.Task(*C: PPPUnit*)); 	(* Called only when TOqueue is not empty *) 		VAR cur:TimeOut; 	BEGIN 		cur:=(*es*)TOunit(*C*).TOqueue;  		IF cur.time < (*es*)Input.Time(*Ker.Time*) THEN   (*es*)  Oberon.Remove(me);  			IF TOunit.cname # "" THEN 				(* output only if ppp is still running. See PPPMain.StopInst *) 				Out.String("PPP timeout"); Out.Ln; 			END; (**) 			(*es*)TOunit(*C*).TOempty:=TRUE; 			cur.callback(cur.params); 		END 	END CheckTimer; 	(* TimeOut Handling *) 	PROCEDURE TIMEOUT* (C: PPPUnit; callb:CallbackProc; p:Params; msec:LONGINT); (* msec: in microS-sec *) 	VAR cur:TimeOut; 	BEGIN 		cur:=C.TOqueue; cur.callback:=callb; cur.params:=p; 		cur.time:=(*es*) Input.Time(*Ker.Time*)+msec;	 		C.TOempty:=FALSE; 		(*es install timer task *) 		TOtask.safe := FALSE; TOtask.time := 0; 		TOtask.handle := CheckTimer; 		Oberon.Install(TOtask); 		TOunit := C; 		(**) 	END TIMEOUT; 	PROCEDURE UNTIMEOUT* (C: PPPUnit; callb:CallbackProc); 	BEGIN	 		C.TOempty:=TRUE; 		(*es*) Oberon.Remove(TOtask); (**) 	END UNTIMEOUT; 	(* CheckPacket - Check  a HDLC-Packet *) 	PROCEDURE CheckPacket(Config: PPPUnit; VAR p: ARRAY OF CHAR; pos, len:INTEGER; VAR prno: INTEGER; VAR item: PT.Item);    (*es*)VAR timeStr: ARRAY 16 OF CHAR; time, date: LONGINT;(**) 	BEGIN 		IF debug THEN 			Oberon.GetClock(time, date); 			Strings.TimeToStr(time,timeStr); Debug.String(timeStr);  			Debug.String('CheckPacket: len='); Debug.Int(len, 5); Debug.Ln;  			T.OutPacket(p, pos, len); 		END; 		IF len > HDLCHeaderLen+2 THEN  			(*[HDLC_Address+HDLC-Control+Protocol] + Checksum (2 Bytes)*) 			IF T.CheckFCS(p, pos, len) THEN  				(* CheckSum ok? The whole packet needed! *) 				IF (p[pos] = HDLCAddress) & (p[pos+1] = HDLCControl) THEN 					PPPHandleReceive(Config, T.GetInt(p, pos+2), p, pos+4, len-6, prno, item); 				ELSE (* silently discarded *) 					IF debug THEN 						Debug.String("Address, Code wrong"); Debug.Ln;  					END; 				END 			ELSE 				IF debug THEN Debug.String("Checksum failure"); END 			END 		ELSE  			IF debug & (len > 0) THEN  				Debug.String("Length too short, length:");  				Debug.Int(len, 6); Debug.Ln;  			END; 		END 	END CheckPacket; 	PROCEDURE XOR20(ch:LONGINT):LONGINT; 	BEGIN RETURN SYSTEM.VAL(LONGINT, (SYSTEM.VAL(SET, ch) / {5} )); 	END XOR20; 	(* ReceivePacket - ReiceiveLoop: Task, needs extended Event (including PPPUnit)*) (*es*) (* ReceivePacket is indirectly called by NetBase.Polldevices when characters at the serial interface are available. So just read the characters into a buffer (Config.data) and return prno=0 (no handler installed for this 	protocol hopefully). When you get end of frame (FlagSymbol) then check it and return the stuff. *) (**)PROCEDURE ReceivePacket*(Config: PPPUnit; VAR prno: INTEGER; VAR item: PT.Item); 	VAR (*es*) (*i:INTEGER;*) 		ch: ARRAY 4 OF CHAR; l: LONGINT; 		(*es*)c, res, endTime: LONGINT; timeOut : TimeOut; 		(* c: P.SerialChannel; *) 	BEGIN 		c:=Config.c; 		(*es*)(* i:=StartPos; ch[0]:=0X;	(* not Esc-Symbol *) *) (*es*)IF receiveFrame.active THEN 			prno := 0; 		ELSE 			(*receiveFrame.deadline := Input.Time + 10(*s*) * Input.TimeUnit;*) 			receiveFrame.i := StartPos; 			receiveFrame.active := TRUE; 			receiveFrame.esc := FALSE; 			ch[0]:=0X; 		END; 		IF receiveFrame.esc THEN ch[0] := EscSymbol ELSE ch[0]:=0X; END; (**) LOOP 			IF (*es*)V24.Available(c)(*c.Available*)>0 THEN		 				(* New chars in buffer ? *) 				IF ch[0] (* last received *) #EscSymbol THEN 					(*es*) V24.Receive(c, ch[0], res); 					(*l := 1; c.Read(ch, 0, l);*) 					IF ch[0] = FlagSymbol THEN (* end of frame received *) 						CheckPacket(Config, Config.data, StartPos, receiveFrame.i-StartPos, prno, item); (*es*)			 (* data now in item *) receiveFrame.active := FALSE; RETURN; 						(* receiveFrame.i:=StartPos; *) 					ELSE 						IF ch[0] # EscSymbol THEN  							Config.data[receiveFrame.i]:=ch[0];  							INC(receiveFrame.i) ; (*es*)				 receiveFrame.esc := FALSE; 						ELSE 							receiveFrame.esc := TRUE; (**) 				END 					END; 				ELSE 					(*es*) V24.Receive(c, ch[0], res); receiveFrame.esc := FALSE; 					(*l := 1; c.Read(ch, 0, l);*) 					Config.data[receiveFrame.i]:=CHR(XOR20(ORD(ch[0]))); 					INC(receiveFrame.i); ch[0]:=0X; (* not Esc-,or Flag-Symbol *) 				END; 				IF receiveFrame.i>=ArrayLength THEN  					Debug.String("Array Overflow!!");  					 (* HALT(99); *)  					receiveFrame.active := FALSE; RETURN 				END; 			ELSE 				RETURN; (* pause until more characters are available *) (**) 			END; 		END 	END ReceivePacket; 	(* SendPacket - Send a packet to the V24 *) PROCEDURE SendPacket* (Config: PPPUnit; prot:INTEGER; 						VAR p:ARRAY OF CHAR; pos, len:INTEGER); VAR minpos, code, k, begin: INTEGER; ch: ARRAY 4 OF CHAR; l0, l1, start: LONGINT; x: CHAR; (*es*)c, res: LONGINT; timeStr: ARRAY 16 OF CHAR; time, date: LONGINT; (*c: P.SerialChannel;*) BEGIN c:=Config.c; 		minpos:=HDLCHeaderLen; IF pos<minpos THEN T.CopyString(p, pos, minpos, len); pos:=minpos; END;	(* More space needed *) DEC(pos, HDLCHeaderLen); INC(len, HDLCHeaderLen); p[pos]:=0FFX; p[pos+1]:=03X;		(* pos + 0: HDLC_Address = 0FFX; pos + 1: HDLC_Control =3X *) T.PutInt(prot, p, pos+2);				(* pos + 2: Protocol *) code:=T.CalcFCS(p, pos, len); p[pos+len]:=CHR(code MOD 256); p[pos+len+1]:=CHR(SYSTEM.LSH(code, -8)); INC(len, 2); (* insert the checksum *) IF debug THEN Oberon.GetClock(time, date); Strings.TimeToStr(time,timeStr); Debug.String(timeStr); Debug.String('SendPacket: len = '); Debug.Int(len, 5); Debug.Ln; T.OutPacket(p, pos, len); END; (* send it to the V24 *) ch[0]:=FlagSymbol; l0 := 1; l1 := l0; start := 0; WHILE l0 > 0 DO 			(*es*)V24.Send(c,ch[start], res); (* c.Write(ch, start, l1); *) DEC(l0, l1); INC(start, l1) END; (*es auskommentiert: der Trick ist irgendwie alle Zeichen zu sammeln, 	die man ohne Maskierung (EscSymbol) senden kann. Wenn man dann 	auf eines trifft, verpackt man es und schickt die Dinger von zuvor 	auf weg. Das ist mir etwas zu undurchsichtig. 		begin:=pos; 		FOR k:=pos TO pos+len-1 DO	x:=p[k]; 			IF ((ORD(x)<20H) & (ORD(x) IN Config.SendAsyncMap))  			OR (x=EscSymbol) OR (x=FlagSymbol) THEN 				l0 :=k-begin; l1 := l0; start := begin; 				WHILE l0 > 0 DO c.Write(p, start, l1); DEC(l0,l1); INC(start,l1);END; 				begin:=k+1; 				ch[0]:=EscSymbol; ch[1]:=CHR(XOR20(ORD(x)));  				l0 := 2; l1 := l0; start := 0; 				WHILE l0 > 0 DO c.Write(ch, start, l1); DEC(l0,l1); INC(start,l1);END;  			END; 		END; 		p[pos+len]:=FlagSymbol; l0 := pos+len+1-begin; l1 := l0; start := begin;  		WHILE l0 > 0 DO c.Write(p, start, l1); DEC(l0, l1); INC(start, l1); END; *) (*es*) FOR k:=pos TO pos+len-1 DO 			x:=p[k]; IF ((ORD(x)<20H) & (ORD(x) IN Config.SendAsyncMap)) OR (x=EscSymbol) OR (x=FlagSymbol) THEN V24.Send(c,EscSymbol, res); IF res # 0 THEN HALT(99); END; V24.Send(c,CHR(XOR20(ORD(x))), res); IF res # 0 THEN HALT(99); END; ELSE V24.Send(c, x, res); IF res # 0 THEN HALT(99); END; END; END; (* frame complete: send end flag *) V24.Send(c,FlagSymbol, res); IF res # 0 THEN HALT(99); END; (**) 	END SendPacket; BEGIN debug := FALSE; (*es*) receiveFrame.active := FALSE; NEW(TOtask); (*NEW(TOrecycle); TOrecycle.next:=TOrecycle; (* Sentinel *)*) END PPPHDLC.

title: Oberon/ETH Oberon/2.3.7/PPPHDLC.Mod


text:
Oberon/ETH Oberon/2.3.7/PPPIPCP.Mod

(* ETH Oberon, Copyright 1990-2003 Computer Systems Institute, ETH Zurich, CH-8092 Zurich. Refer to the license.txt file provided with this distribution. *) MODULE PPPIPCP;	(** non-portable *) (* $VCS  2, Edgar@EdgarSchwarz.de, 25 Apr :0, 10:42:52 $     $Log$ $   2, Edgar@EdgarSchwarz.de, 25 Apr :0, 10:42:52 no more PT.Equal (pm), ask remote IP if nor available by a NAK $   1, Edgar.Schwarz@z.zgs.de, 28 Feb 99, 22:17:0 version for PPP 1.0.0 *) IMPORT FSM:=PPPFSM, HDLC:=PPPHDLC, PT := (*es*)NetBase, NetIP, (*PacketTools,*) T:=PPPTools, Debug := PPPDebug, SYSTEM; CONST (* Protocol Constants *) IPCP*=-07FDFH;	(* =08021H *) MaxStates=16;		(* Slots for VJ Compression *) (* Configure Information Options *) Addrs = 1;								(* IP-Addresses, old *) CompressType = 2;					(* Compression Type *) Addr = 3;								(* IP Address, new *) (* IPCP codes *) VJCompression = 002DH; (* Options Index *) NegAddrs = 0;	(* Accept old IP-Addresses *) NegAddr = 2;		(* Accept Address *) NegVJ = 8; 			(* Accept Van Jacobsen Header Compression *) (* Length of the Configuration Options *) VoidLen = 2; CompressLen = 4; VJLen = 6; AddrLen = 6; AddrsLen = 10; 	(* = Type (1 Byte) + Length (1 Byte) + Data *) TYPE Options*=RECORD O*: SET								(* Bits defined by Options Index *); OurAddress*, HisAddress*: (*es*)NetIP.Adr(*PT.IPAdr*); CompressProt*: INTEGER;	MaxSlot*, CFlag*: SHORTINT;		(* VJ Stuff *) END; IPCPfsm*=POINTER TO IPCPfsmDesc; IPCPfsmDesc=RECORD (FSM.FSMDesc) wo*, go(*es*)*(*-*), ao*, ho(*es*)*(*-*): Options; (* WantOptions, GotOptions, AllowOptions, HisOptions *) AcceptLocal, AcceptRemote: BOOLEAN; (* Accept his proposal for our IP_address / for his IP_address *) END; VAR (* Upcalls to PPP *) PPPHandleIPCPUp*: PROCEDURE (U:HDLC.PPPUnit); PPPHandleIPCPDown*: PROCEDURE (U:HDLC.PPPUnit); ZeroIP*: (*es*)NetIP.Adr(*PT.IPAdr*); i: INTEGER; (* Open - IPCP can come up *) PROCEDURE Open* (f: IPCPfsm); BEGIN f.Flags:={}; FSM.Open(f) END Open; (* Close - Take IPCP down *) PROCEDURE Close* (f: IPCPfsm); BEGIN FSM.Close(f) END Close; (* LowerUp - The Lower Layer is Up *) PROCEDURE LowerUp* (f: IPCPfsm); BEGIN FSM.LowerUp(f) END LowerUp; (* LowerDown - The Lower Layer is Down *) PROCEDURE LowerDown* (f: IPCPfsm); BEGIN FSM.LowerDown(f) END LowerDown; (* Input - New IPCP Packet *) PROCEDURE Input* (f: IPCPfsm; VAR p: ARRAY OF CHAR; pos, len:INTEGER); BEGIN FSM.Input(f, p, pos, len); END Input; (* RecProtRej - Protocol Reject received, pretend his lower layer went down, so we do the same *) PROCEDURE *RecProtRej(f: FSM.FSM; VAR p: ARRAY OF CHAR; pos, len:INTEGER); BEGIN FSM.LowerUp(f) END RecProtRej; (* ResetCI - Reset The Configuration Information *) PROCEDURE *ResetCI (f: FSM.FSM); BEGIN WITH f:IPCPfsm DO 			f.AcceptLocal:=SYSTEM.VAL(LONGINT, f.wo.OurAddress) = SYSTEM.VAL(LONGINT, ZeroIP); f.AcceptRemote:=SYSTEM.VAL(LONGINT, f.wo.HisAddress) = SYSTEM.VAL(LONGINT, ZeroIP); f.go:=f.wo;		(* GotOptions := WantOptions *) END END ResetCI; (* CIlen - Returns Length of the Conf. Inf. *) PROCEDURE *CILen (f: FSM.FSM): INTEGER; VAR i:INTEGER; BEGIN i:=0; WITH f:IPCPfsm DO 			IF (NegAddrs IN f.go.O) THEN INC(i, AddrsLen); END; IF (NegAddr IN f.go.O) THEN INC(i, AddrLen); END; IF (NegVJ IN f.go.O) THEN INC(i, VJLen); END;	(* To update if more Options supported *) END; RETURN i 	END CILen; (* AddCI - Add our desired Conf. Inf. to a packet (at pos) *) PROCEDURE *AddCI (f: FSM.FSM; VAR p: ARRAY OF CHAR; pos: INTEGER; VAR len: INTEGER); BEGIN len:=0; WITH f:IPCPfsm DO 			IF (NegAddrs IN f.go.O) THEN INC(len, AddrsLen); p[pos]:=CHR(Addrs); p[pos+1]:=CHR(AddrsLen); T.PutIP(f.go.OurAddress, p, pos+2); T.PutIP(f.go.HisAddress, p, pos+6); INC(pos, AddrsLen); END; IF (NegAddr IN f.go.O) THEN INC(len, AddrLen); p[pos]:=CHR(Addr); p[pos+1]:=CHR(AddrLen); T.PutIP(f.go.OurAddress, p, pos+2); INC(pos, AddrLen); END; IF (NegVJ IN f.go.O) THEN INC(len, VJLen); p[pos]:=CHR(CompressType); p[pos+1]:=CHR(VJLen); T.PutInt(f.go.CompressProt, p, pos+2); p[pos+4]:=CHR(f.go.MaxSlot); p[pos+5]:=CHR(f.go.CFlag); INC(pos, VJLen); END END																								(* To update if more Options supported *) END AddCI; (* AckCI - An Ack Packet has been received as answer to our req *) PROCEDURE *AckCI (f: FSM.FSM; VAR p: ARRAY OF CHAR; pos, len: INTEGER): BOOLEAN; VAR b:BOOLEAN; BEGIN b:=TRUE; WITH f:IPCPfsm DO				(* No changes to our former req are allowed, otherwise the ack is bad *) IF (NegAddrs IN f.go.O) THEN b:= b & (len>=AddrsLen) & (ORD(p[pos])=Addrs) & (ORD(p[pos+1])=AddrsLen) & T.EqualIP(p, pos+2, f.go.OurAddress) & T.EqualIP(p, pos+6, f.go.HisAddress); DEC(len, AddrsLen); INC(pos, AddrsLen); END; IF (NegAddr IN f.go.O) THEN b:= b & (len>=AddrLen) & (ORD(p[pos])=Addr) & (ORD(p[pos+1])=AddrLen) & T.EqualIP(p, pos+2, f.go.OurAddress); DEC(len, AddrLen); INC(pos, AddrLen); END; IF (NegVJ IN f.go.O) THEN b:=b & (len>=VJLen) & (ORD(p[pos])=CompressType) & (ORD(p[pos+1])=VJLen) & (T.GetInt(p, pos+2)=f.go.CompressProt) & (ORD(p[pos+4])=f.go.MaxSlot) & (ORD(p[pos+5])=f.go.CFlag); DEC(len, VJLen); INC(pos, VJLen); END;																							(* To update if more Options supported *) b:=b & (len=0); IF ~b THEN Debug.String("Received bad Ack!!"); END; RETURN b 		END END AckCI; (* NakCI - A Nak Packet has been received as answer to our req *) PROCEDURE *NakCI (f: FSM.FSM; VAR p: ARRAY OF CHAR; pos, len: INTEGER): BOOLEAN; VAR no, try: Options;	(* no: Options with Naks, try: Options we try next time *) type, size:INTEGER; b, nakd:BOOLEAN; BEGIN b:=TRUE; WITH f:IPCPfsm DO (* same order as we sent it, but only the nak'd ones *) no.O:={}; try.O:=f.go.O; 			IF (NegAddrs IN f.go.O) & (len>=AddrsLen) & (ORD(p[pos])=Addrs) & (ORD(p[pos+1])=AddrsLen) THEN nakd:=FALSE; IF ~T.EqualIP(p, pos+2, f.go.OurAddress) & ~T.EqualIP(p, pos+2, ZeroIP) & f.AcceptLocal THEN T.GetIP(p, pos+2, try.OurAddress); T.GetIP(p, pos+2, f.ho.OurAddress); nakd:=TRUE; ELSE try.OurAddress:=f.go.OurAddress; END; IF ~T.EqualIP(p, pos+6, f.go.HisAddress) & ~T.EqualIP(p, pos+6, ZeroIP) & f.AcceptRemote THEN T.GetIP(p, pos+6, try.HisAddress); T.GetIP(p, pos+6, f.ho.HisAddress); nakd:=TRUE; ELSE try.HisAddress:=f.go.HisAddress; END; IF ~nakd THEN Debug.String(" Addresses-NAK wrong (no changes)"); Debug.Ln; b:=FALSE; END; INCL(no.O, NegAddrs); DEC(len, AddrsLen); INC(pos, AddrsLen); END; IF (NegAddr IN f.go.O) & (len>=AddrLen) & (ORD(p[pos])=Addr) & (ORD(p[pos+1])=AddrLen) THEN IF (f.AcceptLocal & ~T.EqualIP(p, pos+2, ZeroIP)) THEN T.GetIP(p, pos+2, try.OurAddress) (* Accept New Option *) ELSE Debug.String(" Our Address is not accepted or ZeroIP-proposal"); Debug.Ln; END; INCL(no.O, NegAddr); DEC(len, AddrLen); INC(pos, AddrLen); END; IF (NegVJ IN f.go.O) & (len>=VJLen) & (ORD(p[pos])=CompressType) THEN size:=ORD(p[pos+1]); IF (len=VJLen) & (T.GetInt(p, pos+2)=f.go.CompressProt) THEN IF ((ORD(p[pos+4])#f.go.MaxSlot) OR (ORD(p[pos+5])#f.go.CFlag)) THEN	INCL(no.O, NegVJ); IF (ORD(p[pos+4])<=f.go.MaxSlot) THEN try.MaxSlot:=SHORT(ORD(p[pos+4])); try.CFlag:=SHORT(ORD(p[pos+5])); END; DEC(len, VJLen); INC(pos, VJLen); ELSE b:=FALSE;	Debug.String(" Compr-NAK wrong (no changes)"); Debug.Ln;	(* No changes made! *) END; ELSE Debug.String ("An other Compression Type is wanted! Type: "); Debug.Int(T.GetInt(p,pos+2),6); Debug.Ln; INCL(no.O, NegVJ); EXCL(try.O,NegVJ);	(* we switch off VJ-Comp. *) DEC(len, size); INC(pos, size); END; END; (* there may be remaining options, but no changes possible ! (Just checking if Nak is ok) *) WHILE b & (len>VoidLen) DO 				type:=ORD(p[pos]); size:=ORD(p[pos+1]); CASE type OF 					  Addr: b:=((size=AddrLen) & ~(NegAddr IN f.go.O) & ~(NegAddr IN no.O)); | CompressType: b:=((size>=CompressLen) & ~(NegVJ IN f.go.O) & ~(NegVJ IN no.O)); | Addrs: b:=(size=AddrsLen) ELSE END; INC(pos, size); END; b:=b & (len=0); IF len#0 THEN Debug.String ("Len not zero"); Debug.Int(len,6); Debug.Ln; END; IF b & (f.State#FSM.Opened) THEN f.go:=try;		 (* Update State *)	END; RETURN b 		END END NakCI; (* RejCI - A Reject Packet has been received as answer to our req*) PROCEDURE *RejCI (f: FSM.FSM; VAR p: ARRAY OF CHAR; pos, len: INTEGER): BOOLEAN; VAR try: Options; (* try: Option to request next time *) BEGIN WITH f:IPCPfsm DO	(* Look which options were rejected. Same order and same value! Otherwise a bad packet. *) try:=f.go; IF (NegAddrs IN f.go.O) & (len>=AddrsLen) & (ORD(p[pos])=Addrs) & (ORD(p[pos+1])=AddrsLen) & T.EqualIP(p, pos+2, f.go.OurAddress) & T.EqualIP(p, pos+6, f.go.HisAddress) THEN DEC(len, AddrsLen); INC(pos, AddrsLen); EXCL(try.O, NegAddr); END; IF (NegAddr IN f.go.O) & (len>=AddrLen) & (ORD(p[pos])=Addr) & (ORD(p[pos+1])=AddrLen) & T.EqualIP(p, pos+2, f.go.OurAddress) THEN DEC(len, AddrLen); INC(pos, AddrLen); EXCL(try.O, NegAddr); INCL(try.O, NegAddrs); END; IF (NegVJ IN f.go.O) & (len>VJLen) & (ORD(p[pos])=CompressType) & (ORD(p[pos+1])=VJLen) & (T.GetInt(p, pos+2)=f.go.CompressProt) & (ORD(p[pos+4])=f.go.MaxSlot) & (ORD(p[pos+5])=f.go.CFlag) THEN DEC(len, VJLen); INC(pos, VJLen); EXCL(try.O, NegVJ); END; IF len#0 THEN Debug.String("Received bad Reject ! len:"); Debug.Int(len, 5); Debug.Ln; RETURN FALSE ELSE IF f.State#FSM.Opened THEN f.go:=try; END; (* Update the Options *) RETURN TRUE END END END RejCI; (* ReqCI - Conf. Request has arrived: Check the requested CIs and send appropriate respose 		Returns: ConfigureAck, ConfigureNak or ConfigureReject and modified packet (p, pos, length in len) 		If Mode is true always send Reject, never Nak *) PROCEDURE ReqCI (f: FSM.FSM; VAR p: ARRAY OF CHAR; VAR pos, len: INTEGER; Mode:BOOLEAN): SHORTINT; CONST Ack=0; Nak=1; Rej=2; RejAll=3; (* Ack: Can Ack, Nak: Should Nak, Rej: reject of some options needed, RejAll: serious reject: rej whole packet *) VAR type, size, posp, posw, lenp, x:INTEGER; eo:SET; (* eo: Options to Nak/Rej *) status, MaxSlot, CFlag:SHORTINT; BEGIN eo:={}; WITH f:IPCPfsm DO lenp:=len; posp:=pos; status:=Ack; f.ho.O:={}; WHILE (status#RejAll) & (lenp>=VoidLen) DO 				size:=ORD(p[posp+1]); IF (sizelenp) THEN Debug.String("Bad CI Length!"); Debug.Ln; status:=RejAll; ELSE type:=ORD(p[posp]); CASE type OF 						 Addr: INCL(f.ho.O, NegAddr); IF (NegAddr IN f.ao.O) & (size=AddrLen) THEN T.GetIP(p, posp+2, f.ho.HisAddress); IF ~f.AcceptRemote OR T.EqualIP(p, posp+2, ZeroIP) THEN INCL(eo, Addr); IF status=Ack THEN status:=Nak; END; END; ELSE status:=Rej; INCL(eo, Addr); END; | CompressType: INCL(f.ho.O, NegVJ); IF (NegVJ IN f.ao.O) & (size>=CompressLen) THEN x:=T.GetInt(p, posp+2); f.ho.CompressProt:=x; IF (x=VJCompression) &(size=VJLen) THEN MaxSlot:=SHORT(ORD(p[posp+4])); CFlag:=SHORT(ORD(p[posp+5])); f.ho.MaxSlot:=MaxSlot; f.ho.CFlag:=CFlag; IF (MaxSlot>f.ao.MaxSlot) OR (CFlag>f.ao.CFlag) THEN INCL(eo, CompressType); IF status=Ack THEN status:=Nak; END; END; ELSE status:=Rej; INCL(eo, CompressType); END; ELSE status:=Rej; INCL(eo, CompressType) END; | Addrs: INCL(f.ho.O, NegAddrs); IF (NegAddrs IN f.ao.O) & (size=AddrsLen) THEN T.GetIP(p, posp+2, f.ho.HisAddress); T.GetIP(p, posp+6, f.ho.OurAddress); IF (~f.AcceptRemote 								& ~T.EqualIP(p, posp+2, f.go.HisAddress)) OR T.EqualIP(p, posp+2, ZeroIP) THEN INCL(eo, Addrs); IF status=Ack THEN status:=Nak; END; END; IF (~f.AcceptLocal 								& ~T.EqualIP(p, posp+6, f.go.OurAddress)) OR T.EqualIP(p, posp+6, ZeroIP) THEN INCL(eo, Addrs); IF status=Ack THEN status:=Nak; END; END; ELSE status:=Rej; INCL(eo, Addrs); END; ELSE status:=Rej;				(* unknown Type ->reject *) END; DEC(lenp, size); INC(posp, size); END; END; IF lenp#0 THEN status:=RejAll; END; IF (status=RejAll) THEN RETURN FSM.ConfRej; (* len, pos are ok *) ELSIF (status=Ack) THEN (* es, in special case try to get remote address *) IF (len = 0) & (SYSTEM.VAL(LONGINT, f.ho.HisAddress) = SYSTEM.VAL(LONGINT, ZeroIP)) THEN Debug.String("try to get remote address!"); Debug.Ln; p[posp] := CHR(Addr); p[posp+1] := 6X; p[posp+2] := 0X; p[posp+3] := 0X;p[posp+4] := 0X; p[posp+5] := 0X; len := 6; RETURN FSM.ConfNak; ELSE RETURN FSM.ConfAck; (* len, pos are ok *) END; ELSE	IF Mode THEN status:=Rej; END; lenp:=len; posp:=pos; posw:=pos; WHILE lenp#0 DO 					type:=ORD(p[posp]); size:=ORD(p[posp+1]); IF (type IN eo) THEN			(* This type needs to be corrected *) IF status=Nak THEN 	(* make better proposals *) CASE type OF 								  Addr: T.PutIP(f.wo.HisAddress, p, posp+2); (* write over old values *) | CompressType: IF (f.ho.MaxSlot>f.ao.MaxSlot) THEN p[posp+4]:=CHR(f.wo.MaxSlot); END; IF (f.ho.CFlag>f.ao.CFlag) THEN p[posp+5]:=0X; END; | Addrs: T.PutIP(f.wo.HisAddress, p, posp+2); T.PutIP(f.wo.OurAddress, p, posp+6); (* write over old values *) ELSE END; END; IF posw#posp THEN T.CopyString(p, posp, posw, size); END; INC(posw,size); (* 'shift' it together *) END; INC(posp, size); DEC(lenp, size); END; len:=posw-pos; IF status=Rej THEN RETURN FSM.ConfRej; ELSE RETURN FSM.ConfNak; END; END END END ReqCI; (* Up - IPCP is ready *) PROCEDURE *Up (f: FSM.FSM); VAR ip:(*es*)NetIP.Adr(*PT.IPAdr*); i:INTEGER; (*es*)p: ARRAY 16 OF CHAR; BEGIN WITH f: IPCPfsm DO 			IF SYSTEM.VAL(LONGINT, f.ho.HisAddress) = SYSTEM.VAL(LONGINT, ZeroIP) THEN f.ho.HisAddress := f.wo.HisAddress; END; IF SYSTEM.VAL(LONGINT, f.ho.HisAddress) = SYSTEM.VAL(LONGINT, ZeroIP) THEN Debug.String("Could not determine remote IP address!"); Debug.Ln; Close(f); RETURN ELSIF SYSTEM.VAL(LONGINT, f.go.OurAddress) = SYSTEM.VAL(LONGINT, ZeroIP) THEN Debug.String("Could not determine local IP address!"); Debug.Ln; Close(f); RETURN ELSE	(* success ! *) PPPHandleIPCPUp(f.HDLCConfig); 	(* PPP will inform other protocols *) END; END; END Up; (* Down - IPCP has to close *) PROCEDURE *Down (f: FSM.FSM); BEGIN PPPHandleIPCPDown(f.HDLCConfig); 	(* PPP will inform other protocols *) END Down; (* Initialisation IPCP*) PROCEDURE Init* (VAR f:IPCPfsm; C:HDLC.PPPUnit; OurIP, HisIP:(*es*)NetIP.Adr(*PT.IPAdr*)); BEGIN NEW(f); f.Protocol:=IPCP; f.ProtoName:="IPCP";	(* IPCP Protocol *) f.ResetCI:=ResetCI; f.CILen:=CILen; f.AddCI:=AddCI; f.AckCI:=AckCI; f.NakCI:=NakCI; f.RejCI:=RejCI; f.ReqCI:=ReqCI; f.Up:=Up; f.Down:=Down; f.ExtCode:=NIL; f.HDLCConfig:=C; FSM.Init(f); f.AcceptLocal:=SYSTEM.VAL(LONGINT, OurIP) = SYSTEM.VAL(LONGINT, ZeroIP); f.wo.OurAddress:=OurIP; f.AcceptRemote:=SYSTEM.VAL(LONGINT, HisIP) = SYSTEM.VAL(LONGINT, ZeroIP); f.wo.HisAddress:=HisIP; f.wo.O:={NegAddr}; f.wo.CompressProt:=VJCompression; f.wo.MaxSlot:=MaxStates-1; f.wo.CFlag:=1;				(* Want Option *) f.ao.O:={NegAddr, NegAddrs}; f.ao.CompressProt:=VJCompression; f.ao.MaxSlot:=MaxStates-1; f.ao.CFlag:=1;				(* Allow Option *) END Init; BEGIN FOR i:=0 TO (*es*)NetIP.AdrLen(*PT.IPAdrLen*)-1 DO ZeroIP[i]:=0X; END END PPPIPCP.

title: Oberon/ETH Oberon/2.3.7/PPPIPCP.Mod