Trong mỗi agent có một số thành phần lập trình cơ bản dùng để định nghĩa một số quy tắc ứng xử của agent khi tham gia vào OAA, những thông tin cần thiết được cung cấp từ thư viện agent sẽ giúp cho agent thực hiện các hành động khác nhau.
• Declarations of solvables. Mỗi agent cung cấp khả, gửi tới facilitator một danh sách các dịch vụ mà agent đó cung cấp. Facilitator sử dụng thông tin này để đáp ứng lại các yêu cầu cung cấp dịch vụ. Các agent đăng kí dịch vụ mình cung cấp bằng cách truyền tham số vào oaa_Register. Sau khi đăng kí, agent có thể thay đổi khai báo bằng cách sử dụng oaa_Declare, oaa_Undeclare, và oaa_Redeclare.
• Request handlers. Với mỗi khả năng giải quyết của theo kiểu gọi hàm, agent phải cung cấp một thủ tục callback hoặc định nghĩa một sự kiện callback app_do mặc định.
• oaa_SetTimeout(TimeoutDelay). Với việc gọi thủ tục thư viện này, agent có thể đưa ra thời gian timeout khi chờ đợi sự kiện quay vòng.
• app_idle callback. Cho phép một agent định nghĩa ra một thủ tục để agent khác gọi khi không có sự kiện này trong hàng đợi và xảy ra timeout. Nếu muốn viết một thủ tụcnhư thế, ta phải điền thêm thông tin vào libarary bằng cách gọi oaa_RegisterCallback oaa_RegisterCallback(app_idle, ProcedureName)
23 trang |
Chia sẻ: oanh_nt | Lượt xem: 1362 | Lượt tải: 0
Bạn đang xem trước 20 trang tài liệu Chuyên đề Bài tập lớn công nghệ agent, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
BÀI TẬP LỚN MÔN HỌC
CHUYÊN ĐỀ CÔNG NGHỆ AGENT
OAA - Open Agent Architect
Kiến trúc OAA
1. Tổng quan
OAA là một multi-agent framework tập trung vào việc hộ trợ việc tương tác mềm dẻo trong cộng đồng động, đa dạng các agent phần mềm.
Ý tưởng chủ yếu của OAA là delegation: thay cho việc mỗi agent phải mã hoá cứng các hành vi của nó, lý giải nó sẽ tương tác với agent nào và như thế nào, agent trong OAA biểu diễn sự tương tác dưới dạng những điều nó cần cho một agent đặc biệt khác (facilitator agent). Agent này sẽ phối hợp sự hoạt động của cộng đồng agent để hoàn thành công việc, cung cấp các dịch vụ như xử lý song song failure handling và phát hiện xung đột và các client agent không phải quan tâm tới các vần đề đó nữa.
2. Mục đích của việc thiết kế mô hình OAA
Ngày nay, kỹ thuật lập trình dựa trên agent (agent-based programming) đã được nhắc đến nhiều trong các thuật ngữ kĩ thuật. Trong môi trường OAA, các agent hoạt động một cách độc lập và phối hợp với nhau trong một hệ thống mạng phân tán bởi vì chúng được lập trình trên các ngôn ngữ bậc cao, do đó chúng có khả năng hoạt động và tính toán một cách độc lập.
Mục tiêu và các khái niệm về OAA đã được nói đến một cách chi tiết, nên dưới đây, ta sẽ chỉ đề cập một cách ngắn gọn về các khái niệm này:
2.1. Khả năng phối hợp cùng hoạt động
OAA tập trung vào ý tưởng rằng một cộng đồng agent cùng tham gia vào giải quyết một công việc chung. Mặc dù có thể thiết kế chỉ một agent để giải quyết tất cả mọi công việc nhưng sẽ chuyên nghiệp hơn nếu như ta thiết kế những agent “chuyên gia” (expert agent) và mỗi agent đảm nhận một công việc khác nhau. Trong môi trường OAA, phần lớn các yêu cầu của user đều được giải quyết với nhiều agent. Do đó, việc phối hợp hoạt động giữa các agent phải thật tốt, để đảm bảo không có agent nào phải hoạt động quá tải.
2.2. Sự hoạt động phân tán
Cộng đồng các agent rất đa dạng, cho phép các agent có thể chạy trên mọi môi trường khác nhau, được viết bởi các ngôn ngữ khác nhau. Môi trường OAA sẽ cung cấp một số quy tắc chuẩn để agent có thể hoạt động và liên kết được với nhau. Sự hoạt động phân tán mở khả ra khả năng tính toán song song khi nhiều agent cùng thực thi các phần khác nhau của một công việc nào đó.
2.3. Sự thích nghi
Khi có các thành viên mới tham gia vào cộng đồng agent, thì hoạt động tương tác giữa các agent nhìn chung có sự thay đổi. Nếu một agent nào đó tham gia vào hoạt động cộng tác, thì sự tương tác giữa các agent phải đủ linh hoạt, mềm dẻo để cho phép agent mới này tham gia hoạt động. Kiến trúc “plug & play” cho phép xây dựng một hệ thống với các agent đã tồn tại từ trước và có thể dễ dàng phát triển các tính năng mới cho các agent cũ hoặc xây dựng các agent mới.
2.4. Truyền thông giữa các agent
Bởi vì con người luôn muốn tham gia vào hệ thống một cách linh hoạt nên cần phải có một ngôn ngữ đủ mạnh, đủ linh hoạt để có thể diễn tả được ngôn ngữ tự nhiên. Nếu ngôn ngữ ICL (Interagent Communication Language) có thể diễn đạt được một cách đầy đủ ngôn ngữ tự nhiên thì ta hoàn toàn có thể xây dựng được các câu lệnh, các thủ tục và tương tác.
2.5. Hoạt động và tái hoạt động tính toán
Agent không chỉ là những nguồn dữ liệu thụ động thực hiện các hành động và trả lời thông tin theo yêu cầu. Các agent có thể giám sát hoạt động của môi trường xung quanh nó và quyết định khi nào thực hiện hành động, thực hiện hành động nào, cảnh báo cho người dùng về các tình huống thích hợp. Hơn thế nữa, các agent có thể theo dõi sự tương tác giữa các agent khác và đưa ra giải pháp để hệ thống hoạt động tốt hơn.
2.6. Client Agents
Mỗi agent trong OAA hoặc là facilitator agent hoặc là client agent. Client Agent được gọi là Client vì xét trên một khía cạnh nào đó nó là client của một facilitator nào đó, các facilitator này cung cấp sự đối thoại và các dịch vụ cần thiết cho các client. Khi cần, một client agent thực hiện kết nối tới facilitator – parent facilitator. Với kết nối này, agent khai báo cho parent agent của nó biết các dịch vụ mà nó có thể cung cấp. Khi một dịch vụ của agent được yêu cầu, facilitator gửi yêu cầu tới agent đó (sử dụng ICL). Agent phân tích yêu cầu, thực hiện nếu có thể và trả kết quả, báo cáo ... về cho facilitator. Trong quá trình yêu cầu, agent có thể sử dụng một số chức năng được OAA cung cấp.
2.7. Facilitator Agents
Facilitator là một server agent chuyên dụng, chịu trách nhiệm liên kết hoạt động, đối thoại giữa các agent đồng thời giải quyết các vấn đề vướng mắc nảy sinh. Trong nhiều hệ thống, facilitator được dùng để cung cấp các dữ liệu toàn cục cho các client agents, nó cho phép các agent client có thể chấp nhận tương tác qua cơ chế blackboard.
Facilitator còn duy trì mối quan hệ giữa các agent, thông báo khả năng của các agent trong hệ thống, sử dụng các thông tin này để trợ giúp cho quá trình yêu cầu và cung cấp các dịch vụ trong hệ thống.
Chức năng trung tâm của facilitator là khả năng delegation một cách trong suốt. Có nghĩa là một agent yêu cầu có thể tạo ra các yêu cầu, facilitator có thể hiệu chỉnh yêu cầu mà không cần agent yêu cầu phải biết bất kì thông tin gì về tính đồng nhất hay vị trí chính xác của agent cung cấp. Delegation một cách trong suốt hoàn toàn có thể thực hiện được vì khả năng của các agent cũng chính là những dịch vụ mà nó cung cấp chứ không phải là việc tích hợp khả năng đó vào thư viện chung.
2.8. Truyền thông giữa các agent
Ngôn ngữa ICL (Interagent Communication Language) của OAA chính là ngôn ngữ giao tiếp và truyền thông giữa các agents mà không cần biết các agent đó đang chạy trên máy nào, được viết trên ngôn ngữ nào. ICL được thiết kế trên nền mở rộng của ngôn ngữ Prolog, kế thừa những ưu điểm, sự hợp lí và thống nhất của Prolog.
Trong ICL có một số từ khoá, một số thành phần đặc biệt sử dụng câu lệnh ICL, bao gồm khả năng khai báo biến, sự kiện, yêu cầu dịch vụ, đáp ứng yêu cầu, chia sẻ các thành phần dữ liệu.
2.9. Sự quản lí quyền thực thi
Hiện nay, do sự khác nhau về cơ chế của các ngôn ngữ, của các platform nên việc cài đặt, thực thi hoạt động bằng agent là rất thích hợp. Điều này sẽ giải quyết được rất nhiều rắc rối gặp phải khi khởi động một hệ thống và duy trì cho hệ thống hoạt động thông suốt. Hệ thống OAA có một trình quản lý việc thực hiện của các agent (Execution Manager) để quản lí các hoạt động thực thi gọi là Start-It.
Khi một tập các agent được liên kết hoạt động để cùng thực hiện một số nhiệm vụ nào đó, Start-It cung cấp khả năng cài đặt mỗi agent trên một platform thích hợp với agent đó. Theo các giao thức hoạt động của platform này, chỉ cần agent có yêu cầu kết nối tới facilitator thì chắc chắn agent đó sẽ hoạt động được. Một chức năng quan trọng khác của Start-It là giám sát trạng thái của mỗi agent xem chúng hoạt động có chính xác không? Nếu Start-It phát hiện thấy một agent nào đó hoạt động không đúng, nó sẽ thực hiện một số bước nào đó để phục hồi lỗi và tự khởi động lại agent đó.
3. Cơ sở hạ tầng của Agent
Trong phần này, chúng ta sẽ xem xét và giải thích từng thành phần của OAA một cách chi tiết, để giúp những người phát triển OAA có được cái nhìn căn bản nhất về sự hoạt động của các thành phần trong OAA.
3.1. Thư viện Agent
Thư viện agent cung cấp những hàm chức năng căn bản nhất cho mọi agent trong OAA, bao gồm cả agent facilitator. Thư viện này đã được chuyển sang nhiều ngôn ngữ khác nhau và một phần của thư viện này chính là cơ chế cài đặt của mỗi agent. Lập trình viên cần phải gọi các hàm được cung cấp trong thư viện, khai báo các biến, định nghĩa là các hàm callback đã có sẵn trong thư viện. Trong phần này, ta mô tả qua một vài thành phần cơ bản của thư viện agent và một số cách sử dụng thư viện chung cho mọi agent.
3.2. Giao thức giao vận Agent
Hiện nay, mọi hệ thống dựa trên mô hình OAA đều sử dụng TCP/IP như là một giao thức vận chuyển. TCP được cài trên nhiều hệ điều hành khác nhau như Unix, Macintosh, Dos, MS Windows .. nên việc sử dụng TCP/IP là rất linh hoạt, thuận tiện cho việc tương tác giữa các agent chạy trên các nền khác nhau.
Tuy nhiên, OAA được thiết kế sao cho nó có thể cho phép sử dụng nhiều giao thức giao vận khác nữa. Điều này được cài đặt trong API với một lớp giao vận. Lớp giao vận là một lớp riêng, được tải riêng rẽ từ phần còn lại của một số thủ tục của thư viện. Những thủ tục trong lớp giao vận có tên với tiền tố com_. Mọi việc truyền thông giữa các agent thông qua các thủ tục API này.
3.3. Ngôn ngữ ICL
Như đã nói ở trên, trong phần truyền thông giữa các agent, các biểu thức ICL được sử dụng để khai báo các solvable, sự kiện, yêu cầu sử dụng dịch vụ, đáp ứng dịch vụ, chia sẻ dữ liệu thành phần.
Một số framework agent được điều khiển bằng lời nói như là FIPA hay KQML, thì ICL còn có cả một lớp giao thức đối thoại. Lớp đối thoại của ICL được định nghĩa bởi các kiểu sự kiện, kết hợp với danh sách các tham số để tổ chức thành kiểu các sự kiện. Nội dung của lớp này bao gồm cả kết quả trả về, cơ chế kích hoạt, dữ liệu thành phần có thể được nhúng vào các sự kiện khác nhau.
Ta hoàn toàn có thể nhúng thêm nội dung hàm thành phần viết bằng một ngôn ngữ khác vào các sự kiện của ICL, đây là một ưu điêm rất lớn của ICL. Với cơ chế này, không chỉ cung cấp cho facilitator thêm nhiều thông tin về bản chất của các yêu cầu từ các agent khác mà còn giúp facilitator phân loại các yêu cầu
3.3.1. Khai báo các solvable trong agent
Mỗi agent tham gia vào hệ thống OAA phải khai báo, đưa ra các khả năng của nó, các dịch vụ nó có thể cung cấp thông qua ngôn ngữ ICL. Điều đó thiết lập một giao diện ở mức cao giữa các agent, giao diện này được facilitator sử dụng trong việc liên kết, truyền thông giữa các agent để đáp ứng các yêu cầu của các agent khác.
Một yếu tố quan trọng trong khả năng của agent chính là kiểu (type) cung cấp, có thể là khả năng cung cấp thủ tục (procedure solvable), dữ liệu (data solvable) hoặc cơ chế kích hoạt (trigger). Khả năng cung cấp thủ tục và dữ liệu có thể được các agent khác sử dụng một cách trực tiếp (thường thì các agent đó sử dụng khả năng này bằng cách gọi thủ tục oaa_Solve trong thư viện).
Ở mức khái niệm, một solvable cung cấp thủ tục (procedure) thực hiện một hành động nào đó, còn solvable cung cấp dữ liệu (data) lưu giữ một tập các công việc. Ví dụ: Ta tạo một agent cho hệ thống mail, thì solvable cung cấp thủ tục là việc gửi message tới người sử dụng, liệt kê các thông điệp đã được gửi đến theo một chủ đề nào đó hay hiển thị một thông điệp nào đó lên màn hình, còn solvable cung cấp dữ liệu tương ứng với mỗi quan hệ đó với cơ sở dữ liệu hiện tại. Thường thì solvable cung cấp dữ liệu được sử dụng để cung cấp kho dữ liệu dùng chung.
Solvable kích hoạt (trigger) không thể truy nhập trực tiếp từ các agent khác, chúng được sử dụng gián tiếp thông qua việc thiết lập bộ kích hoạt công việc (task trigger) của chúng. Khả năng này là để phục vụ cho các sự kiện xảy ra dưới một điều kiện đặc biệt. Ví dụ: một email agent có thể khai báo một khả năng kích hoạt nhằm kiểm tra các thư đến.
Chú ý rằng có rất nhiều kiểu kích hoạt, task trigger chỉ là một kiểu trong đó. Một agent khai báo các khả năng của chúng bằng cách sử dụng oaa_Declare và oaa_Undeclare trong thư viện
3.3.2. Sự kiện
Việc truyền thông giữa các agent diễn ra dưới dạng các sự kiện, ngay cả hoạt động và cấu trúc của mỗi agent cũng được tổ chức thành kiểu các sự kiện. Trong việc đối thoại giữa các agent, điều đó có thể giúp ích cho việc nhìn nhận các sự kiện này như là những thông điệp. Phần lớn các sự kiện cần thiết cơ bản đều đã có trong thư viện nên không cần các lập trình viên viết lại, ta có thể xem trong oaa_Solve và oaa_AddTrigger.
Ví dụ: lời gọi oaa_Solve(Goal, Params) trong một agent A nào đó, kết quả trả về có dạng ev_solve(GoalId, Goal, Params) đi từ A tới facilitator và trả về thông điệp có dạng ev_solved(GoalId, Requestees, Solvers, Goal, Params, Solutions).
Do các sự kiện này đã được tự động xử lí thông suốt, nên các lập trình viên không cần quan tấm đến chúng một cách chi tiết nữa.
3.3.3. Yêu cầu dịch vụ
Một agent yêu cầu dịch vụ bằng cách gửi mục tiêu cần đạt được của nó tới facilitator. Mỗi yêu cầu có thể có một hay nhiều khả năng giải quyết.
Thư viện OAA cung cấp cho mỗi agent một cơ chế truy nhập đơn thống nhất để có thể yêu cầu dịch vụ từ các agent khác, xem trong oaa_Solve.
oaa_ Solve cung cấp một số các tham số đầu vào khác nhau, các tham số này có thể được dùng để thay đổi yêu cầu mong muốn từ facilitator, hoặc là yêu cầu dịch vụ từ agent khác. Đặc biệt, tham số địa chỉ có phép xác định rõ lời tới một hay nhiều agents. Các agent có thể sử dụng oaa_Solve một cách cục bộ bằng cách đưa vào tham số đầu vào của agent gọi chính địa chỉ của nó.
3.3.4. Dữ liệu thành phần
Dữ liệu thành phần được trả về từ những câu truy vấn yêu cầu dữ liệu. Trong một vài trường hợp, những dữ liệu thành phần này có thể được fully instantiated hoặc là partially instantied.
3.3.5. Cơ chế kích hoạt
OAA trigger cung cấp một cơ chế chung cho các agent có thể xác định rõ các điều kiện để một sự kiện có thể xảy ra. Mỗi agent có thể cài đặt trigger môt cách cục bộ (trên chính nó) hoặc là từ xa (trên facilitator hoặc một agent đồng cấp nào đó). Trigger được chia làm 4 loại: Communication, data, task và time trigger.
Triggers liên hệ với solvable theo 2 cách: Cách 1, tất cả các trigger đều được cài đặt như là data solables, khai báo cho mọi agent. Cách 2, task trigger yêu cầu khai báo một trigger solvable.
3.3.6. Danh sách tham số
Rất nhiều thành phần của thư viện như là solvable, events, procedures .. nhận danh sách tham số đầu vào làm đối số. Ví dụ : khai báo một solvable data với danh sách tham số như sau :
[type(data), single_value(true), persistent(true)]
Nhiều tham số có giá trị mặc định. Khi ta muốn một tham số có giá trị mặc định thì không cần thiết phải xác định toàn bộ đối số.
Một tham số boolean với giá trị true có thể bỏ qua được. Ví dụ: danh sách tham số dưới đây có thể viết như sau:
[type(data), single_value, persistent]
Để lấy giá trị của một tham số từ danh sách các tham số, ta gọi hàm icl_GetParamValue. Ví dụ, trong ngôn ngữ Prolog, có thể lấy giá trị của tham số như sau:
icl_GetParamValue(from(Requestor), Params)
3.3.7. Tên và địa chỉ của Agent
Mỗi agent có thể có một hay nhiều server connection và một hay nhiều client connection. Thường thi facilitator duy trì một kết nối đơn, và mỗi client agent duy trì một kết nối đơn tới facilitator của agent nó.
Mọi agent (bao gồm cả facilitator) đều có tên đại diện, địa chỉ đầy đủ, địa chỉ cục bộ với mỗi kết nối mở client và mỗi kết nối mở server. Quy cách về địa chỉ đầy đủ phụ thuộc vào giao thức giao vận ta sử dụng. Nếu sử dụng TCP/IP, ta sẽ khai báo địa chỉ như sau: addr(tcp(Host, Port ), còn địa chỉ của agent client sẽ ghi như sau: addr( tcp(Host, Port), LocalID).
3.4. Sự kiện lặp
Mọi hành động của các agent đều có cấu trúc xoay quanh một sự kiện lặp, sự kiện này được khởi tạo khi một agent được gọi (thường thì đó là lời gọi của một agent tới các hàm thư viện agent oaa_MainLoop). Việc gọi sự kiện lặp là để lặp lại quá trình kiểm tra các sự kiện trong hàng đợi của agent.
3.5. Các thành phần lập trình cơ bản
Trong mỗi agent có một số thành phần lập trình cơ bản dùng để định nghĩa một số quy tắc ứng xử của agent khi tham gia vào OAA, những thông tin cần thiết được cung cấp từ thư viện agent sẽ giúp cho agent thực hiện các hành động khác nhau.
Declarations of solvables. Mỗi agent cung cấp khả, gửi tới facilitator một danh sách các dịch vụ mà agent đó cung cấp. Facilitator sử dụng thông tin này để đáp ứng lại các yêu cầu cung cấp dịch vụ. Các agent đăng kí dịch vụ mình cung cấp bằng cách truyền tham số vào oaa_Register. Sau khi đăng kí, agent có thể thay đổi khai báo bằng cách sử dụng oaa_Declare, oaa_Undeclare, và oaa_Redeclare.
Request handlers. Với mỗi khả năng giải quyết của theo kiểu gọi hàm, agent phải cung cấp một thủ tục callback hoặc định nghĩa một sự kiện callback app_do mặc định.
oaa_SetTimeout(TimeoutDelay). Với việc gọi thủ tục thư viện này, agent có thể đưa ra thời gian timeout khi chờ đợi sự kiện quay vòng.
app_idle callback. Cho phép một agent định nghĩa ra một thủ tục để agent khác gọi khi không có sự kiện này trong hàng đợi và xảy ra timeout. Nếu muốn viết một thủ tụcnhư thế, ta phải điền thêm thông tin vào libarary bằng cách gọi oaa_RegisterCallback oaa_RegisterCallback(app_idle, ProcedureName)
3.6. Truyền tham số và cách cài đặt
Một số các tham số đầu vào có thể được sử dụng khi yêu cầu lời gọi tới facilitator, một số tham số đó được sử dụng với các agent client. Tham số đầu vào có thể được truyền đạt bằng một trong 3 cách sau:
on the command line
in environment variables
in a setup file.
Ví dụ: để báo cho client agent (hoặc facilitator) biết rằng nó nên kết nối tới parent facilitator trên host 'mymachine.ai.sri.com' và cổng 3345, có thể làm một trong những cách sau:
Dùng các tham số dòng lệnh:
fac -oaa_connect "tcp('mymachine.ai.sri.com', 3345)" ...
Thiết lập biến môi trường OAA_CONNECT để chứa xâu sau:
tcp('mymachine.ai.sri.com', 3345)
Đưa vào trong file setup dòng sau:
oaa_connect( tcp('mymachine.ai.sri.com', 3345)).
3.6.1. File setup
Thư viện agent cần phải load một đoạn mã chứa trong setup file khi nó thực thi, ta làm như sau :
Đường dẫn file được cho trên dòng lệnh (hay trong một biến môi trường) thì sử dụng -setup_file (or SETUP_FILE)
setup.pl nằm trong thư mục hiện hành của agent.
setup.pl nằm trong "home directory" của người dùng chạy agent (trong UNIX, ~/setup.pl; trong Windows NT, %HOMEDRIVE%%HOMEPATH%\setup.pl; trong Windows 95/98, /setup.pl của ổ đĩa hiện hành).
setup.pl trong thư mục gốc ("/" trong UNIX, "C:\" trong Windows).
3.6.2. Các tham số Invocation của Facilitator
Facilitator có thể nhận biết các tham số đầu vào. Trong mỗi trường hợp (trừ setup_file), tham số nên được đưa vào từ dòng lệnh, trong biến môi trường hoặc từ setup file.
3.6.3. Các tham số Invocation của Client Agent
Các tham số Invocation của các Client agent như sau:
• setup_file
Các đoạn mã thư viện kiểm tra điều này bất cứ khi nào oaa_ResolveVariables được gọi.
• -oaa_connect
Tham số này chỉ cho agent biết địa chỉ mạng dùng để kết nối tới một facilitator. Các đoạn mã của thư viện sẽ kiểm tra điều này bất cứ khi nào com_Connect được gọi.
• -oaa_listen
Tham số này chỉ cho các agent biết để mở một socket “chờ”, và địa chỉ mạng dùng cho socket này. Các đoạn mã của thư viện sẽ kiểm tra điều này bất cứ khi nào oaa_SetupCommunication được gọi.
Chương trình:
Chương trình lấy thông số của ổ đĩa cứng và thời gian hệ thống
// $Id: AddClient.c,v 1.3 2002/09/25 21:43:00 mjohnson Exp $
#include
#include
#include
#include
#include
#include "SysInfor.h"
#include
#include
//#include
//#include
#define IDT_TIMER 1
char AgentName[20];
int updatehost_Callback(ICLTerm* goal,ICLTerm* params,ICLTerm* solutions);
int setup_oaa_connection(int argc, char *argv[]);
bool UpdateDatabase();
VOID CALLBACK MyTimerProc(
HWND hwnd, // handle of window for timer messages
UINT message, // WM_TIMER message
UINT idTimer, // timer identifier
DWORD dwTime); // current system time
int main(int argc, char *argv[]) {
UINT nTime=60000;
if(argc!=1)
{
if(argc!=2)
{
printf("Usage : ExecAgent nTime(s)\n");
return EXIT_FAILURE;
}
nTime=atoi(argv[1])*1000;
}
UINT uResult;
uResult=SetTimer(NULL, // handle of main window
IDT_TIMER, // timer identifier
nTime, // 60-second interval
(TIMERPROC) MyTimerProc); // timer callback
if (uResult == 0)
{
printf("No timer is available.");
}
else
printf("\nTimer ready.\n");
//***********************************
strcpy(AgentName,"ExecAgent");
// Initialize the OAA library.
oaa_Init(argc, argv);
// Setup the connection of this agent to the Facilitator.
// See setup_oaa_connection() definition below.
if (!setup_oaa_connection(argc, argv)) {
printf("Could not setup OAA connections...exiting.\n");
return EXIT_FAILURE;
}
//**********************************
UpdateDatabase();
//**********************************
//oaa_MainLoop(TRUE);
MSG msg;
BOOL bRet;
while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
{
if (bRet == -1)
{
// handle the error and possibly exit
printf("Timer error !");
return 1;
}
else
{
if(msg.message==WM_TIMER)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
// Disconnect and exit.
oaa_Disconnect(NULL, NULL);
return EXIT_SUCCESS;
}
/**
* Setups up the the connection between this agent
* and the facilitator.
* @param argc passed in but not used in this implementation
* @param argv passed in but not used in this implementation
* @return TRUE if successful
*/
int setup_oaa_connection(int argc, char *argv[]) {
ICLTerm* mySolvablesAsTerm = icl_NewList(NULL);
icl_AddToList(mySolvablesAsTerm,
icl_NewTermFromString("solvable(updatehost(Result), [callback(updatehost)])"),
TRUE);
// Use this OAA convenience function to setup communications.
if (!oaa_SetupCommunication(AgentName)) {
printf("Could not connect\n");
return FALSE;
}
// Register solvables with the Facilitator.
// This is a "pure client" agent and therefore
// it has no solvables.
// The string "parent" represents the Facilitator.
//mySolvablesAsTerm = icl_NewList(NULL);
if (!oaa_Register("parent", AgentName, mySolvablesAsTerm)) {
printf("Could not register\n");
return FALSE;
}
//Register callback function
if (!oaa_RegisterCallback("updatehost",updatehost_Callback)) {
printf("Could not register addhost callback\n");
return FALSE;
}
// Clean up.
icl_Free(mySolvablesAsTerm);
// Declare agent "ready".
oaa_Ready(TRUE);
return TRUE;
}
VOID CALLBACK MyTimerProc(
HWND hwnd, // handle of window for timer messages
UINT message, // WM_TIMER message
UINT idTimer, // timer identifier
DWORD dwTime) // current system time
{
UpdateDatabase();
}
bool UpdateDatabase()
{
ICLTerm *El1 = NULL;
ICLTerm *El2 = NULL;
ICLTerm *El3 = NULL;
ICLTerm *El4 = NULL;
ICLTerm *goal = NULL;
ICLTerm *in_params = NULL;
ICLTerm *out_params = NULL;
ICLTerm *solutions = NULL;
int solve_success = 0;
char *s1=new char[255],*s3=new char[255];
char *s2=new char[255];
//Host
//GetHostInfor(&s1,&s2,&s3);
//unsigned long nSize;
//GetComputerName(s1,&nSize);
printf("\n************************************************\n Updating database...\n");
gethostname(s1,255);
GetSystemVersion(&s2);
strcpy(s3,"No description");
El1=icl_NewStr(s1);
El2=icl_NewStr(s2);
El3=icl_NewStr(s3);
goal = icl_NewStruct("addhost", 3, El1, El2, El3);
in_params = icl_NewList(NULL);
solve_success = oaa_Solve(goal, in_params, &out_params, &solutions);
if (solve_success) {
printf("\nUpdate host information successful");
}
else {
printf("\nThere was an OAA failure; no solution found for addhost.");
}
icl_Free(goal);
icl_Free(in_params);
icl_Free(out_params);
icl_Free(solutions);
//CPU
char *s4=new char[255];
GetCPUInfor(&s3,&s4);
strcpy(s2,"CPU");
El1=icl_NewStr(s1);
El3=icl_NewStr(s3);
El4=icl_NewStr(s4);
El2=icl_NewStr(s2);
goal = icl_NewStruct("addobject", 4, El1, El2, El3,El4);
in_params = icl_NewList(NULL);
solve_success = oaa_Solve(goal, in_params, &out_params, &solutions);
if (solve_success) {
printf("\nUpdate CPU information successful");
}
else {
printf("\nThere was an OAA failure; no solution found for addobject.");
}
icl_Free(goal);
icl_Free(in_params);
icl_Free(out_params);
icl_Free(solutions);
//System memory
GetSysMemInfor(&s3,&s4);
strcpy(s2,"System Memory");
El1=icl_NewStr(s1);
El3=icl_NewStr(s3);
El4=icl_NewStr(s4);
El2=icl_NewStr(s2);
goal = icl_NewStruct("addobject", 4, El1, El2, El3,El4);
in_params = icl_NewList(NULL);
solve_success = oaa_Solve(goal, in_params, &out_params, &solutions);
if (solve_success) {
printf("\nUpdate system memory information successful");
}
else {
printf("\nThere was an OAA failure; no solution found for addobject.");
}
icl_Free(goal);
icl_Free(in_params);
icl_Free(out_params);
icl_Free(solutions);
//Network adapters
PIP_ADAPTER_INFO pAdapterInfo; // buffer to receive data
pAdapterInfo=new IP_ADAPTER_INFO[10];
ULONG pOutBufLen =sizeof(IP_ADAPTER_INFO)*10;
int nResult=GetAdaptersInfo(pAdapterInfo,&pOutBufLen);
if(nResult==ERROR_SUCCESS)
{
PIP_ADAPTER_INFO p=pAdapterInfo;
//IP_ADDR_STRING IpAddr;
char st3[255],st2[255],st4[255];
while( p!=NULL)
{
if(!p)
break;
strcpy(st2,"unknown");
if(p->AdapterName)
strcpy(st2,p->AdapterName);
else
strcpy(st2,"unknown");
if((p->CurrentIpAddress)&&(p->CurrentIpAddress->IpAddress).String)
strcpy(st3,(p->CurrentIpAddress->IpAddress).String);
else
strcpy(st3,"unknown");
if(p->Description)
strcpy(st4,p->Description);
else
strcpy(st4,"unknown");
sprintf(s2,"Network Adapter %u",p->Index);
sprintf(s3,"\tNetwork adapter information:\tAdapter name :%s\tIP Address :%s",
st2,st3);
if((p->DhcpEnabled))
sprintf(st3,"\tDHCP server :%s",(p->DhcpServer.IpAddress).String);
else
sprintf(st3,"\tDHCP server : unknown");
strcat(s3,st3);
//memcpy(st3,p->Address,p->AddressLength);
//st3[p->AddressLength+1]='\0';
//printf(st3);
sprintf(s4,"\tDescription :%s",st4);
//printf(s3);
El1=icl_NewStr(s1);
El3=icl_NewStr(s3);
El4=icl_NewStr(s4);
El2=icl_NewStr(s2);
goal = icl_NewStruct("addobject", 4, El1, El2, El3,El4);
in_params = icl_NewList(NULL);
solve_success = oaa_Solve(goal, in_params, &out_params, &solutions);
if (solve_success) {
printf("\nUpdate %s information successful",s2);
}
else {
printf("\nThere was an OAA failure; no solution found for addobject.");
}
icl_Free(goal);
icl_Free(in_params);
icl_Free(out_params);
icl_Free(solutions);
p=p->Next;
}
}
else
{
switch(nResult)
{
case ERROR_BUFFER_OVERFLOW:
printf("\nOverflow");
break;
case ERROR_INVALID_PARAMETER:
break;
case ERROR_NO_DATA:
break;
case ERROR_NOT_SUPPORTED:
break;
default:
break;
}
}
//System time
GetSysTimeInfor(&s3,&s4);
strcpy(s2,"System Local Time");
El1=icl_NewStr(s1);
El3=icl_NewStr(s3);
El4=icl_NewStr(s4);
El2=icl_NewStr(s2);
goal = icl_NewStruct("addobject", 4, El1, El2, El3,El4);
in_params = icl_NewList(NULL);
solve_success = oaa_Solve(goal, in_params, &out_params, &solutions);
if (solve_success) {
printf("\nUpdate system time information successful");
}
else {
printf("\nThere was an OAA failure; no solution found for addobject.");
}
icl_Free(goal);
icl_Free(in_params);
icl_Free(out_params);
icl_Free(solutions);
//Keyboard
GetKeyboardInfor(&s3,&s4);
strcpy(s2,"Keyboard");
El1=icl_NewStr(s1);
El3=icl_NewStr(s3);
El4=icl_NewStr(s4);
El2=icl_NewStr(s2);
goal = icl_NewStruct("addobject", 4, El1, El2, El3,El4);
in_params = icl_NewList(NULL);
solve_success = oaa_Solve(goal, in_params, &out_params, &solutions);
if (solve_success) {
printf("\nUpdate keyboard information successful");
}
else {
printf("\nThere was an OAA failure; no solution found for addobject.");
}
icl_Free(goal);
icl_Free(in_params);
icl_Free(out_params);
icl_Free(solutions);
//Mouse
GetMouseInfor(&s3,&s4);
strcpy(s2,"Mouse");
El1=icl_NewStr(s1);
El3=icl_NewStr(s3);
El4=icl_NewStr(s4);
El2=icl_NewStr(s2);
goal = icl_NewStruct("addobject", 4, El1, El2, El3,El4);
in_params = icl_NewList(NULL);
solve_success = oaa_Solve(goal, in_params, &out_params, &solutions);
if (solve_success) {
printf("\nUpdate mouse information successful");
}
else {
printf("\nThere was an OAA failure; no solution found for addobject.");
}
icl_Free(goal);
icl_Free(in_params);
icl_Free(out_params);
icl_Free(solutions);
//Power
GetSysPowerInfor(&s3,&s4);
strcpy(s2,"System Power");
El1=icl_NewStr(s1);
El3=icl_NewStr(s3);
El4=icl_NewStr(s4);
El2=icl_NewStr(s2);
goal = icl_NewStruct("addobject", 4, El1, El2, El3,El4);
in_params = icl_NewList(NULL);
solve_success = oaa_Solve(goal, in_params, &out_params, &solutions);
if (solve_success) {
printf("\nUpdate system power information successful");
}
else {
printf("\nThere was an OAA failure; no solution found for addobject.");
}
icl_Free(goal);
icl_Free(in_params);
icl_Free(out_params);
icl_Free(solutions);
//Logical Drivers
char *str=new char[255];
GetLogicalDriveStrings(strlen(str),str);
//Process string
//int i;
char str1[4];
while(1)
{
if(str[0]=='\0') break;
strcpy(str1,str);
str=str+4;
GetLogicalDriversInfor(str1,&s3,&s4);
//
//printf("\n%s\n%s",s3,s4);
//
sprintf(s2,"Logical Drive %c",str1[0]);
El1=icl_NewStr(s1);
El3=icl_NewStr(s3);
El4=icl_NewStr(s4);
El2=icl_NewStr(s2);
goal = icl_NewStruct("addobject", 4, El1, El2, El3,El4);
in_params = icl_NewList(NULL);
solve_success = oaa_Solve(goal, in_params, &out_params, &solutions);
if (solve_success) {
printf("\nUpdate logical driver %c information successful",str1[0]);
}
else {
printf("\nThere was an OAA failure; no solution found for addobject.");
}
icl_Free(goal);
icl_Free(in_params);
icl_Free(out_params);
icl_Free(solutions);
}
//Process Information
DWORD aProcesses[1024], cbNeeded, cProcesses;
unsigned int i;
if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
return false;
// Calculate how many process identifiers were returned.
cProcesses = cbNeeded / sizeof(DWORD);
// Print the name and process identifier for each process.
for ( i = 0; i < cProcesses; i++ )
{
//PrintProcessNameAndID( aProcesses[i] );
GetProcessInfor(aProcesses[i],&s3,&s4);
sprintf(s2,"Process %u",aProcesses[i]);
El1=icl_NewStr(s1);
El3=icl_NewStr(s3);
El4=icl_NewStr(s4);
El2=icl_NewStr(s2);
goal = icl_NewStruct("addobject", 4, El1, El2, El3,El4);
in_params = icl_NewList(NULL);
solve_success = oaa_Solve(goal, in_params, &out_params, &solutions);
if (solve_success) {
printf("\nUpdate process %u information successful",aProcesses[i]);
}
else {
printf("\nThere was an OAA failure; no solution found for addobject.");
}
icl_Free(goal);
icl_Free(in_params);
icl_Free(out_params);
icl_Free(solutions);
}
return true;
}
int updatehost_Callback(ICLTerm* goal,ICLTerm* params,ICLTerm* solutions)
{
ICLTerm *R1 = NULL;
ICLTerm *solution ;
printf("\nUpdating host ......");
UpdateDatabase();
R1=icl_NewStr("Update successfull.");
// Prepare a struct that contains the satisfied goal.
solution = icl_NewStruct("updatehost", 1, R1);
// Add this solution to the list of solutions.
// This will return TRUE if the add is successful.
return icl_AddToList(solutions, solution, TRUE);
//return EXIT_SUCCESS;
}
Các file đính kèm theo tài liệu này:
- DAN345.doc