You are on page 1of 19

CSC8415 Assignment 2

Network Programming

Introduction
The assignment will be marked out of 100. This assignment is worth 60% of the marks for
the course.

The assignment submission will have two parts, program code and a word processed
report in PDF format. The code goes into the Git repository, and the report will be
submitted using the USQ Studydesk assignment submission.

Assignment Topics
Recall that in assignments 0 and 1, you learned :-

The use of a makefile.


C command line arguments.
Encapsulation in C.
Writing a client.
Writing a server.
Writing functions in C
Configuration
Logging
Making a TCP connection
Reading and Parsing lines from a TCP connection
Transferring files over a TCP connection.
Reading from and writing to files.
Error handling.

In Assignment 2, you will build on everything you learned in assignment 0 and 1, and use
it to implement the non-trivial network programming associated with a police speed
camera.

Task Overview
1.Master pointer to function and void*
2.Customise the base server provide in the framework.
3.Test the base server provide in the framework.
4.Design the server.
5.Implement the server.
6.Test the server that you have implemented.
The following applies to all assignments in this course.
If you are stuck at any stage, which is likely, then seek help in the practicals or on the
forums. Hopefully someone has already had the same problems as yourself, and you can
simply read the solution. If not, then you need to ask.

The student is expected to produce quality code. The code should be properly formatted
and properly commented.

You need to make a new directory in your Git repository called "Ass2", and it will have
subdirectories within that directory as needed.

Your marker will inspect, compile and run your code on the Linux operating system as
provided for this course. The marker will go to the directory associated with the question
and inspect the code. He or she will type the command "make" in order to compile the
program.

Hopefully, the program should compile without errors. Compiler warnings are usually an
indication of something not being done correctly. If you cannot ascertain the cause of a
compiler error or warning, then seek help in the tutorials or the course forums.

The issue of plagiarism is taken seriously. USQ policies on plagiarism may be found here.

Assignment Part 1
a) Pointer to function and void*.
[4 marks] (Git:Assignment2/Part1/A)
Read the man pages for qsort(3) and for strcmp(3). Is strcmp() suitable for use as qsort()'s
comparison function? Is the return value of strcmp() the one that you want? Is the return
value of the correct type? Are the arguments of the correct type? Perhaps you will need to
wrap strcmp() with your own function in order to use this correctly.

Copy the file "sortArr.c" from Appendix 4. (Please provide your own makefile). It
currently sorts an array of structures and prints them out in order of the 'height' attribute of
the structure. Your task is change the program so that it sorts and prints them out in order
using the surname as a primary key, and the given name as a secondary key.

Here are some tutorials on using qsort():-

tutorialspoint
anyexample

b) Modify the demonstration networking server.


[10 marks] (Git:Assignment2/Part1/B)
Obtain a recent version of CscNetLib - at least version "0.5.4". You will find the program
servBaseDemo.c. This will serve as a base for your assignment. You will need to read the
code and test the resulting executable.

The distributed sample code obtains the values "height", "width" and "depth" from the
configuration and serves them to the client. You need to change it so that it no longer
retrieves the depth width and height, but instead retrieves and serves the values of
"PlatesDbase" and "SpeedExceed" in the "SpeedCamera" section of the configuration.
Such a section does not exist in test.ini, so you must create it.

You must validate "PlatesDbase" as being a plausible path name and validate
"SpeedExceed" as being a positive integer.

The retrieval and validation of the values from the configuration must be performed in the
initialisation routine that is passed to servBase_server().

Do not remove the statements in doConn() that print directly to the console, as they will
help you in part d).

c) Test the demonstration networking server.


[4 marks] (Goes in the report)
Test the demonstration server using a telnet client. Your testing needs to clearly
demonstrate the following:-

1.That the demonstration network server works, providing the required file path.
Terminate the server using a SIGINT signal, which can be generated from the
keyboard using a <CTRL> C. Show the result in the log file.

2.That if "PlatesDbase" is not a decent and valid file path or if "SpeedExceed" is not
a valid positive value, the demonstration network server will log an error saying so,
and quit. Show the result in the log file.

d) Further testing of the demonstration networking server.


[4 marks] (Goes in the report)
Test the demonstration server using a telnet client.

1.Use multiple command line windows. Use a telnet command in each command
line window, but do not enter the first line, so that the server is forced to wait for the
line. Then type the lines as needed.

