package Net::UPnP::Service; #----------------------------------------------------------------- # Net::Net::UPnP::Service #----------------------------------------------------------------- use strict; use warnings; use Net::UPnP; use Net::UPnP::ActionResponse; use vars qw($_DEVICE $_DEVICE_DESCRIPTION $SERVICETYPE $SERVICEID $SCPDURL $CONTROLURL $EVENTSUBURL); $_DEVICE = 'device'; $_DEVICE_DESCRIPTION = 'device_description'; $SERVICETYPE = 'serviceType'; $SERVICEID = 'serviceId'; $SCPDURL = 'SCPDURL'; $CONTROLURL = 'controlURL'; $EVENTSUBURL = 'eventSubURL'; #------------------------------ # new #------------------------------ sub new { my($class) = shift; my($this) = { $Net::UPnP::Service::_DEVICE => undef, $Net::UPnP::Service::_DEVICE_DESCRIPTION => '', }; bless $this, $class; } #------------------------------ # device #------------------------------ sub setdevice() { my($this) = shift; if (@_) { $this->{$Net::UPnP::Service::_DEVICE} = $_[0]; } } sub getdevice() { my($this) = shift; $this->{$Net::UPnP::Service::_DEVICE}; } #------------------------------ # device description #------------------------------ sub setdevicedescription() { my($this) = shift; $this->{$Net::UPnP::Service::_DEVICE_DESCRIPTION} = $_[0]; } sub getdevicedescription() { my($this) = shift; my %args = ( name => undef, @_, ); if ($args{name}) { unless ($this->{$Net::UPnP::Service::_DEVICE_DESCRIPTION} =~ m/<$args{name}>(.*)<\/$args{name}>/i) { return ''; } return $1; } $this->{$Net::UPnP::Service::_DEVICE_DESCRIPTION}; } #------------------------------ # getservicetype #------------------------------ sub getservicetype() { my($this) = shift; $this->getdevicedescription(name => $Net::UPnP::Service::SERVICETYPE); } #------------------------------ # getserviceid #------------------------------ sub getserviceid() { my($this) = shift; $this->getdevicedescription(name => $Net::UPnP::Service::SERVICEID); } #------------------------------ # getscpdurl #------------------------------ sub getscpdurl() { my($this) = shift; $this->getdevicedescription(name => $Net::UPnP::Service::SCPDURL); } #------------------------------ # getcontrolurl #------------------------------ sub getcontrolurl() { my($this) = shift; $this->getdevicedescription(name => $Net::UPnP::Service::CONTROLURL); } #------------------------------ # geteventsubrul #------------------------------ sub geteventsubrul() { my($this) = shift; $this->getdevicedescription(name => $Net::UPnP::Service::EVENTSUBURL); } #------------------------------ # geteventsubrul #------------------------------ sub postcontrol() { my($this) = shift; my ($action_name, $action_arg) = @_; my ( $dev, $location_url, $url_base, $ctrl_url, $service_type, $soap_action, $soap_content, $arg_name, $arg_value, $post_addr, $post_port, $post_path, $http_req, $post_res, $action_res, $key, ); $action_res = Net::UPnP::ActionResponse->new(); $dev = $this->getdevice(); $location_url = $dev->getlocation(); $url_base = $dev->geturlbase(); $ctrl_url = $this->getcontrolurl(); #print "$location_url\n"; #print "$url_base\n"; #print "$ctrl_url\n"; unless ($ctrl_url =~ m/http:\/\/(.*)/i) { if (0 < length($url_base)) { $ctrl_url = $url_base . $ctrl_url; } else { if ($location_url =~ m/http:\/\/([0-9a-z.]+)[:]*([0-9]*)\/(.*)/i) { if (defined($3) && 0 < length($3)) { $ctrl_url = "http:\/\/" . $1 . ":" . $2 . $ctrl_url; } else { $ctrl_url = "http:\/\/" . $1 . ":" . $2 . "\/" . $ctrl_url; } } else { $ctrl_url = $location_url . $ctrl_url; } } } #print "$ctrl_url\n"; unless ($ctrl_url =~ m/http:\/\/([0-9a-z.]+)[:]*([0-9]*)\/(.*)/i) { #print "Invalid URL : $ctrl_url\n"; $post_res = Net::UPnP::HTTPResponse->new(); $action_res->sethttpresponse($post_res); return $action_res; } $post_addr = $1; $post_port = $2; $post_path = "\/" . $3; #$post_path = $this->getcontrolurl(); $service_type = $this->getservicetype(); $soap_action = "\"" . $service_type . "#" . $action_name . "\""; $soap_content = <<"SOAP_CONTENT"; \t \t\t SOAP_CONTENT if (ref $action_arg) { while (($arg_name, $arg_value) = each (%{$action_arg} ) ) { if (length($arg_value) <= 0) { $soap_content .= "\t\t\t<$arg_name \/>\n"; next; } $soap_content .= "\t\t\t<$arg_name>$arg_value<\/$arg_name>\n"; } } $soap_content .= <<"SOAP_CONTENT"; \t\t \t SOAP_CONTENT $http_req = Net::UPnP::HTTP->new(); $post_res = $http_req->postsoap($post_addr, $post_port, $post_path, $soap_action, $soap_content); $action_res->sethttpresponse($post_res); return $action_res; } 1; __END__ =head1 NAME Net::UPnP::Service - Perl extension for UPnP. =head1 SYNOPSIS use Net::UPnP::ControlPoint; my $obj = Net::UPnP::ControlPoint->new(); @dev_list = $obj->search(st =>'upnp:rootdevice', mx => 3); $devNum= 0; foreach $dev (@dev_list) { $device_type = $dev->getdevicetype(); if ($device_type ne 'urn:schemas-upnp-org:device:MediaServer:1') { next; } print "[$devNum] : " . $dev->getfriendlyname() . "\n"; unless ($dev->getservicebyname('urn:schemas-upnp-org:service:ContentDirectory:1')) { next; } $condir_service = $dev->getservicebyname('urn:schemas-upnp-org:service:ContentDirectory:1'); unless (defined(condir_service)) { next; } %action_in_arg = ( 'ObjectID' => 0, 'BrowseFlag' => 'BrowseDirectChildren', 'Filter' => '*', 'StartingIndex' => 0, 'RequestedCount' => 0, 'SortCriteria' => '', ); $action_res = $condir_service->postcontrol('Browse', \%action_in_arg); unless ($action_res->getstatuscode() == 200) { next; } $actrion_out_arg = $action_res->getargumentlist(); unless ($actrion_out_arg->{'Result'}) { next; } $result = $actrion_out_arg->{'Result'}; while ($result =~ m/(.*?)<\/dc:title>/sgi) { print "\t$1\n"; } $devNum++; } =head1 DESCRIPTION The package is used a object of UPnP service. =head1 METHODS =over 4 =item B - get the device. $description = $service->getdevice(); Get the parent device of the service. =item B - get the service description of the device description. $description = $service->getdevicedescription( name => $name # undef ); Get the service description of the device description. The function returns the all description when the name parameter is not specified, otherwise return a value the specified name. =item B - get the service type. $service_type = $service->getservicetype(); Get the service type. =item B - get the service id. $service_id = $service->getserviceid(); Get the service id. =item B - post a control action. $action_res = $service->postcontrol($action_name, \%action_arg); Post a control action to the device, and return L. =back =head1 SEE ALSO L =head1 AUTHOR Satoshi Konno skonno@cybergarage.org CyberGarage http://www.cybergarage.org =head1 COPYRIGHT AND LICENSE Copyright (C) 2005 by Satoshi Konno It may be used, redistributed, and/or modified under the terms of BSD License. =cut