You are on page 1of 278

TABLE OF CONTENTS

1. Introduction/ Objectives

2. System Analysis

2.1 Identification of Need


2.2 Preliminary Investigation

3. Feasibility Study

3.1 Technical Feasibility


3.2 Economical Feasibility
3.3 Operational Feasibility

4. Software Engineering Paradigm applied

5. Software and Hardware Requirement Specifications

6. System Design

7. Coding

8. Code Efficiency

9. Optimisation of code

10. Validation checks

1
11. Implementation and Maintenance

11.1 Testing (Testing techniques and Testing strategies used along


with the test data and the errors listed for each test case).

12 System Security measures (Implementation of security for


the s/w developed)

13 Cost Estimation of the Project

14 Reports

15 PERT Chart, Gantt Chart

16 Future scope and further enhancement of the Project

17 Bibliography

18 Glossary

2
INTRODUCTION/OBJECTIVE

Title of the Project

Wireless communication

objective of project

To eliminate wires and cables between stationary and mobile devices, facilitates

fast and smooth data and voice communication.

Introduction

The scope of the project involves the establishment of the connection between the

two entities one master and the other client. Any two devices that come in contact

can exchange data with the help of this bluetooth protocol stack. . The medium of

exchange mostly used is electromagnetic radiations; this is one of the forms of

wireless communication. Due to hardware constraints in using this wireless form of

communication the best approach used in the project for data communication is

through socket programming assuming a network connection.

BLUETOOTH is a Radio specification protocol for wireless connectivity between

various devices having a working range between 10 m to 100m in the 2.4 GHz

3
band. The channel is represented by a pseudo-random hopping sequence

hopping through the 79 or 23 RF channels. Two or more Bluetooth devices using

the same channel form a piconet. There is one master and one or more slave(s) in

each piconet. The BLUETOOTH protocol stack consists of various layers each

having various functionalities.

In the BLUETOOTH protocol stack, the layer just below the Applications layer is

the Session layer, which makes use of OBEX functions, which initiates data

exchange between the two devices.

The OBEX (OBject EXchange) is the session layer of the BLUETOOTH stack. It

manages sessions and dialogues between BLUETOOTH devices. Another

important function of the OBEX is to exchange objects between a set of

BLUETOOTH devices. OBEX also handles multiple connections. It performs all

the operations in a request-response format.

The OBEX layer is designed for use in applications of BLUETOOTH such as File

Transfer, Synchronisation Profile, and Businesscard Exchange. The OBEX layer

will be integrated on the stack and used in any of the devices that are

BLUETOOTH specific. This layer helps in establishing the connection and

maintaining the connection. It helps the dialogue control between the two entities.

4
The scope of the project involves the establishment of the connection between the

two entities – one master and the other client. Any two devices that come in

contact can exchange data with the help of this bluetooth protocol stack. The

medium of exchange mostly used is electromagnetic radiations; this is one of the

forms of wireless communications. Due to the hardware constraints in using this

wireless form of communications, the best approach used in the project for data

communication is through sockets programming assuming a network connection.

This project demonstrates the data exchange between a master and a single client

using the form of OBEX (Object Exchange) present in Sessions layer of the

Bluetooth protocol stack. The data exchange between the two entities is done

through Sockets programming making use of UDP packet data exchange. Each

request of data exchange gets an acknowledgement for the data received since the

data is sent in the form of packets. Each packet size is fixed based on the OBEX

protocol standards.

AN Introduction TO Object Exchange Protocol

One of the most basic and desirable uses of the IrDA infrared communication

protocols is simply to send an arbitrary “thing”, or data object, from one device to

another, and to make it easy for both application developers and users to do so. We

5
refer to this as object exchange (un-capitalized), and it is the subject of the protocol

described in this document.

This document describes the current status of the protocol IrOBEX (for IrDA

Object Exchange, OBEX for short). OBEX is a compact, efficient, binary protocol

that enables a wide range of devices to exchange data in a simple and spontaneous

manner. OBEX is being defined by members of the Infrared Data Association to

interconnect the full range of devices that support IrDA protocols. It is not,

however, limited to use in an IrDA environment.

OBEX performs a function similar to HTTP, a major protocol underlying the

World Wide Web. However, OBEX works for the many very useful devices that

cannot afford the substantial resources required for an HTTP server, and it also

targets devices with different usage models from the Web. OBEX is enough like

HTTP to serve as a compact final hop to a device “not quite” on the Web.

A major use of OBEX is a “Push” or “Pull” application, allowing rapid and

ubiquitous communications among portable devices or in dynamic environments.

For instance, a laptop user pushes a file to another laptop or PDA; an industrial

computer pulls status and diagnostic information from a piece of factory floor

machinery; a digital camera pushes its pictures into a film development kiosk, or if

6
lost can be queried (pulled) for the electronic business card of its owner. However,

OBEX is not limited to quick connect- transfer-disconnect scenarios - it also

allows sessions in which transfers take place over a period of time, maintaining the

connection even when it is idle.

PCs, pagers, PDAs, phones, printers, cameras, auto-tellers, information kiosks,

calculators, data collection devices, watches, home electronics, industrial

machinery, medical instruments, automobiles, and office equipment are all

candidates for using OBEX. To support this wide variety of platforms, OBEX is

designed to transfer flexibly defined “objects”; for example, files, diagnostic

information, electronic business cards, bank account balances, electrocardiogram

strips, or itemized receipts at the grocery store. “Object” has no lofty technical

meaning here; it is intended to convey flexibility in what information can be

transferred. OBEX can also be used for Command and Control functions -

directives to TVs, VCRs, overhead projectors, computers, and machinery. Finally,

OBEX can be used to perform complex tasks such as database transactions and

synchronization.

OBEX is designed to fulfill the following major goals:

1. Application friendly - provide the key tools for rapid development of

applications.

7
2. Compact - minimum strain on resources of small devices.

3. Cross platform.

4. Flexible data handling, including data typing and support for standardized types

- this will allow devices to be simpler to use via more intelligent handling of data

inside.

5. Maps easily into Internet data transfer protocols.

6. Extensible - provide growth path to future needs like security, compression, and

other extended features without burdening more constrained implementations.

7. Testable and Debuggable.

Bluetooth is short-range wireless communications technology

• Announced in May 1998 by an industry consortium (SIG)

• Low cost

• Simple, but powerful, applications

• Huge growth predicted

This project demonstrates the data exchange between a master and a single

client using the form of OBEX (Object Exchange) present in Sessions layer of the

Bluetooth protocol stack. The data exchange between the two entities is done through

Sockets programming making use of UDP packet data exchange. Each request of data

exchange gets an acknowledgement for the data received since the data is sent in the

form of packets. Each packet size is fixed based on the OBEX protocol standards.

8
It is a cutting edge open specification that enables short range (10m – 100m)

wireless connections between computers, handholds, personal digital assistants,

mobile phones, camera phones, printers, digital cameras, headset, keyboards and even

a computer mouse. Bluetooth wireless technology uses a globally available frequency

band of 2.4 GHz, for worldwide compatibility. Bluetooth protocol stack consist of

various layers each having various functionalities.

• A new Global Standard for data and voice.

• Good Bye Cables!

9
OBEX is a session layer of the BLUETOOTH stack. It manages session and

dialogues between Bluetooth devices. It also handles multiple connections. It

performs all the operations in a request response format.

10
SYSTEM ANALYSIS

Identification of Need

If we look around our computer table and notice the one thing present in

abundance? Yes, it is wires. Wires of all sizes and colours entangled mercilessly, so

that if you need to change the wires that connect our speaker, we will first need to

negotiate the guessing game of which wire goes where. Technology, yet again, has

come to our rescue in the form of Bluetooth. We have implemented this technology

to our project. It establishes wireless connection between two entities one master

and other slave. Now a day we would like to surf the Internet through a mobile

phone or using laptop. This can be achieving by this wire less communication

technologies.

11
Preliminary Investigation

After identifying the need we require to provide the framework from which a

comprehensive plan for software development can be established. To achieve this

we have to do some investigation. As our requirement is to communicate between

to computer system or we can say to establish wireless communication between

server and clients. So we must have a server module as well as client module plus

controller module that will control the communication. The major functions that

would be performed are: -

• CONNECT

• PUT

• GET

• SETPATH

• DISCONNECT

• ABORT

12
SYSTEM MODEL

13
CONNECT FUNCTION:

This operation initiates the connection and sets up the basic expectations of each

side of the link.

Request format is:

The CONNECT request and response must each fit in a single packet.

Implementations are not required to recognize more than the first 7 bytes of these

packets, though this may restrict their usage.

The version number is the version of the OBEX protocol

All flags except 0 are currently reserved.

Maximum OBEX packet length is a two byte unsigned int that indicates

maximum size of OBEX packet a device can receive. The max size is of 64k-1.

14
The connect request from the application layer comes with a Target header,

specifying the service available on the server side. The server checks for the

specified Target, if its not a valid Target, connect response with error response code

is sent, else connect response with success code, along with WHO header is sent to

the client.

Many other optional headers can be sent like count, length etc.

PUT FUNCTION:

The put operation sends one object from client to the server.

A PUT request consists of one or more request packets, the last of which has the

Final bit set in the opcode. The implementer may choose whether to include an

object Body header in the first packet, or wait until the response to the initial

packet is received before sending any object body chunks.

Put request format is:

15
The request packet has a Name, Type, Connection-id and a description header. The

type header is required for non-file formats.

Each packet is acknowledged by a response from the server as described in the

general session model discussion above.

Put Response format is :

The put response may be continue-0x90, success-0xA0 for the last packet with an

End-Of- Body-header, anything is considered as failure. The put request may come

with a Target, and has to handled as a connect request.

GET FUNCTION:

The GET operation requests that the server return an object to the client. The

request is normally formatted as follows:

16
The final bit is used in a GET request to identify the last packet containing headers

describing the item being requested, and the request phase of the GET is complete.

Thus signaling the server to start sending the object back. Once a GET is sent with

the final bit, all subsequent GET request packets must set the final bit until the

operation is complete.

Get Response Format:

A typical multi-step GET operation proceeds as follows:

The client sends a GET request that may include a Name header; server responds

with 0x90 (Continue) and headers describing the name and size of the object to be

returned. Seeing the Continue response code, the client sends another GET request

(with final bit set and no new headers) asking for additional data, and the server

responds with a response packet containing more headers (probably Body Headers)

along with another Continue response code. As long as the response is Continue,

17
The client continues to issue GET requests until the final body information (in an

End-of-Body header) arrives, along with the response code 0xA0 Success.

SETPATH FUNCTION:

The SETPATH operation is used to set the “current directory” on the receiving side in

order to enable transfers that need additional path information. For instance, when a

nested set of directories is sent between two machines, SETPATH is used to create

the directory structure on the receiving side. The Path name is contained in a Name

header. The SETPATH request and response each always fit in one OBEX packet

and have the Final bit set.

SetPath Request format is :

SetPath Response Format is :

18
Servers are not required to store objects according to SETPATH request, though it is

certainly useful on general-purpose devices such as PCs or PDAs. If they do not

implement SETPATH, they may return C0 (Bad Request) or C3 (Forbidden), and the

client may decide whether it wishes to proceed. When a new OBEX connection is

established, the OBEX server’s current folder should be its root folder. In this manner

a device may retrieve (or serve) objects from the root folder without requiring the

client to perform a SETPATH to the root first.

DISCONNECT FUNCTION:

This opcode signals the end of the OBEX session. It may include a Description header

for additional user readable information. The DISCONNECT request and response

must each fit in one OBEX packet and have their Final bits set.

Disconnect Request Format is :

Disconnect Response Format is :

19
The response to DISCONNECT is 0xA0 (Success), optionally followed with a

Description header. A DISCONNECT may not be refused. However, if the

disconnect packet contains invalid information, such as an invalid Connection Id

header the response code may be “Service Unavailable” (0xD3). Server side handling

of this case is not required.

ABORT FUNCTION:

The ABORT request is used when the client decides to terminate a multi-packet

operation (such as PUT) before it would normally end. The ABORT request and

response each always fit in one OBEX packet and have the Final bit set. An ABORT

operation may include headers for additional information, such as a Description

header giving the reason for the abort.

Abort Request format is :

20
Abort Response format is :

The response to ABORT is 0xA0 (success), indicating that the abort was received

and the server is now resynchronized with the client. If anything else is returned,

the client should disconnect.

21
FEASIBILITY STUDY

During the feasibility study, the project team should create the following

materials:

• Clear commitment from the project’s key decision maker or executive

sponsor

• Vision statement for the project

• Business case for the software

• Original effort and schedule targets

• Current effort and schedule estimates

• List of top risks to the project and plans to manage each risk

• Detailed user interface prototype, if the system has a significant user

interface element

• Requirements specification

• Software quality assurance plan

• Detailed software development plan

Creation of each of these materials addresses one or more significant project

hazards. Poor requirements, lack of effective executive sponsorship, and

inadequate planning were all cited as major causes of project failure by the

Standish Group survey.

22
If the project team can’t prepare these materials for the feasibility study, you

shouldn’t hold the review meeting because you won’t have enough

information to determine the project’s viability. If the project team tries to

create these materials and repeatedly fails to do so, you should assume that

the project is somehow being prevented from preparing for success and faces

a great risk of cancellation downstream.

The amount of calendar time required to create these materials depends

mostly on how much work is needed to identify the software’s requirements.

If end users know exactly what software they want built, this period might

take only 10 percent of the software’s total development schedule. In more

typical cases, it might take 10 to 20 percent of the total development

schedule. On some projects, the hardest part of the software development job

is helping the end users figure out what they want built, and so occasionally

this part of the project can take 25 percent of the total development schedule

or more. The initial funding request and plans for the Feasibility Review

should take this variability into account.

23
Agenda of the Feasibility Review

The feasibility review should focus on the following questions:

• Is the product concept viable?

• Will it be possible to develop a product that matches the project’s vision

statement?

• What are the current estimated cost of and schedule for completing the project?

• How big is the gap between the original cost and schedule targets and current

estimates?

• Is the business case for the software justified when the current cost and

schedule estimates are considered?

• Have the major risks to the project been identified, and can they be

surmounted?

• Is the requirements specification complete and stable enough to support

remaining development work?

• Have users and developers been able to agree on a detailed user interface

prototype? If not, are the requirements really stable?

• Is the software development plan complete and adequate to support further

development work?

24
The work done during the first 10-20 percent of the project should be

sufficient to answer these questions, which will give the client or top

management enough information to decide whether to fund the rest of the

project.

Major Benefits of the Feasibility Study

Breaking a software project into a feasibility study phase and a main

development phase helps software organizations in at least three ways.

First, some people view any canceled project as a failure, but a project

canceled at the 10-20 percent complete point should be considered a clear

success. Canceling one project that ultimately goes nowhere after it is 10-20

percent instead of 80-90 percent complete (or as Jones points out, 200

percent complete) can pay for the exploratory phases of a lot of other

projects.

Second, a feasibility study sets up a project manager to make more accurate

funding requests than average. The project manager first requests funding for the

feasibility study phase, during which the first 10-20 percent of the project is

completed. After the feasibility study materials have been reviewed and the people

holding the project’s purse strings have made a "go" decision, the manager

25
requests funding for the remainder of the project. At this point there will still be a

large potential variation in project cost.

Finally, requiring the project manager to complete 10-20 percent of a project

before requesting funding for the rest of it forces a focus on upstream activities that

are critical to a project’s success. These activities are often abbreviated or ignored,

and the damaging consequences of such neglect don’t otherwise become apparent

until late in the project. If the project team is required to complete the most

important upstream work before proceeding with downstream work, overall project

risk can be substantially reduced.

Technical Feasibility.

Technical feasibility refers to the ability of the process to take advantage of the

current state of the technology in pursuing further improvement. The technical

capability of the personnel as well as the capability of the available technology

should be considered. Technology transfer between geographical areas and

cultures needs to be analyzed to understand productivity loss (or gain) due to

differences.

26
Economic Feasibility.

This involves the feasibility of the proposed project to generate

economic benefits. A benefit-cost analysis and a breakeven analysis

are important aspects of evaluating the economic feasibility of new

industrial projects. The tangible and intangible aspects of a project

should be translated into economic terms to facilitate a consistent basis

for evaluation.

Scope of Feasibility Analysis

In general terms, the elements of a feasibility analysis for a project should cover the

following:

Need Analysis. This indicates a recognition of a need for the project. The need

may affect the organization itself, another organization, the public, or the

government. A preliminary study is then conducted to confirm and evaluate the

need. A proposal of how the need may be satisfied is then made. Pertinent

questions that should be asked include:

• Is the need significant enough to justify the proposed project?

• Will the need still exist by the time the project is completed?

• What are the alternate means of satisfying the need?

27
• What are the economic, social, environmental, and political impacts of the

need?

28
SOFTWARE ENGINEERING PARADIGM APPLIED

To solve actual problems a team of engineers must incorporate a development

strategy that encompasses the process, methods, and tools layers and the generic

phase. This strategy is often referred to as a process model or a software

engineering paradigm.

Problem
definition

Status Technical
quo development

Solution
integration

All software development can be characterized as a problem-solving loop in

which four distinct stages are encountered: status quo, problem definition, technical

development, and solution integration. Status quo “represents the current state of

affair”; problem definition identifies the specific problem to be solved; technical

development solves the problem through the application of some technology, and

solution integration delivers the results.

29
Either we decide the linear sequential model or the prototyping model, the

model should be appropriate for the customers who have requested the product and

the people who will do the work, (2) the characteristics of the product itself, and (3)

the project environment in which the software team works. When a process model

has been selected, the team then defines a preliminary project plan based on the set

of common process framework activities. Once the preliminary plan is established,

process decomposition begins. That is, a complete plan, reflecting the work tasks

required to populate the formwork activities must be created.

30
SOFTWARE AND HARDWARE REQUIREMENT

SPECIFICATIONS

Hardware :-

Intel Pentium I or Higher

Ethernet LAN Card.

Software:-

Operating System : Linux 7.1

Rdbms / Back End : Postgre Sql

Language: C

Front End : QT Designer

This document is a software requirements specification for the OBEX layer of the

BLUETOOTH protocol stack.

Scope

This SRS presents requirements, use cases and an overview of the project. This

document is to be used as a reference for the development and as a tool for use in

evaluation at the end of the project.

31
Definition, Acronyms and Abbreviations

BLUETOOTH - A Radio Specification protocol for wireless connectivity

between various devices having a working range between 10m to 1000 m in the

2.4 GHz ISM band.

Rfcomm – A cable replacement protocol providing the transport layer facilities.

Client - A BLUETOOTH enabled device, which has requested another

BLUETOOTH

device for a connection to setup a session.

Server - A BLUETOOTH enabled device which has been requested for a

connection.

References :

BLUETOOTH Specifications – Core, Courtesy BLUETOOTH SIG

BLUETOOTH Specifications – Profiles , Courtesy BLUETOOTH SIG

IrDA Specification for the OBEX layer - Courtesy IrDA

Design requirements :

Specification Constraints

32
• The OBEX software should comply with the IrOBEX Specifications given

by the Infrared Data Association (IrDA).

• The OBEX software should comply with the OBEX related Specifications

given by the BLUETOOTH Special Interest Group(SIG).

User Interface Requirements :

The application layer designed to test OBEX API’s forms the User Interface. The

application will be designed to make use of the API’s provided by the OBEX

layer. The user interface has been designed with the help of Qt designer.

External Interface Requirements:

The Message Queues form the Interface between the Application layer and the

OBEX layer. The Sockets form the Interface for the Client and the server. The

communication protocol for the transport layer UDP/IP .

Operational Requirements:

The OBEX (OBject EXchange) is the session layer of the BLUETOOTH stack. It

manages sessions and dialogues between BLUETOOTH devices. Another

33
important function of the OBEX is to exchange objects between a set of

BLUETOOTH devices. OBEX also handles multiple connections. It performs all

the operations in a request-response format.

Target Environment:

The OBEX layer is designed for use in applications of BLUETOOTH such as File

Transfer, Synchronisation Profile, and Businesscard Exchange. The OBEX layer

will be integrated on the stack and used in any of the devices that are

BLUETOOTH specific. This layer helps in establishing the connection and

maintaining the connection. It helps the dialogue control between the two entities.

Assumptions & Dependencies of this software

OBEX layer is a part of the BLUETOOTH stack. Its working depends on the

presence of an Application Layer on top and Transport layer down.

Assumption On Input and Other concepts.

The application residing above the OBEX passes certain requests for operations to be

performed. These form the inputs to the OBEX. The main for the OBEX are organized

34
depending on the APIs of the OBEX layer. The APIs are CONNECT, PUT, GET,

DISCONNECT, ABORT, SETPATH.

Description

The requirement of OBEX layer depends on the functional requirement of the stack.

The outcome of this product is to do the Object Exchange between two entities. It fits

below the Application layer. The OBEX protocol is a session level protocol that

specifies the structure for the conversation between devices. It also contains a model

for representing objects. The OBEX application framework is built on top of the

OBEX protocol. Its main purpose is to facilitate interoperability between devices using

the OBEX protocol. Both of these are discussed in more detail below.