You need to show what happens when two clients attempt to connect to the server at
once. Clearly explain what happened here, referring to the output of the server.

2.Now modify the server code so that the server uses a forking server model. Keep
MaxThreads at 2.
Perform testing as before, so that it demonstrates what happens if you connect two
clients at the same time. Clearly explain what happened here, referring to the output
of the server.

3.Now show what happens when you attempt to connect three clients
simultaneously.

4.Now change MaxThreads to 3 and demonstrate what happens when you attempt to
connect three clients simultaneously.

Assignment Part B
You will implement the server that is specified in Appendix 1.

Understanding UML Sequence Diagrams


[4 marks] (Goes in the report)

Take the time to understand UML sequence diagrams. Here are some references that may
help:-

"Using UML: software engineering with objects and components" by Stevens,


Perdita; Pooley, R. J (available in USQ library)
A Quick Introduction to UML Sequence Diagrams by Trace Modeller

1.[1 mark]
Explain why some messages are unbroken, and some are dotted in UML sequence
diagrams.
2.[3 marks]
Explain what is meant by the "Alt", "Opt" and "loop" in UML sequence diagrams,
and what role does the "guard" play.

Program Design
[12 marks] (Goes in the report)

You need to design your program, and your design will form part of the report. Your
designs for the server will include:-

1.A textual description of the program that you will build.


2.A state transition diagram.
3.An algorithm in pseudo code. Much of this can be inferred from Figure 1.

Implementation of the Server


[50 marks] (Git:Assignment2/Part2)
Marks are further broken down in the following table. Note that the early items are "low
hanging fruit", i.e. plenty of marks for tasks that involve less work, while the later items in
the list involve less marks for more work.
TaskNum Description Marks Estimated lines of code

1 Processing and responding to Connect message. 20 76

2 Accepting or rejecting Report Plate Message 10 55

3 Checking and responding if vehicle unregistered. 4 20

4 Logging to surveillance file 4 32

5 Logging to speeding file 4 40

6 Checking and responding if vehicle wanted 4 47

7 Create image file and get image file contents. 4 60

Code needs to be checked into the Git repository as it is being developed. The marker will
view the current contents and the history of the student's Git repository.

Make sure, when you get something working, that you tag it in the Git repository. You can
go back to this if, what you do after that does not go well. Be sure in your report to tell the
marker which version he or she should test.

Demonstration and Testing


[12 marks] (Goes in the report)
Your report needs to document one or more demonstrations. The demonstrations should
show at least the following scenarios:-

A scenario when a registered vehicle is not speeding.


A scenario when a registered vehicle is speeding.
A scenario involving an unregistered vehicle.
A scenario when a registered vehicle is wanted.

In the report, the documentation of your demonstration should show at least the
following:-

Before the demonstration


The client's console output and the servers's log files.
A listing of the server's database surveillance, speeding and images directories.
The servers's configuration files.

During the demonstration


The input to the client used to drive the demonstration.
After the demonstration
The client's console output and the servers's log files.
A listing of the server's database surveillance, speeding and images directories.
The contents of newly created files in the surveillance and speeding directories.

Your testing should show the actual state of the assignment. You testing can get full marks
even if you have not finished the assignment, or if your testing demonstrates bugs in the
assignment. That is what the testing is about. You lose marks if your testing misrepresents
the state of your assignment.

Appendix 1 Server Specification


Queland Police Speed Cameras
Queensland Police have a slogan that refers to the use of their speed cameras:- "Anywhere,
Anytime". The fictitious Queland Police aim to be like the Queensland police, and are
developing speed cameras in conjunction with the fictitious Zentec corporation. Speed
cameras of the Queland Police are physically attached and wired into the police vehicles.

Zentec Mobile cameras will take the speed of oncoming vehicles while the police cars are
in motion. They will communicate with the server using the protocol "ZentecMC1.1",
when that protocol is fully implemented. Zentec stationary speed cameras, are cheaper,
and cannot take the speed of oncoming vehicles while the police car is in motion. They
will communicate using the protocol "ZentecSC1.0". Queland Police use these cameras in
marked or unmarked cars, and park their vehicles non-obvious locations.

