VOIP Project: Design application - Part 5
In this part we will see in details the UML diagram of the application which will be developed during this project and the specifications of this diagram.
In the figure 1 bellow is shown a preview of the class diagram of the application developed with Qt Creator using PJSIP library. In the diagram below are omitted other external classes which are not used directly by the application.
On top of figure 4, within the grey rectangle, are shown the classes of Qt library which are extended by the created classes by the programmer. The QMainWindow is a class which provides a framework for building a graphical view, this is the reason why this class is extended by Login and MainWindow classes. The other class, QObject is a base class for many classes in Qt. It provides a wide set of features. The QObject class is extended by SipPhoneImpl class as well because of usage of signals, which will be explained more in deep in the upcoming paragraphs.
In the blue rectangle in the same picture are shown the PJSIP library classes which are directly extended by other classes of the project. This classes, Account and Call, provide basic functionalities for the VOIP communication. This classes are extended by PjSipAccount and PjSipCall classes respectively in order to provide a customized behavior.
Another module showed in figure 4, within the orange rectangle, are the view classes, the classes in which is created the graphical user interface and is managed the interaction between the user and the graphical interface. This module consists in two classes, Login and MainWindow, which will be explained in the following paragraphs.
The green rectangle contains the classes which make up the object model of the application. This are simple classes with variables and getters/setters for each of them.
The entry point in the application which is called by main() function is Login class. This class, as mentioned above, is one of the classes which manage the graphical user interface. In the figure 2 is shown the Login class with its function.
As shown above the Login class has only one function, on_loginButton_clicked(), which is an event driven function. This function will be executed when the login button will be pressed. Within this function will be created the instance of the database class in order to retrieve the data for the user and compare them with the data given by the user. If the authentication would have been successful, the instance of the MainWindow class would be created and the show() function of the QMainWindow class that MainWindow class extends would be executed.
Figure 3 shows MainWindow class with all its variables and main functions and the relation with other classes.
The incomingCall variable of this class is a Boolean variable which becomes true when there is an incomingCall. The default value of this variable is false as shown in the figure 3.
The other variable, loginWindowof type QWidget*, is a pointer of the instance of Login class which gets the value when the instance of MainWindow class is created in the on_loginButton_clicked() function of Login class and the constructor of MainWindow class is called.
The sipPhone variable, a pointer of an instance of SipPhoneImpl, is instantiated when the instance of the MainWindow is created, so when the constructor of MainWindow is executed.
currentSipUser , a pointer of a SipUser class’s instance, is a variable which gets the value when an instance of MainWindow class is created as well. This value is passed by Login class to MainWindow class through the constructor when a valid user is authenticated.
The other variable, listOfSchedule, a variable of QListtype, is a variable which consists in a list of pointers of Schedule class’s instances. This variable is populated by the DatabaseInteraction class when the instance of MainWindow is created. In this variable is stored all the information that is extracted from cit_schedule table of the database.
listOfLessonSchedule is similar with listOfScheduleregarding the type, but not the information that this two variables contain. listOfLessonSchedulecontains only a subset of listOfScheduleinformation. In the listOfLessonScheduleis stored the information of cit_scheduletable which has in the column Type the value Lesson.
Different form listOfLessonSchedulethe other variable, listOfOtherSchedule of the same type, contains the information from cit_schedule table which has in the column Type the values different from Lesson.
Another list variable, of type QList, is listOfSipUser, but differently from the list mentioned above, it is a list of pointers of SipUser class’s instances. The information stored in this variable is extracted by cit_user table.
listOfConsultations is a variable of type QList. The information in this variable is loaded in the constructor of the MainWindow class from cit_consultation table.
The list mentioned above are populated through the functions of the DatabaseInteraction class, instance of which is passed in the MainWindow class through the constructor, is used than in MainWindow class to call this methods. The pointer is stored in dbi variable, which has a wider scope than the constructor.
sipState stores the state of the call. This variable is of type QString and it can get the values localRing, remoteRing, calling, and empty stirng.
ringtone and outgoingRing are two variable of type QSoundEffect, which store the ringtone which is played when there are incoming calls, are when are made outgoing calls.
The last variable of MainWindow class, callId, is of type int. This variable stores the id of the incoming, outgoing or ongoing call. This variable is than used to hang up the call when close button is pressed and on_pushButton_closeCall_clicked() function is executed.
The constructor of MainWindow class is as follow, MainWindow(logedInUser : SipUser *, db : DatabaseInteraction *, parent = 0:QWidget *). This constructor is executed when the instance in Login class is created, and the logedInUser, db, parentare variables which are passed by Login class. logedInUservariable is the variable which is then passed to currentSipUservariable in the implementation of the constructor. The db variable is passed to dbi variable explained in the paragraphs above. Parent variable is the instance of Login class, which is created in the beginning of the execution of the application.
getIncomingCall() and setIncomingCall(incomingCall : bool) are the setters and getters of incomingCall variable explained above. onNumberDoubleClick(itemClicked : QTreeWidgetItem *, int) is executed when the double click event has happened on the item of the QTreeWidget that lists the numbers of the users registered in the system.
The other function of MainWindow class, on_callState_changed(role : int, callId : int, state : int, status : int, remoteUri : QString), is a function which is executed when the state of calls changes. The signal for this event is emitted by SipPhoneImpl class’s instance. The first parameter of this function, role, defines the type of call, if it is an incoming call or outgoing call. The second parameter, callId, of the same type, int, is the id of the active instance of Call class. The next parameter, state, defines the stage in which a call is found. The last int variable, status, stores information if a stage of the call is executed correctly or not. remoteUri, the last parameter of this function. This QString variable stores the uri of the remote peer with which the call is held, including protocol, number and domain of remote peer, calling or being called.
on_pushButton_openCall_clicked() is a function that is executed when the user makes an action on the graphic interface of the application, pressing a button, the openCall button. Depending from the value of sipState variable, this function opens an incoming call, or starts a new call.
Another function that is executed when the user makes an action on the graphical interface is on_pushButton_closeCall_clicked(). This function, executed when closeCall button is clicked, ends an ongoing call if there is an ongoing call.
on_pushButton_backSpace_clicked() is executed when the backSpace button is clicked. This function removes the last character from the formed number to dial when there are more than zero characters.
on_comboBox_le_subject_currentIndexChanged(index : int) is a function which is activated when the user makes an action on the graphical interface, but differently from the above functions, this function is executed when the selected item in a combo box is changed not when a button is clicked. on_comboBox_le_subject_currentIndexChanged(index : int) is executed when the selected item in the le_subject combo box is changed. le_subjectcombo box is the one which shows the subjects which a user is associated with in the database, which have the value Lesson in the type column.
Next function which is executed when the selected item in a combo box is changed is on_comboBox_pr_subject_currentIndexChanged(index : int). This functionis executed when the selected item in the pr_subject combo box is changed. pr_subjectcombo box is the one which shows the subjects which a user is associated with in the database, which have the value different from Lesson in the type column.
The other function which is executed when the selected item in a combo box is changed is on_comboBox_co_subject_currentIndexChanged(index : int). This function is executed when this event happens on co_subject combo box. co_subject combo box shows the consultation with which a user is associated with.
The last function of MainWindow class is on_commandLinkButton_addToDial_clicked(). This function is executed when the user clicks on addToDial commandLinkButton in the graphical interface. This function adds the selected number to the numbers to be called.
As shown in the figure 4 bellow and as mentioned in previous paragraphs MainWindow class uses DatabaseInteraction class in order to retrieve the data from the database. The instance of DatabaseInteraction is created in the Login class, then through the constructor is passed to the MainWindow class. In the Login class the instance of the DatabaseInteraction class is instantiated as follow: DatabaseInteraction*db=&DatabaseInteraction::get_instance();, as the constructor of this class is private in order to respect the singleton pattern.
As shown in the picture above DatabaseInteraction class has connection with MainWindow class, by which it is used to retrieve information from the database, and object model classes, which are used to return the information extracted from the database into java objects which are then used by MainWindow class.
After the creation of the instance of the DatabaseInteraction in Login class, the createConnection() function must be called in order to create the connection with the database, where ip of the server, name of database, user name and password to access the database are defined.
As shown in figure 4 the constructor of this class is declared private in order to respect the singleton pattern.
loadSipAccountByUserName(userName : QString) is a public function of this class, as all functions in this class are, except the constructor. This function takes as parameter a variable of type QString, Qt class data type definition for string, which is the user name of a given sip account, and the result of the call in this function is the pointer of a SipAccount instance which contains all the information of the sip account for the given user name parameter. This information is extracted from cit_sip_account table.
The other function of this class, loadScheduleByUserName(userName : QString), returns a pointer to a variable of type QList, a list of schedules for the given user name parameter. The information stored in this variable is extracted from cit_schedule table.
Next function loadClassroomByID(id : QString) returns a pointer of Classroom class’s instance. This instance contains the information for the classroom with the given id in the parameter of the function, extracted from the cit_classroom table.
Function loadSubjectByID(id : QString)after execution returns a pointer to an instance of Subject class. This pointer contains information for the given id as parameter for this function. The information stored in this variable is extracted from cit_schedule table.
loadAllSipAccounts() is a function which extracts all the information that cit_sip_accounttable contains and stores it into a variable of type QList * the value of which is returned in the end of the execution of this method.
A specific user’s information is extracted through the function loadSipUserByUserName(userName : QString). This function as shown, takes as parameter the user name of a specific user, and returns as result all the information for that specific user in a variable of type SipUser * in the end of the execution, information which is extracted from cit_user table.
Another function which returns information extracted from cit_user table is loadAllSipUsers(), but this function differently from previous function does not return a pointer to an instance of the class SipUser, but a pointer to a list with pointer of instances of SipUser class. The last function of this class, loadConsultationsByUseName(userName : QString), returns a pointer to a list which hold the pointers to the instances of Consultation class. The information returned by this function is extracted by cit_schedule table.
As shown above, all functions of the DatabaseInteraction class except the createConnection() use the object model classes. This classes are simple classes with private variables, which have a limited scope only within the class, and respective getters and setters which expose this variables for public access from other classes. The figure 5 shows one of the object model classes, Consultation class.
As shown in the figure 5 above, Consultation class has direct connection only with DatabaseInteraction class, through which other classes can access this class, like MainWindow class, in which are instantiated instances of Consultation class and other object model classes. Consultation in its variables stores information extracted from the database form the view cit_view_consultation, information related to the consultation process organized by the university. The view cit_view_consultationis created from the join of three tables, cit_schedule, cit_subject and cit_consultation in order to get the user name of the professor that teaches a specific subject.
Consultation class has four QString variables and two QTime variables. This datatypes are defined by Qt library. Also as mentioned before this class contains twelve functions, setters and getters, which make the variables of this class available outside of this class by having a public scope.
The fist variable shown in picture 8, part of Consultation class, is subjectID. The type of subjectID is QString and it gets the value from the Subject_Id column of the table cit_schedule table, which in this table is the foreign key, referencing Id column of cit_subject table, a join which is done during the creation of cit_view_consultationview.
professorUserName is another QString variable which is populated by column ProfessorUserName of cit_view_consultationview, column which is originally created in cit_schedule table where it is part of composite primary key together with Subject_Id column, and it is at the same time foreign key referencing UserName column in cit_user table.
The other QString variable of Consultation class is periodicity. This variable is mapped with Periodicity column of cit_view_consultationview. This variable contains the information about the repetition of a consultation activity.
The last QString variable of Consultation class, days, is a variable mapped with Day column of cit_view_consultationview and contains the days of the week in which is held a specific consultation activity.
The other two remaining variables of the Consultation class, startTime and endTime, differently from previous variables are of type QTime and contain the information for the beginning and ending time of a consultation activity. This two variables are mapped with StartTime and EndTime columns of cit_view_consultationview respectively.
The other class of object model block of classes is SipUser class. Detailed picture of this class extracted from class diagram is shown in figure 6 bellow, together with the other class with which SipUser class is connected, Common class.
SipUser class, as the other object model classes, has connection with DatabaseInteraction class, but differently from the other object model classes, it has connection with another class, Common class.
Common class provides an enum, UserPosition. UserPosition is defined as public in a common class, accessible from other classes in order to keep a standardized value of different user positions and avoid conflicts of usage with different alias of the positions that a user has in system. As other object model classes, SipUser class contains only variables with its respective setters and getters. The variables of this class are mapped with the columns of cit_userand cit_sip_accounttable. Instances of this class contain information about the users of the system in each of its variables as described below.
First variable of SipUser class shown in figure 6 above, sipAccount, is a pointer to the instance of SipAccount class. This variable contain information of cit_sip_account table, differently from the other variables of this class. The information stored in this variable is shown more detailed in the figure 9 below.
The other variable of this table, firstName, is a variable of type QString and stores the first name of a given user of the system, information extracted from FirstName column of cit_user table.
lastName is another variable of type QString, and like firstName is mapped with the cit_user table but with LastName column, information which contains the last name of a specific user of the system.
The last variable of this class, as shown in figure 6 above, is position. This variable differently from other variables of this class is an enum UserPosition, an enum defined in Common class. This variable is mapped with Position column of cit_user table and contains information about the position of a specific user of the system.
Figure 7 shows another object model class, Classroom class. This class has only two variables, id and capacity, and their respective setters and getters. This variables are mapped with the columns of cit_classroom table and contains information related with the classes of the university. The first variable of this class, id, is of type QString, as it can be seen in the figure 7. This column is mapped with column Id of the cit_classroom table. This variable contains the id of a specific classroom in an instance of Classroom class.
The other variable of this class is capacity, and this variable differently from the previous variable contains the capacity of students that a classroom can accommodate. The capacity variable is mapped with Capacity column of cit_classroom table.
In the figure 8 bellow is shown the fragment of class diagram of Schedule class and its relations with other classes. The variables of this class are mapped with the columns of the cit_schedule, cit_subject and cit_classroom tables, containing information about the lesson or project activities held in the university.
The first variable of this class, userName, is of type QString and contains the information stored in the UserName column of cit_schedule table. The other variable of this class, subject, is a variable which contains the pointer to the instances of Subject class. The information that contain the instances of Subject class, mapped in the cit_subject table, are explained in details in the next paragraphs. Figure 10 shows the class Subject extracted from class diagram.
The classroom variable is another pointer which points to the Classroom class. This class was explained in details in the previous paragraphs. Figure 7 shows the variables and functions that Classroom class contains.
Thetitlevariable is a QString variable of Schedule class which is mapped with Title column of cit_schedule table. This variable contains the values of the title for a given schedule in a string format.
The other variable of Schedule class, description, contains the description about a specific schedule. This variable is mapped with Description column of cit_schedule table.
Periodicity of the repetition of an event is stored in the periodicity variable, an int variable of Schedule table. The periodicity variable is mapped with Periodicity column of cit_schedule table.
Days of the week in which an activity is held are stored in the day variable. This variable of type QString is mapped with Day column of cit_schedule table.
Periodicity of repetition of an event, stored in the periodicity variable of Schedule class, is related with another variable of this class, date. The date variable is a variable of QDate type and stores the date of an event, but this variable does not take a value if the periodicity variable, in the same instance, has a value greater than 0. This column is mapped with Date column of cit_schedule table.
The starting and ending time of an event are stored in the startTime and endTime variables of Schedule class respectively, which are both variables of type QTime. This variables are mapped with StartTime and EndTime columns of cit_schedule table.
The last variable of Schedule class, type, is a QString variable. In this variable is stored the type of the activity, if it a lesson or project activity. This variable is mapped with Type column of cit_schedule table.
Figure 9 shows the SipAccount class with its variables and functions in the class diagram. SipAccount is a class which has variables that contain the information used for the connection with the PBX server. The variables of this class are mapped with columns of cit_sip_account table. First variable of this class shown in the figure 9 is displayName, a QString variable. This variable is mapped with DisplayName column of cit_sip_account table. This variable contains the alias of VOIP service system.
The next QString variable of this SipAccount class, userName, is a variable which contains the user name with which the users logs into the PBX server. This variable is mapped with UserName column ofcit_sip_accounttable.
The password variable is another QString variable which together with userName variable make possible the authentication of a user of the system in the PBX server. The password variable is mapped with Password column in cit_sip_account table.
Domain column of cit_sip_account table is mapped with domain variable of the SipAccount table. The domain variable is a QString variable and contains the value of the domain pointing to the server where PBX is hosted.
The last variable, number, is declared as a QString variable as well because the number registered in the PBX server can be a string which contains zero in the first index or symbols that are not numbers. The number variable is mapped with Number column of cit_sip_account table. The last object model class of this project, Subject, is shown in the figure 10 below. As it can be seen in the picture, it has three variables with its respective setters and getters. This class contains information about the subjects which are studied in the university, and the variables of this class are mapped with columns of cit_subject table.
The first variable of Subject class shown in figure 10 above, id, is a QString variable which hold the value of the id of a specific subject. The id variable is mapped with Id column of cit_subject table.
The other variable of Subject class, name, is a QString variable as well. It contains the name of a subject and is mapped with Name column of cit_subject table.
Credits differently from the two first variables of Subject class are stored in a int variable credits. This variable is mapped with Credits column of cit_subject table.
One of the most important classes of the application is SipPhoneImpl, shown in figure 11 bellow. In this class are created the functions which implement the functionalities of communication through PBX server by using the PJSIP library. This class, as seen in the figure extracted from the class diagram bellow, has connection with three classes, MainWindow, PjSipAccount and PjSipCall. MainWindow class uses SipPhoneImpl in order to manage accounts, calls and communication in general between users. The other two classes with which SipPhoneImpl has connection, PjSipAccount and PjSipCall are used in order to access a high level API of PJSIP library, which extend classes which implement function that have low level management function for management of devices of the computer in order to make possible a communication through PBX server to happen.
The other variable of this class, ep, is an Endpoint variable. This variable contains all the configuration of the PJSIP libraries in and ending point, including endpoint and transport configuration.
The other variable, tCfg, of type TransportConfig, contains the transport configuration data, like the protocol, port number of the PBX server. aCfg, of type AccountConfig, contains the account configuration data, like the user credentials, domain of the PBX server etc.
The next variable of SipPhoneImpl class, account, is a pointer to the instances of PjSipAccount class. This variable is used to manage the accounts of the users into the PBX server.
Calls in the class SipPhoneImpl are managed through the variable call of this class, a variable which points to the instances of PjSipCall class. Through call variable in this class can be accessed functions of the class in which this variable points, of PjSipCall, enabling the management of calls operations, like making a new call or hanging up an ongoing call.
When a new instance of SipPhoneImpl is created, in the constructor of this class is set up the endpoint, if the process of the creation of the endpoint has been successful the loaded, a bool variable of SipPhoneImpl class is set to true, else this variable is set to false. This variable shows if the application is ready to make the other steps after the creation of the endpoint in order to be fully functional to receive and make calls.
The duration of calls are stored in the connectDuration of SipPhoneImpl. The connectDuration variable is of type int and stores the seconds of call duration.
The constructor of SipPhoneImplclass is as follows: SipPhoneImpl(protocol : QString, port : int, parent = 0:QObject *). The first parameter in the constructor is protocol, a QString parameter, where is passed the protocol that is used in the connection of the application with the PBX server. The next parameter in the constructor of SipPhoneImpl is an integer parameter, port, storing the port in which is realized the connection with the PBX server. The last parameter of the constructor of SipPhoneImpl class, parent, is a pointer of the instance of QObject class. The value of this parameter stores always the pointer of the instances of MainWindow class, because the instance of SipPhoneImpl class in this application is created only in the constructor of MainWindow class when sip phone functionalities are configured.
After the endpoint is configured, the next step needed in order to be able to make and receive call from the application is to create the account which will be registered in the PBX server, in order that the PBX server will be able to find the route to the created application’s endpoint and the user using the instance of the application would be able to receive and make calls. The process of account creation and registration in the PBX server is done by createAccount(idUri:QString, registrarUri:QString, user:QString, password:QString) and registerAccount() functions.
The createAccount(QString idUri, QString registrarUri, QString user, QString password)function in the first parameter, idUri, a QString variable, contains concatenated the protocol, sip, “:” character, the username of the user, the “@” character and the domain of the server. The second parameter registrarUri, a QString parameter as well, is a concatenated string with several elements as well. In the first part of this string is stored the sip protocol followed by the “:” character as well, than in the next part is appended the domain of the PBX server. The third parameter, user, a QString parameter as well, contains only the username of the account. The last parameter of this function, a QString parameter too, is password, which contains the password of the user being created.
After the account is created by the function above it is registered in the PBX server by the registerAccount()function.
After the account is registered trough the above method, it can be unregistered using unregisterAccount() from the PBX server.
After the endpoint is setup and the account is registered into the PBX server through the method mentioned in the previous paragraphs, the application can make calls to other accounts registered in other instances of application or other sip phones through makeCall(number : QString) function. This function takes as parameter only one parameter, number, a QString variable that passes to makeCall(number : QString)function the number which will be called.
The calls initiated through makeCall(number : QString)function, or the incoming calls, can be hanged up through the hangupCall(callId : int) function. This function has only one int parameter which is used in the implementation of hangupCall(callId : int)function in order to hang up the specific call with the given id. The id of the call is generated when there is an incoming call or a new call is initiated through makeCall function.
When there is an incoming call, acceptCall(callId : int) function is used to answer that call. This function takes as parameter the id of the call, as the previous hangupCall(callId : int) function did, in order to answer to a specific call given by id.
The ring(callId : int) function is used when there is an incoming call in order to notify the local instance of the application that there is an incoming call. This function takes as parameter the id of the incoming call and uses it to create a new instance of Call class.
The getConnectDuration() and setConnectDuration(connectDuration : int) functions are the setters and getters of the private variable connectDuration and make it accessible outside the SipPhoneImp class.
In order to check the private loaded variable outside the SipPhoneImpl is used the public function isLoaded(). This function is useful to check if the endpoint and the PJSIP library is loaded properly for a specific instance of SipPhoneImpl outside this class, mainly from MainWindow class, instances of which use the functions of SipPhoneImpl class.
The last three methods of SipPhoneImpl class, emitRegStateStarted(status : bool), emitRegStateChanged(status : bool) and emitCallStateChanged(role : int, callId : int, state : int, status : int, remoteUri : QString) are specific functions for the architecture of Qt and its way of functioning through the concept of signals and slots. According this concept, when an event happens, a signal can be emitted, and this signal can be connected with a slot or function as known in the common programming conventions. So this three functions emit signal when a registration starts, a registration state changes and when a call state changes. The signals that the instances of SipPhoneImpl emit can be connected with slots (functions) of other classes as well. The most important signal of this class is callStateChanged(int role, int callId, int state, int status, QString remoteUri), emitted by emitCallStateChanged(role : int, callId : int, state : int, status : int, remoteUri : QString) function, which actively notifies the application when an event of call state change happens by executing the function with which it is connected. This signal passes to the function with which it is connected with five parameters, int variable callId, which stores the id of the call, int variables state and status, which store the phase in which a call is and its status, and the last parameter, remoteUri, a QString variable which stores the URI of remote peer of communication.
As seen in the figure 11, SipPhoneImpl class is connected with three classes, from which PjSipAccount and PjSipCall classes.
Figure 12 bellow shows the PjSipAccount class from class diagram. As shown belowPjSipAccount class extends a class of PJSIP library, Account, from which it gets the functionalities basic functionalities in order to create a sip account which can be registered to the PBX server.
PjSipAccount class has only one private variable with class scope, parent, a pointer to the SipPhoneImpl class, from which the instances of PjSipAccount instances are created.
PjSipAccount(parent : SipPhoneImpl *) is the constructor of PjSipAccount class where the value of parameter parent of the constructor is passed to the parent private variable of the PjSipAccount class.
The functions of PjSipAccount, onRegState(prm : OnRegStateParam), onRegStarted(prm : OnRegStateParam) and onIncomingCall(iprm : OnIncomingCallParam) are functions which are called when an event happens. When an event happens, this functions call the functions of SipPhoneImpl class which than emit the signals for the functions with which they are connected in the MainWindow class. First two functions are executed when the state of the account registration changes, while the last function onIncomingCall(iprm : OnIncomingCallParam), is executed when there is an incoming call active.
The other class which extends a class of PJSIP library is PjSipCall shown in the picture 16 below. PjSipCall class, same as PjSipAccount class, extends a class of PJSIP library, the Call class, which provides functionalities of calling process. The connection with SipPhoneImpl class is another common characteristics of PjSipCall and PjSipAccount classes, so the instances of PjSipCall are created in the SipPhoneImpl class in order to be used than from MainWindow class.
PjSipCall class has three variables, parent, audioMedia and captureMedia. This class has a customized constructor and three functions as well. First parameter of PjSipCall class is a pointer to the SipPhoneImpl class, from which the instances of PjSipCall class are created. This variable is used in order to access public functions of SipPhoneImpl class and emit the signals of this functions in order to notify the SipPhoneImpl class for calling events happening.
The other two variables of PjSipCall class, audioMedia and captureMedia, are pointers to the instances of AudioMedia class, and they manage the audio device connections when a call happens.
When an instance of PjSipCall is created, in the constructor of this class, PjSipCall(parent : SipPhoneImpl *, acc : Account, call_id = PJSUA_INVALID_ID :int), are passed three parameters, from which the last one is optional, and has a default value, PJSUA_INVALID_ID, if it isn’t passed when the instance is created. The last two parameters of this constructor are passed to the constructor of the Call superclass when the constructor is executed. The first parameter in the constructor, a pointer to the instances of SipPhoneImpl class, is used to access the public functions of this class, and when the constructor of the class is executed, its value is passed to the private variable, parent, of the PjSipCall class.
All three functions of PjSipCall class are executed when a call event happens. The most important function of this class, onCallState(prm : OnCallStateParam), executes the function emitCallStateChanged(ci.role, ci.id, ci.state, ci.lastStatusCode, QString::fromStdString(ci.remoteUri)) of SipPhoneImpl class, a function which emits the emitCallStateChanged(int role, int callId, int state, int status, QString remoteUri) signal, and after this signal is emitted, the function of MainWindow class with which this signal is connected gets executed. All the classes shown in the class diagram of figure 4 compose a complete and fully functional application. It is the main part of the system, which of course needs the other part of components in order to function. In the classes explained above are implemented several patters and well know coding standards in order to achieve a good quality of the final result.
< Part 4: Understanding VOIP Part 6: Patterns >
(please report broken link in the comment)
In the figure 1 bellow is shown a preview of the class diagram of the application developed with Qt Creator using PJSIP library. In the diagram below are omitted other external classes which are not used directly by the application.
On top of figure 4, within the grey rectangle, are shown the classes of Qt library which are extended by the created classes by the programmer. The QMainWindow is a class which provides a framework for building a graphical view, this is the reason why this class is extended by Login and MainWindow classes. The other class, QObject is a base class for many classes in Qt. It provides a wide set of features. The QObject class is extended by SipPhoneImpl class as well because of usage of signals, which will be explained more in deep in the upcoming paragraphs.
In the blue rectangle in the same picture are shown the PJSIP library classes which are directly extended by other classes of the project. This classes, Account and Call, provide basic functionalities for the VOIP communication. This classes are extended by PjSipAccount and PjSipCall classes respectively in order to provide a customized behavior.
Another module showed in figure 4, within the orange rectangle, are the view classes, the classes in which is created the graphical user interface and is managed the interaction between the user and the graphical interface. This module consists in two classes, Login and MainWindow, which will be explained in the following paragraphs.
The green rectangle contains the classes which make up the object model of the application. This are simple classes with variables and getters/setters for each of them.
The entry point in the application which is called by main() function is Login class. This class, as mentioned above, is one of the classes which manage the graphical user interface. In the figure 2 is shown the Login class with its function.
As shown above the Login class has only one function, on_loginButton_clicked(), which is an event driven function. This function will be executed when the login button will be pressed. Within this function will be created the instance of the database class in order to retrieve the data for the user and compare them with the data given by the user. If the authentication would have been successful, the instance of the MainWindow class would be created and the show() function of the QMainWindow class that MainWindow class extends would be executed.
Figure 3 shows MainWindow class with all its variables and main functions and the relation with other classes.
The incomingCall variable of this class is a Boolean variable which becomes true when there is an incomingCall. The default value of this variable is false as shown in the figure 3.
The other variable, loginWindowof type QWidget*, is a pointer of the instance of Login class which gets the value when the instance of MainWindow class is created in the on_loginButton_clicked() function of Login class and the constructor of MainWindow class is called.
The sipPhone variable, a pointer of an instance of SipPhoneImpl, is instantiated when the instance of the MainWindow is created, so when the constructor of MainWindow is executed.
currentSipUser , a pointer of a SipUser class’s instance, is a variable which gets the value when an instance of MainWindow class is created as well. This value is passed by Login class to MainWindow class through the constructor when a valid user is authenticated.
The other variable, listOfSchedule, a variable of QList
listOfLessonSchedule is similar with listOfScheduleregarding the type, but not the information that this two variables contain. listOfLessonSchedulecontains only a subset of listOfScheduleinformation. In the listOfLessonScheduleis stored the information of cit_scheduletable which has in the column Type the value Lesson.
Different form listOfLessonSchedulethe other variable, listOfOtherSchedule of the same type, contains the information from cit_schedule table which has in the column Type the values different from Lesson.
Another list variable, of type QList, is listOfSipUser, but differently from the list mentioned above, it is a list of pointers of SipUser class’s instances. The information stored in this variable is extracted by cit_user table.
listOfConsultations is a variable of type QList
The list mentioned above are populated through the functions of the DatabaseInteraction class, instance of which is passed in the MainWindow class through the constructor, is used than in MainWindow class to call this methods. The pointer is stored in dbi variable, which has a wider scope than the constructor.
sipState stores the state of the call. This variable is of type QString and it can get the values localRing, remoteRing, calling, and empty stirng.
ringtone and outgoingRing are two variable of type QSoundEffect, which store the ringtone which is played when there are incoming calls, are when are made outgoing calls.
The last variable of MainWindow class, callId, is of type int. This variable stores the id of the incoming, outgoing or ongoing call. This variable is than used to hang up the call when close button is pressed and on_pushButton_closeCall_clicked() function is executed.
The constructor of MainWindow class is as follow, MainWindow(logedInUser : SipUser *, db : DatabaseInteraction *, parent = 0:QWidget *). This constructor is executed when the instance in Login class is created, and the logedInUser, db, parentare variables which are passed by Login class. logedInUservariable is the variable which is then passed to currentSipUservariable in the implementation of the constructor. The db variable is passed to dbi variable explained in the paragraphs above. Parent variable is the instance of Login class, which is created in the beginning of the execution of the application.
getIncomingCall() and setIncomingCall(incomingCall : bool) are the setters and getters of incomingCall variable explained above. onNumberDoubleClick(itemClicked : QTreeWidgetItem *, int) is executed when the double click event has happened on the item of the QTreeWidget that lists the numbers of the users registered in the system.
The other function of MainWindow class, on_callState_changed(role : int, callId : int, state : int, status : int, remoteUri : QString), is a function which is executed when the state of calls changes. The signal for this event is emitted by SipPhoneImpl class’s instance. The first parameter of this function, role, defines the type of call, if it is an incoming call or outgoing call. The second parameter, callId, of the same type, int, is the id of the active instance of Call class. The next parameter, state, defines the stage in which a call is found. The last int variable, status, stores information if a stage of the call is executed correctly or not. remoteUri, the last parameter of this function. This QString variable stores the uri of the remote peer with which the call is held, including protocol, number and domain of remote peer, calling or being called.
on_pushButton_openCall_clicked() is a function that is executed when the user makes an action on the graphic interface of the application, pressing a button, the openCall button. Depending from the value of sipState variable, this function opens an incoming call, or starts a new call.
Another function that is executed when the user makes an action on the graphical interface is on_pushButton_closeCall_clicked(). This function, executed when closeCall button is clicked, ends an ongoing call if there is an ongoing call.
on_pushButton_backSpace_clicked() is executed when the backSpace button is clicked. This function removes the last character from the formed number to dial when there are more than zero characters.
on_comboBox_le_subject_currentIndexChanged(index : int) is a function which is activated when the user makes an action on the graphical interface, but differently from the above functions, this function is executed when the selected item in a combo box is changed not when a button is clicked. on_comboBox_le_subject_currentIndexChanged(index : int) is executed when the selected item in the le_subject combo box is changed. le_subjectcombo box is the one which shows the subjects which a user is associated with in the database, which have the value Lesson in the type column.
Next function which is executed when the selected item in a combo box is changed is on_comboBox_pr_subject_currentIndexChanged(index : int). This functionis executed when the selected item in the pr_subject combo box is changed. pr_subjectcombo box is the one which shows the subjects which a user is associated with in the database, which have the value different from Lesson in the type column.
The other function which is executed when the selected item in a combo box is changed is on_comboBox_co_subject_currentIndexChanged(index : int). This function is executed when this event happens on co_subject combo box. co_subject combo box shows the consultation with which a user is associated with.
The last function of MainWindow class is on_commandLinkButton_addToDial_clicked(). This function is executed when the user clicks on addToDial commandLinkButton in the graphical interface. This function adds the selected number to the numbers to be called.
As shown in the figure 4 bellow and as mentioned in previous paragraphs MainWindow class uses DatabaseInteraction class in order to retrieve the data from the database. The instance of DatabaseInteraction is created in the Login class, then through the constructor is passed to the MainWindow class. In the Login class the instance of the DatabaseInteraction class is instantiated as follow: DatabaseInteraction*db=&DatabaseInteraction::get_instance();, as the constructor of this class is private in order to respect the singleton pattern.
As shown in the picture above DatabaseInteraction class has connection with MainWindow class, by which it is used to retrieve information from the database, and object model classes, which are used to return the information extracted from the database into java objects which are then used by MainWindow class.
After the creation of the instance of the DatabaseInteraction in Login class, the createConnection() function must be called in order to create the connection with the database, where ip of the server, name of database, user name and password to access the database are defined.
As shown in figure 4 the constructor of this class is declared private in order to respect the singleton pattern.
loadSipAccountByUserName(userName : QString) is a public function of this class, as all functions in this class are, except the constructor. This function takes as parameter a variable of type QString, Qt class data type definition for string, which is the user name of a given sip account, and the result of the call in this function is the pointer of a SipAccount instance which contains all the information of the sip account for the given user name parameter. This information is extracted from cit_sip_account table.
The other function of this class, loadScheduleByUserName(userName : QString), returns a pointer to a variable of type QList
Next function loadClassroomByID(id : QString) returns a pointer of Classroom class’s instance. This instance contains the information for the classroom with the given id in the parameter of the function, extracted from the cit_classroom table.
Function loadSubjectByID(id : QString)after execution returns a pointer to an instance of Subject class. This pointer contains information for the given id as parameter for this function. The information stored in this variable is extracted from cit_schedule table.
loadAllSipAccounts() is a function which extracts all the information that cit_sip_accounttable contains and stores it into a variable of type QList
A specific user’s information is extracted through the function loadSipUserByUserName(userName : QString). This function as shown, takes as parameter the user name of a specific user, and returns as result all the information for that specific user in a variable of type SipUser * in the end of the execution, information which is extracted from cit_user table.
Another function which returns information extracted from cit_user table is loadAllSipUsers(), but this function differently from previous function does not return a pointer to an instance of the class SipUser, but a pointer to a list with pointer of instances of SipUser class. The last function of this class, loadConsultationsByUseName(userName : QString), returns a pointer to a list which hold the pointers to the instances of Consultation class. The information returned by this function is extracted by cit_schedule table.
As shown above, all functions of the DatabaseInteraction class except the createConnection() use the object model classes. This classes are simple classes with private variables, which have a limited scope only within the class, and respective getters and setters which expose this variables for public access from other classes. The figure 5 shows one of the object model classes, Consultation class.
As shown in the figure 5 above, Consultation class has direct connection only with DatabaseInteraction class, through which other classes can access this class, like MainWindow class, in which are instantiated instances of Consultation class and other object model classes. Consultation in its variables stores information extracted from the database form the view cit_view_consultation, information related to the consultation process organized by the university. The view cit_view_consultationis created from the join of three tables, cit_schedule, cit_subject and cit_consultation in order to get the user name of the professor that teaches a specific subject.
Consultation class has four QString variables and two QTime variables. This datatypes are defined by Qt library. Also as mentioned before this class contains twelve functions, setters and getters, which make the variables of this class available outside of this class by having a public scope.
The fist variable shown in picture 8, part of Consultation class, is subjectID. The type of subjectID is QString and it gets the value from the Subject_Id column of the table cit_schedule table, which in this table is the foreign key, referencing Id column of cit_subject table, a join which is done during the creation of cit_view_consultationview.
professorUserName is another QString variable which is populated by column ProfessorUserName of cit_view_consultationview, column which is originally created in cit_schedule table where it is part of composite primary key together with Subject_Id column, and it is at the same time foreign key referencing UserName column in cit_user table.
The other QString variable of Consultation class is periodicity. This variable is mapped with Periodicity column of cit_view_consultationview. This variable contains the information about the repetition of a consultation activity.
The last QString variable of Consultation class, days, is a variable mapped with Day column of cit_view_consultationview and contains the days of the week in which is held a specific consultation activity.
The other two remaining variables of the Consultation class, startTime and endTime, differently from previous variables are of type QTime and contain the information for the beginning and ending time of a consultation activity. This two variables are mapped with StartTime and EndTime columns of cit_view_consultationview respectively.
The other class of object model block of classes is SipUser class. Detailed picture of this class extracted from class diagram is shown in figure 6 bellow, together with the other class with which SipUser class is connected, Common class.
SipUser class, as the other object model classes, has connection with DatabaseInteraction class, but differently from the other object model classes, it has connection with another class, Common class.
Common class provides an enum, UserPosition. UserPosition is defined as public in a common class, accessible from other classes in order to keep a standardized value of different user positions and avoid conflicts of usage with different alias of the positions that a user has in system. As other object model classes, SipUser class contains only variables with its respective setters and getters. The variables of this class are mapped with the columns of cit_userand cit_sip_accounttable. Instances of this class contain information about the users of the system in each of its variables as described below.
First variable of SipUser class shown in figure 6 above, sipAccount, is a pointer to the instance of SipAccount class. This variable contain information of cit_sip_account table, differently from the other variables of this class. The information stored in this variable is shown more detailed in the figure 9 below.
The other variable of this table, firstName, is a variable of type QString and stores the first name of a given user of the system, information extracted from FirstName column of cit_user table.
lastName is another variable of type QString, and like firstName is mapped with the cit_user table but with LastName column, information which contains the last name of a specific user of the system.
The last variable of this class, as shown in figure 6 above, is position. This variable differently from other variables of this class is an enum UserPosition, an enum defined in Common class. This variable is mapped with Position column of cit_user table and contains information about the position of a specific user of the system.
Figure 7 shows another object model class, Classroom class. This class has only two variables, id and capacity, and their respective setters and getters. This variables are mapped with the columns of cit_classroom table and contains information related with the classes of the university. The first variable of this class, id, is of type QString, as it can be seen in the figure 7. This column is mapped with column Id of the cit_classroom table. This variable contains the id of a specific classroom in an instance of Classroom class.
The other variable of this class is capacity, and this variable differently from the previous variable contains the capacity of students that a classroom can accommodate. The capacity variable is mapped with Capacity column of cit_classroom table.
In the figure 8 bellow is shown the fragment of class diagram of Schedule class and its relations with other classes. The variables of this class are mapped with the columns of the cit_schedule, cit_subject and cit_classroom tables, containing information about the lesson or project activities held in the university.
The first variable of this class, userName, is of type QString and contains the information stored in the UserName column of cit_schedule table. The other variable of this class, subject, is a variable which contains the pointer to the instances of Subject class. The information that contain the instances of Subject class, mapped in the cit_subject table, are explained in details in the next paragraphs. Figure 10 shows the class Subject extracted from class diagram.
The classroom variable is another pointer which points to the Classroom class. This class was explained in details in the previous paragraphs. Figure 7 shows the variables and functions that Classroom class contains.
Thetitlevariable is a QString variable of Schedule class which is mapped with Title column of cit_schedule table. This variable contains the values of the title for a given schedule in a string format.
The other variable of Schedule class, description, contains the description about a specific schedule. This variable is mapped with Description column of cit_schedule table.
Periodicity of the repetition of an event is stored in the periodicity variable, an int variable of Schedule table. The periodicity variable is mapped with Periodicity column of cit_schedule table.
Days of the week in which an activity is held are stored in the day variable. This variable of type QString is mapped with Day column of cit_schedule table.
Periodicity of repetition of an event, stored in the periodicity variable of Schedule class, is related with another variable of this class, date. The date variable is a variable of QDate type and stores the date of an event, but this variable does not take a value if the periodicity variable, in the same instance, has a value greater than 0. This column is mapped with Date column of cit_schedule table.
The starting and ending time of an event are stored in the startTime and endTime variables of Schedule class respectively, which are both variables of type QTime. This variables are mapped with StartTime and EndTime columns of cit_schedule table.
The last variable of Schedule class, type, is a QString variable. In this variable is stored the type of the activity, if it a lesson or project activity. This variable is mapped with Type column of cit_schedule table.
Figure 9 shows the SipAccount class with its variables and functions in the class diagram. SipAccount is a class which has variables that contain the information used for the connection with the PBX server. The variables of this class are mapped with columns of cit_sip_account table. First variable of this class shown in the figure 9 is displayName, a QString variable. This variable is mapped with DisplayName column of cit_sip_account table. This variable contains the alias of VOIP service system.
The next QString variable of this SipAccount class, userName, is a variable which contains the user name with which the users logs into the PBX server. This variable is mapped with UserName column ofcit_sip_accounttable.
The password variable is another QString variable which together with userName variable make possible the authentication of a user of the system in the PBX server. The password variable is mapped with Password column in cit_sip_account table.
Domain column of cit_sip_account table is mapped with domain variable of the SipAccount table. The domain variable is a QString variable and contains the value of the domain pointing to the server where PBX is hosted.
The last variable, number, is declared as a QString variable as well because the number registered in the PBX server can be a string which contains zero in the first index or symbols that are not numbers. The number variable is mapped with Number column of cit_sip_account table. The last object model class of this project, Subject, is shown in the figure 10 below. As it can be seen in the picture, it has three variables with its respective setters and getters. This class contains information about the subjects which are studied in the university, and the variables of this class are mapped with columns of cit_subject table.
The first variable of Subject class shown in figure 10 above, id, is a QString variable which hold the value of the id of a specific subject. The id variable is mapped with Id column of cit_subject table.
The other variable of Subject class, name, is a QString variable as well. It contains the name of a subject and is mapped with Name column of cit_subject table.
Credits differently from the two first variables of Subject class are stored in a int variable credits. This variable is mapped with Credits column of cit_subject table.
One of the most important classes of the application is SipPhoneImpl, shown in figure 11 bellow. In this class are created the functions which implement the functionalities of communication through PBX server by using the PJSIP library. This class, as seen in the figure extracted from the class diagram bellow, has connection with three classes, MainWindow, PjSipAccount and PjSipCall. MainWindow class uses SipPhoneImpl in order to manage accounts, calls and communication in general between users. The other two classes with which SipPhoneImpl has connection, PjSipAccount and PjSipCall are used in order to access a high level API of PJSIP library, which extend classes which implement function that have low level management function for management of devices of the computer in order to make possible a communication through PBX server to happen.
The other variable of this class, ep, is an Endpoint variable. This variable contains all the configuration of the PJSIP libraries in and ending point, including endpoint and transport configuration.
The other variable, tCfg, of type TransportConfig, contains the transport configuration data, like the protocol, port number of the PBX server. aCfg, of type AccountConfig, contains the account configuration data, like the user credentials, domain of the PBX server etc.
The next variable of SipPhoneImpl class, account, is a pointer to the instances of PjSipAccount class. This variable is used to manage the accounts of the users into the PBX server.
Calls in the class SipPhoneImpl are managed through the variable call of this class, a variable which points to the instances of PjSipCall class. Through call variable in this class can be accessed functions of the class in which this variable points, of PjSipCall, enabling the management of calls operations, like making a new call or hanging up an ongoing call.
When a new instance of SipPhoneImpl is created, in the constructor of this class is set up the endpoint, if the process of the creation of the endpoint has been successful the loaded, a bool variable of SipPhoneImpl class is set to true, else this variable is set to false. This variable shows if the application is ready to make the other steps after the creation of the endpoint in order to be fully functional to receive and make calls.
The duration of calls are stored in the connectDuration of SipPhoneImpl. The connectDuration variable is of type int and stores the seconds of call duration.
The constructor of SipPhoneImplclass is as follows: SipPhoneImpl(protocol : QString, port : int, parent = 0:QObject *). The first parameter in the constructor is protocol, a QString parameter, where is passed the protocol that is used in the connection of the application with the PBX server. The next parameter in the constructor of SipPhoneImpl is an integer parameter, port, storing the port in which is realized the connection with the PBX server. The last parameter of the constructor of SipPhoneImpl class, parent, is a pointer of the instance of QObject class. The value of this parameter stores always the pointer of the instances of MainWindow class, because the instance of SipPhoneImpl class in this application is created only in the constructor of MainWindow class when sip phone functionalities are configured.
After the endpoint is configured, the next step needed in order to be able to make and receive call from the application is to create the account which will be registered in the PBX server, in order that the PBX server will be able to find the route to the created application’s endpoint and the user using the instance of the application would be able to receive and make calls. The process of account creation and registration in the PBX server is done by createAccount(idUri:QString, registrarUri:QString, user:QString, password:QString) and registerAccount() functions.
The createAccount(QString idUri, QString registrarUri, QString user, QString password)function in the first parameter, idUri, a QString variable, contains concatenated the protocol, sip, “:” character, the username of the user, the “@” character and the domain of the server. The second parameter registrarUri, a QString parameter as well, is a concatenated string with several elements as well. In the first part of this string is stored the sip protocol followed by the “:” character as well, than in the next part is appended the domain of the PBX server. The third parameter, user, a QString parameter as well, contains only the username of the account. The last parameter of this function, a QString parameter too, is password, which contains the password of the user being created.
After the account is created by the function above it is registered in the PBX server by the registerAccount()function.
After the account is registered trough the above method, it can be unregistered using unregisterAccount() from the PBX server.
After the endpoint is setup and the account is registered into the PBX server through the method mentioned in the previous paragraphs, the application can make calls to other accounts registered in other instances of application or other sip phones through makeCall(number : QString) function. This function takes as parameter only one parameter, number, a QString variable that passes to makeCall(number : QString)function the number which will be called.
The calls initiated through makeCall(number : QString)function, or the incoming calls, can be hanged up through the hangupCall(callId : int) function. This function has only one int parameter which is used in the implementation of hangupCall(callId : int)function in order to hang up the specific call with the given id. The id of the call is generated when there is an incoming call or a new call is initiated through makeCall function.
When there is an incoming call, acceptCall(callId : int) function is used to answer that call. This function takes as parameter the id of the call, as the previous hangupCall(callId : int) function did, in order to answer to a specific call given by id.
The ring(callId : int) function is used when there is an incoming call in order to notify the local instance of the application that there is an incoming call. This function takes as parameter the id of the incoming call and uses it to create a new instance of Call class.
The getConnectDuration() and setConnectDuration(connectDuration : int) functions are the setters and getters of the private variable connectDuration and make it accessible outside the SipPhoneImp class.
In order to check the private loaded variable outside the SipPhoneImpl is used the public function isLoaded(). This function is useful to check if the endpoint and the PJSIP library is loaded properly for a specific instance of SipPhoneImpl outside this class, mainly from MainWindow class, instances of which use the functions of SipPhoneImpl class.
The last three methods of SipPhoneImpl class, emitRegStateStarted(status : bool), emitRegStateChanged(status : bool) and emitCallStateChanged(role : int, callId : int, state : int, status : int, remoteUri : QString) are specific functions for the architecture of Qt and its way of functioning through the concept of signals and slots. According this concept, when an event happens, a signal can be emitted, and this signal can be connected with a slot or function as known in the common programming conventions. So this three functions emit signal when a registration starts, a registration state changes and when a call state changes. The signals that the instances of SipPhoneImpl emit can be connected with slots (functions) of other classes as well. The most important signal of this class is callStateChanged(int role, int callId, int state, int status, QString remoteUri), emitted by emitCallStateChanged(role : int, callId : int, state : int, status : int, remoteUri : QString) function, which actively notifies the application when an event of call state change happens by executing the function with which it is connected. This signal passes to the function with which it is connected with five parameters, int variable callId, which stores the id of the call, int variables state and status, which store the phase in which a call is and its status, and the last parameter, remoteUri, a QString variable which stores the URI of remote peer of communication.
As seen in the figure 11, SipPhoneImpl class is connected with three classes, from which PjSipAccount and PjSipCall classes.
Figure 12 bellow shows the PjSipAccount class from class diagram. As shown belowPjSipAccount class extends a class of PJSIP library, Account, from which it gets the functionalities basic functionalities in order to create a sip account which can be registered to the PBX server.
PjSipAccount class has only one private variable with class scope, parent, a pointer to the SipPhoneImpl class, from which the instances of PjSipAccount instances are created.
PjSipAccount(parent : SipPhoneImpl *) is the constructor of PjSipAccount class where the value of parameter parent of the constructor is passed to the parent private variable of the PjSipAccount class.
The functions of PjSipAccount, onRegState(prm : OnRegStateParam), onRegStarted(prm : OnRegStateParam) and onIncomingCall(iprm : OnIncomingCallParam) are functions which are called when an event happens. When an event happens, this functions call the functions of SipPhoneImpl class which than emit the signals for the functions with which they are connected in the MainWindow class. First two functions are executed when the state of the account registration changes, while the last function onIncomingCall(iprm : OnIncomingCallParam), is executed when there is an incoming call active.
The other class which extends a class of PJSIP library is PjSipCall shown in the picture 16 below. PjSipCall class, same as PjSipAccount class, extends a class of PJSIP library, the Call class, which provides functionalities of calling process. The connection with SipPhoneImpl class is another common characteristics of PjSipCall and PjSipAccount classes, so the instances of PjSipCall are created in the SipPhoneImpl class in order to be used than from MainWindow class.
PjSipCall class has three variables, parent, audioMedia and captureMedia. This class has a customized constructor and three functions as well. First parameter of PjSipCall class is a pointer to the SipPhoneImpl class, from which the instances of PjSipCall class are created. This variable is used in order to access public functions of SipPhoneImpl class and emit the signals of this functions in order to notify the SipPhoneImpl class for calling events happening.
The other two variables of PjSipCall class, audioMedia and captureMedia, are pointers to the instances of AudioMedia class, and they manage the audio device connections when a call happens.
When an instance of PjSipCall is created, in the constructor of this class, PjSipCall(parent : SipPhoneImpl *, acc : Account, call_id = PJSUA_INVALID_ID :int), are passed three parameters, from which the last one is optional, and has a default value, PJSUA_INVALID_ID, if it isn’t passed when the instance is created. The last two parameters of this constructor are passed to the constructor of the Call superclass when the constructor is executed. The first parameter in the constructor, a pointer to the instances of SipPhoneImpl class, is used to access the public functions of this class, and when the constructor of the class is executed, its value is passed to the private variable, parent, of the PjSipCall class.
All three functions of PjSipCall class are executed when a call event happens. The most important function of this class, onCallState(prm : OnCallStateParam), executes the function emitCallStateChanged(ci.role, ci.id, ci.state, ci.lastStatusCode, QString::fromStdString(ci.remoteUri)) of SipPhoneImpl class, a function which emits the emitCallStateChanged(int role, int callId, int state, int status, QString remoteUri) signal, and after this signal is emitted, the function of MainWindow class with which this signal is connected gets executed. All the classes shown in the class diagram of figure 4 compose a complete and fully functional application. It is the main part of the system, which of course needs the other part of components in order to function. In the classes explained above are implemented several patters and well know coding standards in order to achieve a good quality of the final result.
< Part 4: Understanding VOIP Part 6: Patterns >
(please report broken link in the comment)
Comments
Post a Comment