Functional Requirements

The OBEX specifications consist of the three application profiles, viz., Object Push

profile, File Transfer profile and Synchronization profile.

Functions associated for the Object Push profile

• Object Push function

• Business Card Exchange function

35
The Object Push function initiates the function that pushes one or more Objects to a

Push Server.

The Business Card Exchange function initiates the function that exchanges Business

cards with a Push Server.

The major functions performed by OBEX for any Application are:

CONNECT, PUT , GET , SETPATH ,DISCONNECT and ABORT.

Non Functional Requirements:

The software can be implemented only on UNIX/LINUX systems on which

PostgreSql and Qt designer are installed. The application will run on all POSIX

compliant systems. The response time should be satisfactory for normal users.

SYSTEM DESIGN

System Description

36
OBEX WITHIN THE BLUETOOTH STACK

Low Level Design:

Low level design is a stage in a project wherein the inputs from H.L.D. are used

and the lowest ordker specifications are arrived. Low-level design can be further

classified in to 3 phases as Data Design , Procedural Design ,j Interface design.

In LLD all details regarding the implementations of each module have to be

worked out in detail , all algorithnnnn and data structure issues are resolved in this

phase as well also the detailed program logic should be given for coding. The

outputs of this process can be used by the programmer dirrrrectly to start coding.

Data Design

37
Data Structures used globally:

Struct packet_info

___uint8_t opcode;

___uint8_t headers[NO_OF_HEADERS];

___uint16_t hdr_length[NO_OF_HEADERS];

___uint8_t flag, constant;

___uint16_t maxsize;

};

struct ap2ctrl

{ long mtype;

pid_t pid;

_uint8_t buffer[MAZ_OBJECT_SIZE];/* The actual data to be sent*/

_uint32_t length; /* length of buffer, ipaddr-iip address of remote m/c */

unsigned short int port;

struct in_addr ipaddr;

};

Procedural Design

The OBEX layer is main divide into 2 procedure controller and child.

38
Controller:

Contoller handles all the inputs coming from Appliction layer and the peer OBEX.

This procedure manages multiple connection/ sessions. It forks a child for every

connection. It checks for validity of connections & data sends the data packets to

respective child.

Child:

The controller for every connection request from the Application creates an

instance of this procedure. There after data transfer (requests and responses)

between Child & controller and between the child and the application is by the

means of message queue.

Interface Design:

Message queues from the interface between the Application layer & the OBEX

layer. The OBEX Controller and the child also communicate by the same

means. The message queues used transfer data in one direction only.

Socket layer forms the interface for the OBEX client and the OBEX server. The

communication protocol for the transport layer is UDP/IP. This is currently

simulation the lower layers. To port the software into a different environment the

IP address has to be changed suitably. Care should be taken regarding the port

numbers

39
CODING

The files of Server Side is as follows:

Common.h

40
#include<stdio.h>

#include<sys/types.h>

#include<string.h>

#include "types.h"

void init_packet_info(struct packet_info *s_packet);

__uint8_t *ATOU(__uint8_t *asc);

__uint8_t *construct_packet(int packet_type,struct

packet_info s_packet,__uint16_t *len);

postgress.h

41
#ifndef POSTGRES_H

#define POSTGRES_H

#include "postgres_ext.h"

#include "c.h"

#include "utils/elog.h"

#include "utils/mcxt.h"

#include "utils/palloc.h"

/* ------------------------------------------------

Section 1: simple type definitions

------------------------------------------------*/

typedef int16 int2;

typedef int32 int4;

typedef float float4;

typedef double float8;

typedef int4 aclitem;

#define InvalidOid 0

#define OidIsValid(objectId) ((bool) ((objectId) !=

InvalidOid))

/* unfortunately, both regproc and RegProcedure are used

*/

42
typedef Oid regproc;

typedef Oid RegProcedure;

/* ptr to func returning (char *) */

#if defined(__mc68000__) && defined(__ELF__)

typedef int32 ((*func_ptr) ());

#else

typedef char *((*func_ptr) ());

#endif

#define RegProcedureIsValid(p) OidIsValid(p)

/* ------------------------------------------------

Section 2: variable length and array types

-------------------------------------------------*/

struct varlena

int32 vl_len;

char vl_dat[1];

};

#define VARSIZE(PTR) (((struct varlena *)(PTR))->vl_len)

#define VARDATA(PTR) (((struct varlena *)(PTR))->vl_dat)

43
#define VARHDRSZ ((int32) sizeof(int32))

typedef struct varlena bytea;

typedef struct varlena text;

typedef int2 int2vector[INDEX_MAX_KEYS];

typedef Oid oidvector[INDEX_MAX_KEYS];

#undef TUPLE_TOASTER_ACTIVE

#undef TUPLE_TOASTER_ALL_TYPES

#ifdef TUPLE_TOASTER_ACTIVE

typedef struct varattrib

int32 va_header; /* External/compressed storage */

/* flags and item size */

union

struct

int32 va_rawsize; /* Plain data size */

}va_compressed; /* Compressed stored

attribute */

struct

44
{

int32 va_rawsize; /* Plain data size */

Oid va_valueid; /* Unique identifier of value

*/

Oid va_longrelid; /* RelID where to find

chunks */

Oid va_rowid; /* Main tables row Oid */

int16 va_attno;/* Main tables attno */

}va_external;

/* External stored attribute */

char va_data[1]; /* Plain stored attribute */

} va_content;

} varattrib;

#define VARATT_FLAG_EXTERNAL 0x8000

#define VARATT_FLAG_COMPRESSED 0x4000

#define VARATT_MASK_FLAGS 0xc000

#define VARATT_MASK_SIZE 0x3fff

45
#define VARATT_SIZEP(_PTR)(((varattrib *)(_PTR))-

>va_header)

#define VARATT_SIZE(PTR) (VARATT_SIZEP(PTR) &

VARATT_MASK_SIZE)

#define VARATT_DATA(PTR) (((varattrib *)(PTR))-

>va_content.va_data)

#define VARATT_IS_EXTENDED(PTR)\

((VARATT_SIZEP(PTR) & VARATT_MASK_FLAGS) != 0)

#define VARATT_IS_EXTERNAL(PTR)\

((VARATT_SIZEP(PTR) & VARATT_FLAG_EXTERNAL)!= 0)

#define VARATT_IS_COMPRESSED(PTR) \

((VARATT_SIZEP(PTR) & VARATT_FLAG_COMPRESSED) != 0)

extern varattrib *heap_tuple_untoast_attr(varattrib *

attr);

#define VARATT_GETPLAIN(_ARG,_VAR) {

if (VARATTR_IS_EXTENDED(_ARG))

(_VAR) = (void *)heap_tuple_untoast_attr(_ARG);

46
else

(_VAR) = (_ARG);

#define VARATT_FREE(_ARG,VAR) do {

if ((void *)(_VAR) != (void *)(_ARG))

pfree((void *)(_VAR));

} while (0)

#else /* TUPLE_TOASTER_ACTIVE */

#define VARATT_SIZE(__PTR) VARSIZE(__PTR)

#define VARATT_SIZEP(__PTR) VARSIZE(__PTR)

#endif /* TUPLE_TOASTER_ACTIVE */

typedef union nameData

char data[NAMEDATALEN];

47
int alignmentDummy;

} NameData;

typedef NameData *Name;

#define NameStr(name) ((name).data)

/*-------------------------------------------

Section 3: TransactionId and CommandId

-------------------------------------------- */

typedef uint32 TransactionId;

#define InvalidTransactionId 0

typedef uint32 CommandId;

#define FirstCommandId 0

/* ------------------------------------------------

Section 4: genbki macros used by the

catalog/pg_xxx.h files

----------------------------------------------- */

#define CATALOG(x) \

typedef struct CppConcat(FormData_,x)

#define DATA(x) extern int errno

#define DESCR(x) extern int errno

48
#define DECLARE_INDEX(x) extern int errno

#define DECLARE_UNIQUE_INDEX(x) extern int errno

#define BUILD_INDICES

#define BOOTSTRAP

#define BKI_BEGIN

#define BKI_END

/* ------------------------------------------------

Section 5: random stuff CSIGNBIT, STATUS...

--------------------------------------------------

*/

#define ISIGNBIT (0x80000000)

#define WSIGNBIT (0x8000)

/* msb for char */

#define CSIGNBIT (0x80)

#define STATUS_OK (0)

#define STATUS_ERROR (-1)

#define STATUS_NOT_FOUND (-2)

#define STATUS_INVALID (-3)

#define STATUS_UNCATALOGUED (-4)

49
#define STATUS_REPLACED (-5)

#define STATUS_NOT_DONE (-6)

#define STATUS_BAD_PACKET (-7)

#define STATUS_FOUND (1)

/* ---------------------------------------

Cyrillic on the fly charsets recode

------------------------------------------- */

#ifdef CYR_RECODE

extern void SetCharSet();

#endif /* CYR_RECODE */

#endif /* POSTGRES_H */

50
postgres-ext.h

#ifndef POSTGRES_EXT_H

#define POSTGRES_EXT_H

typedef unsigned int Oid;

#define NAMEDATALEN 32

#endif

51
types.h

#include <unistd.h>

#include <stdio.h>

#include <stdlib.h>

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

#include <error.h>

#include <errno.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <netinet/tcp.h>

#include <arpa/inet.h>

#include <signal.h>

/*definition of standard port and queues*/

#define CTRLQ1ID 1234L

#define APSRVQ2ID5432L

#define CTRL_PORT650

52
/*standard size information for this implemntation of

obex*/

#define MAX_PACKET_SIZE 1024

#define DEF_PACKET_SIZE 0xFF

#define MSGMAX 4080

/*max allowed by linux during the time

of implementation*/

#define MAX_OBJECT_SIZE MSGMAX-sizeof(long)-

sizeof(pid_t)-4-sizeof(unsigned short)-sizeof(struct

in_addr)

#define UUID 16

#define VERSION 0x10

#define NO_OF_HEADERS 12

#define NAME 0x01

#define TYPE 0x42

#define LENGTH 0xC3

#define TIME 0x44

#define DESCRIPTION 0x05

#define WHO 0x4A

#define TARGET 0x46

53
#define BODY 0x48

#define END_OF_BODY 0x49

#define CONNECT_ID 0xCB

#define AUTH_CHAL 0x4D

#define AUTH_RESP 0x43

#define CONNECT 0x80

#define DISCONNECT 0xA0

#define PUT 0x02

#define FPUT 0x82

#define GET 0x03

#define SETPATH 0x85

#define ABORT 0xFF

#define CONTINUE 0x10

#define SUCCESS 0x20

#define BAD_REQ 0x40

#define UNAUTH 0x41

#define FORBID 0x43

#define NOT_FOUND 0x44

#define REQ_TIMEOUT 0x48

#define LENGTH_REQ 0x4B

54
#define ENTITY_LARGE 0x4D

#define UNSUPP_TYPE 0x4F

#define INTERNAL_ERR 0x50

#define NOT_IMP 0x51

#define SERV_UNAV 0x53

#define CONNECT_RESP 0x01

#define PUT_RESP 0x02

#define DISCON_RESP 0x03

#define GET_RESP 0x04

#define SET_RESP 0x05

#define ABORT_RESP 0x06

enum{ CHILD_NOEXIST=1 , REQ_FAILURE , RESOURCE_FAILURE ,

TIMED_OUT ,ILLEGAL_RESP};

#define SIZE_OF_ID 0x04

#define SIZE_OF_TIME 0x04

#define SIZE_OF_LEN 0x04

#define ALLOC_MEM(type,num) (type *)malloc(num

*sizeof(type))

#define DTOH(num,l,r) (num<<((l-1)*8))>>((r-1)*8);

55
struct connect_info{

__uint64_t length;

__uint8_t who[UUID+1],wflag;

__uint8_t target[UUID+1],tflag;

ushort sin_port;

char inet_addr[16];

};

struct packet_info{

__uint8_t opcode;

/*__uint32_t length;

__uint32_t connect_id;

__uint32_t time; */

__uint8_t *headers[NO_OF_HEADERS];

__uint16_t hdr_length[NO_OF_HEADERS];

__uint8_t flag,constant;

__uint16_t maxsize;

};

struct ap2ctrl

56
{

long mtype;

pid_t pid;

__uint8_t buffer[MAX_OBJECT_SIZE];/*The actual data

to be sent*/

__uint32_t length;/*length-lenght of buffer,ipaddr-

iip address of remote m/c*/

unsigned short int port;

struct in_addr ipaddr;

};

enum { _target , _connect_id , _who , _name , _type ,

_descript , _length, _time , _body , _end_of_body ,

_auth_chal , _auth_resp };

#define CONNECT_FLAGS 0x00

#define TRUE 1

#define FALSE 0

57
appclient.c

#define APSRVQ2ID 5432L

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

#include <stdlib.h>

#include <stdio.h>

#include <error.h>

#include <signal.h>

#include <unistd.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <netinet/tcp.h>

#include <arpa/inet.h>

#include "types.h"

#define CTRL_PORT 650

#define CTRLQ1ID 1235L

#define MSGMAX 4080

58
#define MAX_OBJECT_SIZE MSGMAX-sizeof(long)-

sizeof(pid_t)-4-sizeof(unsigned short)-sizeof(struct

in_addr)

pid_t pid;

void initq2(int *q2id)

if( (*q2id=msgget(pid,IPC_CREAT|IPC_EXCL|0777))==-1)

printf("\nExit in initq2");

exit(-1);

static void finish(int ab)

int srid;

srid=msgget(pid,0777);

msgctl(srid,IPC_RMID,NULL);

printf("\nExit in finish");

exit(0);

59
}

operations(struct ap2ctrl *rbuf)

int q2id;

getchar();

free(rbuf);

q2id=msgget(pid,0777);

msgctl(q2id,IPC_RMID,NULL);

exit(0);

int main(void)

int q2id,q1id;

char c,c1=0,c2;

char ip[100];

struct msqid_ds info;

long type=0;

ssize_t num;

int i;

60
__uint8_t *buf;

struct ap2ctrl *rbuf=(struct

ap2ctrl*)malloc(sizeof(struct ap2ctrl));

pid=getpid();

while(rbuf==NULL)

rbuf=(struct ap2ctrl*)malloc(sizeof(struct ap2ctrl));

rbuf->mtype=1;

/*initq2(&q2id);*/

signal(SIGINT,finish);

printf("c-->CONNECT\nd-->DISCONNECT\np-->PUT\n");

while(1){

printf("?");

scanf("%c",&c);

getchar();

if(c=='c'){

printf("Enter IP address remote machine:\n");

scanf("%s",ip);

getchar();

/*signal(SIGSEGV,finish);*/

if(!inet_aton(ip,&(rbuf->ipaddr)))

61
perror("inet_aton");

rbuf->port=htons(CTRL_PORT);

rbuf->buffer[0]=CONNECT;

rbuf->length=1;

rbuf->pid=pid;

if((q1id=msgget(CTRLQ1ID,0777))!=-1)

msgsnd(q1id,rbuf,sizeof(struct ap2ctrl)-sizeof(long),0);

if((q2id=msgget(pid,0777))!=-1)

msgrcv(q2id,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),0,0);

printf("\nConnect Response == %x\n",rbuf-

>buffer[0]);

while(1){

printf("?");

scanf("%c",&c2);

getchar();

switch(c2){

case 'p':

rbuf->buffer[0]=PUT;

buf=rbuf->buffer+1;

62
printf("Enter Your data:\n");

fgets(buf,MAX_OBJECT_SIZE-1,stdin);

rbuf->length=strlen(buf);

if((q1id=msgget(CTRLQ1ID,0777))!=-1)

msgsnd(q1id,rbuf,sizeof(struct

ap2ctrl)-sizeof(long),0);

if((q2id=msgget(pid,0777))!=-1)

msgrcv(q2id,rbuf,sizeof(struct ap2ctrl)-sizeof(long),0,0);

printf("\nPut Response == %x\n",rbuf->buffer[0]);

break;

case 'd':

c1=1;

break;

case '\n':

break;

default:

printf("\nInvalid Command\n");

if(c1)

break;

63
}

if(c1)

break;

printf("\nSending Disconnect Packet ");

rbuf->buffer[0]=DISCONNECT;

if((q1id=msgget(CTRLQ1ID,0777))!=-1)

msgsnd(q1id,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),0);

if((q2id=msgget(pid,0777))!=-1)

msgrcv(q2id,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),0,0);

printf("\nDisconnect Response == %x\n",rbuf-

>buffer[0]);

finish(0);

64
appserver.c

#define APSRVQ2ID 5432L

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

#include <stdlib.h>

#include <stdio.h>

#include <error.h>

#include <signal.h>

#include <unistd.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <netinet/tcp.h>

#include <arpa/inet.h>

#include "types.h"

#include "libpq-fe.h"

#define CTRLQ1ID 1234L

#define APSRVQ2ID 5432L

#define MSGMAX 4080

65
#define MAX_OBJECT_SIZE MSGMAX-sizeof(long)-

sizeof(pid_t)-4-sizeof(unsigned short)-sizeof(struct

in_addr)

void initq2(int *q2id)

if( (*q2id=msgget(APSRVQ2ID,IPC_CREAT|IPC_EXCL|

0777))==-1)

printf("\nExit in initq2");

exit(-1);

static void finish(int ab)

int srid;

srid=msgget(APSRVQ2ID,0777);

msgctl(srid,IPC_RMID,NULL);

printf("\nExit in finish");

exit(0);

66
int main(void)

int q2id,q1id;

struct msqid_ds info;

long type=0;

ssize_t num;

int i,j,k;

char vid[7][31];

PGresult *res;

int ntuples;

char cmd[250];

PGconn *conn;

char *tstamp;

char

*dbname="Vcard",*user="root",*pghost="localhost",*pgport="

5432";

struct ap2ctrl *rbuf=(struct

ap2ctrl*)malloc(sizeof(struct ap2ctrl));

while(rbuf==NULL)

rbuf=(struct ap2ctrl*)malloc(sizeof(struct ap2ctrl));

67
rbuf->mtype=1;

initq2(&q2id);

signal(SIGINT,finish);

/*signal(SIGSEGV,finish);*/

while(1)

q2id=msgget(APSRVQ2ID,0777) ;

msgctl(q2id,IPC_STAT,&info);

if(info.msg_qnum>=1) /*CHECKING FOR NEW MESSAGES

ON Q1*/

if( (q2id=msgget(APSRVQ2ID,0777)) == -1)

printf("Unable to open msgq1");

perror("msgget");

exit(-1);

num=msgrcv(q2id,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),type,0);

switch(rbuf->buffer[0])