Your task is to implement the protocol "ZentecSC1.0" for the server of the Zentec
stationary camera, which will be used by the Queland Police. A client that may be used to
test the server will be provided for you.

The cameras have a GPS unit and know the location of the vehicle, the direction that the
camera is pointed. The speed cameras are able to read the number plates of passing
vehicles, and accurately judge the speed that those vehicles are travelling at.

The cameras report to a central server using a secure virtual private network. The camera
attempts to connect as soon as it powers up, and remains connected to the server until
power down.

As each vehicle passes, the camera photographs the vehicle, takes its speed, and deciphers
the numberplate, and reports to the server. If the vehicle is exceeding the speed limit by
more than allowable difference, then the photograph of the vehicle is also sent to the
server.

The camera has its own computer display, located in the police vehicle, and the ability to
turn on the siren of the police car. If the passing vehicle or its owner is wanted, then the
server will instruct the camera to turn on the police siren and display the details of the
vehicle to pursue.
Client for the Assignment
An actual Zentec speed camera is a complex and capable piece of equipment. It
automatically reads number plates, estimates vehicle speed, and takes photographs. The
specialised equipment of the speed camera is beyond the scope of this assignment, and you
will simulate the speed camera. You may do this using the client code supplied to you.

You will need to simulate the camera by entering the data (plate number, speed and
direction) directly from the keyboard, or by redirection of the standard input so that these
things come from a file. The format of the input from the user will be one number plate per
line of input, with each line containing the plate number followed by the speed, followed
by the direction.

For the sake of the assignment, the photograph taken by the camera will be simulated by a
simple image file. In order to simplify testing, the same image file is sent every time a
photograph needs to be sent.

Responses to the user from the supplied client will be displayed on standard output, and
logged to a file, which will be useful for testing.

Communication between the Client and the Server


The client and the server talk over a TCP connection using line based messages. The
following a UML sequence explains the interactions between the client and the server in
detail. Data elements mentioned in the diagram are further explained in the glossary:-

Figure 1

In general, messages passed between the client and the server each take the form of a
single line of text with words separated by spaces. The line is terminated by a newline
character, and anything after the newline character is not part of the message. A word may
contain spaces, if it is enclosed in quotes.

Line based messages have single word names. They are :-

1.Connect (Request a session with the server)


2.ConnAck (Request for session granted)
3.ConnReject (Request for session denied)
4.ReportPlate (Report sighting of a number plate)
5.RepPlateRejected (reject Report Plate message)
6.RepPlateAccepted (accept Report Plate message)
7.RepPlateReqPursuit (accept Report Plate message and Request pursuit of the
vehicle.)
8.Disconnect (Client says goodbye)

The first word of these messages is the message name. Other words on the line may
follow, and each word contains the data element, in order, as shown in the sequence
diagram and documented in the glossary.
All message sequences are initiated by the client. When no communication is happening,
the server connected server thread waits for a message to arrive.

The send image message, which carries a JPEG image, is an exception, i.e. clearly it is not
a line based message. The file sent has a fixed size, and the receiving end knows whether
to expect it, and knows the size. The sender sends the agreed number of bytes. The
receiver accepts the agreed number of bytes.

Establishing the Connection


Once a TCP connection is established the client sends a Connect message. One part of the
Connect message is protoName, which is the name of the protocol. For this assignment we
will only use the protocol "ZentecSC1.0". Other protocols, such as "ZentecMC1.1", are
possible, but they are beyond the scope of this assignment.

If the server agrees to talk using the requested protocol, then it responds with a ConnAck
message. Otherwise it responds with a ConnReject message. Your server should always
accept the "ZentecSC1.0" protocol, so long as the Connect message is valid, but your
marker may well test your client with an invalid one.

Reporting a Passing Vehicle


When a vehicle passes, the camera will initiate a conversation using a ReportPlate
message. If the vehicle was speeding, then the client must send an image of the vehicle,
which captures the number plate. The ReplortPlate message includes information about
whether the client wants to send an image, and if so, the size of the image.

If the format or values in the ReportPlate message are not valid, then the server will
respond with a RepPlateRejected message. In this case, the client will not send an image,
and the server will not expect one.

Otherwise, the ReportPlate message was valid, and the server will reply with one of two
messages:- either a RepPlateAccepted message or a RepPlateReqPursuit message. Either
one of these messages indicates acceptance of the ReportPlate message.