68
{

case CONNECT : rbuf->buffer[0]=CONNECT_RESP;

rbuf->buffer[1]=SUCCESS;

rbuf->pid=APSRVQ2ID;

if((q1id=msgget(CTRLQ1ID,0777))!=-1)

if(msgsnd(q1id,rbuf,sizeof(struct

ap2ctrl)-sizeof(long),0)==-1)

perror("msgsnd");

else

perror("msgget");

printf("\nConnection accepted from Host: %s Port:

%u\n",inet_ntoa(rbuf->ipaddr),ntohs(rbuf->port));

break;

case PUT:

printf("\nMessage received from Host: %s Port:

%u\n",inet_ntoa(rbuf->ipaddr),ntohs(rbuf->port));

printf("Length == %d\n",rbuf->length);

69
for(i=1;i<rbuf->length;i++)

printf("%c",rbuf->buffer[i]);

printf("\n");

k=1;

for(i=0;i<7;i++)

for(j=0;rbuf->buffer[k]!='\0';j++)

vid[i][j]=rbuf->buffer[k++];

// printf("\nK== %d j==%d\n",k,j);

vid[i][j]='\0';

k++;

//rbuf->buffer[k++];

// printf("\n %s \n",vid[i]);

conn=PQsetdbLogin(pghost,pgport,NULL,NULL,dbname,user,NULL

);

70
sprintf(cmd,"select * from scard where vcardid=

%d",atoi(vid[0]));

res=PQexec(conn,cmd);

ntuples=PQntuples(res);

if(ntuples==0)

sprintf(cmd,"insert into scard values (%d ,'%s',

'%s','%s',%d,'%s',

%d)",atoi(vid[0]),vid[1],vid[2],vid[3],atoi(vid[4]),vid[5]

,atoi(vid[6]));

res=PQexec(conn,cmd);

else

// sprintf(cmd,"select * from scard where vcardid=

%d",atoi(vid[0]));

// res=PQexec(conn,cmd);

tstamp=PQgetvalue(res,0,6);

if(atoi(tstamp)<atoi(vid[6]))

71
sprintf(cmd,"delete from scard where vcardid=

%d",atoi(vid[0]));

res=PQexec(conn,cmd);

sprintf(cmd,"insert into scard values (%d ,'%s',

'%s','%s',%d,'%s',

%d)",atoi(vid[0]),vid[1],vid[2],vid[3],atoi(vid[4]),vid[5]

,atoi(vid[6]));

res=PQexec(conn,cmd);

if(PQresultStatus(res)==PGRES_COMMAND_OK)

printf("comm successful \n");

PQclear(res);

PQfinish(conn);

break;

case GET:break;

default:

break;

72
}

printf("\vExited decently");

73
blockchild.c

#include "common.h"

int max_packet_size=MAX_PACKET_SIZE;

int appln_qid;

int sdnew;

struct sockaddr_in *remote_addr;

pid_t pid;

void init_q_info(struct ap2ctrl *rbuf)

rbuf->pid=getpid();

rbuf->mtype=1;

rbuf->length=0;

__uint16_t htod(__uint8_t *buf,__uint16_t *i,int j)

__uint16_t res=0;

int k;

for(k=0;k<j-1;k++){

74
res|=buf[(*i)];

(*i)++;

res<<=8;

res|=buf[*i];

(*i)++;

return res;

void child_exit(__uint8_t err)

int clid;

struct ap2ctrl *rbuf=ALLOC_MEM(struct ap2ctrl,1);

if(remote_addr) free(remote_addr);

remote_addr=NULL;

rbuf->pid=getpid();

rbuf->mtype=1;

rbuf->buffer[0]=err;

rbuf->length=1;

if((clid=msgget(appln_qid,0777))!=-1)

75
msgsnd(clid,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),0);

if((clid=msgget(pid,0777) )!=-1)

msgctl(clid,IPC_RMID,NULL);

if(rbuf) free(rbuf);

rbuf=NULL;

close(sdnew);

exit(err);

void gen_sock_resp(__uint8_t resp)

__uint8_t *buf=ALLOC_MEM(__uint8_t,3);

buf[0]=resp;

buf[1]=0;

buf[2]=3;

while(sendto(sdnew,(void *)buf,3,0,(struct sockaddr

*)remote_addr,sizeof(struct sockaddr_in))==-1);

if(buf) free(buf);

buf=NULL;

76
}

void gen_q_resp(__uint8_t resp)

int clid;

struct ap2ctrl *rbuf=ALLOC_MEM(struct ap2ctrl,1);

rbuf->buffer[0]=SUCCESS;

rbuf->length=1;

rbuf->pid=pid;

rbuf->mtype=1;

if((clid=msgget(appln_qid,0777))==-1){

perror("msgget");

init_q_info(rbuf);

if(rbuf) free(rbuf);

rbuf=NULL;

child_exit(0);

while(msgsnd(clid,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),0)==-1){

perror("msgsnd");

77
switch(errno){

case EIDRM:

case EACCES:

case EAGAIN:

init_q_info(rbuf);

if(rbuf) free(rbuf);

rbuf=NULL;

child_exit(0);

init_q_info(rbuf);

if(rbuf) free(rbuf);

rbuf=NULL;

return;

void init_q()

int qid;

if((qid=msgget(pid,IPC_CREAT|IPC_EXCL|0777)) == -1 )

78
{

//printf("First exit");

perror("msgget");

exit(-1);

else if(qid==0)

msgctl(qid,IPC_RMID,NULL);

if( (qid=msgget(pid,IPC_CREAT|IPC_EXCL|0777))==-

1)

//printf("Second exit");

perror("msgget");

exit(-1);

return;

void init_sock(struct sockaddr_in *local_addr)

79
local_addr->sin_family=PF_INET;

local_addr->sin_port=0;

local_addr->sin_addr.s_addr=INADDR_ANY;

memset(&(local_addr->sin_zero),'\0',8);

if((sdnew=socket(PF_INET,SOCK_DGRAM,0))==-1)

perror("socket:");

exit(-1);

if(bind(sdnew,(struct sockaddr *)local_addr,sizeof(struct

sockaddr_in))==-1)

close(sdnew);

exit(-1);

void extract_packet_headers(struct packet_info

*pinfo,__uint8_t *buf,__uint16_t len,int req)

__uint16_t hd_length=0,j=0,i=3;

80
switch(buf[0]){

case CONNECT:

i=7;

break;

case SETPATH:

i=5;

break;

case SUCCESS:

case CONTINUE:

case BAD_REQ:

case UNAUTH:

case FORBID:

case NOT_FOUND:

case REQ_TIMEOUT:

case ENTITY_LARGE:

case UNSUPP_TYPE:

case INTERNAL_ERR:

case NOT_IMP:

case SERV_UNAV:

switch(req){

81
case CONNECT:

i=7;

if(i>=len)

return;

while(i<len){

switch(buf[i++]){

case LENGTH:

pinfo->headers[_length]=ALLOC_MEM(__uint8_t,4);

for(j=0;j<4;j++,i++)

pinfo->headers[_length][j]=buf[i];

break;

case BODY:

hd_length=0;

hd_length=htod(buf,&i,2);

pinfo->headers[_body]=

ALLOC_MEM(__uint8_t,hd_length-3);

pinfo->hdr_length[_body]=(hd_length-3);

for(j=0;j<pinfo->hdr_length[_body];j++,i++)

82
pinfo->headers[_body][j]=buf[i];

break;

case END_OF_BODY:

hd_length=0;

hd_length=htod(buf,&i,2);

pinfo->headers[_end_of_body]=

ALLOC_MEM(__uint8_t,hd_length-3);

pinfo->hdr_length[_end_of_body]=(hd_length-3);

for(j=0;j<pinfo->hdr_length[_end_of_body];j++,i++)

pinfo->headers[_end_of_body][j]=buf[i];

break;

void hand_disc_to_ap(__uint8_t *fbuf,__uint16_t plen)

int clid;

struct ap2ctrl *rbuf=ALLOC_MEM(struct ap2ctrl,1);

83
/*check for validity of packet.return false if not valid

and response is an failure respose*/

gen_sock_resp(SUCCESS);

rbuf->length=(__uint32_t)1;

rbuf->buffer[0]=DISCONNECT;

rbuf->port=remote_addr->sin_port;

rbuf->ipaddr=remote_addr->sin_addr;

if((clid=msgget(APSRVQ2ID,0777) )==-1){

rbuf->pid=getpid();

msgsnd(clid,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),0);

/*main local resources freed before fn. called*/

if(rbuf) free(rbuf);

rbuf=NULL;

child_exit(0);

84
void hand_disc_from_app(struct ap2ctrl *rbuf)

__uint16_t len;

int clid;

/* Send Disconnect request */

gen_sock_resp(DISCONNECT);

/*Send "Diconnect Successful" message to application

layer*/

rbuf->length=1;

rbuf->buffer[0]=SUCCESS;

if((clid=msgget(appln_qid,0777) )!=-1){

rbuf->pid=getpid();

msgsnd(clid,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),0);

/*Free Resources related to queues*/

if(rbuf) free(rbuf);

rbuf=NULL;

85
child_exit(0);

void hand_put_to_ap(__uint8_t *recv_buf,__uint16_t plen)

__uint8_t *buf,*sbuf;

__uint16_t len;

int packetsize,i=0;

__uint32_t buf_len=0;

socklen_t sock_length=sizeof(struct sockaddr_in);

int clid,j,k;

struct packet_info *pinfo=ALLOC_MEM(struct packet_info,1);

struct packet_info *rinfo=ALLOC_MEM(struct packet_info,1);

struct ap2ctrl *rbuf=ALLOC_MEM(struct ap2ctrl,1);

#define HPTAF free(pinfo) , free(rinfo), free(rbuf)

#define HPTAC(err) HPTAF,child_exit(err);

init_packet_info(pinfo);

init_packet_info(rinfo);

86
rbuf->mtype=1;

rbuf->pid=getpid();

rbuf->port=remote_addr->sin_port;

rbuf->ipaddr=remote_addr->sin_addr;

extract_packet_headers(rinfo,recv_buf,plen,PUT);

/*check if length specified*/

if(!rinfo->headers[_length]){

gen_sock_resp(LENGTH_REQ);

/*if the fn succeeds then free local resources and

return*/

HPTAF;

return;

/*assign the length of data to rbuf->length*/

k=0;

rbuf->length=htod(rinfo->headers[_length],(__uint16_t

*)&k,4);

if(rinfo->headers[_end_of_body]){

gen_sock_resp(BAD_REQ);

87
HPTAF;

return;

rbuf->buffer[buf_len++]=PUT;

if(rinfo->headers[_body]){

if(rbuf->length<rinfo->hdr_length[_body]){

gen_sock_resp(ENTITY_LARGE);

HPTAF;

return;

gen_sock_resp(CONTINUE);

rbuf->buffer[0]=PUT;

for(j=0;j<rinfo->hdr_length[_body];j++)

rbuf->buffer[buf_len++]=rinfo->headers[_body][j];

else

gen_sock_resp(CONTINUE);

if(recv_buf) free(recv_buf);

recv_buf=NULL;

88
recv_buf=(__uint8_t

*)ALLOC_MEM(__uint8_t,max_packet_size);

while(1){

while((packetsize=recvfrom(sdnew,(void

*)recv_buf,max_packet_size,0,(struct sockaddr

*)remote_addr,&sock_length))==-1);

switch(recv_buf[0]){

case PUT:

init_packet_info(rinfo);

extract_packet_headers(rinfo,recv_buf,packetsize,PUT);

if(!rinfo->headers[_body]){

gen_sock_resp(NOT_IMP);

break;

if(buf_len-1+rinfo->hdr_length[_body]>rbuf-

>length){

gen_sock_resp(ENTITY_LARGE);

break;

89
if(rinfo->headers[_end_of_body]){

gen_sock_resp(BAD_REQ);

break;

gen_sock_resp(CONTINUE);

for(j=0;j<rinfo->hdr_length[_body];j++)

rbuf->buffer[buf_len++]=rinfo-

>headers[_body][j];

break;

case FPUT:

init_packet_info(rinfo);

extract_packet_headers(rinfo,recv_buf,packetsize,PUT);

if(!rinfo->headers[_end_of_body]){

gen_sock_resp(NOT_IMP);

break;

if(buf_len-1+rinfo-

>hdr_length[_end_of_body]>rbuf->length){

gen_sock_resp(ENTITY_LARGE);

break;

90
}

gen_sock_resp(SUCCESS);

for(j=0;j<rinfo->hdr_length[_end_of_body];j++)

rbuf->buffer[buf_len++]=rinfo-

>headers[_end_of_body][j];

rbuf->length=buf_len;

//printf("\nThe received message:\n");

//printf("Length=%d opcode=%x\n",rbuf-

>length,rbuf->buffer[0]);

//for(j=1;j<rbuf->length;j++)

//printf("%c",rbuf->buffer[j]);

//printf("\n");

if((clid=msgget(appln_qid,0777))==-1)

HPTAC(RESOURCE_FAILURE);

if((msgsnd(clid,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),0))==-1)

HPTAC(RESOURCE_FAILURE);

free(pinfo),free(rinfo);

//HPTAF;

return;

91
case ABORT:

gen_sock_resp(SUCCESS);

HPTAF;

return;

default:

gen_sock_resp(BAD_REQ);

init_packet_info(rinfo);

init_packet_info(pinfo);

void hand_put_from_ap(struct ap2ctrl *rbuf)

__uint8_t

*recv_buf=ALLOC_MEM(__uint8_t,max_packet_size),*buf=NULL;

struct packet_info *pinfo=ALLOC_MEM(struct

packet_info,1);

92
__uint16_t size_of_body=max_packet_size-

6,tot_packet_size,len;

__uint16_t body_ctr=1;

int i,lastchunk=FALSE,k;

socklen_t sock_length=sizeof(struct sockaddr_in);

init_packet_info(pinfo);

/*if(rbuf->name){

pinfo->headers[_name]=ALLOC_MEM(__uint8_t,strlen(rbuf-

>name));

pinfo->hdr_length[_name]=strlen(rbuf->name)-1;

}*/

/*Assume size given*/

pinfo->headers[_length]=ALLOC_MEM(__uint8_t,4);

pinfo->hdr_length[_length]=4;

for(k=1;k<=4;k++)

pinfo->headers[_length][k-1]=DTOH(rbuf->length-1,k,4);

pinfo->opcode=PUT;

pinfo->maxsize=max_packet_size;

93
buf=construct_packet(PUT,*pinfo,&len);

if(sendto(sdnew,(void *)buf,(int)len,0,(struct sockaddr

*)remote_addr,sizeof(struct sockaddr_in))==-1){

init_q_info(rbuf);

gen_q_resp(INTERNAL_ERR);

init_packet_info(pinfo);

if(pinfo) free(pinfo);

pinfo=NULL;

if(buf) free(buf);

buf=NULL;

if(recv_buf) free(recv_buf);

recv_buf=NULL;

return;

rbuf->length--;

while(1){

while(recvfrom(sdnew,(void

*)recv_buf,max_packet_size,0,(struct sockaddr

*)remote_addr,&sock_length)==-1);

init_packet_info(pinfo);

94
switch(recv_buf[0]){

case CONTINUE:

pinfo->maxsize=max_packet_size;

if(rbuf->length>size_of_body){

pinfo->opcode=PUT;

pinfo->headers[_body]=

ALLOC_MEM(__uint8_t,size_of_body);

pinfo->hdr_length[_body]=size_of_body;

for(i=0;i<size_of_body;i++,body_ctr++,rbuf->length--)

pinfo->headers[_body][i]=

rbuf->buffer[body_ctr++];

buf=construct_packet(PUT,*pinfo,&len);

rbuf->length-=size_of_body;

while(sendto(sdnew,(void

*)buf,max_packet_size,0,(struct sockaddr

*)remote_addr,sizeof(struct sockaddr_in))==-1);

else{

pinfo->opcode=PUT;

95
pinfo-

>headers[_end_of_body]=ALLOC_MEM(__uint8_t,rbuf->length);

pinfo->hdr_length[_end_of_body]=rbuf->length;

for(i=0;i<rbuf->length;i++,body_ctr++)

pinfo->headers[_end_of_body][i]=

rbuf->buffer[body_ctr];

buf=construct_packet(PUT,*pinfo,&len);

buf[0]=FPUT;

lastchunk=TRUE;

while(sendto(sdnew,(void *)buf,6+pinfo-

>hdr_length[_end_of_body],0,(struct sockaddr

*)remote_addr,sizeof(struct sockaddr_in))==-1);

if(buf) free(buf);

buf=NULL;

break;

case SUCCESS:

/*assume thisif(lastchunk){*/

init_q_info(rbuf);

gen_q_resp(SUCCESS);

96
init_packet_info(pinfo);

if(pinfo) free(pinfo);

pinfo=NULL;

if(buf) free(buf);

buf=NULL;

if(recv_buf) free(recv_buf);

recv_buf=NULL;

return;

default:

gen_sock_resp(ABORT);

while(recvfrom(sdnew,(void

*)recv_buf,max_packet_size,0,(struct sockaddr

*)remote_addr,&sock_length)==-1);

init_q_info(rbuf);

init_packet_info(pinfo);

if(recv_buf) free(recv_buf);

recv_buf=NULL;

if(pinfo) free(pinfo);

pinfo=NULL;

if(buf[0]!=SUCCESS){

97
gen_sock_resp(DISCONNECT);

if(buf) free(buf);

buf=NULL;

child_exit(INTERNAL_ERR);

if(buf) free(buf);

buf=NULL;

gen_q_resp(ABORT);

return;

static void finish(int ab)

int srid;

srid=msgget(pid,0777);

msgctl(srid,IPC_RMID,NULL);

while(close(sdnew));

exit(0);

98
}

int main(int argc,char** argv)

int clid,chtype;

struct msqid_ds *info=ALLOC_MEM(struct msqid_ds,1);

struct ap2ctrl *rbuf=ALLOC_MEM(struct ap2ctrl,1);

struct packet_info *pinfo=ALLOC_MEM(struct

packet_info,1);

struct sockaddr_in *local_addr=ALLOC_MEM(struct

sockaddr_in,1);

__uint8_t *snd_buf,*recv_buf;

__uint16_t len,temp;

socklen_t sock_length=sizeof(struct sockaddr_in);

int packetsize,i;

long type=0;

signal(SIGSEGV,finish);

signal(SIGINT,finish);

#define FREE_MAIN if(info) free(info),info=NULL;

if(rbuf) free(rbuf),rbuf=NULL; if(local_addr)

free(local_addr),local_addr=NULL; if(recv_buf)

99
free(recv_buf),recv_buf=NULL; if(snd_buf)

free(snd_buf),snd_buf=NULL;

pid=getpid();/*pid initialized*/

init_q();/*generate queue to receive data*/

init_sock(local_addr);

/*create a socket and bind it to random port, sdnew

initialized*/

do{

if(((clid=msgget(pid,0777))==-1) ||

(msgctl(clid,IPC_STAT,info)==-1) ){

FREE_MAIN;

child_exit(INTERNAL_ERR);

}while(info->msg_qnum<1);

if(((clid=msgget(pid,0777)) == -1) ||

(msgrcv(clid,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),type,0)==-1))

FREE_MAIN;

child_exit(INTERNAL_ERR);

100
}

/*global variables*/

remote_addr=ALLOC_MEM(struct sockaddr_in,1);

remote_addr->sin_addr=rbuf->ipaddr;

remote_addr->sin_port=rbuf->port;

remote_addr->sin_family=PF_INET;

memset(&(remote_addr->sin_zero),0,8);

appln_qid=rbuf->pid;

//cout<<"\nIp addr == \n"<<remote_addr-

>sin_addr.s_addr<<endl;

//cout<<"\nPort === \n"<<remote_addr->sin_port<<endl;

if((clid=msgget(pid,0777)) == -1){/*unable to open

application queue*/

FREE_MAIN;

child_exit(0);/*cannot send an error message to

client*/

if(rbuf->buffer[0]==CONNECT){

/*child is behaving as a client*/;

101
/*send connect request*/

init_packet_info(pinfo);

pinfo->opcode=CONNECT;

pinfo->maxsize=MAX_PACKET_SIZE;

snd_buf=construct_packet(CONNECT,*pinfo,&len);

while(sendto(sdnew,(void *)snd_buf,(int)len,0,(struct

sockaddr *)remote_addr,sizeof(struct sockaddr_in))==-1);

if(snd_buf) free(snd_buf);

snd_buf=NULL;

recv_buf=ALLOC_MEM(__uint8_t,max_packet_size);

while((packetsize=recvfrom(sdnew,(void

*)recv_buf,max_packet_size,0,(struct sockaddr

*)remote_addr,&sock_length))==-1);

if(recv_buf[0]!=SUCCESS){/*connection set failed*/

FREE_MAIN;

child_exit(SERV_UNAV);

gen_q_resp(SUCCESS);

i=5;/*position of max packet size in a connet packet*/

temp=htod(recv_buf,(__uint16_t *)&i,2);

102
if(temp<DEF_PACKET_SIZE){

gen_sock_resp(DISCONNECT);

packetsize=recvfrom(sdnew,(void

*)recv_buf,max_packet_size,0,(struct sockaddr

*)&remote_addr,&sock_length);

FREE_MAIN;

child_exit(INTERNAL_ERR);

}/*default packet size is 255 bytes as per current

OBEX specs*/

if(temp<max_packet_size){

max_packet_size=temp;

recv_buf=(__uint8_t

*)realloc(recv_buf,max_packet_size);

//printf("temp == %d\n",temp);

//printf("max == %d\n",max_packet_size);

while(1){

do{

if(((clid=msgget(pid,0777))==-1) ||

(msgctl(clid,IPC_STAT,info)==-1) ){

103
FREE_MAIN;

child_exit(INTERNAL_ERR);

}while(info->msg_qnum<1);/*Wait for messages*/

if(((clid=msgget(pid,0777)) == -1) ||

(msgrcv(clid,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),type,0)==-1)){

FREE_MAIN;

child_exit(INTERNAL_ERR);

}/*Read the messages*/

/*check for packet validity*/

/*assume packet is valid*/

switch(rbuf->buffer[0]){

case PUT:

hand_put_from_ap(rbuf);

break;

case GET:

gen_q_resp(NOT_IMP);

break;

case SETPATH:

104
gen_q_resp(NOT_IMP);

break;

case DISCONNECT:

if(info) free(info),info=NULL;

if(local_addr) free(local_addr),local_addr=NULL;

if(recv_buf) free(recv_buf),recv_buf=NULL; if(snd_buf)

free(snd_buf),snd_buf=NULL;

hand_disc_from_app(rbuf);

break;

default:

gen_q_resp(BAD_REQ);

else{

/*child behaves as a server*/

recv_buf=ALLOC_MEM(__uint8_t,max_packet_size);

i=7;

temp=htod(rbuf->buffer,(__uint16_t *)&i,2);

105
if(temp<DEF_PACKET_SIZE){

init_packet_info(pinfo);

pinfo->opcode=CONNECT;

pinfo->maxsize=MAX_PACKET_SIZE;

snd_buf=construct_packet(CONNECT,*pinfo,&len);

snd_buf[0]=SERV_UNAV;

while(sendto(sdnew,(void *)snd_buf,(int)len,0,(struct

sockaddr *)remote_addr,sizeof(struct sockaddr_in))==-1);

/*free resources*/

child_exit(INTERNAL_ERR);

}/*default packet size is 255 bytes as per current

OBEX specs*/

if(temp<max_packet_size){

max_packet_size=temp;

recv_buf=(__uint8_t

*)realloc(recv_buf,max_packet_size);

init_packet_info(pinfo);

pinfo->opcode=CONNECT;

pinfo->maxsize=MAX_PACKET_SIZE;//MAX_PACKET_SIZE;

106
snd_buf=construct_packet(CONNECT,*pinfo,&len);

snd_buf[0]=SUCCESS;

while(sendto(sdnew,(void *)snd_buf,(int) len,0,(struct

sockaddr *)remote_addr,sizeof(struct sockaddr_in))==-1);

if(snd_buf) free(snd_buf);

snd_buf=NULL;

while(1){

while((packetsize=recvfrom(sdnew,(void

*)recv_buf,max_packet_size,0,(struct sockaddr

*)remote_addr,&sock_length))==-1);

/*Check validity of packet*/

/*assume it is valid*/

switch(recv_buf[0]){

case PUT:

hand_put_to_ap(recv_buf,

(__uint16_t)packetsize);

break;

case GET:

107
gen_sock_resp(NOT_IMP);

break;

case SETPATH:

gen_sock_resp(NOT_IMP);

break;

case DISCONNECT:

if(info) free(info),info=NULL; if(rbuf)

free(rbuf), rbuf=NULL; if(local_addr)

free(local_addr),local_addr=NULL; if(recv_buf)

free(recv_buf),recv_buf=NULL; if(snd_buf)

free(snd_buf),snd_buf=NULL;

hand_disc_to_ap(recv_buf,(__uint16_t)packetsize);

break;

default:

gen_sock_resp(BAD_REQ);

break;

108
}

common.c

#include<stdio.h>

#include<sys/types.h>

#include<string.h>

#include "types.h"

__uint8_t hdrs[]={ TARGET, CONNECT_ID , WHO , NAME , TYPE

, DESCRIPTION , LENGTH , TIME , BODY, END_OF_BODY ,

AUTH_CHAL , AUTH_RESP };

void init_packet_info(struct packet_info *s_packet)

int i;

for(i=0;i<NO_OF_HEADERS;i++){

if(!s_packet->headers[i])

free(s_packet->headers[i]);

s_packet->headers[i]=NULL;

109
__uint8_t *ATOU(__uint8_t *asc)

int i,temp=strlen((const char *)asc),j;

__uint8_t *uni=(__uint8_t *)malloc(temp*2+1);

for(i=0,j=0;i<temp;i++,j+=2){

uni[j]=0x00;

uni[j+1]=asc[i];

uni[j]='\0';

return uni;

__uint8_t *construct_packet(int packet_type,struct

packet_info s_packet,__uint16_t *len)

__uint16_t tlen=0,total=3,temp;

__uint8_t *buf,*p,i;

__uint16_t j;

if(packet_type==CONNECT || packet_type==CONNECT_RESP)

total+=4;

110
else if(packet_type==SETPATH)

total+=2;

for(i=0;i<NO_OF_HEADERS;i++)

if(s_packet.headers[i]){

if(hdrs[i]<0x40)

total+=s_packet.hdr_length[i]*2+4;

else if(hdrs[i]>=0x40 && hdrs[i]<0x80)

total+=s_packet.hdr_length[i]+3;

else if(hdrs[i]>=0xC0)

total+=s_packet.hdr_length[i]+1;

*len=total;

//printf("Length=%x\n",total);

buf=(__uint8_t *)malloc(total);

buf[tlen++]=s_packet.opcode;

buf[tlen++]=DTOH(total,1,2);

buf[tlen++]=DTOH(total,2,2);

if(packet_type==CONNECT || packet_type==CONNECT_RESP){

buf[tlen++]=VERSION;

buf[tlen++]=s_packet.flag;

111
buf[tlen++]=DTOH(s_packet.maxsize,1,2);

buf[tlen++]=DTOH(s_packet.maxsize,2,2);

else if(packet_type==SETPATH){

buf[tlen++]=s_packet.flag;

buf[tlen++]=s_packet.constant;

for(i=0;i<NO_OF_HEADERS;i++)

if(s_packet.headers[i]){

buf[tlen++]=hdrs[i];

if(hdrs[i]>=40 && hdrs[i]<0x80){

buf[tlen++]=DTOH(s_packet.hdr_length[i]+3,1,2);

buf[tlen++]=DTOH(s_packet.hdr_length[i]+3,2,2);

for(j=0;j<s_packet.hdr_length[i];j++)

buf[tlen++]=s_packet.headers[i][j];

else if(hdrs[i]<40){

buf[tlen++]=DTOH(s_packet.hdr_length[i]+3,1,2);

buf[tlen++]=DTOH(s_packet.hdr_length[i]+3,2,2);

for(j=0;j<s_packet.hdr_length[i];j++){

112
buf[tlen++]=0x00;

buf[tlen++]=s_packet.headers[i][j];

buf[tlen++]='\0';

else if(hdrs[i]>=0xC0)

for(j=0;j<s_packet.hdr_length[i];j++)

buf[tlen++]=s_packet.headers[i][j];

return buf;

113
Controller.c

#include "common.h"

int sd;

struct sockaddr_in local_addr;

void init_q1(int *q1id)

if( (*q1id=msgget(CTRLQ1ID,IPC_CREAT|IPC_EXCL|0777))

== -1 )

//printf("First exit");

perror("msgget");

exit(-1);

else if(*q1id==0)

msgctl(*q1id,IPC_RMID,NULL);

if( (*q1id=msgget(CTRLQ1ID,IPC_CREAT|IPC_EXCL|

0777))==-1)

114
//printf("Second exit");

perror("msgget");

exit(-1);

return;

void init_sock(struct sockaddr_in *local_addr)

local_addr->sin_family=PF_INET;

local_addr->sin_port=htons(CTRL_PORT);

local_addr->sin_addr.s_addr=INADDR_ANY;

memset(&(local_addr->sin_zero),'\0',8);

if((sd=socket(PF_INET,SOCK_DGRAM,0))==-1)

perror("socket:");

exit(-1);

if(bind(sd,(struct sockaddr *)local_addr,sizeof(struct

sockaddr_in))==-1)

115
{

close(sd);

perror("bind");

exit(-1);

int hand_con_req(struct ap2ctrl *rbuf)

pid_t pid;

int clid;

//printf("\nIn here");

if((pid=fork())==0)

execlp("./blockchild","blockchild",(char *)0);

else if(pid<0)

return FALSE;

/*Wait for message queue q4 to be created*/

while( (clid=msgget(pid,0777) )==-1);

if( (msgsnd(clid,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),0)) ==-1)

return FALSE;

116
/*send message to child:first rbuf*/

return TRUE;

int hand_con_res(struct ap2ctrl *rbuf)

pid_t pid;

int clid;

if(rbuf->buffer[1]==SUCCESS)

close(sd);

if((pid=fork())==0)

execlp("./blockchild","blockchild",(char *)0);/*INSTEAD

EXEC LATER WITH THE CHILD PROGRAM*/

else if(pid<0)

return FALSE;

else{

sd=socket(PF_INET,SOCK_DGRAM,0);

bind(sd,(struct sockaddr *)&local_addr,sizeof(struct

sockaddr_in));

117
/*Wait for message queue q4 to be created*/

while( (clid=msgget(pid,0777) )==-1);

if( (msgsnd(clid,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),0)) ==-1)

return FALSE;

/*send message to child:first rbuf*/

return TRUE;

else

struct sockaddr_in *remote_addr=ALLOC_MEM(struct

sockaddr_in,1);

__uint16_t connect_resp_size=7;

__uint8_t *buf=(__uint8_t *)malloc(sizeof(__uint8_t));

remote_addr->sin_family=PF_INET;

remote_addr->sin_port=htons(rbuf->port);

remote_addr->sin_addr=rbuf->ipaddr;

memset(&(remote_addr->sin_zero),'\0',8);

118
buf[0]=0x53;

buf[1]=DTOH(connect_resp_size,1,2);

buf[2]=DTOH(connect_resp_size,2,2);

buf[3]=0x10;

buf[4]=0;

buf[5]=DTOH(MAX_PACKET_SIZE,1,2);

buf[6]=DTOH(MAX_PACKET_SIZE,2,2);

if(sendto(sd,(void *)buf,(int)connect_resp_size,0,

(struct sockaddr *)remote_addr,sizeof(struct

sockaddr_in))==-1)

free(remote_addr);

free(buf);

return FALSE;

free(remote_addr);

free(buf);

return TRUE;

119
int hand_connect_sock(__uint8_t *buf,int packsize,struct

sockaddr_in *remote_addr)

int q2id,i;

struct ap2ctrl *rbuf=(struct ap2ctrl

*)malloc(sizeof(struct ap2ctrl));

//printf("2. Port=%u ip addrr=%u\n",remote_addr-

>sin_port,remote_addr->sin_addr.s_addr);

rbuf->port=remote_addr->sin_port;

/*if(!inet_aton(remote_addr->sin_addr,&(rbuf->ipaddr)))

return FALSE;*/

rbuf->ipaddr.s_addr=remote_addr->sin_addr.s_addr;

//printf("3. Port=%u ip addrr=%u \n",rbuf->port,rbuf-

>ipaddr.s_addr);

rbuf->mtype=1;

rbuf->buffer[0]=CONNECT;

for(i=0;i<packsize;i++)

rbuf->buffer[i+2]=buf[i];

rbuf->length=packsize+2;

120
if( (q2id=msgget(APSRVQ2ID,0777))==-1){

perror("msgget:");

return FALSE;

if( (msgsnd(q2id,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),0)) ==-1){

perror("msgsnd:");

return FALSE;

return TRUE;

void gen_err_ap(__uint8_t err_code,struct ap2ctrl *rbuf)

struct ap2ctrl *sbuf;

int ob2ap;

sbuf=(struct ap2ctrl *)malloc(sizeof(struct

ap2ctrl));

sbuf->mtype=1;

sbuf->pid=0;

121
sbuf->buffer[0]=err_code;

sbuf->length=1;

sbuf->ipaddr.s_addr=INADDR_ANY;

if( (ob2ap=msgget(rbuf->pid,0777))==-1)

return;

msgsnd(ob2ap,sbuf,sizeof(struct ap2ctrl)-sizeof(long),0);

free(sbuf);

void gen_resp_sock(int err,struct sockaddr_in

*remote_addr)

__uint8_t *buf=(char *)malloc(7); /*THE SIZE SPEC HERE ie

7 seven has 2b made common #def val*/

buf[0]=err;

buf[1]=DTOH(7,1,2) ;

buf[2]=DTOH(7,2,2);

122
buf[3]=0x10;

buf[4]=0x00;

buf[5]=buf[6]=0;

sendto(sd,(void *)buf,7,0,(struct sockaddr

*)remote_addr,sizeof(struct sockaddr_in));

free(buf) ;

int snd2chld(struct ap2ctrl *rbuf)

int clid;

if( (clid=msgget(rbuf->pid,0777))==-1)

return FALSE;

if( (msgsnd(clid,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),0))==-1)

return FALSE;

return TRUE;

123
static void finish(int ab)

int srid;

srid=msgget(CTRLQ1ID,0777);

msgctl(srid,IPC_RMID,NULL);

while(close(sd));

exit(0);

int main(void)

int q1id,conn_reqtd=0;

struct sockaddr_in remote_addr;

struct msqid_ds info;

int ctrlid;

long type=0;

ssize_t num;

__uint8_t buf[MAX_PACKET_SIZE];

int packetsize,sock_length=sizeof(struct sockaddr_in);

124
struct ap2ctrl *rbuf=(struct

ap2ctrl*)malloc(sizeof(struct ap2ctrl));

init_q1(&q1id);

init_sock(&local_addr);

rbuf->mtype=1;

signal(SIGINT,finish);

signal(SIGSEGV,finish);

while(1){

if((ctrlid=msgget(CTRLQ1ID,0777)) == -1){

perror("msgget");

exit(-1);

msgctl(ctrlid,IPC_STAT,&info);

if(info.msg_qnum>=1){ /*CHECKING FOR NEW MESSAGES ON

Q1*/

if((ctrlid=msgget(CTRLQ1ID,0777)) == -1){

//printf("Unable to open msgq1");

perror("msgget");

exit(-1);

125
}

num=msgrcv(ctrlid,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),type,0);

switch(rbuf->buffer[0]){

case CONNECT :

if(!hand_con_req(rbuf))/*definite

fork in func */

gen_err_ap(INTERNAL_ERR,rbuf);/*err msg

to appln client*/

break;

case CONNECT_RESP :

if(conn_reqtd){

conn_reqtd--;

if(!hand_con_res(rbuf))

gen_err_ap(INTERNAL_ERR,rbuf);

else

gen_err_ap(ILLEGAL_RESP,rbuf);/*err msg to */

break;

default :

126
if(!snd2chld(rbuf))

gen_err_ap(CHILD_NOEXIST,rbuf);

break;

if((packetsize=recvfrom(sd,(void

*)buf,MAX_PACKET_SIZE,MSG_DONTWAIT,(struct sockaddr

*)&remote_addr,&sock_length))!=-1){

switch(buf[0]){

case CONNECT:

//printf("1. Port=%u ip addrr=

%u\n",remote_addr.sin_port,remote_addr.sin_addr.s_addr);

if(!hand_connect_sock(buf,packetsize,&remote_addr))

gen_resp_sock(SERV_UNAV,&remote_addr);

conn_reqtd++;

break;

default:

gen_resp_sock(BAD_REQ,&remote_addr);

127
}

servercontroller.c

#include "common.h"

int sd;

struct sockaddr_in local_addr;

void init_q1(int *q1id)

if( (*q1id=msgget(CTRLQ1ID,IPC_CREAT|IPC_EXCL|0777))

== -1 )

//printf("First exit");

perror("msgget");

exit(-1);

128
else if(*q1id==0)

msgctl(*q1id,IPC_RMID,NULL);

if( (*q1id=msgget(CTRLQ1ID,IPC_CREAT|IPC_EXCL|

0777))==-1)

//printf("Second exit");

perror("msgget");

exit(-1);

return;

void init_sock(struct sockaddr_in *local_addr)

local_addr->sin_family=PF_INET;

local_addr->sin_port=htons(CTRL_PORT);

local_addr->sin_addr.s_addr=INADDR_ANY;

129
memset(&(local_addr->sin_zero),'\0',8);

if((sd=socket(PF_INET,SOCK_DGRAM,0))==-1)

perror("socket:");

exit(-1);

if(bind(sd,(struct sockaddr *)local_addr,sizeof(struct

sockaddr_in))==-1)

close(sd);

perror("bind");

exit(-1);

int hand_con_req(struct ap2ctrl *rbuf)

pid_t pid,temp_pid;

int clid;

//printf("\nIn here");

130
if((pid=fork())==0)

execlp("./blockchild","blockchild",(char *)0);

else if(pid<0)

return FALSE;

/*Wait for message queue q4 to be created*/

do{

while( (clid=msgget(pid,0777) )==-1 &&

(temp_pid=waitpid(pid,NULL,WNOHANG))==0);

}while(temp_pid==-1);

if(clid==-1)

return FALSE;

if( (msgsnd(clid,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),0)) ==-1)

return FALSE;

/*send message to child:first rbuf*/

return TRUE;

int hand_con_res(struct ap2ctrl *rbuf)

131
pid_t pid,temp_pid;

int clid;

if(rbuf->buffer[1]==SUCCESS)

close(sd);

if((pid=fork())==0)

execlp("./blockchild","blockchild",(char *)0);/*INSTEAD

EXEC LATER WITH THE CHILD PROGRAM*/

else if(pid<0)

return FALSE;

else{

sd=socket(PF_INET,SOCK_DGRAM,0);

bind(sd,(struct sockaddr *)&local_addr,sizeof(struct

sockaddr_in));

/*Wait for message queue q4 to be created*/

do{

while( (clid=msgget(pid,0777) )==-1 &&

(temp_pid=waitpid(pid,NULL,WNOHANG))==0);

}while(temp_pid==-1);

132
if(clid==-1)

return FALSE;

if( (msgsnd(clid,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),0)) ==-1)

return FALSE;

/*send message to child:first rbuf*/

return TRUE;

else

struct sockaddr_in *remote_addr=ALLOC_MEM(struct

sockaddr_in,1);

__uint16_t connect_resp_size=7;

__uint8_t *buf=(__uint8_t *)malloc(sizeof(__uint8_t));

remote_addr->sin_family=PF_INET;

remote_addr->sin_port=htons(rbuf->port);

remote_addr->sin_addr=rbuf->ipaddr;

memset(&(remote_addr->sin_zero),'\0',8);

buf[0]=0x53;

buf[1]=DTOH(connect_resp_size,1,2);

133
buf[2]=DTOH(connect_resp_size,2,2);

buf[3]=0x10;

buf[4]=0;

buf[5]=DTOH(MAX_PACKET_SIZE,1,2);

buf[6]=DTOH(MAX_PACKET_SIZE,2,2);

if(sendto(sd,(void *)buf,(int)connect_resp_size,0,

(struct sockaddr *)remote_addr,sizeof(struct

sockaddr_in))==-1)

free(remote_addr);

free(buf);

return FALSE;

free(remote_addr);

free(buf);

return TRUE;

int hand_connect_sock(__uint8_t *buf,int packsize,struct

sockaddr_in *remote_addr)

134
{

int q2id,i;

struct ap2ctrl *rbuf=(struct ap2ctrl

*)malloc(sizeof(struct ap2ctrl));

//printf("2. Port=%u ip addrr=%u\n",remote_addr-

>sin_port,remote_addr->sin_addr.s_addr);

rbuf->port=remote_addr->sin_port;

/*if(!inet_aton(remote_addr->sin_addr,&(rbuf->ipaddr)))

return FALSE;*/

rbuf->ipaddr.s_addr=remote_addr->sin_addr.s_addr;

//printf("3. Port=%u ip addrr=%u \n",rbuf->port,rbuf-

>ipaddr.s_addr);

rbuf->mtype=1;

rbuf->buffer[0]=CONNECT;

for(i=0;i<packsize;i++)

rbuf->buffer[i+2]=buf[i];

rbuf->length=packsize+2;

if( (q2id=msgget(APSRVQ2ID,0777))==-1){

perror("msgget:");

return FALSE;

135
}

if( (msgsnd(q2id,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),0)) ==-1){

perror("msgsnd:");

return FALSE;

return TRUE;

void gen_err_ap(__uint8_t err_code,struct ap2ctrl *rbuf)

struct ap2ctrl *sbuf;

int ob2ap;

sbuf=(struct ap2ctrl *)malloc(sizeof(struct

ap2ctrl));

sbuf->mtype=1;

sbuf->pid=0;

sbuf->buffer[0]=err_code;

sbuf->length=1;

sbuf->ipaddr.s_addr=INADDR_ANY;

136
if( (ob2ap=msgget(rbuf->pid,0777))==-1)

return;

msgsnd(ob2ap,sbuf,sizeof(struct ap2ctrl)-sizeof(long),0);

free(sbuf);

void gen_resp_sock(int err,struct sockaddr_in

*remote_addr)

__uint8_t *buf=(char *)malloc(7); /*THE SIZE SPEC HERE ie

7 seven has 2b made common #def val*/

buf[0]=err;

buf[1]=DTOH(7,1,2) ;

buf[2]=DTOH(7,2,2);

buf[3]=0x10;

buf[4]=0x00;

buf[5]=buf[6]=0;

137
sendto(sd,(void *)buf,7,0,(struct sockaddr

*)remote_addr,sizeof(struct sockaddr_in));

free(buf) ;

int snd2chld(struct ap2ctrl *rbuf)

int clid;

if( (clid=msgget(rbuf->pid,0777))==-1)

return FALSE;

if( (msgsnd(clid,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),0))==-1)

return FALSE;

return TRUE;

static void finish(int ab)

int srid;

srid=msgget(CTRLQ1ID,0777);

msgctl(srid,IPC_RMID,NULL);

while(close(sd));

138
exit(0);

int main(void)

int q1id,conn_reqtd=0;

struct sockaddr_in remote_addr;

struct msqid_ds info;

int ctrlid;

long type=0;

ssize_t num;

__uint8_t buf[MAX_PACKET_SIZE];

int packetsize,sock_length=sizeof(struct sockaddr_in);

struct ap2ctrl *rbuf=(struct

ap2ctrl*)malloc(sizeof(struct ap2ctrl));

init_q1(&q1id);

init_sock(&local_addr);

rbuf->mtype=1;

signal(SIGINT,finish);

signal(SIGSEGV,finish);

139
while(1){

if((ctrlid=msgget(CTRLQ1ID,0777)) == -1){

perror("msgget");

exit(-1);

msgctl(ctrlid,IPC_STAT,&info);

if(info.msg_qnum>=1){ /*CHECKING FOR NEW MESSAGES ON

Q1*/

if((ctrlid=msgget(CTRLQ1ID,0777)) == -1){

//printf("Unable to open msgq1");

perror("msgget");

exit(-1);

num=msgrcv(ctrlid,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),type,0); switch(rbuf->buffer[0]){

case CONNECT :

if(!hand_con_req(rbuf))/*definite

fork in func */

gen_err_ap(INTERNAL_ERR,rbuf);/*err msg

to appln client*/

140
break;

case CONNECT_RESP :

if(conn_reqtd){

conn_reqtd--;

if(!hand_con_res(rbuf))

gen_err_ap(INTERNAL_ERR,rbuf);

else

gen_err_ap(ILLEGAL_RESP,rbuf);/*err msg to */

break;

default :

if(!snd2chld(rbuf))

gen_err_ap(CHILD_NOEXIST,rbuf);

break;

} /*end of switch1*/

if((packetsize=recvfrom(sd,(void

*)buf,MAX_PACKET_SIZE,MSG_DONTWAIT,(struct sockaddr

*)&remote_addr,&sock_length))!=-1){

141
switch(buf[0]){

case CONNECT:

//printf("1. Port=%u ip addrr=

%u\n",remote_addr.sin_port,remote_addr.sin_addr.s_addr);

if(!hand_connect_sock(buf,packetsize,&remote_addr))

gen_resp_sock(SERV_UNAV,&remote_addr);

conn_reqtd++;

break;

default:

gen_resp_sock(BAD_REQ,&remote_addr);

The files of Client Side is as follows:

Common.h

#include<stdio.h>

#include<sys/types.h>

142
#include<string.h>

#include "types.h"

void init_packet_info(struct packet_info *s_packet);

__uint8_t *ATOU(__uint8_t *asc);

__uint8_t *construct_packet(int packet_type,struct

packet_info s_packet,__uint16_t *len);

postgress.h

#ifndef POSTGRES_H

#define POSTGRES_H

#include "postgres_ext.h"

143
#include "c.h"

#include "utils/elog.h"

#include "utils/mcxt.h"

#include "utils/palloc.h"

/* ------------------------------------------------

Section 1: simple type definitions

------------------------------------------------*/

typedef int16 int2;

typedef int32 int4;

typedef float float4;

typedef double float8;

typedef int4 aclitem;

#define InvalidOid 0

#define OidIsValid(objectId) ((bool) ((objectId) !=

InvalidOid))

/* unfortunately, both regproc and RegProcedure are used

*/

typedef Oid regproc;

typedef Oid RegProcedure;

/* ptr to func returning (char *) */

144
#if defined(__mc68000__) && defined(__ELF__)

typedef int32 ((*func_ptr) ());

#else

typedef char *((*func_ptr) ());

#endif

#define RegProcedureIsValid(p) OidIsValid(p)

/* ------------------------------------------------

Section 2: variable length and array types

-------------------------------------------------*/

struct varlena

int32 vl_len;

char vl_dat[1];

};

#define VARSIZE(PTR) (((struct varlena *)(PTR))->vl_len)

#define VARDATA(PTR) (((struct varlena *)(PTR))->vl_dat)

#define VARHDRSZ ((int32) sizeof(int32))

typedef struct varlena bytea;

typedef struct varlena text;

typedef int2 int2vector[INDEX_MAX_KEYS];

145
typedef Oid oidvector[INDEX_MAX_KEYS];

#undef TUPLE_TOASTER_ACTIVE

#undef TUPLE_TOASTER_ALL_TYPES

#ifdef TUPLE_TOASTER_ACTIVE

typedef struct varattrib

int32 va_header; /* External/compressed storage */

/* flags and item size */

union

struct

int32 va_rawsize; /* Plain data size */

}va_compressed; /* Compressed stored

attribute */

struct

int32 va_rawsize; /* Plain data size */

Oid va_valueid; /* Unique identifier of value

146
*/

Oid va_longrelid; /* RelID where to find

chunks */

Oid va_rowid; /* Main tables row Oid */

int16 va_attno;/* Main tables attno */

}va_external;

/* External stored attribute */

char va_data[1]; /* Plain stored attribute */

} va_content;

} varattrib;

#define VARATT_FLAG_EXTERNAL 0x8000

#define VARATT_FLAG_COMPRESSED 0x4000

#define VARATT_MASK_FLAGS 0xc000

#define VARATT_MASK_SIZE 0x3fff

#define VARATT_SIZEP(_PTR)(((varattrib *)(_PTR))-

>va_header)

#define VARATT_SIZE(PTR) (VARATT_SIZEP(PTR) &

VARATT_MASK_SIZE)

147
#define VARATT_DATA(PTR) (((varattrib *)(PTR))-

>va_content.va_data)

#define VARATT_IS_EXTENDED(PTR)\

((VARATT_SIZEP(PTR) & VARATT_MASK_FLAGS) != 0)

#define VARATT_IS_EXTERNAL(PTR)\

((VARATT_SIZEP(PTR) & VARATT_FLAG_EXTERNAL)!= 0)

#define VARATT_IS_COMPRESSED(PTR) \

((VARATT_SIZEP(PTR) & VARATT_FLAG_COMPRESSED) != 0)

extern varattrib *heap_tuple_untoast_attr(varattrib *

attr);

#define VARATT_GETPLAIN(_ARG,_VAR) {

if (VARATTR_IS_EXTENDED(_ARG))

(_VAR) = (void *)heap_tuple_untoast_attr(_ARG);

else

(_VAR) = (_ARG);

148
}

#define VARATT_FREE(_ARG,VAR) do {

if ((void *)(_VAR) != (void *)(_ARG))

pfree((void *)(_VAR));

} while (0)

#else /* TUPLE_TOASTER_ACTIVE */

#define VARATT_SIZE(__PTR) VARSIZE(__PTR)

#define VARATT_SIZEP(__PTR) VARSIZE(__PTR)

#endif /* TUPLE_TOASTER_ACTIVE */

typedef union nameData

char data[NAMEDATALEN];

int alignmentDummy;

} NameData;

typedef NameData *Name;

#define NameStr(name) ((name).data)

149
/*-------------------------------------------

Section 3: TransactionId and CommandId

-------------------------------------------- */

typedef uint32 TransactionId;

#define InvalidTransactionId 0

typedef uint32 CommandId;

#define FirstCommandId 0

/* ------------------------------------------------

Section 4: genbki macros used by the

catalog/pg_xxx.h files

----------------------------------------------- */

#define CATALOG(x) \

typedef struct CppConcat(FormData_,x)

#define DATA(x) extern int errno

#define DESCR(x) extern int errno

#define DECLARE_INDEX(x) extern int errno

#define DECLARE_UNIQUE_INDEX(x) extern int errno

#define BUILD_INDICES

#define BOOTSTRAP

150
#define BKI_BEGIN

#define BKI_END

/* ------------------------------------------------

Section 5: random stuff CSIGNBIT, STATUS...

--------------------------------------------------

*/

#define ISIGNBIT (0x80000000)

#define WSIGNBIT (0x8000)

/* msb for char */

#define CSIGNBIT (0x80)

#define STATUS_OK (0)

#define STATUS_ERROR (-1)

#define STATUS_NOT_FOUND (-2)

#define STATUS_INVALID (-3)

#define STATUS_UNCATALOGUED (-4)

#define STATUS_REPLACED (-5)

#define STATUS_NOT_DONE (-6)

#define STATUS_BAD_PACKET (-7)

#define STATUS_FOUND (1)

151
/* ---------------------------------------

Cyrillic on the fly charsets recode

------------------------------------------- */

#ifdef CYR_RECODE

extern void SetCharSet();

#endif /* CYR_RECODE */

#endif /* POSTGRES_H */

postgres-ext.h

#ifndef POSTGRES_EXT_H

#define POSTGRES_EXT_H

152
typedef unsigned int Oid;

#define NAMEDATALEN 32

#endif

types.h

#include <unistd.h>

#include <stdio.h>

153
#include <stdlib.h>

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

#include <error.h>

#include <errno.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <netinet/tcp.h>

#include <arpa/inet.h>

#include <signal.h>

/*definition of standard port and queues*/

#define CTRLQ1ID 1234L

#define APSRVQ2ID5432L

#define CTRL_PORT650

/*standard size information for this implemntation of

obex*/

#define MAX_PACKET_SIZE 1024

#define DEF_PACKET_SIZE 0xFF

154
#define MSGMAX 4080

/*max allowed by linux during the time

of implementation*/

#define MAX_OBJECT_SIZE MSGMAX-sizeof(long)-

sizeof(pid_t)-4-sizeof(unsigned short)-sizeof(struct

in_addr)

#define UUID 16

#define VERSION 0x10

#define NO_OF_HEADERS 12

#define NAME 0x01

#define TYPE 0x42

#define LENGTH 0xC3

#define TIME 0x44

#define DESCRIPTION 0x05

#define WHO 0x4A

#define TARGET 0x46

#define BODY 0x48

#define END_OF_BODY 0x49

#define CONNECT_ID 0xCB

#define AUTH_CHAL 0x4D

155
#define AUTH_RESP 0x43

#define CONNECT 0x80

#define DISCONNECT 0xA0

#define PUT 0x02

#define FPUT 0x82

#define GET 0x03

#define SETPATH 0x85

#define ABORT 0xFF

#define CONTINUE 0x10

#define SUCCESS 0x20

#define BAD_REQ 0x40

#define UNAUTH 0x41

#define FORBID 0x43

#define NOT_FOUND 0x44

#define REQ_TIMEOUT 0x48

#define LENGTH_REQ 0x4B

#define ENTITY_LARGE 0x4D

#define UNSUPP_TYPE 0x4F

#define INTERNAL_ERR 0x50

#define NOT_IMP 0x51

156
#define SERV_UNAV 0x53

#define CONNECT_RESP 0x01

#define PUT_RESP 0x02

#define DISCON_RESP 0x03

#define GET_RESP 0x04

#define SET_RESP 0x05

#define ABORT_RESP 0x06

enum{ CHILD_NOEXIST=1 , REQ_FAILURE , RESOURCE_FAILURE ,

TIMED_OUT ,ILLEGAL_RESP};

#define SIZE_OF_ID 0x04

#define SIZE_OF_TIME 0x04

#define SIZE_OF_LEN 0x04

#define ALLOC_MEM(type,num) (type *)malloc(num

*sizeof(type))

#define DTOH(num,l,r) (num<<((l-1)*8))>>((r-1)*8);

struct connect_info{

__uint64_t length;

__uint8_t who[UUID+1],wflag;

__uint8_t target[UUID+1],tflag;

157
ushort sin_port;

char inet_addr[16];

};

struct packet_info{

__uint8_t opcode;

/*__uint32_t length;

__uint32_t connect_id;

__uint32_t time; */

__uint8_t *headers[NO_OF_HEADERS];

__uint16_t hdr_length[NO_OF_HEADERS];

__uint8_t flag,constant;

__uint16_t maxsize;

};

struct ap2ctrl

long mtype;

pid_t pid;

158
__uint8_t buffer[MAX_OBJECT_SIZE];/*The actual data

to be sent*/

__uint32_t length;/*length-lenght of buffer,ipaddr-

iip address of remote m/c*/

unsigned short int port;

struct in_addr ipaddr;

};

enum { _target , _connect_id , _who , _name , _type ,

_descript , _length, _time , _body , _end_of_body ,

_auth_chal , _auth_resp };

#define CONNECT_FLAGS 0x00

#define TRUE 1

#define FALSE 0

appclient.c

#define APSRVQ2ID 5432L

159
#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

#include <stdlib.h>

#include <stdio.h>

#include <error.h>

#include <signal.h>

#include <unistd.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <netinet/tcp.h>

#include <arpa/inet.h>

#include "types.h"

#define CTRL_PORT 650

#define CTRLQ1ID 1235L

#define MSGMAX 4080

#define MAX_OBJECT_SIZE MSGMAX-sizeof(long)-

sizeof(pid_t)-4-sizeof(unsigned short)-sizeof(struct

in_addr)

pid_t pid;

160
void initq2(int *q2id)

if( (*q2id=msgget(pid,IPC_CREAT|IPC_EXCL|0777))==-1)

printf("\nExit in initq2");

exit(-1);

static void finish(int ab)

int srid;

srid=msgget(pid,0777);

msgctl(srid,IPC_RMID,NULL);

printf("\nExit in finish");

exit(0);

operations(struct ap2ctrl *rbuf)

int q2id;

161
getchar();

free(rbuf);

q2id=msgget(pid,0777);

msgctl(q2id,IPC_RMID,NULL);

exit(0);

int main(void)

int q2id,q1id;

char c,c1=0,c2;

char ip[100];

struct msqid_ds info;

long type=0;

ssize_t num;

int i;

__uint8_t *buf;

struct ap2ctrl *rbuf=(struct

ap2ctrl*)malloc(sizeof(struct ap2ctrl));

pid=getpid();

162
while(rbuf==NULL)

rbuf=(struct ap2ctrl*)malloc(sizeof(struct ap2ctrl));

rbuf->mtype=1;

/*initq2(&q2id);*/

signal(SIGINT,finish);

printf("c-->CONNECT\nd-->DISCONNECT\np-->PUT\n");

while(1){

printf("?");

scanf("%c",&c);

getchar();

if(c=='c'){

printf("Enter IP address remote machine:\n");

scanf("%s",ip);

getchar();

/*signal(SIGSEGV,finish);*/

if(!inet_aton(ip,&(rbuf->ipaddr)))

perror("inet_aton");

rbuf->port=htons(CTRL_PORT);

rbuf->buffer[0]=CONNECT;

rbuf->length=1;

163
rbuf->pid=pid;

if((q1id=msgget(CTRLQ1ID,0777))!=-1)

msgsnd(q1id,rbuf,sizeof(struct ap2ctrl)-sizeof(long),0);

if((q2id=msgget(pid,0777))!=-1)

msgrcv(q2id,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),0,0);

printf("\nConnect Response == %x\n",rbuf-

>buffer[0]);

while(1){

printf("?");

scanf("%c",&c2);

getchar();

switch(c2){

case 'p':

rbuf->buffer[0]=PUT;

buf=rbuf->buffer+1;

printf("Enter Your data:\n");

fgets(buf,MAX_OBJECT_SIZE-1,stdin);

rbuf->length=strlen(buf);

if((q1id=msgget(CTRLQ1ID,0777))!=-1)

164
msgsnd(q1id,rbuf,sizeof(struct

ap2ctrl)-sizeof(long),0);

if((q2id=msgget(pid,0777))!=-1)

msgrcv(q2id,rbuf,sizeof(struct ap2ctrl)-sizeof(long),0,0);

printf("\nPut Response == %x\n",rbuf->buffer[0]);

break;

case 'd':

c1=1;

break;

case '\n':

break;

default:

printf("\nInvalid Command\n");

if(c1)

break;

if(c1)

break;

165
}

printf("\nSending Disconnect Packet ");

rbuf->buffer[0]=DISCONNECT;

if((q1id=msgget(CTRLQ1ID,0777))!=-1)

msgsnd(q1id,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),0);

if((q2id=msgget(pid,0777))!=-1)

msgrcv(q2id,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),0,0);

printf("\nDisconnect Response == %x\n",rbuf-

>buffer[0]);

finish(0);

appserver.c

#define APSRVQ2ID 5432L

#include <sys/types.h>

166
#include <sys/ipc.h>

#include <sys/msg.h>

#include <stdlib.h>

#include <stdio.h>

#include <error.h>

#include <signal.h>

#include <unistd.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <netinet/tcp.h>

#include <arpa/inet.h>

#include "types.h"

#include "libpq-fe.h"

#define CTRLQ1ID 1234L

#define APSRVQ2ID 5432L

#define MSGMAX 4080

#define MAX_OBJECT_SIZE MSGMAX-sizeof(long)-

sizeof(pid_t)-4-sizeof(unsigned short)-sizeof(struct

in_addr)

void initq2(int *q2id)

167
{

if( (*q2id=msgget(APSRVQ2ID,IPC_CREAT|IPC_EXCL|

0777))==-1)

printf("\nExit in initq2");

exit(-1);

static void finish(int ab)

int srid;

srid=msgget(APSRVQ2ID,0777);

msgctl(srid,IPC_RMID,NULL);

printf("\nExit in finish");

exit(0);

int main(void)

int q2id,q1id;

struct msqid_ds info;

168
long type=0;

ssize_t num;

int i,j,k;

char vid[7][31];

PGresult *res;

int ntuples;

char cmd[250];

PGconn *conn;

char *tstamp;

char

*dbname="Vcard",*user="root",*pghost="localhost",*pgport="

5432";

struct ap2ctrl *rbuf=(struct

ap2ctrl*)malloc(sizeof(struct ap2ctrl));

while(rbuf==NULL)

rbuf=(struct ap2ctrl*)malloc(sizeof(struct ap2ctrl));

rbuf->mtype=1;

initq2(&q2id);

signal(SIGINT,finish);

/*signal(SIGSEGV,finish);*/

169
while(1)

q2id=msgget(APSRVQ2ID,0777) ;

msgctl(q2id,IPC_STAT,&info);

if(info.msg_qnum>=1) /*CHECKING FOR NEW MESSAGES

ON Q1*/

if( (q2id=msgget(APSRVQ2ID,0777)) == -1)

printf("Unable to open msgq1");

perror("msgget");

exit(-1);

num=msgrcv(q2id,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),type,0);

switch(rbuf->buffer[0])

case CONNECT : rbuf->buffer[0]=CONNECT_RESP;

rbuf->buffer[1]=SUCCESS;

rbuf->pid=APSRVQ2ID;

170
if((q1id=msgget(CTRLQ1ID,0777))!=-1)

if(msgsnd(q1id,rbuf,sizeof(struct

ap2ctrl)-sizeof(long),0)==-1)

perror("msgsnd");

else

perror("msgget");

printf("\nConnection accepted from Host: %s Port:

%u\n",inet_ntoa(rbuf->ipaddr),ntohs(rbuf->port));

break;

case PUT:

printf("\nMessage received from Host: %s Port:

%u\n",inet_ntoa(rbuf->ipaddr),ntohs(rbuf->port));

printf("Length == %d\n",rbuf->length);

for(i=1;i<rbuf->length;i++)

printf("%c",rbuf->buffer[i]);

printf("\n");

k=1;

171
for(i=0;i<7;i++)

for(j=0;rbuf->buffer[k]!='\0';j++)

vid[i][j]=rbuf->buffer[k++];

// printf("\nK== %d j==%d\n",k,j);

vid[i][j]='\0';

k++;

//rbuf->buffer[k++];

// printf("\n %s \n",vid[i]);

conn=PQsetdbLogin(pghost,pgport,NULL,NULL,dbname,user,NULL

);

sprintf(cmd,"select * from scard where vcardid=

%d",atoi(vid[0]));

res=PQexec(conn,cmd);

ntuples=PQntuples(res);

172
if(ntuples==0)

sprintf(cmd,"insert into scard values (%d ,'%s',

'%s','%s',%d,'%s',

%d)",atoi(vid[0]),vid[1],vid[2],vid[3],atoi(vid[4]),vid[5]

,atoi(vid[6]));

res=PQexec(conn,cmd);

else

// sprintf(cmd,"select * from scard where vcardid=

%d",atoi(vid[0]));

// res=PQexec(conn,cmd);

tstamp=PQgetvalue(res,0,6);

if(atoi(tstamp)<atoi(vid[6]))

sprintf(cmd,"delete from scard where vcardid=

%d",atoi(vid[0]));

res=PQexec(conn,cmd);

173
sprintf(cmd,"insert into scard values (%d ,'%s',

'%s','%s',%d,'%s',

%d)",atoi(vid[0]),vid[1],vid[2],vid[3],atoi(vid[4]),vid[5]

,atoi(vid[6]));

res=PQexec(conn,cmd);

if(PQresultStatus(res)==PGRES_COMMAND_OK)

printf("comm successful \n");

PQclear(res);

PQfinish(conn);

break;

case GET:break;

default:

break;

174
printf("\vExited decently");

blockchild.c

#include "common.h"

175
int max_packet_size=MAX_PACKET_SIZE;

int appln_qid;

int sdnew;

struct sockaddr_in *remote_addr;

pid_t pid;

void init_q_info(struct ap2ctrl *rbuf)

rbuf->pid=getpid();

rbuf->mtype=1;

rbuf->length=0;

__uint16_t htod(__uint8_t *buf,__uint16_t *i,int j)

__uint16_t res=0;

int k;

for(k=0;k<j-1;k++){

res|=buf[(*i)];

(*i)++;

res<<=8;

176
}

res|=buf[*i];

(*i)++;

return res;

void child_exit(__uint8_t err)

int clid;

struct ap2ctrl *rbuf=ALLOC_MEM(struct ap2ctrl,1);

if(remote_addr) free(remote_addr);

remote_addr=NULL;

rbuf->pid=getpid();

rbuf->mtype=1;

rbuf->buffer[0]=err;

rbuf->length=1;

if((clid=msgget(appln_qid,0777))!=-1)

msgsnd(clid,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),0);

if((clid=msgget(pid,0777) )!=-1)

177
msgctl(clid,IPC_RMID,NULL);

if(rbuf) free(rbuf);

rbuf=NULL;

close(sdnew);

exit(err);

void gen_sock_resp(__uint8_t resp)

__uint8_t *buf=ALLOC_MEM(__uint8_t,3);

buf[0]=resp;

buf[1]=0;

buf[2]=3;

while(sendto(sdnew,(void *)buf,3,0,(struct sockaddr

*)remote_addr,sizeof(struct sockaddr_in))==-1);

if(buf) free(buf);

buf=NULL;

void gen_q_resp(__uint8_t resp)

178
{

int clid;

struct ap2ctrl *rbuf=ALLOC_MEM(struct ap2ctrl,1);

rbuf->buffer[0]=SUCCESS;

rbuf->length=1;

rbuf->pid=pid;

rbuf->mtype=1;

if((clid=msgget(appln_qid,0777))==-1){

perror("msgget");

init_q_info(rbuf);

if(rbuf) free(rbuf);

rbuf=NULL;

child_exit(0);

while(msgsnd(clid,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),0)==-1){

perror("msgsnd");

switch(errno){

case EIDRM:

case EACCES:

179
case EAGAIN:

init_q_info(rbuf);

if(rbuf) free(rbuf);

rbuf=NULL;

child_exit(0);

init_q_info(rbuf);

if(rbuf) free(rbuf);

rbuf=NULL;

return;

void init_q()

int qid;

if((qid=msgget(pid,IPC_CREAT|IPC_EXCL|0777)) == -1 )

//printf("First exit");

perror("msgget");

180
exit(-1);

else if(qid==0)

msgctl(qid,IPC_RMID,NULL);

if( (qid=msgget(pid,IPC_CREAT|IPC_EXCL|0777))==-

1)

//printf("Second exit");

perror("msgget");

exit(-1);

return;

void init_sock(struct sockaddr_in *local_addr)

local_addr->sin_family=PF_INET;

local_addr->sin_port=0;

local_addr->sin_addr.s_addr=INADDR_ANY;

181
memset(&(local_addr->sin_zero),'\0',8);

if((sdnew=socket(PF_INET,SOCK_DGRAM,0))==-1)

perror("socket:");

exit(-1);

if(bind(sdnew,(struct sockaddr *)local_addr,sizeof(struct

sockaddr_in))==-1)

close(sdnew);

exit(-1);

void extract_packet_headers(struct packet_info

*pinfo,__uint8_t *buf,__uint16_t len,int req)

__uint16_t hd_length=0,j=0,i=3;

switch(buf[0]){

case CONNECT:

i=7;

182
break;

case SETPATH:

i=5;

break;

case SUCCESS:

case CONTINUE:

case BAD_REQ:

case UNAUTH:

case FORBID:

case NOT_FOUND:

case REQ_TIMEOUT:

case ENTITY_LARGE:

case UNSUPP_TYPE:

case INTERNAL_ERR:

case NOT_IMP:

case SERV_UNAV:

switch(req){

case CONNECT:

i=7;

183
}

if(i>=len)

return;

while(i<len){

switch(buf[i++]){

case LENGTH:

pinfo->headers[_length]=ALLOC_MEM(__uint8_t,4);

for(j=0;j<4;j++,i++)

pinfo->headers[_length][j]=buf[i];

break;

case BODY:

hd_length=0;

hd_length=htod(buf,&i,2);

pinfo->headers[_body]=

ALLOC_MEM(__uint8_t,hd_length-3);

pinfo->hdr_length[_body]=(hd_length-3);

for(j=0;j<pinfo->hdr_length[_body];j++,i++)

pinfo->headers[_body][j]=buf[i];

break;

case END_OF_BODY:

184
hd_length=0;

hd_length=htod(buf,&i,2);

pinfo->headers[_end_of_body]=

ALLOC_MEM(__uint8_t,hd_length-3);

pinfo->hdr_length[_end_of_body]=(hd_length-3);

for(j=0;j<pinfo->hdr_length[_end_of_body];j++,i++)

pinfo->headers[_end_of_body][j]=buf[i];

break;

void hand_disc_to_ap(__uint8_t *fbuf,__uint16_t plen)

int clid;

struct ap2ctrl *rbuf=ALLOC_MEM(struct ap2ctrl,1);

/*check for validity of packet.return false if not valid

and response is an failure respose*/

185
gen_sock_resp(SUCCESS);

rbuf->length=(__uint32_t)1;

rbuf->buffer[0]=DISCONNECT;

rbuf->port=remote_addr->sin_port;

rbuf->ipaddr=remote_addr->sin_addr;

if((clid=msgget(APSRVQ2ID,0777) )==-1){

rbuf->pid=getpid();

msgsnd(clid,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),0);

/*main local resources freed before fn. called*/

if(rbuf) free(rbuf);

rbuf=NULL;

child_exit(0);

void hand_disc_from_app(struct ap2ctrl *rbuf)

__uint16_t len;

186
int clid;

/* Send Disconnect request */

gen_sock_resp(DISCONNECT);

/*Send "Diconnect Successful" message to application

layer*/

rbuf->length=1;

rbuf->buffer[0]=SUCCESS;

if((clid=msgget(appln_qid,0777) )!=-1){

rbuf->pid=getpid();

msgsnd(clid,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),0);

/*Free Resources related to queues*/

if(rbuf) free(rbuf);

rbuf=NULL;

child_exit(0);

187
void hand_put_to_ap(__uint8_t *recv_buf,__uint16_t plen)

__uint8_t *buf,*sbuf;

__uint16_t len;

int packetsize,i=0;

__uint32_t buf_len=0;

socklen_t sock_length=sizeof(struct sockaddr_in);

int clid,j,k;

struct packet_info *pinfo=ALLOC_MEM(struct packet_info,1);

struct packet_info *rinfo=ALLOC_MEM(struct packet_info,1);

struct ap2ctrl *rbuf=ALLOC_MEM(struct ap2ctrl,1);

#define HPTAF free(pinfo) , free(rinfo), free(rbuf)

#define HPTAC(err) HPTAF,child_exit(err);

init_packet_info(pinfo);

init_packet_info(rinfo);

rbuf->mtype=1;

rbuf->pid=getpid();

rbuf->port=remote_addr->sin_port;

188
rbuf->ipaddr=remote_addr->sin_addr;

extract_packet_headers(rinfo,recv_buf,plen,PUT);

/*check if length specified*/

if(!rinfo->headers[_length]){

gen_sock_resp(LENGTH_REQ);

/*if the fn succeeds then free local resources and

return*/

HPTAF;

return;

/*assign the length of data to rbuf->length*/

k=0;

rbuf->length=htod(rinfo->headers[_length],(__uint16_t

*)&k,4);

if(rinfo->headers[_end_of_body]){

gen_sock_resp(BAD_REQ);

HPTAF;

return;

189
rbuf->buffer[buf_len++]=PUT;

if(rinfo->headers[_body]){

if(rbuf->length<rinfo->hdr_length[_body]){

gen_sock_resp(ENTITY_LARGE);

HPTAF;

return;

gen_sock_resp(CONTINUE);

rbuf->buffer[0]=PUT;

for(j=0;j<rinfo->hdr_length[_body];j++)

rbuf->buffer[buf_len++]=rinfo->headers[_body][j];

else

gen_sock_resp(CONTINUE);

if(recv_buf) free(recv_buf);

recv_buf=NULL;

recv_buf=(__uint8_t

*)ALLOC_MEM(__uint8_t,max_packet_size);

while(1){

190
while((packetsize=recvfrom(sdnew,(void

*)recv_buf,max_packet_size,0,(struct sockaddr

*)remote_addr,&sock_length))==-1);

switch(recv_buf[0]){

case PUT:

init_packet_info(rinfo);

extract_packet_headers(rinfo,recv_buf,packetsize,PUT);

if(!rinfo->headers[_body]){

gen_sock_resp(NOT_IMP);

break;

if(buf_len-1+rinfo->hdr_length[_body]>rbuf-

>length){

gen_sock_resp(ENTITY_LARGE);

break;

if(rinfo->headers[_end_of_body]){

gen_sock_resp(BAD_REQ);

break;

191
}

gen_sock_resp(CONTINUE);

for(j=0;j<rinfo->hdr_length[_body];j++)

rbuf->buffer[buf_len++]=rinfo-

>headers[_body][j];

break;

case FPUT:

init_packet_info(rinfo);

extract_packet_headers(rinfo,recv_buf,packetsize,PUT);

if(!rinfo->headers[_end_of_body]){

gen_sock_resp(NOT_IMP);

break;

if(buf_len-1+rinfo-

>hdr_length[_end_of_body]>rbuf->length){

gen_sock_resp(ENTITY_LARGE);

break;

gen_sock_resp(SUCCESS);

for(j=0;j<rinfo->hdr_length[_end_of_body];j++)

192
rbuf->buffer[buf_len++]=rinfo-

>headers[_end_of_body][j];

rbuf->length=buf_len;

//printf("\nThe received message:\n");

//printf("Length=%d opcode=%x\n",rbuf-

>length,rbuf->buffer[0]);

//for(j=1;j<rbuf->length;j++)

//printf("%c",rbuf->buffer[j]);

//printf("\n");

if((clid=msgget(appln_qid,0777))==-1)

HPTAC(RESOURCE_FAILURE);

if((msgsnd(clid,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),0))==-1)

HPTAC(RESOURCE_FAILURE);

free(pinfo),free(rinfo);

//HPTAF;

return;

case ABORT:

gen_sock_resp(SUCCESS);

HPTAF;

193
return;

default:

gen_sock_resp(BAD_REQ);

init_packet_info(rinfo);

init_packet_info(pinfo);

void hand_put_from_ap(struct ap2ctrl *rbuf)

__uint8_t

*recv_buf=ALLOC_MEM(__uint8_t,max_packet_size),*buf=NULL;

struct packet_info *pinfo=ALLOC_MEM(struct

packet_info,1);

__uint16_t size_of_body=max_packet_size-

6,tot_packet_size,len;

__uint16_t body_ctr=1;

int i,lastchunk=FALSE,k;

194
socklen_t sock_length=sizeof(struct sockaddr_in);

init_packet_info(pinfo);

/*if(rbuf->name){

pinfo->headers[_name]=ALLOC_MEM(__uint8_t,strlen(rbuf-

>name));

pinfo->hdr_length[_name]=strlen(rbuf->name)-1;

}*/

/*Assume size given*/

pinfo->headers[_length]=ALLOC_MEM(__uint8_t,4);

pinfo->hdr_length[_length]=4;

for(k=1;k<=4;k++)

pinfo->headers[_length][k-1]=DTOH(rbuf->length-1,k,4);

pinfo->opcode=PUT;

pinfo->maxsize=max_packet_size;

buf=construct_packet(PUT,*pinfo,&len);

if(sendto(sdnew,(void *)buf,(int)len,0,(struct sockaddr

*)remote_addr,sizeof(struct sockaddr_in))==-1){

init_q_info(rbuf);

195
gen_q_resp(INTERNAL_ERR);

init_packet_info(pinfo);

if(pinfo) free(pinfo);

pinfo=NULL;

if(buf) free(buf);

buf=NULL;

if(recv_buf) free(recv_buf);

recv_buf=NULL;

return;

rbuf->length--;

while(1){

while(recvfrom(sdnew,(void

*)recv_buf,max_packet_size,0,(struct sockaddr

*)remote_addr,&sock_length)==-1);

init_packet_info(pinfo);

switch(recv_buf[0]){

case CONTINUE:

pinfo->maxsize=max_packet_size;

if(rbuf->length>size_of_body){

196
pinfo->opcode=PUT;

pinfo->headers[_body]=

ALLOC_MEM(__uint8_t,size_of_body);

pinfo->hdr_length[_body]=size_of_body;

for(i=0;i<size_of_body;i++,body_ctr++,rbuf->length--)

pinfo->headers[_body][i]=

rbuf->buffer[body_ctr++];

buf=construct_packet(PUT,*pinfo,&len);

rbuf->length-=size_of_body;

while(sendto(sdnew,(void

*)buf,max_packet_size,0,(struct sockaddr

*)remote_addr,sizeof(struct sockaddr_in))==-1);

else{

pinfo->opcode=PUT;

pinfo-

>headers[_end_of_body]=ALLOC_MEM(__uint8_t,rbuf->length);

pinfo->hdr_length[_end_of_body]=rbuf->length;

for(i=0;i<rbuf->length;i++,body_ctr++)

pinfo->headers[_end_of_body][i]=

197
rbuf->buffer[body_ctr];

buf=construct_packet(PUT,*pinfo,&len);

buf[0]=FPUT;

lastchunk=TRUE;

while(sendto(sdnew,(void *)buf,6+pinfo-

>hdr_length[_end_of_body],0,(struct sockaddr

*)remote_addr,sizeof(struct sockaddr_in))==-1);

if(buf) free(buf);

buf=NULL;

break;

case SUCCESS:

/*assume thisif(lastchunk){*/

init_q_info(rbuf);

gen_q_resp(SUCCESS);

init_packet_info(pinfo);

if(pinfo) free(pinfo);

pinfo=NULL;

if(buf) free(buf);

buf=NULL;

198
if(recv_buf) free(recv_buf);

recv_buf=NULL;

return;

default:

gen_sock_resp(ABORT);

while(recvfrom(sdnew,(void

*)recv_buf,max_packet_size,0,(struct sockaddr

*)remote_addr,&sock_length)==-1);

init_q_info(rbuf);

init_packet_info(pinfo);

if(recv_buf) free(recv_buf);

recv_buf=NULL;

if(pinfo) free(pinfo);

pinfo=NULL;

if(buf[0]!=SUCCESS){

gen_sock_resp(DISCONNECT);

if(buf) free(buf);

buf=NULL;

child_exit(INTERNAL_ERR);

199
if(buf) free(buf);

buf=NULL;

gen_q_resp(ABORT);

return;

static void finish(int ab)

int srid;

srid=msgget(pid,0777);

msgctl(srid,IPC_RMID,NULL);

while(close(sdnew));

exit(0);

int main(int argc,char** argv)

int clid,chtype;

struct msqid_ds *info=ALLOC_MEM(struct msqid_ds,1);

200
struct ap2ctrl *rbuf=ALLOC_MEM(struct ap2ctrl,1);

struct packet_info *pinfo=ALLOC_MEM(struct

packet_info,1);

struct sockaddr_in *local_addr=ALLOC_MEM(struct

sockaddr_in,1);

__uint8_t *snd_buf,*recv_buf;

__uint16_t len,temp;

socklen_t sock_length=sizeof(struct sockaddr_in);

int packetsize,i;

long type=0;

signal(SIGSEGV,finish);

signal(SIGINT,finish);

#define FREE_MAIN if(info) free(info),info=NULL;

if(rbuf) free(rbuf),rbuf=NULL; if(local_addr)

free(local_addr),local_addr=NULL; if(recv_buf)

free(recv_buf),recv_buf=NULL; if(snd_buf)

free(snd_buf),snd_buf=NULL;

pid=getpid();/*pid initialized*/

init_q();/*generate queue to receive data*/

init_sock(local_addr);

201
/*create a socket and bind it to random port, sdnew

initialized*/

do{

if(((clid=msgget(pid,0777))==-1) ||

(msgctl(clid,IPC_STAT,info)==-1) ){

FREE_MAIN;

child_exit(INTERNAL_ERR);

}while(info->msg_qnum<1);

if(((clid=msgget(pid,0777)) == -1) ||

(msgrcv(clid,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),type,0)==-1))

FREE_MAIN;

child_exit(INTERNAL_ERR);

/*global variables*/

remote_addr=ALLOC_MEM(struct sockaddr_in,1);

remote_addr->sin_addr=rbuf->ipaddr;

202
remote_addr->sin_port=rbuf->port;

remote_addr->sin_family=PF_INET;

memset(&(remote_addr->sin_zero),0,8);

appln_qid=rbuf->pid;

//cout<<"\nIp addr == \n"<<remote_addr-

>sin_addr.s_addr<<endl;

//cout<<"\nPort === \n"<<remote_addr->sin_port<<endl;

if((clid=msgget(pid,0777)) == -1){/*unable to open

application queue*/

FREE_MAIN;

child_exit(0);/*cannot send an error message to

client*/

if(rbuf->buffer[0]==CONNECT){

/*child is behaving as a client*/;

/*send connect request*/

init_packet_info(pinfo);

pinfo->opcode=CONNECT;

pinfo->maxsize=MAX_PACKET_SIZE;

snd_buf=construct_packet(CONNECT,*pinfo,&len);

203
while(sendto(sdnew,(void *)snd_buf,(int)len,0,(struct

sockaddr *)remote_addr,sizeof(struct sockaddr_in))==-1);

if(snd_buf) free(snd_buf);

snd_buf=NULL;

recv_buf=ALLOC_MEM(__uint8_t,max_packet_size);

while((packetsize=recvfrom(sdnew,(void

*)recv_buf,max_packet_size,0,(struct sockaddr

*)remote_addr,&sock_length))==-1);

if(recv_buf[0]!=SUCCESS){/*connection set failed*/

FREE_MAIN;

child_exit(SERV_UNAV);

gen_q_resp(SUCCESS);

i=5;/*position of max packet size in a connet packet*/

temp=htod(recv_buf,(__uint16_t *)&i,2);

if(temp<DEF_PACKET_SIZE){

gen_sock_resp(DISCONNECT);

packetsize=recvfrom(sdnew,(void

*)recv_buf,max_packet_size,0,(struct sockaddr

*)&remote_addr,&sock_length);

204
FREE_MAIN;

child_exit(INTERNAL_ERR);

}/*default packet size is 255 bytes as per current

OBEX specs*/

if(temp<max_packet_size){

max_packet_size=temp;

recv_buf=(__uint8_t

*)realloc(recv_buf,max_packet_size);

//printf("temp == %d\n",temp);

//printf("max == %d\n",max_packet_size);

while(1){

do{

if(((clid=msgget(pid,0777))==-1) ||

(msgctl(clid,IPC_STAT,info)==-1) ){

FREE_MAIN;

child_exit(INTERNAL_ERR);

}while(info->msg_qnum<1);/*Wait for messages*/

205
if(((clid=msgget(pid,0777)) == -1) ||

(msgrcv(clid,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),type,0)==-1)){

FREE_MAIN;

child_exit(INTERNAL_ERR);

}/*Read the messages*/

/*check for packet validity*/

/*assume packet is valid*/

switch(rbuf->buffer[0]){

case PUT:

hand_put_from_ap(rbuf);

break;

case GET:

gen_q_resp(NOT_IMP);

break;

case SETPATH:

gen_q_resp(NOT_IMP);

break;

case DISCONNECT:

206
if(info) free(info),info=NULL;

if(local_addr) free(local_addr),local_addr=NULL;

if(recv_buf) free(recv_buf),recv_buf=NULL; if(snd_buf)

free(snd_buf),snd_buf=NULL;

hand_disc_from_app(rbuf);

break;

default:

gen_q_resp(BAD_REQ);

else{

/*child behaves as a server*/

recv_buf=ALLOC_MEM(__uint8_t,max_packet_size);

i=7;

temp=htod(rbuf->buffer,(__uint16_t *)&i,2);

if(temp<DEF_PACKET_SIZE){

init_packet_info(pinfo);

pinfo->opcode=CONNECT;

207
pinfo->maxsize=MAX_PACKET_SIZE;

snd_buf=construct_packet(CONNECT,*pinfo,&len);

snd_buf[0]=SERV_UNAV;

while(sendto(sdnew,(void *)snd_buf,(int)len,0,(struct

sockaddr *)remote_addr,sizeof(struct sockaddr_in))==-1);

/*free resources*/

child_exit(INTERNAL_ERR);

}/*default packet size is 255 bytes as per current

OBEX specs*/

if(temp<max_packet_size){

max_packet_size=temp;

recv_buf=(__uint8_t

*)realloc(recv_buf,max_packet_size);

init_packet_info(pinfo);

pinfo->opcode=CONNECT;

pinfo->maxsize=MAX_PACKET_SIZE;//MAX_PACKET_SIZE;

snd_buf=construct_packet(CONNECT,*pinfo,&len);

snd_buf[0]=SUCCESS;

208
while(sendto(sdnew,(void *)snd_buf,(int) len,0,(struct

sockaddr *)remote_addr,sizeof(struct sockaddr_in))==-1);

if(snd_buf) free(snd_buf);

snd_buf=NULL;

while(1){

while((packetsize=recvfrom(sdnew,(void

*)recv_buf,max_packet_size,0,(struct sockaddr

*)remote_addr,&sock_length))==-1);

/*Check validity of packet*/

/*assume it is valid*/

switch(recv_buf[0]){

case PUT:

hand_put_to_ap(recv_buf,

(__uint16_t)packetsize);

break;

case GET:

gen_sock_resp(NOT_IMP);

break;

209
case SETPATH:

gen_sock_resp(NOT_IMP);

break;

case DISCONNECT:

if(info) free(info),info=NULL; if(rbuf)

free(rbuf), rbuf=NULL; if(local_addr)

free(local_addr),local_addr=NULL; if(recv_buf)

free(recv_buf),recv_buf=NULL; if(snd_buf)

free(snd_buf),snd_buf=NULL;

hand_disc_to_ap(recv_buf,(__uint16_t)packetsize);

break;

default:

gen_sock_resp(BAD_REQ);

break;

common.c

210
#include<stdio.h>

#include<sys/types.h>

#include<string.h>

#include "types.h"

__uint8_t hdrs[]={ TARGET, CONNECT_ID , WHO , NAME , TYPE

, DESCRIPTION , LENGTH , TIME , BODY, END_OF_BODY ,

AUTH_CHAL , AUTH_RESP };

void init_packet_info(struct packet_info *s_packet)

int i;

for(i=0;i<NO_OF_HEADERS;i++){

if(!s_packet->headers[i])

free(s_packet->headers[i]);

s_packet->headers[i]=NULL;

__uint8_t *ATOU(__uint8_t *asc)

int i,temp=strlen((const char *)asc),j;

211
__uint8_t *uni=(__uint8_t *)malloc(temp*2+1);

for(i=0,j=0;i<temp;i++,j+=2){

uni[j]=0x00;

uni[j+1]=asc[i];

uni[j]='\0';

return uni;

__uint8_t *construct_packet(int packet_type,struct

packet_info s_packet,__uint16_t *len)

__uint16_t tlen=0,total=3,temp;

__uint8_t *buf,*p,i;

__uint16_t j;

if(packet_type==CONNECT || packet_type==CONNECT_RESP)

total+=4;

else if(packet_type==SETPATH)

total+=2;

for(i=0;i<NO_OF_HEADERS;i++)

212
if(s_packet.headers[i]){

if(hdrs[i]<0x40)

total+=s_packet.hdr_length[i]*2+4;

else if(hdrs[i]>=0x40 && hdrs[i]<0x80)

total+=s_packet.hdr_length[i]+3;

else if(hdrs[i]>=0xC0)

total+=s_packet.hdr_length[i]+1;

*len=total;

//printf("Length=%x\n",total);

buf=(__uint8_t *)malloc(total);

buf[tlen++]=s_packet.opcode;

buf[tlen++]=DTOH(total,1,2);

buf[tlen++]=DTOH(total,2,2);

if(packet_type==CONNECT || packet_type==CONNECT_RESP){

buf[tlen++]=VERSION;

buf[tlen++]=s_packet.flag;

buf[tlen++]=DTOH(s_packet.maxsize,1,2);

buf[tlen++]=DTOH(s_packet.maxsize,2,2);

213
else if(packet_type==SETPATH){

buf[tlen++]=s_packet.flag;

buf[tlen++]=s_packet.constant;

for(i=0;i<NO_OF_HEADERS;i++)

if(s_packet.headers[i]){

buf[tlen++]=hdrs[i];

if(hdrs[i]>=40 && hdrs[i]<0x80){

buf[tlen++]=DTOH(s_packet.hdr_length[i]+3,1,2);

buf[tlen++]=DTOH(s_packet.hdr_length[i]+3,2,2);

for(j=0;j<s_packet.hdr_length[i];j++)

buf[tlen++]=s_packet.headers[i][j];

else if(hdrs[i]<40){

buf[tlen++]=DTOH(s_packet.hdr_length[i]+3,1,2);

buf[tlen++]=DTOH(s_packet.hdr_length[i]+3,2,2);

for(j=0;j<s_packet.hdr_length[i];j++){

buf[tlen++]=0x00;

buf[tlen++]=s_packet.headers[i][j];

214
buf[tlen++]='\0';

else if(hdrs[i]>=0xC0)

for(j=0;j<s_packet.hdr_length[i];j++)

buf[tlen++]=s_packet.headers[i][j];

return buf;

Controller.c

#include "common.h"

215
int sd;

struct sockaddr_in local_addr;

void init_q1(int *q1id)

if( (*q1id=msgget(CTRLQ1ID,IPC_CREAT|IPC_EXCL|0777))

== -1 )

//printf("First exit");

perror("msgget");

exit(-1);

else if(*q1id==0)

msgctl(*q1id,IPC_RMID,NULL);

if( (*q1id=msgget(CTRLQ1ID,IPC_CREAT|IPC_EXCL|

0777))==-1)

//printf("Second exit");

perror("msgget");

exit(-1);

216
}

return;

void init_sock(struct sockaddr_in *local_addr)

local_addr->sin_family=PF_INET;

local_addr->sin_port=htons(CTRL_PORT);

local_addr->sin_addr.s_addr=INADDR_ANY;

memset(&(local_addr->sin_zero),'\0',8);

if((sd=socket(PF_INET,SOCK_DGRAM,0))==-1)

perror("socket:");

exit(-1);

if(bind(sd,(struct sockaddr *)local_addr,sizeof(struct

sockaddr_in))==-1)

close(sd);

perror("bind");

217
exit(-1);

int hand_con_req(struct ap2ctrl *rbuf)

pid_t pid;

int clid;

//printf("\nIn here");

if((pid=fork())==0)

execlp("./blockchild","blockchild",(char *)0);

else if(pid<0)

return FALSE;

/*Wait for message queue q4 to be created*/

while( (clid=msgget(pid,0777) )==-1);

if( (msgsnd(clid,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),0)) ==-1)

return FALSE;

/*send message to child:first rbuf*/

return TRUE;

218
int hand_con_res(struct ap2ctrl *rbuf)

pid_t pid;

int clid;

if(rbuf->buffer[1]==SUCCESS)

close(sd);

if((pid=fork())==0)

execlp("./blockchild","blockchild",(char *)0);/*INSTEAD

EXEC LATER WITH THE CHILD PROGRAM*/

else if(pid<0)

return FALSE;

else{

sd=socket(PF_INET,SOCK_DGRAM,0);

bind(sd,(struct sockaddr *)&local_addr,sizeof(struct

sockaddr_in));

/*Wait for message queue q4 to be created*/

while( (clid=msgget(pid,0777) )==-1);

219
if( (msgsnd(clid,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),0)) ==-1)

return FALSE;

/*send message to child:first rbuf*/

return TRUE;

else

struct sockaddr_in *remote_addr=ALLOC_MEM(struct

sockaddr_in,1);

__uint16_t connect_resp_size=7;

__uint8_t *buf=(__uint8_t *)malloc(sizeof(__uint8_t));

remote_addr->sin_family=PF_INET;

remote_addr->sin_port=htons(rbuf->port);

remote_addr->sin_addr=rbuf->ipaddr;

memset(&(remote_addr->sin_zero),'\0',8);

buf[0]=0x53;

buf[1]=DTOH(connect_resp_size,1,2);

220
buf[2]=DTOH(connect_resp_size,2,2);

buf[3]=0x10;

buf[4]=0;

buf[5]=DTOH(MAX_PACKET_SIZE,1,2);

buf[6]=DTOH(MAX_PACKET_SIZE,2,2);

if(sendto(sd,(void *)buf,(int)connect_resp_size,0,

(struct sockaddr *)remote_addr,sizeof(struct

sockaddr_in))==-1)

free(remote_addr);

free(buf);

return FALSE;

free(remote_addr);

free(buf);

return TRUE;

221
int hand_connect_sock(__uint8_t *buf,int packsize,struct

sockaddr_in *remote_addr)

int q2id,i;

struct ap2ctrl *rbuf=(struct ap2ctrl

*)malloc(sizeof(struct ap2ctrl));

//printf("2. Port=%u ip addrr=%u\n",remote_addr-

>sin_port,remote_addr->sin_addr.s_addr);

rbuf->port=remote_addr->sin_port;

/*if(!inet_aton(remote_addr->sin_addr,&(rbuf->ipaddr)))

return FALSE;*/

rbuf->ipaddr.s_addr=remote_addr->sin_addr.s_addr;

//printf("3. Port=%u ip addrr=%u \n",rbuf->port,rbuf-

>ipaddr.s_addr);

rbuf->mtype=1;

rbuf->buffer[0]=CONNECT;

for(i=0;i<packsize;i++)

rbuf->buffer[i+2]=buf[i];

rbuf->length=packsize+2;

if( (q2id=msgget(APSRVQ2ID,0777))==-1){

222
perror("msgget:");

return FALSE;

if( (msgsnd(q2id,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),0)) ==-1){

perror("msgsnd:");

return FALSE;

return TRUE;

void gen_err_ap(__uint8_t err_code,struct ap2ctrl *rbuf)

struct ap2ctrl *sbuf;

int ob2ap;

sbuf=(struct ap2ctrl *)malloc(sizeof(struct

ap2ctrl));

sbuf->mtype=1;

sbuf->pid=0;

sbuf->buffer[0]=err_code;

223
sbuf->length=1;

sbuf->ipaddr.s_addr=INADDR_ANY;

if( (ob2ap=msgget(rbuf->pid,0777))==-1)

return;

msgsnd(ob2ap,sbuf,sizeof(struct ap2ctrl)-sizeof(long),0);

free(sbuf);

void gen_resp_sock(int err,struct sockaddr_in

*remote_addr)

__uint8_t *buf=(char *)malloc(7); /*THE SIZE SPEC HERE ie

7 seven has 2b made common #def val*/

buf[0]=err;

buf[1]=DTOH(7,1,2) ;

buf[2]=DTOH(7,2,2);

buf[3]=0x10;

224
buf[4]=0x00;

buf[5]=buf[6]=0;

sendto(sd,(void *)buf,7,0,(struct sockaddr

*)remote_addr,sizeof(struct sockaddr_in));

free(buf) ;

int snd2chld(struct ap2ctrl *rbuf)

int clid;

if( (clid=msgget(rbuf->pid,0777))==-1)

return FALSE;

if( (msgsnd(clid,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),0))==-1)

return FALSE;

return TRUE;

static void finish(int ab)

225
{

int srid;

srid=msgget(CTRLQ1ID,0777);

msgctl(srid,IPC_RMID,NULL);

while(close(sd));

exit(0);

int main(void)

int q1id,conn_reqtd=0;

struct sockaddr_in remote_addr;

struct msqid_ds info;

int ctrlid;

long type=0;

ssize_t num;

__uint8_t buf[MAX_PACKET_SIZE];

int packetsize,sock_length=sizeof(struct sockaddr_in);

226
struct ap2ctrl *rbuf=(struct

ap2ctrl*)malloc(sizeof(struct ap2ctrl));

init_q1(&q1id);

init_sock(&local_addr);

rbuf->mtype=1;

signal(SIGINT,finish);

signal(SIGSEGV,finish);

while(1){

if((ctrlid=msgget(CTRLQ1ID,0777)) == -1){

perror("msgget");

exit(-1);

msgctl(ctrlid,IPC_STAT,&info);

if(info.msg_qnum>=1){ /*CHECKING FOR NEW MESSAGES ON

Q1*/

if((ctrlid=msgget(CTRLQ1ID,0777)) == -1){

//printf("Unable to open msgq1");

perror("msgget");

exit(-1);

227
}

num=msgrcv(ctrlid,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),type,0);

switch(rbuf->buffer[0]){

case CONNECT :

if(!hand_con_req(rbuf))/*definite

fork in func */

gen_err_ap(INTERNAL_ERR,rbuf);/*err msg

to appln client*/

break;

case CONNECT_RESP :

if(conn_reqtd){

conn_reqtd--;

if(!hand_con_res(rbuf))

gen_err_ap(INTERNAL_ERR,rbuf);

else

gen_err_ap(ILLEGAL_RESP,rbuf);/*err msg to */

break;

default :

228
if(!snd2chld(rbuf))

gen_err_ap(CHILD_NOEXIST,rbuf);

break;

if((packetsize=recvfrom(sd,(void

*)buf,MAX_PACKET_SIZE,MSG_DONTWAIT,(struct sockaddr

*)&remote_addr,&sock_length))!=-1){

switch(buf[0]){

case CONNECT:

//printf("1. Port=%u ip addrr=

%u\n",remote_addr.sin_port,remote_addr.sin_addr.s_addr);

if(!hand_connect_sock(buf,packetsize,&remote_addr))

gen_resp_sock(SERV_UNAV,&remote_addr);

conn_reqtd++;

break;

default:

gen_resp_sock(BAD_REQ,&remote_addr);

229
}

clientController.c

#include "common.h"

#define CTRL_PORT 0

#define CTRLQ1ID 1235l

int sd;

struct sockaddr_in local_addr;

void init_q1(int *q1id)

if( (*q1id=msgget(CTRLQ1ID,IPC_CREAT|IPC_EXCL|0777))

== -1 )

//printf("First exit");

perror("msgget");

exit(-1);

230
}

else if(*q1id==0)

msgctl(*q1id,IPC_RMID,NULL);

if( (*q1id=msgget(CTRLQ1ID,IPC_CREAT|IPC_EXCL|

0777))==-1)

//printf("Second exit");

perror("msgget");

exit(-1);

return;

void init_sock(struct sockaddr_in *local_addr)

local_addr->sin_family=PF_INET;

231
local_addr->sin_port=htons(CTRL_PORT);

local_addr->sin_addr.s_addr=INADDR_ANY;

memset(&(local_addr->sin_zero),'\0',8);

if((sd=socket(PF_INET,SOCK_DGRAM,0))==-1)

perror("socket:");

exit(-1);

if(bind(sd,(struct sockaddr *)local_addr,sizeof(struct

sockaddr_in))==-1)

close(sd);

perror("bind");

exit(-1);

int hand_con_req(struct ap2ctrl *rbuf)

pid_t pid,temp_pid;

232
int clid;

//printf("\nIn here");

if((pid=fork())==0)

execlp("./blockchild","blockchild",(char *)0);

else if(pid<0)

return FALSE;

/*Wait for message queue q4 to be created*/

do{

while( (clid=msgget(pid,0777) )==-1 &&

(temp_pid=waitpid(pid,NULL,WNOHANG))==0);

}while(temp_pid==-1);

if(clid==-1)

return FALSE;

if( (msgsnd(clid,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),0)) ==-1)

return FALSE;

/*send message to child:first rbuf*/

return TRUE;

233
int hand_con_res(struct ap2ctrl *rbuf)

pid_t pid,temp_pid;

int clid;

if(rbuf->buffer[1]==SUCCESS)

close(sd);

if((pid=fork())==0)

execlp("./blockchild","blockchild",(char *)0);/*INSTEAD

EXEC LATER WITH THE CHILD PROGRAM*/

else if(pid<0)

return FALSE;

else{

sd=socket(PF_INET,SOCK_DGRAM,0);

bind(sd,(struct sockaddr *)&local_addr,sizeof(struct

sockaddr_in));

/*Wait for message queue q4 to be created*/

do{

234
while( (clid=msgget(pid,0777) )==-1 &&

(temp_pid=waitpid(pid,NULL,WNOHANG))==0);

}while(temp_pid==-1);

if(clid==-1)

return FALSE;

if( (msgsnd(clid,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),0)) ==-1)

return FALSE;

/*send message to child:first rbuf*/

return TRUE;

else

struct sockaddr_in *remote_addr=ALLOC_MEM(struct

sockaddr_in,1);

__uint16_t connect_resp_size=7;

__uint8_t *buf=(__uint8_t *)malloc(sizeof(__uint8_t));

remote_addr->sin_family=PF_INET;

remote_addr->sin_port=htons(rbuf->port);

remote_addr->sin_addr=rbuf->ipaddr;

235
memset(&(remote_addr->sin_zero),'\0',8);

buf[0]=0x53;

buf[1]=DTOH(connect_resp_size,1,2);

buf[2]=DTOH(connect_resp_size,2,2);

buf[3]=0x10;

buf[4]=0;

buf[5]=DTOH(MAX_PACKET_SIZE,1,2);

buf[6]=DTOH(MAX_PACKET_SIZE,2,2);

if(sendto(sd,(void *)buf,(int)connect_resp_size,0,

(struct sockaddr *)remote_addr,sizeof(struct

sockaddr_in))==-1)

free(remote_addr);

free(buf);

return FALSE;

free(remote_addr);

free(buf);

return TRUE;

236
}

int hand_connect_sock(__uint8_t *buf,int packsize,struct

sockaddr_in *remote_addr)

int q2id,i;

struct ap2ctrl *rbuf=(struct ap2ctrl

*)malloc(sizeof(struct ap2ctrl));

//printf("2. Port=%u ip addrr=%u\n",remote_addr-

>sin_port,remote_addr->sin_addr.s_addr);

rbuf->port=remote_addr->sin_port;

/*if(!inet_aton(remote_addr->sin_addr,&(rbuf->ipaddr)))

return FALSE;*/

rbuf->ipaddr.s_addr=remote_addr->sin_addr.s_addr;

//printf("3. Port=%u ip addrr=%u \n",rbuf->port,rbuf-

>ipaddr.s_addr);

rbuf->mtype=1;

rbuf->buffer[0]=CONNECT;

for(i=0;i<packsize;i++)

rbuf->buffer[i+2]=buf[i];

rbuf->length=packsize+2;

237
if( (q2id=msgget(APSRVQ2ID,0777))==-1){

perror("msgget:");

return FALSE;

if( (msgsnd(q2id,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),0)) ==-1){

perror("msgsnd:");

return FALSE;

return TRUE;

void gen_err_ap(__uint8_t err_code,struct ap2ctrl *rbuf)

struct ap2ctrl *sbuf;

int ob2ap;

sbuf=(struct ap2ctrl *)malloc(sizeof(struct

ap2ctrl));

sbuf->mtype=1;

sbuf->pid=0;

sbuf->buffer[0]=err_code;

238
sbuf->length=1;

sbuf->ipaddr.s_addr=INADDR_ANY;

if( (ob2ap=msgget(rbuf->pid,0777))==-1)

return;

msgsnd(ob2ap,sbuf,sizeof(struct ap2ctrl)-sizeof(long),0);

free(sbuf);

void gen_resp_sock(int err,struct sockaddr_in

*remote_addr)

__uint8_t *buf=(char *)malloc(7); /*THE SIZE SPEC HERE ie

7 seven has 2b made common #def val*/

buf[0]=err;

buf[1]=DTOH(7,1,2) ;

buf[2]=DTOH(7,2,2);

buf[3]=0x10;

buf[4]=0x00;

239
buf[5]=buf[6]=0;

sendto(sd,(void *)buf,7,0,(struct sockaddr

*)remote_addr,sizeof(struct sockaddr_in));

free(buf) ;

int snd2chld(struct ap2ctrl *rbuf)

int clid;

if( (clid=msgget(rbuf->pid,0777))==-1)

return FALSE;

if( (msgsnd(clid,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),0))==-1)

return FALSE;

return TRUE;

static void finish(int ab)

int srid;

srid=msgget(CTRLQ1ID,0777);

240
msgctl(srid,IPC_RMID,NULL);

while(close(sd));

exit(0);

int main(void)

int q1id,conn_reqtd=0;

struct sockaddr_in remote_addr;

struct msqid_ds info;

int ctrlid;

long type=0;

ssize_t num;

__uint8_t buf[MAX_PACKET_SIZE];

int packetsize,sock_length=sizeof(struct sockaddr_in);

struct ap2ctrl *rbuf=(struct

ap2ctrl*)malloc(sizeof(struct ap2ctrl));

init_q1(&q1id);

init_sock(&local_addr);

rbuf->mtype=1;

241
signal(SIGINT,finish);

signal(SIGSEGV,finish);

while(1){

if((ctrlid=msgget(CTRLQ1ID,0777)) == -1){

perror("msgget");

exit(-1);

msgctl(ctrlid,IPC_STAT,&info);

if(info.msg_qnum>=1){ /*CHECKING FOR NEW MESSAGES ON

Q1*/

if((ctrlid=msgget(CTRLQ1ID,0777)) == -1){

//printf("Unable to open msgq1");

perror("msgget");

exit(-1);

num=msgrcv(ctrlid,rbuf,sizeof(struct ap2ctrl)-

sizeof(long),type,0); switch(rbuf->buffer[0]){

case CONNECT :

if(!hand_con_req(rbuf))/*definite

fork in func */

242
gen_err_ap(INTERNAL_ERR,rbuf);/*err msg

to appln client*/

break;

case CONNECT_RESP :

if(conn_reqtd){

conn_reqtd--;

if(!hand_con_res(rbuf))

gen_err_ap(INTERNAL_ERR,rbuf);

else

gen_err_ap(ILLEGAL_RESP,rbuf);/*err msg to */

break;

default :

if(!snd2chld(rbuf))

gen_err_ap(CHILD_NOEXIST,rbuf);

break;

} /*end of switch1*/

243
if((packetsize=recvfrom(sd,(void

*)buf,MAX_PACKET_SIZE,MSG_DONTWAIT,(struct sockaddr

*)&remote_addr,&sock_length))!=-1){

switch(buf[0]){

case CONNECT:

//printf("1. Port=%u ip addrr=

%u\n",remote_addr.sin_port,remote_addr.sin_addr.s_addr);

if(!hand_connect_sock(buf,packetsize,&remote_addr))

gen_resp_sock(SERV_UNAV,&remote_addr);

conn_reqtd++;

break;

default:

gen_resp_sock(BAD_REQ,&remote_addr);

244
CODE EFFICIENCY

As we know the code efficiency is the degree to which the code or software

makes optimal use of system resources as indicated by the following subattributes:

time behavior, resource behavior.

This coding is efficiently working as when it runs it makes optimal use of its

system resources.

245
OPTIMISATION OF CODE

246
VALIDATION CHECKS

In the coding of this project validation checks are implemented. This

validation put in practise to check whether the packet size which server

is transmitting is valid or not. Whatever is the fixed size of packet to

tranmit should be followed so that the same validation can be perform on

the receiving end. Following code is checking validity of packet size to

ensure that whether the packet size is right.

if(snd_buf) free(snd_buf);assure

snd_buf=NULL;

recv_buf=ALLOC_MEM(__uint8_t,max_packet_size);

while((packetsize=recvfrom(sdnew,(void

*)recv_buf,max_packet_size,0,(struct sockaddr

*)remote_addr,&sock_length))==-1);

We can perform different set of activities that ensure that the software or the

project has been built is traceable to requirements.

247
IMPLEMENTATION AND MAINTANANCE

Implementation:

The OBEX layer will be coded in C language. The operating system used for

developing will be Linux. The working of OBEX layer will be demonstrated using

connected systems, in the absence of wireless device running BLUETOOTH stack.

The system calls used are listed below:

1. int socket (int family, int type, int protocol);

This system call creates a socket. The family is AF_INET (Internet protocols),

the socket type is SOCK_DGRAM (stream socket) which implies that the protocol

used is UDP.

2. int bind (int sockfd, struct sockaddr *myaddr, int addrlen);

This system call binds the socket to a port.The first argument specifies the file

descriptor of the socket ,the second argument is a pointer to a protocol-specific

address and the third argument is the size of this address structure.

248
3. int sendto(int sockfd, const void *msg, int len, unsigned int flags,const struct

sockaddr *to, int tolen);

This call is basically the same as the call to send() with the addition of two other

pieces of information. to is a pointer to a struct sockaddr (which you'll probably

have as a struct sockaddr_in and cast it at the last minute) which contains the

destination IP address and port. tolen can simply be set to sizeof(struct sockaddr).

4. int recvfrom(int sockfd, void *buf, int len, unsigned int flags, struct

sockaddr *from, int *fromlen);

This is just like recv() with the addition of a couple fields. from is a pointer to a

local struct sockaddr that will be filled with the IP address and port of the

originating machine. fromlen is a pointer to a local int that should be initialized to

sizeof(struct sockaddr). When the function returns, fromlen will contain the length

of the address actually stored in from. recvfrom() returns the number of bytes

received, or -1 on error (with errno set accordingly.)

5. int close(int fd);

The normal unix close system call is used to close the socket.

249
6. int execlp(const char *filename, char *const arg0,…);

When a process calls the execlp function, that process is completely replaced by the

new program, and the new program starts executing at its main function.

7 . int msgget(key_t key,int msgflag) ;

This function returns the message queue identifier associated with the value of the

argument key.

8. int msgctl(key_t key,int cmd,struct msqid_ds *buf);

This function is used to perform the control operation as specified by the argument

cmd on the queue identified by key.

9. int msgsnd(int msqid,struct msgbuf * buf,size_t msgsz,int msgflag);

This function is used to enqueue the message contained in the argument buf to the

queue identified by the argument msqid .

250
10. ssize_t msgrcv(int msqid,struct msgbuf * buf,size_t msgsz,long mtype,int

msgflag);

This function is used to read a message from the message queue specified by msqid

into the msgbuf pointed to by buf removing from the queue the read message on

success.

Modules and Thier Description

The modules involved in the implementations of the projects:-

1. Controller Module.

2. Child Module.

3. Application Server Module.

4. Application Client Module.

The Controller Module: -

This module is executed on both the server and the client as background process. It

alternatively listens for messages on the queue and data packets on port #650.

The module functionally is as follows:

251
1. Socket Functionality:

 A socket is created to connect to another machines using UDP. This

socket is then bound to a port to accept connections on Port # 650.

 Recvfrom system call is executed, hence the controller waits for

requests for connection. If there are more than one simultaneous

requests, the request are put into a queue leading to the Application

Server.

 The response from the Application Server is checked and the child

module is exceed one by one the for each of the clients. The

connection is spawned onto another socket and any further

communication takes place through this socket between the client and

the corresponding child.

 Communication between the client and child is carried on successfully

without being distributed or distributing other connections.

 The controller continues to listen for new requests.

2. Message Queue Functionality:

 Create a queue to listen to requests from the application layer.

 Listen for new messages on the queue.

 Determine the type of message.

252
 If it is a connection request, then exec a child(client side child ) and

allow the child to take care of the connect request.

 If it is a successful connect response, the exec a child (server side child

) and allow this to communicate with the peer child on the client side.

 For all other requests, forward the message received to the respective

child.

The child Module:

The child listens for messages on the its queue ( in the case of client side

child ) and data packets via sockets ( it the case of server side child ).

On determining the type of message received via the message queue , the child

module constructs the corresponding data packet ,sends the data packet across to

the peer child via the socket and waits for the response on the socket.

On determining the type of data packet received via the socket, the child module

forwards the data via the message queue to the application layer and waits for the

response via the message queue.

253
The Application Server Module:

This module listens for requests on its message queue. Upon receiving a valid

request, it generates the response code and forwards the message containing the

response code to the controller queue. Along with the response code, the message

forwarded also consists of the pid of the process that sent the request originally and

data requested if any).

The Client Module:

This module provides the GUI for activities such as updating the Vcard information

repository, initiating a connect request for establishing a session.

254
SOFTWARE TESTING METHODS

The software was tested on a machine running Red Hat LINUX 7.1 operating

system.

Initially the software was tested successfully on a loop-back system and

successfully tested with full functionality.

This software was then implemented on a Ethernet local area network. The client

logged into the server and established a session successfully. All the requests issued

by the client were executed successfully . Multiple clients were created who also

logged into the server successfully with full functionality.

The response time for the connection to be established and response for the

requests issued was found to be satisfactory .

There are many ways to conduct software testing, but the most common methods

rely on the following steps.

Test Case Design

Test cases should be designed in such a way as to uncover quickly and easily as

many errors as possible. They should "exercise" the program by using and

producing inputs and outputs that are both correct and incorrect.

255
Variables should be tested using all possible values (for small ranges) or typical

and out-of-bound values (for larger ranges). They should also be tested using valid

and invalid types and conditions. Arithmetical and logical comparisons should be

examined as well, again using both correct and incorrect parameters.

The objective is to test all modules and then the whole system as completely as

possible using a reasonably wide range of conditions.

White-Box Testing

White box method relies on intimate knowledge of the code and a procedural

design to derive the test cases. It is most widely utilized in unit testing to determine

all possible paths within a module, to execute all loops and to test all logical

expressions.

Using white-box testing, the software engineer can (1) guarantee that all

independent paths within a module have been exercised at least once; (2) examine

all logical decisions on their true and false sides; (3) execute all loops and test their

operation at their limits; and (4) exercise internal data structures to assure their

validity.

This form of testing concentrates on the procedural detail. However, there is no

automated tool or testing system for this testing method. Therefore even for

256
relatively small systems, exhaustive white-box testing is impossible because of all

the possible path permutations.

Basis Path Testing

Basis path testing is a white-box technique. It allows the design and definition of a

basis set of execution paths. The test cases created from the basis set allow the

program to be executed in such a way as to examine each possible path through the

program by executing each statement at least once.

Control Structure Testing

Because basis path testing alone is insufficient, other techniques should be utilized.

Condition testing can be utilized to design test cases which examine the logical

conditions in a program. It focuses on all conditions in the program and includes

testing of both relational expressions and arithmetic expressions.

This can be accomplished using branch testing and/or domain testing methods.

Branch testing executes both true and false branches of a condition. Domain testing

utilizes values on the left-hand side of the relation by making them greater than,

equal to and less then the right-hand side value. This method test both values and

the relation operators in the expression.

257
Data flow testing method is effective for error protection because it is based on the

relationship between statements in the program according to the definition and uses

of variables.

Loop testing method concentrates on validity of the loop structures.

Black-box Testing

Black box on the other hand focuses on the overall functionality of the software.

That is why it is the chosen method for designing test cases used in functional

testing. This method allows the functional testing to uncover faults like incorrect or

missing functions, errors in any of the interfaces, errors in data structures or

databases and errors related to performance and program initialization or

termination.

To perform successful black-box test, the relationships between the many different

modules in the system model need to be understood. Next, all necessary ways of

testing all object relationships need to be defined. For this, a graph representing all

the objects can be constructed. Each object is represented by a node and then links

between the nodes show the direct node-to-node relationship. An arrow on the link

shows the direction of the relationship. Each node and link is the further described

258
by node weight or link weight respectively. This method is called graph-based

testing.

Equivalence partitioning on the other hand divides input conditions into

equivalence classes such as Boolean, value, range or set of values. These classes

represent a set of valid or invalid states for input conditions.

Boundary values analysis (BVA), as the term suggests, concentrates on designing

test cases that examine the upper and lower limits of the equivalence class. These

test cases are not based solely on input conditions as in equivalence partitioning

above but on output conditions as well.

Condition (back-to-back) testing involves development of identical but independent

versions of a "critical" program/system. Both versions are then run and tested in

parallel to see if the produced outputs are identical.

SOFTWARE TESTING STRATEGIES

In order to conduct a proper and thorough set of tests, the types of testing

mentioned below should be performed in the order in which they are described.

However, some system or hardware can happen concurrently with software testing.

259
Unit Testing

Unit testing procedure utilizes the white-box method and concentrates on testing

individual programming units. These units are sometimes referred to as modules or

atomic modules and they represent the smallest programming entity.

Unit testing is essentially a set of path test performed to examine the many different

paths through the modules. These types of tests are conducted to prove that all

paths in the program are solid and without errors and will not cause abnormal

termination of the program or other undesirable results.

Integration Testing

Integration testing focuses on testing multiple modules working together. Two

basic types of integration are usually used: top-down or bottom up.

Top down, as the term suggests, starts at the top of the program hierarchy and

travels down its branches. This can be done in either depth-first (shortest path down

to the deepest level) or breadth-first (across the hierarchy, before proceeding to the

next level). The main advantage of this type of integration is that the basic skeleton

of the program/system can be seen and tested early. The main disadvantage is the

use of program stubs until the actual modules are written. This basically limits the

260
up-flow of information and therefore does not provide for a good test of the top

level modules.

Bottom-up type of integration has the lowest level modules built and tested first on

individual bases and in clusters using test drivers. This insures each module is fully

tested before its utilized by its calling module. This method has a great advantage

in uncovering errors in critical modules early. Main disadvantage is the fact that

most or many modules must be build before a working program can be presented.

Integration testing procedure can be performed in three ways: Top-down, Bottom-

up, or using an approach called "Big-Bang" (Humphrey, 1989).

Top-Down Strategy

Top down integration is basically an approach where modules are developed and

tested starting at the top level of the programming hierarchy and continuing with

the lower levels.

It is an incremental approach because we proceed one level at a time. It can be done

in either "depth" or "breadth" manner.

261
• Depth means we proceed from the top level all the way down to the lowest

level.

• Breadth, on the other hand, means that we start at the top of the hierarchy and

then go to the next level. We develop and test all modules at this level before

continuing with another level.

Either way, this testing procedure allows us to establish a complete skeleton of the

system or product.

The benefits of Top-down integration are that, having the skeleton, we can test

major functions early in the development process.

At the same time we can also test any interfaces that we have and thus discover any

errors in that area very early on.

But the major benefit of this procedure is that we have a partially working model to

demonstrate to the clients and the top management. This of course builds

everybody’s confidence not only in the development team but also in the model

itself. We have something that proves our design was correct and we took the

correct approach to implement it.

However, there are some drawbacks to this procedure as well:

262
Using stubs does not permit all the necessary upward data flow. There is simply not

enough data in the stubs to feed back to the calling module.

As a result, the top level modules can not be really tested properly and every time

the stubs are replaced with the actual modules, the calling modules should be re-

tested for integrity again.

Bottom-Up Strategy

Bottom-up approach, as the name suggests, is the opposite of the Top-down

method.

This process starts with building and testing the low level modules first, working its

way up the hierarchy.

Because the modules at the low levels are very specific, we may need to combine

several of them into what is sometimes called a cluster or build in order to test them

properly.

Then to test these builds, a test driver has to be written and put in place.

The advantage of Bottom-up integration is that there is no need for program stubs

as we start developing and testing with the actual modules.

263
Starting at the bottom of the hierarchy also means that the critical modules are

usually build first and therefore any errors in these modules are discovered early in

the process.

As with Top-down integration, there are some drawbacks to this procedure.

In order to test the modules we have to build the test drivers which are more

complex than stubs. And in addition to that they themselves have to be tested. So

more effort is required.

A major disadvantage to Bottom-up integration is that no working model can be

presented or tested until many modules have been built (Humphrey, 1989).

This also means that any errors in any of the interfaces are discovered very late in

the process.

Function Testing

Function testing is a testing process that is black-box in nature. It is aimed at

examining the overall functionality of the product. It usually includes testing of all

the interfaces and should therefore involve the clients in the process.

264
Because every aspect of the software system is being tested, the specifications for

this test should be very detailed describing who, where, when and how will conduct

the tests and what exactly will be tested.

The portion of the testing that will involve the clients is usually conducted as an

alpha test where the developers closely monitor how the clients use the system.

They take notes on what needs to be improved.

System Testing

Final stage of the testing process should be System Testing. This type of test

involves examination of the whole computer system. All the software components,

all the hardware components and any interfaces.

The whole computer based system is checked not only for validity but also for met

objectives.

It should include recovery testing, security testing, stress testing and performance

testing.

Recovery testing uses test cases designed to examine how easily and completely the

system can recover from a disaster (power shut down, blown circuit, disk crash,

interface failure, insufficient memory, etc.). It is desirable to have a system capable

of recovering quickly and with minimal human intervention. It should also have a

265
log of activities happening before the crash (these should be part of daily

operations) and a log of messages during the failure (if possible) and upon re-start.

Security testing involves testing the system in order to make sure that unauthorized

personnel or other systems cannot gain access to the system and information or

resources within it. Programs that check for access to the system via passwords are

tested along with any organizational security procedures established.

Stress testing encompasses creating unusual loads on the system in attempts to

brake it. System is monitored for performance loss and susceptibility to crashing

during the load times. If it does crash as a result of high load, it provides for just

one more recovery test.

Performance testing involves monitoring and recording the performance levels

during regular and low and high stress loads. It tests the amount of resource usage

under the just described conditions and serves as basis for making a forecast of

additional resources needed (if any) in the future. It is important to note that

performance objectives should have been developed during the planning stage and

performance testing is to assure that these objectives are being met. However, these

tests may be run in initial stages of production to compare the actual usage to the

forecasted figures.

266
SYSTEM SECURITY MESURES

267
COST ESTIMATION OF THE PROJECT

268
FUTURE SCOPE AND FURTHER ENHANCEMENT OF
THE PROJECT

269
BIBLIOGRAPHY

The books referred to during the course of the project :

• UNIX NETWORK PROGRAMMING .

Author : W. RICHARD STEVENS

• Advanced Programming in the UNIX Environment .

Author : W. RICHARD STEVENS

• Beej’s Guide to Network Programming .

• BLUETOOTH Specifications - Core, Profiles provided by BLUETOOTH SIG

• IrDA Specifications for The OBEX layer - provided by IrDA

270
GLOSSARY

ADSL

Abbr. Asymmetric Digital Subscriber Line. A Digital Subscriber Line System

(DSL) to carry outbroadband data connections via the conventional copper cable

connection network. ADSL systems are manufactured without exception for

bidirectional transmissions with both flow directions (downstream and upstream).

Unlike the SDSL systems (Symmetric DSL) the flow directions of the ADSL do

not have the same band breadth. The downstream channel in thedirection of the

subscriber (participant) comes as a broad band (e.g., 6 Mbits/s), whereas the

upstream channel in the opposite direction (back channel) comes as a relatively

narrow band (e.g., 16 kbits/s) and is primarily meant to transmit control messages.

This is why the concept ofasymmetry is used. In this manner, ADSL can be used

for the transport of multimedial data in the connection area of the telephone

network/ISDN. Connection of the terminal devices (television set, control devices,

etc) is provided via a special decoder device, the Set Top Box.

271
API

Abbr. Application Program Interface. Interface for application programs for access

to already defined routines such as standardised communication services.

AT Modem Commands

Abbr. Attention. A control sign with the North American Hayes Standard for

modem communication, which is found at the beginning of nearly all commands

(Hayes command set).

For this reason the standard is also often called ’AT Standard’. The globally

introduced industry standard has in the meantime become the object of an ITU

recommendation under the designation ITU-T V.25ter.

CF Card

With this card all handheld and pocket PCs with Compact Flash Slot can be

extended by the Bluetooth TM function – and can communicate and cooperate with

other Bluetooth TM components such as printers or mobile phones.

272
DECT

Abbr. Digital Enhanced Cordless Telecommunication, formerly: Digital European

Cordless Telecommunication. Digital ETSI standard for cordless phones, wireless

TK installations and wireless LANs. DECT features: first-class speech quality,

highly bugproof, identification of

subscribers, no unauthorised usage, dynamic channel selection, handling channel

balance disturbances, possibility of setting up cellular networks, very high contact

density, interruption-free switching between channels (Seamless Handover), rapid

connection established within 50 ms, data transmission, flexible data rate

allocation, interworking with the public telephone

DTMF

Multiple frequency tone transmission. The transmission of multiple frequency

tones (DTMF) on an existing connection allows for the control of various

counterparts. The most frequent applications are the input of passwords to call up

answerphones/mailboxes as well as the so-called Call-Back and Call-Through

processes for the usage of different telephone providers. But even for frequent

dialling of menu-controlled

273
telephone installations or the phoning of services with selection options, it can be

very helpful to store the required DTMF sequence together with the call number.

Electro smog (EMV)

Abbr. Electromagnetic compatibility. Unspecific description of the influences of

electric and magnetic fields (radiation) upon technical systems and nature,

including living things; at the same time measure ment for the acceptance of

electromagnetic radiation in/within electrical and electronic devices, systems and

installations.

GPS

Abbr. Global Positioning System. Also used under the name of NAVSTAR-GPS

global satellite system (NAVSTAR, „Navigation Star“) within the area of

responsibility of the US Ministry of Defence (Department of Defense, DoD) for

high-precision localisation, navigation and time allocation. Usage of this system by

civilians, including non-authorised users is guaranteed by consent of the DoD

within the frame of the Standard Positioning Service (SPS). GPS works with 24

orbiting satellites (NAVSTAR satellites) - 21 operational and three spare satellites

– on 6 orbits with a path height of ca 20,180 km. The NAVSTAR satellites emit

radio signals on the frequency 1.57542 GHz, that contain time information (world

274
time with a precision of 2 x 10-13 seconds) and path information through which the

corresponding signal times can be ascertained very precisely. In case the GPS

receiver receives simultaneously the radio signals from min. three GPS satellites,

the receiver will be able to determine exactly on the basis of the running times of

the individual signals the coordinates of his position to 10 m up to 100 m.

GSM

Abbr. Global System for Mobile Communications. Initially a European mobile

radio concept, based on the GSM Standard, when the CEPT workgroup „Groupe

Special Mobile“ (GSM) took up its development in 1982, the work of whom being

continued since 1989 by ETSI (European

Telecommunications Standards Institute). Nowadays the digital Standard GSM

embodies the internationally most successful cellular mobile radio concept. More

than 110 countries with over 200 network providers have opted for GSM. Globally

there are by now 120 millions of subscribers using GSM, and first forecasts for the

year 2000 predict ca 250 million GSM subscribers. The biggest GSM market

worldwide is China.

275
IEEE 802

Standard (series) of the IEEE workgroup 802 with specifications (techniques for

linking up to the cable network, access procedures, security protocols etc) for

LANs and comparable long distance networks.

IP

Abbr. Internet Protocol. An important internet protocol (RFC 791) from the TCP/IP

protocol family of the internet layer (layer 3 of the OSI reference model,

accordingly) with functions for connecting path and flow control. The

connectionless (Connectionless Mode) and unsecured

protocol allows for a network-crossing package-orientated data exchange between

terminal systems addressed via 32-Bit-IP addresses. Each package – so-called IP

datagramme – is provided with a sending and a receiving address with the aid of

which the datagrammes can

reach their target station from router to router, independently of their previous path.

The IP carries out a best-effort delivery service: the network tries by all means to

deliver the datagrammes, but without guaranteeing that they will be delivered or

that they are correct. The

276
future will also see Integrated Services (IS, RFC 1633) which are to carry out

guaranteed services such as band breadth guarantees. An IP network is the sum of

all addresses with an equal network share. This is written as 128.29.0.0 or 128.29

(host-bits set to 0). In the broadcast address of a network all host-bits are set to 1,

e.g., 128.29.255.255. A disadvantage of the class division is the inefficient usage of

the address store.

IrDA

Abbr. Infrared Data Association. Association dealing with specifications of infrared

data transmission.

ISDN

Abbr. Integrated Services Digital Network. Communication concept on the basis of

path provided 64-kbits/s connections (N-ISDN - Narrowband ISDN) for public

mass communications and local appliations that are to replace gradually the

existing analogue telephone networks. The trend for higher band breadths is

expressed by present efforts for a broadband ISDN (B-ISDN –Broadband

Integrated Services Digital Network). In Germany the national ISDN is part of the

official telephone network of Deutsche Telekom. The designation of ISDN is

277
limited here to the connection area (ISDN connections) and the services available

(ISDN services or service features).

278

You might also like