The server will check to see if a file with the numberplate as a name exists in the Wanted
directory, with a format as documented. If the file exists then the server will respond with
a RepPlateReqPursuit message populated with details obtained from the wanted file, as
shown in the sequence diagram .

If the vehicle was not wanted, then the server will check to see if a file with a numberplate
as a name exists with the CurrentRego directory. If it does not, then the vehicle is not
registered. Since the server may not know the details of the unregistered vehicle, it will
issue a RepPlateReqPursuit message, with the plateNum field, but without make, model,
color and ownersName fields.

As shown in the sequence diagram, the ReportPlate message indicates whether an image
will immediately follow, and gives the size of the image. On receipt of a
RepPlateAccepted or a RepPlateReqPursuit message, the client will if sending, send the
image and the server will receive it.

Server Records
The server will always create a record in the surveillance log, of the vehicle passing, as
documented in the section on the File System Database of the server.

If the client sent an image, then the vehicle is speeding, and if so, the server will create an
entry in the speeding log, (with a format as documented under "File-system Database of
the Server"), and will create a file in the images directory (with a format as documented
there too).

Disconnecting
If the client receives a RequestPersuit message, then after sending an image file, if the
vehicle was speeding, it will disconnect the connection, as the police car now needs to
move. The client may also disconnect on request from the user. In order to disconnect, the
client sends a Disconnect message, and then terminates the TCP connection.
File-system Database of the Server
The server interacts with a database that holds the details of numberplates. For the purpose
of this assignment, the database will take the form of a file-system directory tree. The
database consists of directories, with given directory names. Files that the server must read
have data in ini file format. Files that the server must write will be written in log file
format. A graphical depiction of the directory tree follows:-

Figure 2

The Base Directory


The base directory for the server database is the directory given in the "PlatesDbase" entry
in the "SpeedCamera" section of the configuration. It contains the subdirectories
"CurrentRego", "Wanted", "Surveilance", "Speeding", and "Images".

CurrentRego
If the server wishes to know if a reported number plate belongs to a car with registration
that has not expired, it can do so by checking for the existence of a file in this directory
with the plate number as the file name. The contents of this file is beyond the scope of this
assignment.

If the file exists in this directory, then the rego is current. If the file does not exist, then the
vehicle is unregistered, and the server will notify the camera, which will activate the siren
and instruct the police to pursue.

Wanted
A vehicle may be registered, but it may be stolen, or its owner involved in a crime. If a file
exists in this directory with the number plate as the file name, then it means that the
vehicle is wanted, and the server will notify the camera, which will activate the siren and
instruct the police to pursue.

The files in this directory have ini file format, and contains the following data sections and
items:-

Wanted section
History A short textual description of the problem.
Vehicle section
Make Make of the vehicle
Model Model of the vehicle
Person section
Name Name of a wanted person, or empty
Gender The word "male" or the word "female" or empty
DOB date of birth, e.g. "20160523" or empty

Surveillance
The surveillance file, which goes in the "Surveillance" directory, is created in response to
the client's Connect message. The name of the file has the date and time of the Connect
messagefollowed by the camera ID number (in the form
"YYYYMMDD.hhmmss.llddddd", where :-

"YYYY" is the year part of the date, e.g. "2016"


"MM" is the month part of the date, e.g. "09".
"DD" is the day part of the date, e.g. "27".
"hh" is the hour part of the date, e.g. "15".
"mm" is the minute part of the date, e.g. "55".
"ss" is the second part of the date, e.g. "56".
"ll" are two letters of the camera ID, e.g. "gu".
"ddddd" are five digits of the camera ID, e.g. "56787".

An example of such a file name would be "20161126.093412.hy78237" (without the


quotes). The date and time of the Connect message is the date and time according to the
server's reckoning.

When the server receives a ReportPlate message, it creates an entry the surveillance file.
The details of each passing car are logged in the form of a new line in that file. Each line
has the following fields in order, which are explained in further details in the glossary:-

date.time of the observation by the camera, [YYYYMMDD.hhmmss]. This is the


time by the server's reckoning.
plateNum
lattitude lattitude
longitude longitude
speed speed of the vehicle
direction direction of the vehicle
An example line from that file would be :-
[20160423.142356] ABC123 32.23489 -134.21956 57 -45

The file is further processed by a batch process in due time, and such processing is beyond
the scope of this assignment.

Speeding
The speeding file, which goes in the "Speeding" directory, is created in response to the
client's Connect message. File names in in the "Speeding" directory have the same format
as files in the "Surveillance" directory.

While all vehicle observations get logged to the surveillance file, only observations where
the vehicle is speeding get logged to a file in the "Speeding" directory.

Entries in this file are similar to entries in the surveillance file. The date.time, plateNum,
lattitude, longitude and speed are all present, in the same order as in a surveillance entry,
and these are followed by an additional field, the file name of the image file, which is
explained directly below.

Images
Every observation in the "Speeding" directory is accompanied by an image in the
"Images" directory. The name of a file containing the photograph in this directory is given
by the date and timeof the Connect Message followed by a connection image count
followed by the substring ".jpg". The connection image count is a number that the server
associates with the connection, and increments it every time it saves an image. An example
of the resulting file name would be "20160830.172356.5123.jpg".

Glossary
1.protoName

Description: The name of the protocol, which is "ZentecSC1.0".

Used in: The Connect message

2.cameraId

Description: Serial number of the camera.

Format: It consists of two letters followed by 5 digits, e.g. "hy48927".

Used in:

The Connect message


File names in the server database.

Origin: The camera.


3.lattitude

Description: The north/south part of a geolocation.

Used in:

The Connect message


Surveillance log entries and Speeding log entries in the file system database
of the server.

Format: decimal degrees (i.e. a floating point number in the range -90 to 90
specified to 5 digits after the decimal point.

4.longitude

Description: The east/west part of a geolocation.

Used in:

The Connect message


Surveillance log entries and Speeding log entries in the file system database
of the server.

Format: decimal degrees (i.e. a floating point number in the range -180 to 180
specified to 5 digits after the decimal point.

5.dateTime

Description: The date and time

Used in:

Speeding log entries in the file system database of the server.


Survellance log entries in the file system database of the server.
The file name of a speeding log file.
The file name of a surveillance log file.

Format: "YYYYMMDD.hhmmss" (without the quotes), where :-

"YYYY" is the year part of the date, e.g. "2016"


"MM" is the month part of the date, e.g. "09".
"DD" is the day part of the date, e.g. "27".
"hh" is the hour part of the date, e.g. "15".
"mm" is the minute part of the date, e.g. "55".
"ss" is the second part of the date, e.g. "56".
An example would be "20161126.093412" (without the quotes).

6.speedLimit
Description: The speed limit at a given geolocation.

Used in:

The ConnAck message.


Speeding log entries in the file system database of the server.

Format: Positive integer.

Origin: Calculated by the server, from camera geolocation.

7.speedExceed

Description: The maximum value that a vehicle may exceed the speed limit before a
speeding ticket is issued.

Used in: The ConnAck message.

Format: Positive integer.

Origin: From the server configuration.

8.speed

Description: The speed limit that a vehicle travelled at.

Used in:

The ReportPlate message.


Speeding log entries in the file system database of the server.
Survellance log entries in the file system database of the server.

Format: Positive integer.

9.direction

Description: The direction of travel of a vehicle in degrees easterly from North.

Used in: The ReportPlate message.

Format: integer in the range -180 to 180.

Origin: The camera calculates the direction of a passing vehicle.

10.isImage

Description: Indicates whether the photograph of a vehicle will follow.

Used in: The ReportPlate message.

Format: The word "image" or the word "noImage".


11.imageSize

Description: The size of an image to be uploaded.

Used in: The ReportPlate message.

Format: Positive integer.

Origin: Client determines size of image file.

12.plateNum

Description: The text on a number plate that identifies a registered vehicle.

Used in:

The ReportPlate message.


The RepPlateReqPursuit message.
Speeding log entries in the file system database of the server.
Survellance log entries in the file system database of the server.

Format: A sequence of at least 4 and at most 8 uppercase letters and digits.

Origin: Speed Camera.

13.make

Description: Make of a vehicle

Used in: The RepPlateReqPursuit message.

Format: Short string

Origin: Entry in the wanted files of database of the server.

14.model

Description: Model of a vehicle

Used in: The RepPlateReqPursuit message.

Format: Short string. May contain spaces.

Origin: Entry in the wanted files of database of the server.

15.color

Description: vehicle color

Used in: The RepPlateReqPursuit message.


Format: Short string. May contain spaces.

Origin: Entry in the wanted files of database of the server.

16.reason

Description: Reason for rejection of Connect or ReportPlate message.

Used in:

The ConnReject message.


The RepPlateRejected message.

Format: Short string. May contain spaces.

Origin: The server.

17.ownerName

Description: Name of the owner of the vehcle.

Used in: The RepPlateReqPursuit message.

Format: Short string. May contain spaces.

Origin: Entry in the wanted files of database of the server.

Note: If this information is not known, e.g. if the vehicle has been stolen, this field
may be empty, and in this case the this field will still be present in the
RepPlateReqPursuit message, but will be an empty string, i.e. "" (with the quotes)

18.gender

Description: gender of the owner of the vehcle.

Used in: The RepPlateReqPursuit message.

Format: Either the word "male" or the word "female" (without the quotes)

Origin: Entry in the wanted files of database of the server.

Note: If this information is not known, e.g. if the vehicle has been stolen, this field
may be empty, and in this case the this field will still be present in the
RepPlateReqPursuit message, but will be an empty string, i.e. "" (with the quotes)

19.DOB

Description: date of birth of the owner of the vehcle.

Used in: The RepPlateReqPursuit message.


Format: YYYYMMDD

Origin: Entry in the wanted files of database of the server.

Note: If this information is not known, e.g. if the vehicle has been stolen, this field
may be empty, and in this case the this field will still be present in the
RepPlateReqPursuit message, but will be an empty string, i.e. "" (with the quotes)

20.History

Description: Reason that the car is wanted.

Used in: Not used

Format: String. May contain spaces.

Origin: Entry in the wanted files of database of the server.

21.Connection Image Count

Description: The connection image count is a number that the server associates with
the connection.

Used in:

File name of an image file in the file system database of the server.
Entry in a "Speeding" file in the file system database of the server.

Format: integer

Origin: Server initiates to zero, then increments every time it saves an image.

Appendix 2 Server determination of Speed limit


The server will eventually consult Queland's road speed limit library which uses an up to
date database of Queland's roads.

The assignment will simulate Queland's road speed limit library using the following
function:-

int getSpeedLimit(double latitude, double longitude)


{ char latlong[99];
long sum = 0;
char *p = latlong;
unsigned char ch;

sprintf(latlong, "%16.7e,%16.7e", lattitude, longitude);


while (ch=(*p++))
sum = 293 * sum + ch;
return (sum % 8) * 10 + 40;
}
Appendix 3 isValid_plateNum()
int isValid_plateNum(char *str)
{ int len;
char ch, *p;

// Is the length OK?


len = strlen(str);
if (len<MinPlateNumLen || len>MaxPlateNumLen)
return FALSE;

// Loop through each character.


p = str;
while (ch = (*p++))
{ if (!isupper(ch) && !isdigit(ch))
return FALSE;
}

// Done.
return TRUE;
}

Appendix 4 SortArr.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <CscNetLib/std.h>

typedef struct
{ float height;
char *givenName;
char *surName;
} person_t;

person_t people[] =
{
{ 176.4, "John", "Smith" }
, { 170.4, "Fred", "Blogs" }
, { 160.4, "Janet", "Farley" }
, { 150.4, "Jill", "Franks" }
, { 155.4, "Jane", "Fredrickson" }
, { 165.4, "Jack", "Jackson" }
, { 165.0, "Benjamin", "Brown" }
, { 155.0, "Kieth", "Spinks" }
, { 149.3, "Billy", "Baxter" }
, { 148.3, "Billy", "Jackson" }
, { 148.3, "Michael", "Hurley" }
, { 148.3, "Lita", "Crane" }
};

int cmpr_personHeight(const void *aa, const void *bb)


{ const person_t *a = aa;
const person_t *b = bb;
if (a->height > b->height)
return 1;
else if (a->height < b->height)
return -1;
else
return 0;
}

void main(int argc, char **argv)


{ int iPers;

qsort(&people, dim(people), sizeof(people[0]), cmpr_personHeight);


for (iPers=0; iPers<dim(people); iPers++)
{ printf( "%7.3f %s %s\n"
, people[iPers].height
, people[iPers].givenName
, people[iPers].surName
);
}
}

You might also like